qt frontend improvements

This commit is contained in:
Wolfgang Thaller 2018-01-10 18:49:17 +01:00
parent c5af425bd7
commit cba86f86a7
4 changed files with 122 additions and 44 deletions

View File

@ -1,14 +1,16 @@
find_package(Qt5Widgets)
find_package(Qt5Gui)
if(TARGET Qt5::Widgets)
if(TARGET Qt5::Gui)
add_library(front-end-qt
host_vdriver.h
qt.h
qt.cpp
available_geometry.h
available_geometry.cpp
../x/x_keycodes.cpp
)
target_link_libraries(front-end-qt syn68k Qt5::Widgets)
target_link_libraries(front-end-qt syn68k Qt5::Gui)
target_include_directories(front-end-qt
PUBLIC .)
endif()

View File

@ -0,0 +1,88 @@
#include <QVector>
#include <QRect>
#include <QGuiApplication>
#include <QScreen>
#include <QWindow>
#include <QEventLoop>
#include <QResizeEvent>
#include "host-os-config.h"
#ifndef LINUX
/* Actually, this should be the Qt-on-anything-but-X11 case. */
QVector<QRect> getAvailableScreenGeometries()
{
QVector<QRect> geometries;
for(QScreen *screen : QGuiApplication::screens())
geometries.push_back(screen->availableGeometry());
return geometries;
}
#else
/* Figure out available screen geometries by opening
invisible maximized windows on each screen.
QScreen::availableGeometry() is documented not to work
on multi-screen X11 systems.
This version should still work even where it isn't needed.
*/
template <class F>
struct SizeTestWindow : QWindow
{
F f;
SizeTestWindow(F f)
: f(f)
{
}
void resizeEvent(QResizeEvent *evt) override
{
f(evt->size());
}
};
template <class F>
QWindow* makeSizeTestWindow(F f) { return new SizeTestWindow<F>(f); }
QVector<QRect> getAvailableScreenGeometries()
{
QVector<QWindow*> windows;
int windowCount = 0;
QEventLoop loop;
for(QScreen *screen : QGuiApplication::screens())
{
++windowCount;
QWindow *window = makeSizeTestWindow(
[&loop, &windowCount](QSize sz) {
if(sz.width() > 100 && sz.height() > 100)
{
if(--windowCount <= 0)
loop.exit();
}
}
);
windows.push_back(window);
window->setFlag(Qt::FramelessWindowHint, true);
window->setFlag(Qt::NoDropShadowWindowHint, true);
window->setOpacity(0);
window->resize(100,100);
window->setPosition(screen->availableGeometry().topLeft());
window->showMaximized();
}
loop.exec();
QVector<QRect> geometries;
for(QWindow *w : windows)
{
geometries.push_back(w->geometry());
delete w;
}
return geometries;
}
#endif

View File

@ -0,0 +1,6 @@
#pragma once
#include <QVector>
#include <QRect>
QVector<QRect> getAvailableScreenGeometries();

View File

