148 lines
3.0 KiB
C++
148 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <EGL/egl.h>
|
|
|
|
#include <cstdint>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
#include <QImage>
|
|
#include <QList>
|
|
#include <QRectF>
|
|
#include <QSize>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <QVariantMap>
|
|
#include <QtQml/qqml.h>
|
|
#include <qtmetamacros.h>
|
|
|
|
#include <qwayland-wlr-layer-shell-unstable-v1.h>
|
|
#include <wayland-client-protocol.h>
|
|
|
|
#include "wallpapersurface.hpp"
|
|
|
|
namespace ZShell::internal {
|
|
|
|
class WallpaperSurface;
|
|
|
|
class WallpaperService : public QObject {
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
|
|
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REQUIRED)
|
|
Q_PROPERTY(QVariantMap crops READ crops WRITE setCrops NOTIFY cropsChanged)
|
|
|
|
public:
|
|
explicit WallpaperService(QObject* parent = nullptr);
|
|
~WallpaperService() override;
|
|
|
|
[[nodiscard]] QString path() const;
|
|
void setPath(const QString& path);
|
|
|
|
void addScreen(const QString& screen);
|
|
void removeScreen(const QString& screen);
|
|
|
|
[[nodiscard]] const QVariantMap& crops() const;
|
|
void setCrops(const QVariantMap& crops);
|
|
|
|
Q_INVOKABLE void redraw();
|
|
|
|
Q_INVOKABLE void setCrop(const QString& screen, const QVariantMap& crop);
|
|
|
|
signals:
|
|
void pathChanged();
|
|
void cropsChanged();
|
|
|
|
private:
|
|
friend class WallpaperSurface;
|
|
|
|
void bindGlobals();
|
|
static void registryGlobal(
|
|
void* data,
|
|
struct wl_registry* registry,
|
|
uint32_t name,
|
|
const char* interface,
|
|
uint32_t version);
|
|
|
|
void storeGlobal(const char* interface, void* proxy);
|
|
|
|
[[nodiscard]] bool setupGl();
|
|
[[nodiscard]] uint32_t createProgram();
|
|
|
|
void uploadImage();
|
|
|
|
bool decode(const QString& path);
|
|
|
|
bool ensureDecodeSize();
|
|
|
|
[[nodiscard]] QSize largestBufferSize();
|
|
|
|
void queue(WallpaperSurface* surface);
|
|
void queueAll();
|
|
|
|
void startDrawing();
|
|
void loop();
|
|
|
|
void present();
|
|
|
|
void drawSurface(WallpaperSurface* surface);
|
|
|
|
void wake();
|
|
|
|
[[nodiscard]] wl_event_queue* eventQueue() const { return m_queue; }
|
|
|
|
[[nodiscard]] QRectF sourceRect(
|
|
const QVariantMap& crops,
|
|
const QString& screen,
|
|
const QSize& size) const;
|
|
|
|
void start();
|
|
|
|
void addSurfaces();
|
|
void addSurface(const QString& screen);
|
|
|
|
QString m_path;
|
|
QStringList m_screens;
|
|
QVariantMap m_crops;
|
|
|
|
QImage m_image;
|
|
|
|
QSize m_sourceSize;
|
|
QSize m_decodeSize;
|
|
|
|
wl_display* m_display = nullptr;
|
|
wl_registry* m_registry = nullptr;
|
|
wl_compositor* m_compositor = nullptr;
|
|
QtWayland::zwlr_layer_shell_v1* m_layerShell = nullptr;
|
|
QtWayland::wp_viewporter* m_viewporter = nullptr;
|
|
QtWayland::wp_fractional_scale_manager_v1* m_scaleManager = nullptr;
|
|
|
|
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
|
EGLConfig m_config = nullptr;
|
|
EGLContext m_context = EGL_NO_CONTEXT;
|
|
uint32_t m_texture = 0;
|
|
uint32_t m_program = 0;
|
|
int m_sizeUniform = -1;
|
|
int m_cropUniform = -1;
|
|
|
|
QList<WallpaperSurface*> m_surfaces;
|
|
|
|
std::thread m_thread;
|
|
mutable std::recursive_mutex m_mutex;
|
|
std::vector<WallpaperSurface*> m_pending;
|
|
wl_event_queue* m_queue = nullptr;
|
|
|
|
int m_wake[2] = {-1, -1};
|
|
|
|
bool m_stop = false;
|
|
bool m_drawing = false;
|
|
|
|
bool started = false;
|
|
|
|
bool m_forceDecode = false;
|
|
bool m_imageChanged = false;
|
|
};
|
|
|
|
} // namespace ZShell::internal
|