#ifndef REMOTING_HOST_LINUX_PIPEWIRE_MOUSE_CURSOR_CAPTURER_H_
#define REMOTING_HOST_LINUX_PIPEWIRE_MOUSE_CURSOR_CAPTURER_H_
#include <memory>
#include <optional>
#include "base/containers/flat_map.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "remoting/host/desktop_display_info.h"
#include "remoting/host/desktop_display_info_monitor.h"
#include "remoting/host/linux/capture_stream.h"
#include "remoting/host/linux/capture_stream_manager.h"
#include "remoting/proto/coordinates.pb.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 {
class PipewireMouseCursorCapturer : public CaptureStreamManager::Observer,
public CaptureStream::CursorObserver {
public:
class Observer : public base::CheckedObserver {
public:
using Subscription = base::ScopedClosureRunner;
virtual void OnCursorShapeChanged(PipewireMouseCursorCapturer* capturer) {}
virtual void OnCursorPositionChanged(
PipewireMouseCursorCapturer* capturer) {}
};
explicit PipewireMouseCursorCapturer(
std::unique_ptr<DesktopDisplayInfoMonitor> display_info_monitor,
base::WeakPtr<CaptureStreamManager> stream_manager);
~PipewireMouseCursorCapturer() override;
[[nodiscard]] Observer::Subscription AddObserver(Observer* observer);
std::unique_ptr<webrtc::MouseCursor> GetLatestCursor();
const std::optional<webrtc::DesktopVector>& GetLatestGlobalCursorPosition();
const std::optional<protocol::FractionalCoordinate>&
GetLatestFractionalCursorPosition();
base::WeakPtr<PipewireMouseCursorCapturer> GetWeakPtr();
private:
friend class PipewireMouseCursorCapturerTest;
struct MonitorInfo {
double scale;
int left;
int top;
int width;
int height;
};
void OnPipewireCaptureStreamAdded(
base::WeakPtr<CaptureStream> stream) override;
void OnPipewireCaptureStreamRemoved(webrtc::ScreenId screen_id) override;
void OnCursorShapeChanged(CaptureStream* stream) override;
void OnCursorPositionChanged(CaptureStream* stream) override;
void OnDisplayInfo();
void RemoveObserver(Observer* observer);
base::ObserverList<Observer> observers_ GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<webrtc::SharedDesktopFrame> latest_cursor_frame_
GUARDED_BY_CONTEXT(sequence_checker_);
webrtc::DesktopVector latest_cursor_hotspot_
GUARDED_BY_CONTEXT(sequence_checker_);
std::optional<webrtc::DesktopVector> latest_global_cursor_position_
GUARDED_BY_CONTEXT(sequence_checker_);
std::optional<protocol::FractionalCoordinate>
latest_fractional_cursor_position_ GUARDED_BY_CONTEXT(sequence_checker_);
private:
std::unique_ptr<DesktopDisplayInfoMonitor> display_info_monitor_
GUARDED_BY_CONTEXT(sequence_checker_);
CaptureStreamManager::Observer::Subscription stream_manager_subscription_
GUARDED_BY_CONTEXT(sequence_checker_);
base::flat_map<webrtc::ScreenId, CaptureStream::CursorObserver::Subscription>
stream_subscriptions_ GUARDED_BY_CONTEXT(sequence_checker_);
base::flat_map<webrtc::ScreenId, MonitorInfo> monitors_
GUARDED_BY_CONTEXT(sequence_checker_);
DesktopDisplayInfo::PixelType pixel_type_
GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<PipewireMouseCursorCapturer> weak_ptr_factory_{this};
};
}
#endif