Merge branch 'master' of ssh://github.com/86Box/86Box into cleanup30

This commit is contained in:
RichardG867
2022-07-08 19:22:52 -03:00
101 changed files with 224686 additions and 859 deletions

View File

@@ -179,7 +179,8 @@ if(WIN32)
enable_language(RC)
target_sources(86Box PUBLIC ../win/86Box-qt.rc)
target_sources(plat PRIVATE win_joystick_rawinput.c)
target_link_libraries(86Box hid)
target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp)
target_link_libraries(86Box hid d3d9)
# CMake 3.22 messed this up for clang/clang++
# See https://gitlab.kitware.com/cmake/cmake/-/issues/22611
@@ -239,12 +240,24 @@ if(WIN32)
# needed for static builds
qt_import_plugins(plat INCLUDE Qt${QT_MAJOR}::QWindowsIntegrationPlugin Qt${QT_MAJOR}::QICOPlugin Qt${QT_MAJOR}::QWindowsVistaStylePlugin)
else()
install(CODE "
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE)
execute_process(
COMMAND $<TARGET_FILE:Qt${QT_MAJOR}::windeployqt>
\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$<TARGET_FILE_NAME:86Box>\")
")
if(USE_QT6)
install(CODE "
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE)
execute_process(
COMMAND $<TARGET_FILE:Qt${QT_MAJOR}::windeployqt>
\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$<TARGET_FILE_NAME:86Box>\")
")
else()
find_program(WINDEPLOYQT_EXECUTABLE windeployqt)
if(WINDEPLOYQT_EXECUTABLE)
install(CODE "
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE)
execute_process(
COMMAND ${WINDEPLOYQT_EXECUTABLE}
\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$<TARGET_FILE_NAME:86Box>\")
")
endif()
endif()
endif()
endif()

View File

@@ -49,6 +49,8 @@ plat_vidapi(char* api) {
return 3;
} else if (!strcasecmp(api, "qt_vulkan")) {
return 4;
} else if (!strcasecmp(api, "qt_d3d9")) {
return 5;
}
return 0;
@@ -73,6 +75,9 @@ char* plat_vidapi_name(int api) {
case 4:
name = "qt_vulkan";
break;
case 5:
name = "qt_d3d9";
break;
default:
fatal("Unknown renderer: %i\n", api);
break;

167
src/qt/qt_d3d9renderer.cpp Normal file
View File

@@ -0,0 +1,167 @@
#include "qt_d3d9renderer.hpp"
#include <QResizeEvent>
#include <QTimer>
extern "C"
{
#include <86box/86box.h>
#include <86box/video.h>
}
D3D9Renderer::D3D9Renderer(QWidget *parent)
: QWidget{parent}, RendererCommon()
{
QPalette pal = palette();
pal.setColor(QPalette::Window, Qt::black);
setAutoFillBackground(true);
setPalette(pal);
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_OpaquePaintEvent);
windowHandle = (HWND)winId();
surfaceInUse = true;
RendererCommon::parentWidget = parent;
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
D3D9Renderer::~D3D9Renderer()
{
finalize();
}
void D3D9Renderer::finalize()
{
if (!finalized) {
while (surfaceInUse) {}
finalized = true;
}
surfaceInUse = true;
if (d3d9surface) { d3d9surface->Release(); d3d9surface = nullptr;}
if (d3d9dev) { d3d9dev->Release(); d3d9dev = nullptr; }
if (d3d9) { d3d9->Release(); d3d9 = nullptr; };
}
void D3D9Renderer::hideEvent(QHideEvent *event)
{
finalize();
}
void D3D9Renderer::showEvent(QShowEvent *event)
{
params = {};
if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9))) {
return error("Failed to create Direct3D 9 context");
}
params.Windowed = true;
params.SwapEffect = D3DSWAPEFFECT_FLIPEX;
params.BackBufferWidth = width() * devicePixelRatioF();
params.BackBufferHeight = height() * devicePixelRatioF();
params.BackBufferCount = 1;
params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
params.hDeviceWindow = windowHandle;
HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, &params, nullptr, &d3d9dev);
if (FAILED(result)) result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &params, nullptr, &d3d9dev);
if (FAILED(result)) {
return error("Failed to create Direct3D 9 device");
}
result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr);
if (FAILED(result)) result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr);
if (FAILED(result)) {
return error("Failed to create Direct3D 9 surface");
}
if (!alreadyInitialized) {
emit initialized();
alreadyInitialized = true;
}
surfaceInUse = false;
finalized = false;
}
void D3D9Renderer::paintEvent(QPaintEvent *event)
{
IDirect3DSurface9* backbuffer = nullptr;
RECT srcRect, dstRect;
HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
if (FAILED(result)) {
return;
}
srcRect.top = source.top();
srcRect.bottom = source.bottom();
srcRect.left = source.left();
srcRect.right = source.right();
dstRect.top = destination.top();
dstRect.bottom = destination.bottom();
dstRect.left = destination.left();
dstRect.right = destination.right();
d3d9dev->BeginScene();
while (surfaceInUse) {}
surfaceInUse = true;
d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR);
result = d3d9dev->EndScene();
surfaceInUse = false;
if (SUCCEEDED(result)) {
if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) {
finalize();
showEvent(nullptr);
}
}
}
bool D3D9Renderer::event(QEvent *event)
{
bool res = false;
if (!eventDelegate(event, res)) return QWidget::event(event);
return res;
}
void D3D9Renderer::resizeEvent(QResizeEvent *event)
{
onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF());
params.BackBufferWidth = event->size().width() * devicePixelRatioF();
params.BackBufferHeight = event->size().height() * devicePixelRatioF();
if (d3d9dev) d3d9dev->Reset(&params);
QWidget::resizeEvent(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();
return;
}
surfaceInUse = true;
source.setRect(x, y, w, h);
RECT srcRect;
D3DLOCKED_RECT lockRect;
srcRect.top = source.top();
srcRect.bottom = source.bottom();
srcRect.left = source.left();
srcRect.right = source.right();
if (screenshots) {
video_screenshot((uint32_t *) &(buffer32->line[y][x]), 0, 0, 2048);
}
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_blit_complete();
d3d9surface->UnlockRect();
}
else video_blit_complete();
surfaceInUse = false;
QTimer::singleShot(0, this, [this] { this->update(); });
}

