Working multimonitor
This commit is contained in:
@@ -932,6 +932,7 @@ load_video(void)
|
||||
voodoo_enabled = !!config_get_int(cat, "voodoo", 0);
|
||||
ibm8514_enabled = !!config_get_int(cat, "8514a", 0);
|
||||
xga_enabled = !!config_get_int(cat, "xga", 0);
|
||||
herc_enabled = !!config_get_int(cat, "herc_enabled", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2480,6 +2481,11 @@ save_video(void)
|
||||
else
|
||||
config_set_int(cat, "xga", xga_enabled);
|
||||
|
||||
if (herc_enabled == 0)
|
||||
config_delete_var(cat, "herc_enabled");
|
||||
else
|
||||
config_set_int(cat, "herc_enabled", herc_enabled);
|
||||
|
||||
delete_section_if_empty(cat);
|
||||
}
|
||||
|
||||
|
@@ -117,7 +117,7 @@ extern char *plat_vidapi_name(int api);
|
||||
extern int plat_setvid(int api);
|
||||
extern void plat_vidsize(int x, int y);
|
||||
extern void plat_setfullscreen(int on);
|
||||
extern void plat_resize(int x, int y);
|
||||
extern void plat_resize_monitor(int x, int y, int monitor_index);
|
||||
extern void plat_vidapi_enable(int enabled);
|
||||
extern void plat_vidapi_reload(void);
|
||||
extern void plat_vid_reload_options(void);
|
||||
|
@@ -62,6 +62,8 @@ extern void ui_check_menu_item(int id, int checked);
|
||||
|
||||
extern wchar_t *ui_window_title(wchar_t *s);
|
||||
extern void ui_status_update(void);
|
||||
extern void ui_init_monitor(int monitor_index);
|
||||
extern void ui_deinit_monitor(int monitor_index);
|
||||
extern int ui_sb_find_part(int tag);
|
||||
extern void ui_sb_set_ready(int ready);
|
||||
extern void ui_sb_update_panes(void);
|
||||
|
@@ -56,8 +56,13 @@ typedef struct {
|
||||
int cols[256][2][2];
|
||||
|
||||
uint8_t *vram;
|
||||
int monitor_index;
|
||||
int prev_monitor_index;
|
||||
} hercules_t;
|
||||
|
||||
#define VIDEO_MONITOR_PROLOGUE() { dev->prev_monitor_index = monitor_index_global; monitor_index_global = dev->monitor_index; }
|
||||
#define VIDEO_MONITOR_EPILOGUE() { monitor_index_global = dev->prev_monitor_index; }
|
||||
|
||||
static void *hercules_init(const device_t *info);
|
||||
|
||||
#endif /*VIDEO_HERCULES_H*/
|
||||
|
@@ -126,6 +126,7 @@ typedef struct monitor_t
|
||||
#define MONITORS_NUM 8
|
||||
extern monitor_t monitors[MONITORS_NUM];
|
||||
extern int monitor_index_global;
|
||||
extern int herc_enabled;
|
||||
|
||||
typedef rgb_t PALETTE[256];
|
||||
|
||||
@@ -239,6 +240,8 @@ extern void cgapal_rebuild(void);
|
||||
extern void hline(bitmap_t *b, int x1, int y, int x2, uint32_t col);
|
||||
extern void updatewindowsize(int x, int y);
|
||||
|
||||
extern void video_monitor_init(int);
|
||||
extern void video_monitor_close(int);
|
||||
extern void video_init(void);
|
||||
extern void video_close(void);
|
||||
extern void video_reset_close(void);
|
||||
|
@@ -8,7 +8,7 @@ extern "C"
|
||||
#include <86box/video.h>
|
||||
}
|
||||
|
||||
D3D9Renderer::D3D9Renderer(QWidget *parent)
|
||||
D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index)
|
||||
: QWidget{parent}, RendererCommon()
|
||||
{
|
||||
QPalette pal = palette();
|
||||
@@ -27,6 +27,7 @@ D3D9Renderer::D3D9Renderer(QWidget *parent)
|
||||
RendererCommon::parentWidget = parent;
|
||||
|
||||
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
this->m_monitor_index = monitor_index;
|
||||
}
|
||||
|
||||
D3D9Renderer::~D3D9Renderer()
|
||||
@@ -138,8 +139,8 @@ void D3D9Renderer::resizeEvent(QResizeEvent *event)
|
||||
|
||||
void D3D9Renderer::blit(int x, int y, int w, int h)
|
||||
{
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || surfaceInUse) {
|
||||
video_blit_complete();
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) {
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
return;
|
||||
}
|
||||
surfaceInUse = true;
|
||||
@@ -156,12 +157,12 @@ void D3D9Renderer::blit(int x, int y, int w, int h)
|
||||
}
|
||||
if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) {
|
||||
for (int y1 = 0; y1 < h; y1++) {
|
||||
video_copy(((uint8_t*)lockRect.pBits) + (y1 * lockRect.Pitch), &(buffer32->line[y + y1][x]), w * 4);
|
||||
video_copy(((uint8_t*)lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4);
|
||||
}
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
d3d9surface->UnlockRect();
|
||||
}
|
||||
else video_blit_complete();
|
||||
else video_blit_complete_monitor(m_monitor_index);
|
||||
surfaceInUse = false;
|
||||
QTimer::singleShot(0, this, [this] { this->update(); });
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ class D3D9Renderer : public QWidget, public RendererCommon
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit D3D9Renderer(QWidget *parent = nullptr);
|
||||
explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0);
|
||||
~D3D9Renderer();
|
||||
bool hasBlitFunc() override { return true; }
|
||||
void blit(int x, int y, int w, int h) override;
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
|
||||
std::atomic<bool> surfaceInUse{false}, finalized{false};
|
||||
bool alreadyInitialized = false;
|
||||
int m_monitor_index = 0;
|
||||
};
|
||||
|
||||
#endif // D3D9RENDERER_HPP
|
||||
|
@@ -126,15 +126,17 @@ main_thread_fn()
|
||||
/* If needed, handle a screen resize. */
|
||||
if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) {
|
||||
if (vid_resize & 2)
|
||||
plat_resize(fixed_size_x, fixed_size_y);
|
||||
plat_resize_monitor(fixed_size_x, fixed_size_y, 0);
|
||||
else
|
||||
plat_resize(scrnsz_x, scrnsz_y);
|
||||
plat_resize_monitor(scrnsz_x, scrnsz_y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
is_quit = 1;
|
||||
}
|
||||
|
||||
static std::thread* main_thread;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false);
|
||||
@@ -258,7 +260,7 @@ int main(int argc, char* argv[]) {
|
||||
main_window->installEventFilter(&socket);
|
||||
socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET"));
|
||||
}
|
||||
pc_reset_hard_init();
|
||||
//pc_reset_hard_init();
|
||||
|
||||
/* Set the PAUSE mode depending on the renderer. */
|
||||
// plat_pause(0);
|
||||
@@ -284,13 +286,15 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
/* Initialize the rendering window, or fullscreen. */
|
||||
auto main_thread = std::thread([] {
|
||||
main_thread_fn();
|
||||
QTimer::singleShot(0, &app, []
|
||||
{
|
||||
pc_reset_hard_init();
|
||||
main_thread = new std::thread(main_thread_fn);
|
||||
});
|
||||
|
||||
auto ret = app.exec();
|
||||
cpu_thread_run = 0;
|
||||
main_thread.join();
|
||||
main_thread->join();
|
||||
|
||||
socket.close();
|
||||
return ret;
|
||||
|
@@ -139,7 +139,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
statusBar()->setVisible(!hide_status_bar);
|
||||
statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }");
|
||||
ui->toolBar->setVisible(!hide_tool_bar);
|
||||
|
||||
renderers[0].reset(nullptr);
|
||||
auto toolbar_spacer = new QWidget();
|
||||
toolbar_spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
ui->toolBar->addWidget(toolbar_spacer);
|
||||
@@ -494,6 +494,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
#endif
|
||||
|
||||
setContextMenuPolicy(Qt::PreventContextMenu);
|
||||
|
||||
connect(this, &MainWindow::initRendererMonitor, this, &MainWindow::initRendererMonitorSlot);
|
||||
connect(this, &MainWindow::initRendererMonitorForNonQtThread, this, &MainWindow::initRendererMonitorSlot, Qt::BlockingQueuedConnection);
|
||||
connect(this, &MainWindow::destroyRendererMonitor, this, &MainWindow::destroyRendererMonitorSlot);
|
||||
connect(this, &MainWindow::destroyRendererMonitorForNonQtThread, this, &MainWindow::destroyRendererMonitorSlot, Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
@@ -534,10 +539,41 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
ui->stackedWidget->mouse_exit_func();
|
||||
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software);
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (renderers[i]) renderers[i]->close();
|
||||
}
|
||||
QApplication::processEvents();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void MainWindow::initRendererMonitorSlot(int monitor_index)
|
||||
{
|
||||
auto& secondaryRenderer = this->renderers[monitor_index];
|
||||
secondaryRenderer.reset(new RendererStack(nullptr, monitor_index));
|
||||
if (secondaryRenderer) {
|
||||
connect(this, &MainWindow::pollMouse, secondaryRenderer.get(), &RendererStack::mousePoll, Qt::DirectConnection);
|
||||
connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index]
|
||||
{
|
||||
this->renderers[monitor_index]->show();
|
||||
});
|
||||
secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
secondaryRenderer->setWindowTitle(QObject::tr("86Box Monitor #") + QString::number(monitor_index + 1));
|
||||
if (vid_resize == 2) {
|
||||
secondaryRenderer->setFixedSize(fixed_size_x, fixed_size_y);
|
||||
}
|
||||
secondaryRenderer->show();
|
||||
secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
secondaryRenderer->setWindowIcon(this->windowIcon());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::destroyRendererMonitorSlot(int monitor_index)
|
||||
{
|
||||
if (this->renderers[monitor_index]) {
|
||||
this->renderers[monitor_index].release()->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
delete ui;
|
||||
}
|
||||
@@ -554,15 +590,15 @@ void MainWindow::showEvent(QShowEvent *event) {
|
||||
+ (hide_status_bar ? 0 : statusBar()->height())
|
||||
+ (hide_tool_bar ? 0 : ui->toolBar->height()));
|
||||
|
||||
scrnsz_x = fixed_size_x;
|
||||
scrnsz_y = fixed_size_y;
|
||||
monitors[0].mon_scrnsz_x = fixed_size_x;
|
||||
monitors[0].mon_scrnsz_y = fixed_size_y;
|
||||
}
|
||||
else if (window_remember && vid_resize == 1) {
|
||||
ui->stackedWidget->setFixedSize(window_w, window_h);
|
||||
adjustSize();
|
||||
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
scrnsz_x = window_w;
|
||||
scrnsz_y = window_h;
|
||||
monitors[0].mon_scrnsz_x = window_w;
|
||||
monitors[0].mon_scrnsz_y = window_h;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1360,7 +1396,7 @@ void MainWindow::on_actionFullscreen_triggered() {
|
||||
+ (!hide_status_bar ? statusBar()->height() : 0)
|
||||
+ (!hide_tool_bar ? ui->toolBar->height() : 0));
|
||||
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
}
|
||||
} else {
|
||||
if (video_fullscreen_first)
|
||||
@@ -1487,9 +1523,13 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void MainWindow::blitToWidget(int x, int y, int w, int h)
|
||||
void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index)
|
||||
{
|
||||
ui->stackedWidget->blit(x, y, w, h);
|
||||
if (monitor_index >= 1) {
|
||||
if (renderers[monitor_index]) renderers[monitor_index]->blit(x, y, w, h);
|
||||
else video_blit_complete_monitor(monitor_index);
|
||||
}
|
||||
else ui->stackedWidget->blit(x, y, w, h);
|
||||
}
|
||||
|
||||
void MainWindow::keyReleaseEvent(QKeyEvent* event)
|
||||
@@ -1537,7 +1577,7 @@ void MainWindow::on_actionResizable_window_triggered(bool checked) {
|
||||
ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
|
||||
ui->menuWindow_scale_factor->setEnabled(! checked);
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1770,7 +1810,7 @@ void MainWindow::on_actionHiDPI_scaling_triggered()
|
||||
{
|
||||
dpi_scale ^= 1;
|
||||
ui->actionHiDPI_scaling->setChecked(dpi_scale);
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionHide_status_bar_triggered()
|
||||
@@ -1786,7 +1826,7 @@ void MainWindow::on_actionHide_status_bar_triggered()
|
||||
} else {
|
||||
int vid_resize_orig = vid_resize;
|
||||
vid_resize = 0;
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
vid_resize = vid_resize_orig;
|
||||
}
|
||||
}
|
||||
@@ -1804,7 +1844,7 @@ void MainWindow::on_actionHide_tool_bar_triggered()
|
||||
} else {
|
||||
int vid_resize_orig = vid_resize;
|
||||
vid_resize = 0;
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
vid_resize = vid_resize_orig;
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
|
||||
class MediaMenu;
|
||||
class RendererStack;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
@@ -26,7 +27,7 @@ public:
|
||||
|
||||
void showMessage(const QString& header, const QString& message);
|
||||
void getTitle(wchar_t* title);
|
||||
void blitToWidget(int x, int y, int w, int h);
|
||||
void blitToWidget(int x, int y, int w, int h, int monitor_index);
|
||||
QSize getRenderWidgetSize();
|
||||
void setSendKeyboardInput(bool enabled);
|
||||
signals:
|
||||
@@ -40,6 +41,10 @@ signals:
|
||||
void updateStatusBarTip(int tag);
|
||||
void updateMenuResizeOptions();
|
||||
void updateWindowRememberOption();
|
||||
void initRendererMonitor(int monitor_index);
|
||||
void destroyRendererMonitor(int monitor_index);
|
||||
void initRendererMonitorForNonQtThread(int monitor_index);
|
||||
void destroyRendererMonitorForNonQtThread(int monitor_index);
|
||||
|
||||
void setTitle(const QString& title);
|
||||
void setFullscreen(bool state);
|
||||
@@ -51,6 +56,8 @@ public slots:
|
||||
void showSettings();
|
||||
void hardReset();
|
||||
void togglePause();
|
||||
void initRendererMonitorSlot(int monitor_index);
|
||||
void destroyRendererMonitorSlot(int monitor_index);
|
||||
private slots:
|
||||
void on_actionFullscreen_triggered();
|
||||
void on_actionSettings_triggered();
|
||||
@@ -118,6 +125,7 @@ protected:
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
std::unique_ptr<MachineStatus> status;
|
||||
std::array<std::unique_ptr<RendererStack>, 8> renderers;
|
||||
std::shared_ptr<MediaMenu> mm;
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
|
@@ -52,7 +52,7 @@ extern MainWindow* main_window;
|
||||
QElapsedTimer elapsed_timer;
|
||||
|
||||
static std::atomic_int blitmx_contention = 0;
|
||||
static std::mutex blitmx;
|
||||
static std::recursive_mutex blitmx;
|
||||
|
||||
class CharPointer {
|
||||
public:
|
||||
|
@@ -51,14 +51,21 @@ extern "C" {
|
||||
double mouse_sensitivity = 1.0;
|
||||
}
|
||||
|
||||
struct mouseinputdata {
|
||||
int deltax, deltay, deltaz;
|
||||
int mousebuttons;
|
||||
};
|
||||
static mouseinputdata mousedata;
|
||||
|
||||
extern "C" void macos_poll_mouse();
|
||||
extern MainWindow *main_window;
|
||||
RendererStack::RendererStack(QWidget *parent)
|
||||
RendererStack::RendererStack(QWidget *parent, int monitor_index)
|
||||
: QStackedWidget(parent)
|
||||
, ui(new Ui::RendererStack)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_monitor_index = monitor_index;
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
char *mouse_type = getenv("EMU86BOX_MOUSE"), auto_mouse_type[16];
|
||||
if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) {
|
||||
@@ -313,7 +320,7 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
case Renderer::Direct3D9:
|
||||
{
|
||||
this->createWinId();
|
||||
auto hw = new D3D9Renderer(this);
|
||||
auto hw = new D3D9Renderer(this, m_monitor_index);
|
||||
rendererWindow = hw;
|
||||
connect(hw, &D3D9Renderer::error, this, [this](QString str)
|
||||
{
|
||||
@@ -398,14 +405,14 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
void
|
||||
RendererStack::blitDummy(int x, int y, int w, int h)
|
||||
{
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
blitDummied = true;
|
||||
}
|
||||
|
||||
void
|
||||
RendererStack::blitRenderer(int x, int y, int w, int h)
|
||||
{
|
||||
if (blitDummied) { blitDummied = false; video_blit_complete(); return; }
|
||||
if (blitDummied) { blitDummied = false; video_blit_complete_monitor(m_monitor_index); return; }
|
||||
directBlitting = true;
|
||||
rendererWindow->blit(x, y, w, h);
|
||||
directBlitting = false;
|
||||
@@ -415,8 +422,8 @@ RendererStack::blitRenderer(int x, int y, int w, int h)
|
||||
void
|
||||
RendererStack::blitCommon(int x, int y, int w, int h)
|
||||
{
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set() || blitDummied) {
|
||||
video_blit_complete();
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set() || blitDummied) {
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
return;
|
||||
}
|
||||
sx = x;
|
||||
@@ -426,13 +433,13 @@ RendererStack::blitCommon(int x, int y, int w, int h)
|
||||
uint8_t *imagebits = std::get<uint8_t *>(imagebufs[currentBuf]);
|
||||
for (int y1 = y; y1 < (y + h); y1++) {
|
||||
auto scanline = imagebits + (y1 * rendererWindow->getBytesPerRow()) + (x * 4);
|
||||
video_copy(scanline, &(buffer32->line[y1][x]), w * 4);
|
||||
video_copy(scanline, &(monitors[m_monitor_index].target_buffer->line[y1][x]), w * 4);
|
||||
}
|
||||
|
||||
if (screenshots) {
|
||||
video_screenshot((uint32_t *) imagebits, x, y, 2048);
|
||||
}
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
emit blitToRenderer(currentBuf, sx, sy, sw, sh);
|
||||
currentBuf = (currentBuf + 1) % imagebufs.size();
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ class RendererStack : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RendererStack(QWidget *parent = nullptr);
|
||||
explicit RendererStack(QWidget *parent = nullptr, int monitor_index = 0);
|
||||
~RendererStack();
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
@@ -87,16 +87,11 @@ private:
|
||||
|
||||
Ui::RendererStack *ui;
|
||||
|
||||
struct mouseinputdata {
|
||||
int deltax, deltay, deltaz;
|
||||
int mousebuttons;
|
||||
};
|
||||
mouseinputdata mousedata;
|
||||
|
||||
int x, y, w, h, sx, sy, sw, sh;
|
||||
|
||||
int currentBuf = 0;
|
||||
int isMouseDown = 0;
|
||||
int m_monitor_index = 0;
|
||||
|
||||
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> imagebufs;
|
||||
|
||||
|
@@ -57,14 +57,14 @@ wchar_t* ui_window_title(wchar_t* str)
|
||||
|
||||
extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index)
|
||||
{
|
||||
main_window->blitToWidget(x, y, w, h);
|
||||
main_window->blitToWidget(x, y, w, h, monitor_index);
|
||||
}
|
||||
|
||||
void mouse_poll() {
|
||||
main_window->pollMouse();
|
||||
}
|
||||
|
||||
void plat_resize(int w, int h) {
|
||||
void plat_resize_monitor(int w, int h, int monitor_index) {
|
||||
main_window->resizeContents(w, h);
|
||||
}
|
||||
|
||||
@@ -98,6 +98,20 @@ int ui_msgbox_header(int flags, void *header, void* message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ui_init_monitor(int monitor_index) {
|
||||
if (QThread::currentThread() == main_window->thread()) {
|
||||
emit main_window->initRendererMonitor(monitor_index);
|
||||
}
|
||||
else emit main_window->initRendererMonitorForNonQtThread(monitor_index);
|
||||
}
|
||||
|
||||
void ui_deinit_monitor(int monitor_index) {
|
||||
if (QThread::currentThread() == main_window->thread()) {
|
||||
emit main_window->destroyRendererMonitor(monitor_index);
|
||||
}
|
||||
else emit main_window->destroyRendererMonitorForNonQtThread(monitor_index);
|
||||
}
|
||||
|
||||
int ui_msgbox(int flags, void *message) {
|
||||
return ui_msgbox_header(flags, nullptr, message);
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ static zwp_pointer_constraints_v1* conf_pointer_interface = nullptr;
|
||||
static zwp_locked_pointer_v1* conf_pointer = nullptr;
|
||||
|
||||
static int rel_mouse_x = 0, rel_mouse_y = 0;
|
||||
static bool wl_init_ok = false;
|
||||
|
||||
void rel_mouse_event(void* data, zwp_relative_pointer_v1* zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real)
|
||||
{
|
||||
@@ -92,15 +93,18 @@ static const struct wl_registry_listener registry_listener = {
|
||||
|
||||
void wl_init()
|
||||
{
|
||||
wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display");
|
||||
if (display)
|
||||
{
|
||||
auto registry = wl_display_get_registry(display);
|
||||
if (registry)
|
||||
if (!wl_init_ok) {
|
||||
wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display");
|
||||
if (display)
|
||||
{
|
||||
wl_registry_add_listener(registry, ®istry_listener, nullptr);
|
||||
wl_display_roundtrip(display);
|
||||
auto registry = wl_display_get_registry(display);
|
||||
if (registry)
|
||||
{
|
||||
wl_registry_add_listener(registry, ®istry_listener, nullptr);
|
||||
wl_display_roundtrip(display);
|
||||
}
|
||||
}
|
||||
wl_init_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -66,6 +66,7 @@ hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
uint8_t old;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
switch (addr) {
|
||||
case 0x03b0:
|
||||
case 0x03b2:
|
||||
@@ -146,6 +147,8 @@ hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VIDEO_MONITOR_EPILOGUE()
|
||||
}
|
||||
|
||||
|
||||
@@ -295,6 +298,7 @@ hercules_poll(void *priv)
|
||||
int drawcursor;
|
||||
uint32_t *p;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
|
||||
if (! dev->linepos) {
|
||||
@@ -516,6 +520,7 @@ hercules_poll(void *priv)
|
||||
}
|
||||
}
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE()
|
||||
}
|
||||
|
||||
|
||||
@@ -527,6 +532,7 @@ hercules_init(const device_t *info)
|
||||
|
||||
dev = (hercules_t *)malloc(sizeof(hercules_t));
|
||||
memset(dev, 0x00, sizeof(hercules_t));
|
||||
dev->monitor_index = monitor_index_global;
|
||||
|
||||
overscan_x = 16;
|
||||
overscan_y = 28;
|
||||
|
@@ -275,6 +275,10 @@ vid_table_log(const char *fmt, ...)
|
||||
void
|
||||
video_reset_close(void)
|
||||
{
|
||||
for (int i = 1; i < MONITORS_NUM; i++)
|
||||
video_monitor_close(i);
|
||||
|
||||
monitor_index_global = 0;
|
||||
video_inform(VIDEO_FLAG_TYPE_NONE, &timing_default);
|
||||
was_reset = 0;
|
||||
}
|
||||
@@ -321,6 +325,7 @@ video_reset(int card)
|
||||
vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n",
|
||||
card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0);
|
||||
|
||||
monitor_index_global = 0;
|
||||
loadfont("roms/video/mda/mda.rom", 0);
|
||||
|
||||
/* Do not initialize internal cards here. */
|
||||
@@ -332,6 +337,13 @@ video_reset(int card)
|
||||
|
||||
/* Initialize the video card. */
|
||||
device_add(video_cards[card].device);
|
||||
|
||||
if (herc_enabled) {
|
||||
video_monitor_init(1);
|
||||
monitor_index_global = 1;
|
||||
device_add(&hercules_device);
|
||||
monitor_index_global = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the Voodoo if configured. */
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/path.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/thread.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
@@ -101,6 +102,7 @@ static uint32_t cga_2_table[16];
|
||||
static uint8_t thread_run = 0;
|
||||
monitor_t monitors[MONITORS_NUM];
|
||||
int monitor_index_global = 0;
|
||||
int herc_enabled = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy;
|
||||
@@ -926,8 +928,10 @@ video_monitor_init(int index)
|
||||
monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event();
|
||||
monitors[index].mon_blit_data_ptr->buffer_not_in_use = thread_create_event();
|
||||
monitors[index].mon_blit_data_ptr->thread_run = 1;
|
||||
monitors[index].mon_blit_data_ptr->monitor_index = index;
|
||||
monitors[index].mon_pal_lookup = calloc(sizeof(uint32_t), 256);
|
||||
monitors[index].mon_cga_palette = calloc(1, sizeof(int));
|
||||
if (index >= 1) ui_init_monitor(index);
|
||||
thread_create(blit_thread, monitors[index].mon_blit_data_ptr);
|
||||
}
|
||||
|
||||
@@ -938,6 +942,7 @@ video_monitor_close(int monitor_index)
|
||||
monitors[monitor_index].mon_blit_data_ptr->thread_run = 0;
|
||||
thread_set_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread);
|
||||
thread_wait(monitors[monitor_index].mon_blit_data_ptr->blit_thread);
|
||||
if (monitor_index >= 1) ui_deinit_monitor(monitor_index);
|
||||
thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->buffer_not_in_use);
|
||||
thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->blit_complete);
|
||||
thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread);
|
||||
|
Reference in New Issue
Block a user