aquamarine/include/aquamarine/backend/Wayland.hpp

186 lines
7.7 KiB
C++

#pragma once
#include "./Backend.hpp"
#include "../allocator/Swapchain.hpp"
#include "../output/Output.hpp"
#include "../input/Input.hpp"
#include <hyprutils/memory/WeakPtr.hpp>
#include <wayland-client.h>
#include <wayland.hpp>
#include <xdg-shell.hpp>
#include <linux-dmabuf-v1.hpp>
#include <tuple>
namespace Aquamarine {
class CBackend;
class CWaylandBackend;
class CWaylandOutput;
class CWaylandPointer;
typedef std::function<void(void)> FIdleCallback;
class CWaylandBuffer {
public:
CWaylandBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_);
~CWaylandBuffer();
bool good();
bool pendingRelease = false;
private:
struct {
Hyprutils::Memory::CSharedPointer<CCWlBuffer> buffer;
} waylandState;
Hyprutils::Memory::CWeakPointer<IBuffer> buffer;
Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend;
friend class CWaylandOutput;
};
class CWaylandOutput : public IOutput {
public:
virtual ~CWaylandOutput();
virtual bool commit();
virtual bool test();
virtual Hyprutils::Memory::CSharedPointer<IBackendImplementation> getBackend();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void moveCursor(const Hyprutils::Math::Vector2D& coord);
virtual void scheduleFrame();
virtual Hyprutils::Math::Vector2D cursorPlaneSize();
Hyprutils::Memory::CWeakPointer<CWaylandOutput> self;
private:
CWaylandOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_);
Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend;
Hyprutils::Memory::CSharedPointer<CWaylandBuffer> wlBufferFromBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
void sendFrameAndSetCallback();
void onFrameDone();
void onEnter(Hyprutils::Memory::CSharedPointer<CCWlPointer> pointer, uint32_t serial);
// frame loop
bool frameScheduledWhileWaiting = false;
bool readyForFrameCallback = false; // true after attaching a buffer
bool frameScheduled = false;
struct {
std::vector<std::pair<Hyprutils::Memory::CWeakPointer<IBuffer>, Hyprutils::Memory::CSharedPointer<CWaylandBuffer>>> buffers;
} backendState;
struct {
Hyprutils::Memory::CSharedPointer<IBuffer> cursorBuffer;
Hyprutils::Memory::CSharedPointer<CCWlSurface> cursorSurface;
Hyprutils::Memory::CSharedPointer<CCWlBuffer> cursorWlBuffer;
uint32_t serial = 0;
Hyprutils::Math::Vector2D hotspot;
} cursorState;
struct {
Hyprutils::Memory::CSharedPointer<CCWlSurface> surface;
Hyprutils::Memory::CSharedPointer<CCXdgSurface> xdgSurface;
Hyprutils::Memory::CSharedPointer<CCXdgToplevel> xdgToplevel;
Hyprutils::Memory::CSharedPointer<CCWlCallback> frameCallback;
} waylandState;
friend class CWaylandBackend;
friend class CWaylandPointer;
};
class CWaylandKeyboard : public IKeyboard {
public:
CWaylandKeyboard(Hyprutils::Memory::CSharedPointer<CCWlKeyboard> keyboard_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_);
virtual ~CWaylandKeyboard();
virtual const std::string& getName();
Hyprutils::Memory::CSharedPointer<CCWlKeyboard> keyboard;
Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend;
private:
const std::string name = "wl_keyboard";
};
class CWaylandPointer : public IPointer {
public:
CWaylandPointer(Hyprutils::Memory::CSharedPointer<CCWlPointer> pointer_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_);
virtual ~CWaylandPointer();
virtual const std::string& getName();
Hyprutils::Memory::CSharedPointer<CCWlPointer> pointer;
Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend;
private:
const std::string name = "wl_pointer";
};
class CWaylandBackend : public IBackendImplementation {
public:
virtual ~CWaylandBackend();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
Hyprutils::Memory::CWeakPointer<CWaylandBackend> self;
private:
CWaylandBackend(Hyprutils::Memory::CSharedPointer<CBackend> backend);
void initSeat();
void initShell();
bool initDmabuf();
void createOutput(const std::string& szName);
//
Hyprutils::Memory::CWeakPointer<CBackend> backend;
std::vector<Hyprutils::Memory::CSharedPointer<CWaylandOutput>> outputs;
std::vector<Hyprutils::Memory::CSharedPointer<CWaylandKeyboard>> keyboards;
std::vector<Hyprutils::Memory::CSharedPointer<CWaylandPointer>> pointers;
std::vector<FIdleCallback> idleCallbacks;
// pointer focus
Hyprutils::Memory::CWeakPointer<CWaylandOutput> focusedOutput;
uint32_t lastEnterSerial = 0;
// dmabuf formats
std::vector<SDRMFormat> dmabufFormats;
struct {
wl_display* display = nullptr;
// hw-s types
Hyprutils::Memory::CSharedPointer<CCWlRegistry> registry;
Hyprutils::Memory::CSharedPointer<CCWlSeat> seat;
Hyprutils::Memory::CSharedPointer<CCWlShm> shm;
Hyprutils::Memory::CSharedPointer<CCXdgWmBase> xdg;
Hyprutils::Memory::CSharedPointer<CCWlCompositor> compositor;
Hyprutils::Memory::CSharedPointer<CCZwpLinuxDmabufV1> dmabuf;
Hyprutils::Memory::CSharedPointer<CCZwpLinuxDmabufFeedbackV1> dmabufFeedback;
// control
bool dmabufFailed = false;
} waylandState;
struct {
int fd = -1;
std::string nodeName = "";
} drmState;
friend class CBackend;
friend class CWaylandKeyboard;
friend class CWaylandPointer;
friend class CWaylandOutput;
friend class CWaylandBuffer;
};
};