View File

@@ -0,0 +1,44 @@
#ifndef D3D9RENDERER_HPP
#define D3D9RENDERER_HPP
#include <QWidget>
#include "qt_renderercommon.hpp"
#include <windows.h>
#include <d3d9.h>
#include <atomic>
class D3D9Renderer : public QWidget, public RendererCommon
{
Q_OBJECT
public:
explicit D3D9Renderer(QWidget *parent = nullptr);
~D3D9Renderer();
bool hasBlitFunc() override { return true; }
void blit(int x, int y, int w, int h) override;
void finalize() override;
protected:
void showEvent(QShowEvent* event) override;
void hideEvent(QHideEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void paintEvent(QPaintEvent *event) override;
bool event(QEvent* event) override;
QPaintEngine* paintEngine() const override { return nullptr; }
signals:
void initialized();
void error(QString);
private:
HWND windowHandle = 0;
D3DPRESENT_PARAMETERS params{};
IDirect3D9Ex* d3d9 = nullptr;
IDirect3DDevice9Ex* d3d9dev = nullptr;
IDirect3DSurface9* d3d9surface = nullptr;
std::atomic<bool> surfaceInUse{false}, finalized{false};
bool alreadyInitialized = false;
};
#endif // D3D9RENDERER_HPP

View File

@@ -583,24 +583,25 @@ void MachineStatus::updateTip(int tag)
{
int category = tag & 0xfffffff0;
int item = tag & 0xf;
if (!MediaMenu::ptr) return;
switch (category) {
case SB_CASSETTE:
d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title());
if (d->cassette.label && MediaMenu::ptr->cassetteMenu) d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title());
break;
case SB_CARTRIDGE:
d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title());
if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title());
break;
case SB_FLOPPY:
d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title());
if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title());
break;
case SB_CDROM:
d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title());
if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title());
break;
case SB_ZIP:
d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title());
if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title());
break;
case SB_MO:
d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title());
if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title());
break;
case SB_HDD:
break;

View File