@ -1,5 +1,5 @@
#include <QApplication>
#include <QGuiApplication>
#include <QPainter>
#include <QRasterWindow>
#include <QMouseEvent>
@ -21,6 +21,8 @@
#include "ScrapMgr.h"
#include "rsys/refresh.h"
#include "available_geometry.h"
//#include "keycode_map.h"
#include <iostream>
@ -59,7 +61,7 @@ namespace
{
class ExecutorWindow;
vdriver_modes_t zero_modes = { 0, 0 };
QApplication *qapp;
QGuiApplication *qapp;
QImage *qimage;
uint16_t keymod = 0;
ExecutorWindow *window;
@ -188,7 +190,6 @@ class ExecutorWindow : public QRasterWindow
public:
ExecutorWindow()
{
resize(vdriver_width, vdriver_height);
setFlag(Qt::FramelessWindowHint, true);
setFlag(Qt::NoDropShadowWindowHint, true);
}
@ -200,7 +201,7 @@ public:
{
for(const QRect& r : e->region())
painter.drawImage(r, *qimage, r);
}
}
}
void mouseMoveEvent(QMouseEvent *ev)
@ -370,6 +371,7 @@ void Executor::vdriver_set_rootless_region(RgnHandle rgn)
void Executor::vdriver_opt_register(void)
{
}
bool Executor::vdriver_init(int _max_width, int _max_height, int _max_bpp,
bool fixed_p, int *argc, char *argv[])
{
@ -385,18 +387,20 @@ bool Executor::vdriver_acceptable_mode_p(int width, int height, int bpp,
return false;
}
bool Executor::vdriver_set_mode(int width, int height, int bpp, bool grayscale_p)
{
qapp = new QApplication(fakeArgc, fakeArgv);
window = new ExecutorWindow();
qapp = new QGuiApplication(fakeArgc, fakeArgv);
#ifdef MACOSX
macosx_hide_menu_bar(0);
#endif
QScreen *screen = qapp->screens()[0];
QVector<QRect> screenGeometries = getAvailableScreenGeometries();
printf("set_mode: %d %d %d\n", width, height, bpp);
if(vdriver_fbuf)
delete[] vdriver_fbuf;
QRect geom = screen->geometry();//screen->availableGeometry();
QRect geom = screenGeometries[0];
vdriver_width = geom.width();
vdriver_height = geom.height();
@ -407,6 +411,7 @@ bool Executor::vdriver_set_mode(int width, int height, int bpp, bool grayscale_p
if(bpp)
vdriver_bpp = bpp;
vdriver_row_bytes = vdriver_width * vdriver_bpp / 8;
vdriver_row_bytes = (vdriver_row_bytes+3) & ~3;
vdriver_log2_bpp = ROMlib_log2[vdriver_bpp];
vdriver_mode_list = &zero_modes;
@ -415,15 +420,13 @@ bool Executor::vdriver_set_mode(int width, int height, int bpp, bool grayscale_p
vdriver_fbuf = new uint8_t[vdriver_row_bytes * vdriver_height * 5];
qimage = new QImage(vdriver_fbuf, vdriver_width, vdriver_height, vdriver_row_bytes,
vdriver_bpp == 1 ? QImage::Format_Mono : QImage::Format_Indexed8);
qimage->setColorTable({qRgb(0,0,0),qRgb(255,255,255)});
qimage = new QImage(vdriver_fbuf, vdriver_width, vdriver_height, vdriver_row_bytes, QImage::Format_Indexed8);
window->resize(vdriver_width, vdriver_height);
window->show();
#ifdef MACOSX
macosx_hide_menu_bar(0);
#endif
window = new ExecutorWindow();
window->setGeometry(geom);
window->showMaximized();
return true;
}
void Executor::vdriver_set_colors(int first_color, int num_colors, const ColorSpec *colors)
@ -461,7 +464,7 @@ void Executor::vdriver_update_screen_rects(int num_rects, const vdriver_rect_t *
{
rgn += QRect(r[i].left, r[i].top, r[i].right-r[i].left, r[i].bottom-r[i].top);
//vdriver_update_screen(r[i].top, r[i].left, r[i].bottom, r[i].right, cursor_p);
}
}
window->update(rgn);
}
@ -541,31 +544,10 @@ void Executor::host_set_cursor(char *cursor_data,
int Executor::host_set_cursor_visible(int show_p)
{
/* if(show_p)
if(show_p)
host_set_cursor(NULL, NULL, 0, 0);
else
window->setCursor(Qt::BlankCursor);*/
return true;
}
uchar data2[32];
uchar *mask2 = (uchar*)cursor_mask;
std::copy(cursor_data, cursor_data+32, data2);
for(int i = 0; i<32; i++)
mask2[i] |= data2[i];
QBitmap crsr = QBitmap::fromData(QSize(16, 16), (const uchar*)data2, QImage::Format_Mono);
QBitmap mask = QBitmap::fromData(QSize(16, 16), (const uchar*)mask2, QImage::Format_Mono);
theCursor = QCursor(crsr, mask, hotspot_x, hotspot_y);
}
window->setCursor(theCursor); // TODO: should we check for visibility?
}
int Executor::host_set_cursor_visible(int show_p)
{
/* if(show_p)
host_set_cursor(NULL, NULL, 0, 0);
else
window->setCursor(Qt::BlankCursor);*/
window->setCursor(Qt::BlankCursor);
return true;
}