75 lines
1.7 KiB
C++
75 lines
1.7 KiB
C++
#include "viewport.hxx"
|
|
|
|
#include <QApplication>
|
|
#include <QEvent>
|
|
#include <QGuiApplication>
|
|
|
|
Viewport::Viewport(QWidget* parent, Qt::WindowFlags f)
|
|
: QWidget(parent, f) {
|
|
setAttribute(Qt::WA_DontCreateNativeAncestors);
|
|
setAttribute(Qt::WA_NativeWindow);
|
|
setAttribute(Qt::WA_PaintOnScreen);
|
|
setAttribute(Qt::WA_NoSystemBackground);
|
|
}
|
|
|
|
Viewport::~Viewport() = default;
|
|
|
|
void Viewport::setView(RedrawArgs new_args) {
|
|
args = new_args;
|
|
update();
|
|
}
|
|
|
|
QPaintEngine* Viewport::paintEngine() const {
|
|
return nullptr;
|
|
}
|
|
|
|
bool Viewport::event(QEvent* event) {
|
|
switch (event->type()) {
|
|
case QEvent::Type::WinIdChange:
|
|
recreate();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return QWidget::event(event);
|
|
}
|
|
|
|
void Viewport::paintEvent(QPaintEvent* event) {
|
|
if (!core)
|
|
recreate();
|
|
core->redraw(args);
|
|
}
|
|
|
|
void Viewport::resizeEvent(QResizeEvent* event) {
|
|
if (!core)
|
|
return;
|
|
updateSize();
|
|
QWidget::resizeEvent(event);
|
|
}
|
|
|
|
void Viewport::recreate() try {
|
|
auto* app = qobject_cast<QGuiApplication*>(QApplication::instance());
|
|
if (!app)
|
|
throw std::runtime_error("not a GUI application (WTF?)");
|
|
|
|
auto* native = app->nativeInterface<QNativeInterface::QX11Application>();
|
|
if (!native)
|
|
throw std::runtime_error("X11 interface is not available");
|
|
|
|
auto* xcb_connection = native->connection();
|
|
std::uint32_t x11_window = winId();
|
|
|
|
fprintf(stderr, "connection %p, window %#08x\n", xcb_connection, x11_window);
|
|
|
|
core.reset();
|
|
core = BoxCore::from_xcb(xcb_connection, x11_window);
|
|
updateSize();
|
|
} catch (const std::exception& e) {
|
|
fprintf(stderr, "failed to recreate the viewport: %s", e.what());
|
|
}
|
|
|
|
void Viewport::updateSize() {
|
|
const QSize device_size = size() * devicePixelRatio();
|
|
core->configure(device_size.width(), device_size.height());
|
|
}
|