@@ -120,10 +120,7 @@ main_thread_fn()
}
} else {
/* Just so we dont overload the host OS. */
if (drawits < -1 || dopause)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
else
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
/* If needed, handle a screen resize. */

View File

@@ -281,6 +281,10 @@ MainWindow::MainWindow(QWidget *parent) :
ui->actionVulkan->setVisible(false);
ui->actionOpenGL_3_0_Core->setVisible(false);
}
#if !defined Q_OS_WINDOWS
ui->actionDirect3D_9->setVisible(false);
if (vid_api == 5) vid_api = 0;
#endif
#if !QT_CONFIG(vulkan)
if (vid_api == 4) vid_api = 0;
@@ -295,6 +299,7 @@ MainWindow::MainWindow(QWidget *parent) :
actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES);
actGroup->addAction(ui->actionOpenGL_3_0_Core);
actGroup->addAction(ui->actionVulkan);
actGroup->addAction(ui->actionDirect3D_9);
actGroup->setExclusive(true);
connect(actGroup, &QActionGroup::triggered, [this](QAction* action) {
@@ -316,6 +321,9 @@ MainWindow::MainWindow(QWidget *parent) :
case 4:
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Vulkan);
break;
case 5:
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9);
break;
}
});
@@ -1341,6 +1349,7 @@ void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) {
void MainWindow::on_actionFullscreen_triggered() {
if (video_fullscreen > 0) {
showNormal();
if (vid_api == 5) ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9);
ui->menubar->show();
if (!hide_status_bar) ui->statusbar->show();
if (!hide_tool_bar) ui->toolBar->show();

View File

@@ -54,7 +54,7 @@
<x>0</x>
<y>0</y>
<width>724</width>
<height>23</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuAction">
@@ -105,6 +105,7 @@
<addaction name="actionHardware_Renderer_OpenGL_ES"/>
<addaction name="actionOpenGL_3_0_Core"/>
<addaction name="actionVulkan"/>
<addaction name="actionDirect3D_9"/>
</widget>
<widget class="QMenu" name="menuWindow_scale_factor">
<property name="title">
@@ -745,6 +746,17 @@
<string>MCA devices...</string>
</property>
</action>
<action name="actionDirect3D_9">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Direct3D 9</string>
</property>
<property name="vid_api" stdset="0">
<number>5</number>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@@ -510,6 +510,7 @@ void MediaMenu::zipEject(int i) {
zip_t *dev = (zip_t *) zip_drives[i].priv;
zip_disk_close(dev);
zip_drives[i].image_path[0] = 0;
if (zip_drives[i].bus_type) {
/* Signal disk change to the emulated machine. */
zip_insert(dev);
@@ -609,6 +610,7 @@ void MediaMenu::moEject(int i) {
mo_t *dev = (mo_t *) mo_drives[i].priv;
mo_disk_close(dev);
mo_drives[i].image_path[0] = 0;
if (mo_drives[i].bus_type) {
/* Signal disk change to the emulated machine. */
mo_insert(dev);

View File

@@ -22,13 +22,16 @@ public:
virtual uint32_t getBytesPerRow() { return 2048 * 4; }
virtual std::vector<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() = 0;
virtual std::vector<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() { std::vector<std::tuple<uint8_t*, std::atomic_flag*>> buffers; return buffers; }
/* Does renderer implement options dialog */
virtual bool hasOptions() const { return false; }
/* Returns options dialog for renderer */
virtual QDialog *getOptions(QWidget *parent) { return nullptr; }
virtual bool hasBlitFunc() { return false; }
virtual void blit(int x, int y, int w, int h) {}
protected:
bool eventDelegate(QEvent *event, bool &result);

View File

@@ -25,6 +25,9 @@
#include "qt_openglrenderer.hpp"
#include "qt_softwarerenderer.hpp"
#include "qt_vulkanwindowrenderer.hpp"
#ifdef Q_OS_WIN
#include "qt_d3d9renderer.hpp"
#endif
#include "qt_mainwindow.hpp"
#include "qt_util.hpp"
@@ -224,13 +227,27 @@ RendererStack::switchRenderer(Renderer renderer)
startblit();
if (current) {
rendererWindow->finalize();
if (rendererWindow->hasBlitFunc()) {
while (directBlitting) {}
connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection);
disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer);
} else {
connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection);
disconnect(this, &RendererStack::blit, this, &RendererStack::blitCommon);
}
removeWidget(current.get());
disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr);
/* Create new renderer only after previous is destroyed! */
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); });
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) {
createRenderer(renderer);
disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy);
blitDummied = false;
QTimer::singleShot(1000, this, [this]() { this->blitDummied = false; } );
});
current.release()->deleteLater();
rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater();
} else {
createRenderer(renderer);
}
@@ -292,6 +309,30 @@ RendererStack::createRenderer(Renderer renderer)
current.reset(this->createWindowContainer(hw, this));
break;
}
#ifdef Q_OS_WIN
case Renderer::Direct3D9:
{
this->createWinId();
auto hw = new D3D9Renderer(this);
rendererWindow = hw;
connect(hw, &D3D9Renderer::error, this, [this](QString str)
{
auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->show();
imagebufs = {};
endblit();
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
});
connect(hw, &D3D9Renderer::initialized, this, [this]()
{
endblit();
emit rendererChanged();
});
current.reset(hw);
break;
}
#endif
#if QT_CONFIG(vulkan)
case Renderer::Vulkan:
{
@@ -340,18 +381,41 @@ RendererStack::createRenderer(Renderer renderer)
currentBuf = 0;
if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) {
if (rendererWindow->hasBlitFunc()) {
connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection);
}
else {
connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection);
}
if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan && renderer != Renderer::Direct3D9) {
imagebufs = rendererWindow->getBuffers();
endblit();
emit rendererChanged();
}
}
void
RendererStack::blitDummy(int x, int y, int w, int h)
{
video_blit_complete();
blitDummied = true;
}
void
RendererStack::blitRenderer(int x, int y, int w, int h)
{
if (blitDummied) { blitDummied = false; video_blit_complete(); return; }
directBlitting = true;
rendererWindow->blit(x, y, w, h);
directBlitting = false;
}
// called from blitter thread
void
RendererStack::blit(int x, int y, int w, int h)
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()) {
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();
return;
}

