feat: Migrate Wayland POC to Qt6 and QScreenCapture
This commit is contained in:
parent
ab4bb5a7ec
commit
7dbc11afe1
@ -9,12 +9,12 @@ set(CMAKE_BUILD_TYPE Release)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Qt5 COMPONENTS Core Gui WaylandClient REQUIRED)
|
||||
find_package(Qt6 COMPONENTS Core Gui WaylandClient Multimedia Widgets MultimediaWidgets REQUIRED)
|
||||
|
||||
# Add the Wayland POC executable
|
||||
add_executable(wayland_poc "wayland_poc.cpp")
|
||||
|
||||
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner++)
|
||||
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
|
||||
|
||||
set(WAYLAND_PROTOCOLS_DIR "${CMAKE_CURRENT_BINARY_DIR}/wayland_protocols")
|
||||
file(MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR})
|
||||
@ -38,11 +38,20 @@ add_custom_target(generate_wayland_protocols ALL
|
||||
${WAYLAND_PROTOCOLS_DIR}/zkde-screencast-unstable-v1-client-protocol.h
|
||||
)
|
||||
|
||||
target_include_directories(wayland_poc PRIVATE ${WAYLAND_PROTOCOLS_DIR})
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(PIPEWIRE REQUIRED libpipewire-0.3)
|
||||
|
||||
|
||||
|
||||
target_include_directories(wayland_poc PRIVATE ${WAYLAND_PROTOCOLS_DIR} ${PIPEWIRE_INCLUDE_DIRS})
|
||||
add_dependencies(wayland_poc generate_wayland_protocols)
|
||||
|
||||
target_link_libraries(wayland_poc
|
||||
Qt5::Core
|
||||
Qt5::Gui
|
||||
Qt5::WaylandClient
|
||||
)
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::WaylandClient
|
||||
Qt6::Multimedia
|
||||
Qt6::Widgets
|
||||
Qt6::MultimediaWidgets
|
||||
${PIPEWIRE_LIBRARIES}
|
||||
)
|
||||
|
||||
106
wayland_poc.cpp
106
wayland_poc.cpp
@ -1,99 +1,23 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#include <QGuiApplication>
|
||||
#include <QtWaylandClient/QWaylandClientExtensionTemplate>
|
||||
#include <QNativeInterface>
|
||||
|
||||
#include "qwayland-zkde-screencast-unstable-v1.h"
|
||||
|
||||
class ScreencastManager : public QObject, public QtWayland::zkde_screencast_unstable_v1
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScreencastManager(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
, QtWayland::zkde_screencast_unstable_v1(5) // Version 5 is required for stream_output
|
||||
{
|
||||
if (!isInitialized()) {
|
||||
qCritical() << "Failed to initialize zkde_screencast_unstable_v1. Make sure KWin is running and supports this protocol.";
|
||||
QCoreApplication::quit();
|
||||
return;
|
||||
}
|
||||
qDebug() << "zkde_screencast_unstable_v1 initialized.";
|
||||
|
||||
// Request a screencast of the primary screen
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
if (!screen) {
|
||||
qCritical() << "No primary screen found.";
|
||||
QCoreApplication::quit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto *waylandScreen = qobject_cast<QNativeInterface::QWaylandScreen *>(screen->nativeInterface())) {
|
||||
wl_output *output = waylandScreen->output();
|
||||
if (!output) {
|
||||
qCritical() << "Failed to get native Wayland output from QWaylandScreen.";
|
||||
QCoreApplication::quit();
|
||||
return;
|
||||
}
|
||||
// Create a stream for the output
|
||||
// The 'mode' parameter (last argument) can be Hidden = 1, Embedded = 2, Metadata = 4
|
||||
// We'll use Metadata for now.
|
||||
stream_output(output, 4); // 4 for Metadata cursor mode
|
||||
} else {
|
||||
qCritical() << "Failed to get Wayland screen interface from QScreen.";
|
||||
QCoreApplication::quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Implement the generated Wayland protocol callbacks
|
||||
void zkde_screencast_unstable_v1_stream_created(zkde_screencast_stream_unstable_v1 *stream) override
|
||||
{
|
||||
qDebug() << "Screencast stream created!";
|
||||
// Connect to the stream's signals to get the PipeWire node ID
|
||||
connect(static_cast<QtWayland::zkde_screencast_stream_unstable_v1 *>(stream), &QtWayland::zkde_screencast_stream_unstable_v1::created, this, &ScreencastManager::onStreamCreated);
|
||||
connect(static_cast<QtWayland::zkde_screencast_stream_unstable_v1 *>(stream), &QtWayland::zkde_screencast_stream_unstable_v1::closed, this, &ScreencastManager::onStreamClosed);
|
||||
connect(static_cast<QtWayland::zkde_screencast_stream_unstable_v1 *>(stream), &QtWayland::zkde_screencast_stream_unstable_v1::failed, this, &ScreencastManager::onStreamFailed);
|
||||
}
|
||||
|
||||
void zkde_screencast_unstable_v1_stream_destroyed(zkde_screencast_stream_unstable_v1 *stream) override
|
||||
{
|
||||
qDebug() << "Screencast stream destroyed.";
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onStreamCreated(quint32 node_id)
|
||||
{
|
||||
qDebug() << "PipeWire node ID:" << node_id;
|
||||
// Here you would typically use the node_id to connect to PipeWire and start processing frames.
|
||||
QCoreApplication::quit(); // For POC, quit after getting the node ID
|
||||
}
|
||||
|
||||
void onStreamClosed()
|
||||
{
|
||||
qDebug() << "Screencast stream closed.";
|
||||
QCoreApplication::quit();
|
||||
}
|
||||
|
||||
void onStreamFailed(const QString &error)
|
||||
{
|
||||
qCritical() << "Screencast stream failed:" << error;
|
||||
QCoreApplication::quit();
|
||||
}
|
||||
};
|
||||
#include <QMediaCaptureSession>
|
||||
#include <QScreenCapture>
|
||||
#include <QVideoWidget>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QApplication app(argc, argv);
|
||||
|
||||
qDebug() << "Starting Wayland POC...";
|
||||
QVideoWidget videoWidget;
|
||||
videoWidget.show();
|
||||
|
||||
ScreencastManager manager;
|
||||
QMediaCaptureSession captureSession;
|
||||
|
||||
QScreenCapture *screenCapture = new QScreenCapture(&app);
|
||||
captureSession.setScreenCapture(screenCapture);
|
||||
captureSession.setVideoOutput(&videoWidget);
|
||||
|
||||
screenCapture->start();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "wayland_poc.moc"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user