View File

@@ -45,7 +45,8 @@ public:
OpenGL,
OpenGLES,
OpenGL3,
Vulkan
Vulkan,
Direct3D9
};
void switchRenderer(Renderer renderer);
@@ -72,10 +73,13 @@ public:
signals:
void blitToRenderer(int buf_idx, int x, int y, int w, int h);
void blit(int x, int y, int w, int h);
void rendererChanged();
public slots:
void blit(int x, int y, int w, int h);
void blitCommon(int x, int y, int w, int h);
void blitRenderer(int x, int y, int w, int h);
void blitDummy(int x, int y, int w, int h);
void mousePoll();
private:
@@ -98,6 +102,7 @@ private:
RendererCommon *rendererWindow { nullptr };
std::unique_ptr<QWidget> current;
std::atomic<bool> directBlitting{false}, blitDummied{false};
};
#endif // QT_RENDERERCONTAINER_HPP

View File

@@ -24,6 +24,7 @@ extern "C" {
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/video.h>
#include <86box/vid_xga_device.h>
}
#include "qt_deviceconfig.hpp"
@@ -47,6 +48,7 @@ void SettingsDisplay::save() {
gfxcard = ui->comboBoxVideo->currentData().toInt();
voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0;
ibm8514_enabled = ui->checkBox8514->isChecked() ? 1 : 0;
xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0;
}
void SettingsDisplay::onCurrentMachineChanged(int machineId) {
@@ -101,6 +103,14 @@ void SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() {
DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast<Settings*>(Settings::settings));
}
void SettingsDisplay::on_pushButtonConfigureXga_clicked() {
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast<Settings*>(Settings::settings));
} else {
DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast<Settings*>(Settings::settings));
}
}
void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) {
if (index < 0) {
return;
@@ -119,10 +129,20 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) {
bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0;
ui->checkBox8514->setEnabled(hasIsa16 || has_MCA);
if (hasIsa16 || has_MCA) {
ui->checkBox8514->setChecked(ibm8514_enabled > 0);
ui->checkBox8514->setChecked(ibm8514_enabled);
}
ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA);
if (hasIsa16 || has_MCA)
ui->checkBoxXga->setChecked(xga_enabled);
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked());
}
void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) {
ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked);
}
void SettingsDisplay::on_checkBoxXga_stateChanged(int state) {
ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked);
}

View File

@@ -22,8 +22,10 @@ public slots:
private slots:
void on_checkBoxVoodoo_stateChanged(int state);
void on_checkBoxXga_stateChanged(int state);
void on_comboBoxVideo_currentIndexChanged(int index);
void on_pushButtonConfigureVoodoo_clicked();
void on_pushButtonConfigureXga_clicked();
void on_pushButtonConfigure_clicked();
private:

View File

@@ -70,7 +70,21 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="3" column="2">
<widget class="QPushButton" name="pushButtonConfigureXga">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkBoxXga">
<property name="text">
<string>XGA</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>