Serial Passthrough

This commit is contained in:
Jasmine Iwanek
2023-02-14 20:37:58 -05:00
parent 16b9a5d3e0
commit f643391975
52 changed files with 1622 additions and 95 deletions

View File

@@ -221,6 +221,12 @@ if(WIN32 AND NOT MINGW)
target_sources(plat PRIVATE ../win/win_opendir.c)
endif()
if(WIN32)
target_sources(plat PRIVATE ../win/win_serial_passthrough.c)
else()
target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c)
endif()
if (APPLE)
target_sources(ui PRIVATE macos_event_filter.mm)
if(MOLTENVK)

View File

@@ -27,6 +27,8 @@
#include <QCheckBox>
#include <QFrame>
#include <QLabel>
#include <QDir>
#include <QSettings>
extern "C" {
#include <86box/86box.h>
@@ -40,6 +42,10 @@ extern "C" {
#include "qt_filefield.hpp"
#include "qt_models_common.hpp"
#ifdef Q_OS_LINUX
# include <sys/stat.h>
# include <sys/sysmacros.h>
#endif
DeviceConfig::DeviceConfig(QWidget *parent)
: QDialog(parent)
@@ -53,6 +59,40 @@ DeviceConfig::~DeviceConfig()
delete ui;
}
static QStringList
EnumerateSerialDevices()
{
QStringList serialDevices, ttyEntries;
QByteArray devstr(1024, 0);
#ifdef Q_OS_LINUX
QDir class_dir("/sys/class/tty/");
QDir dev_dir("/dev/");
ttyEntries = class_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::System, QDir::SortFlag::Name);
for (int i = 0; i < ttyEntries.size(); i++) {
if (class_dir.exists(ttyEntries[i] + "/device/driver/") && dev_dir.exists(ttyEntries[i])
&& QFileInfo(dev_dir.canonicalPath() + '/' + ttyEntries[i]).isReadable()
&& QFileInfo(dev_dir.canonicalPath() + '/' + ttyEntries[i]).isWritable()) {
serialDevices.push_back("/dev/" + ttyEntries[i]);
}
}
#endif
#ifdef Q_OS_WINDOWS
QSettings comPorts("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat, nullptr);
for (int i = 0; i < comPorts.childKeys().length(); i++) {
serialDevices.push_back(QString("\\\\.\\") + comPorts.value(comPorts.childKeys()[i]).toString());
}
#endif
#ifdef Q_OS_MACOS
QDir dev_dir("/dev/");
dev_dir.setNameFilters({ "tty.*", "cu.*" });
QDir::Filters serial_dev_flags = QDir::Files | QDir::NoSymLinks | QDir::Readable | QDir::Writable | QDir::NoDotAndDotDot | QDir::System;
for (const auto &device : dev_dir.entryInfoList(serial_dev_flags, QDir::SortFlag::Name)) {
serialDevices.push_back(device.canonicalFilePath());
}
#endif
return serialDevices;
}
void
DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings)
{
@@ -205,6 +245,27 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
dc.ui->formLayout->addRow(config->description, fileField);
break;
}
case CONFIG_SERPORT:
{
auto *cbox = new QComboBox();
cbox->setObjectName(config->name);
auto *model = cbox->model();
int currentIndex = 0;
auto serialDevices = EnumerateSerialDevices();
char *selected = config_get_string(device_context.name, const_cast<char *>(config->name), const_cast<char *>(config->default_string));
Models::AddEntry(model, "None", -1);
for (int i = 0; i < serialDevices.size(); i++) {
int row = Models::AddEntry(model, serialDevices[i], i);
if (selected == serialDevices[i]) {
currentIndex = row;
}
}
dc.ui->formLayout->addRow(config->description, cbox);
cbox->setCurrentIndex(currentIndex);
break;
}
}
++config;
}
@@ -236,6 +297,15 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
config_set_string(device_context.name, const_cast<char *>(config->name), const_cast<char *>(config->bios[idx].internal_name));
break;
}
case CONFIG_SERPORT:
{
auto *cbox = dc.findChild<QComboBox *>(config->name);
auto path = cbox->currentText().toUtf8();
if (path == "None")
path = "";
config_set_string(device_context.name, const_cast<char *>(config->name), path);
break;
}
case CONFIG_HEX16:
{
auto *cbox = dc.findChild<QComboBox *>(config->name);

View File

@@ -43,7 +43,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin)
# include "qt_winrawinputfilter.hpp"
# include "qt_winmanagerfilter.hpp"
# include <86box/win.h>
# include <Shobjidl.h>
# include <shobjidl.h>
#endif
extern "C" {

View File

@@ -27,6 +27,7 @@ extern "C" {
#include <86box/machine.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/serial_passthrough.h>
}
#include "qt_deviceconfig.hpp"
@@ -66,6 +67,15 @@ SettingsPorts::SettingsPorts(QWidget *parent)
auto *checkBox = findChild<QCheckBox *>(QString("checkBoxSerial%1").arg(i + 1));
checkBox->setChecked(com_ports[i].enabled > 0);
}
ui->checkBoxSerialPassThru1->setChecked(serial_passthrough_enabled[0]);
ui->pushButtonSerialPassThru1->setEnabled(serial_passthrough_enabled[0]);
ui->checkBoxSerialPassThru2->setChecked(serial_passthrough_enabled[1]);
ui->pushButtonSerialPassThru2->setEnabled(serial_passthrough_enabled[1]);
ui->checkBoxSerialPassThru3->setChecked(serial_passthrough_enabled[2]);
ui->pushButtonSerialPassThru3->setEnabled(serial_passthrough_enabled[2]);
ui->checkBoxSerialPassThru4->setChecked(serial_passthrough_enabled[3]);
ui->pushButtonSerialPassThru4->setEnabled(serial_passthrough_enabled[3]);
}
SettingsPorts::~SettingsPorts()
@@ -87,6 +97,11 @@ SettingsPorts::save()
auto *checkBox = findChild<QCheckBox *>(QString("checkBoxSerial%1").arg(i + 1));
com_ports[i].enabled = checkBox->isChecked() ? 1 : 0;
}
serial_passthrough_enabled[0] = ui->checkBoxSerialPassThru1->isChecked();
serial_passthrough_enabled[1] = ui->checkBoxSerialPassThru2->isChecked();
serial_passthrough_enabled[2] = ui->checkBoxSerialPassThru3->isChecked();
serial_passthrough_enabled[3] = ui->checkBoxSerialPassThru4->isChecked();
}
void
@@ -112,3 +127,51 @@ SettingsPorts::on_checkBoxParallel4_stateChanged(int state)
{
ui->comboBoxLpt4->setEnabled(state == Qt::Checked);
}
void
SettingsPorts::on_pushButtonSerialPassThru1_clicked()
{
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 1, qobject_cast<Settings *>(Settings::settings));
}
void
SettingsPorts::on_pushButtonSerialPassThru2_clicked()
{
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 2, qobject_cast<Settings *>(Settings::settings));
}
void
SettingsPorts::on_pushButtonSerialPassThru3_clicked()
{
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 3, qobject_cast<Settings *>(Settings::settings));
}
void
SettingsPorts::on_pushButtonSerialPassThru4_clicked()
{
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast<Settings *>(Settings::settings));
}
void
SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked)
{
ui->pushButtonSerialPassThru1->setEnabled(checked);
}
void
SettingsPorts::on_checkBoxSerialPassThru2_clicked(bool checked)
{
ui->pushButtonSerialPassThru2->setEnabled(checked);
}
void
SettingsPorts::on_checkBoxSerialPassThru3_clicked(bool checked)
{
ui->pushButtonSerialPassThru3->setEnabled(checked);
}
void
SettingsPorts::on_checkBoxSerialPassThru4_clicked(bool checked)
{
ui->pushButtonSerialPassThru4->setEnabled(checked);
}

View File

@@ -15,6 +15,30 @@ public:
~SettingsPorts();
void save();
private slots:
void on_checkBoxSerialPassThru4_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru3_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru2_clicked(bool checked);
private slots:
void on_pushButtonSerialPassThru4_clicked();
private slots:
void on_pushButtonSerialPassThru3_clicked();
private slots:
void on_pushButtonSerialPassThru2_clicked();
private slots:
void on_pushButtonSerialPassThru1_clicked();
private slots:
void on_checkBoxSerialPassThru1_clicked(bool checked);
private slots:
void on_checkBoxParallel3_stateChanged(int arg1);
void on_checkBoxParallel2_stateChanged(int arg1);

View File

@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
@@ -26,7 +26,7 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
@@ -70,29 +70,8 @@
</item>
</layout>
</item>
<item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBoxSerial1">
<property name="text">
<string>Serial port 1</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBoxParallel1">
<property name="text">
<string>Parallel port 1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBoxSerial2">
<property name="text">
<string>Serial port 2</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBoxParallel2">
<property name="text">
@@ -100,13 +79,6 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBoxSerial3">
<property name="text">
<string>Serial port 3</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBoxParallel3">
<property name="text">
@@ -114,10 +86,17 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBoxSerial4">
<item row="2" column="0">
<widget class="QCheckBox" name="checkBoxSerial3">
<property name="text">
<string>Serial port 4</string>
<string>Serial port 3</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBoxSerial1">
<property name="text">
<string>Serial port 1</string>
</property>
</widget>
</item>
@@ -128,20 +107,117 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBoxSerial2">
<property name="text">
<string>Serial port 2</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBoxParallel1">
<property name="text">
<string>Parallel port 1</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBoxSerial4">
<property name="text">
<string>Serial port 4</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout_5">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
<item row="4" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBoxSerialPassThru3">
<property name="text">
<string>Serial port passthrough 3</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButtonSerialPassThru1">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBoxSerialPassThru1">
<property name="text">
<string>Serial port passthrough 1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBoxSerialPassThru2">
<property name="text">
<string>Serial port passthrough 2</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBoxSerialPassThru4">
<property name="text">
<string>Serial port passthrough 4</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButtonSerialPassThru2">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pushButtonSerialPassThru3">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="pushButtonSerialPassThru4">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>

View File

@@ -17,7 +17,7 @@
#include "qt_winmanagerfilter.hpp"
#include <Windows.h>
#include <windows.h>
#include <86box/win.h>
bool

View File

@@ -35,7 +35,7 @@
#include <QMenuBar>
#include <Windows.h>
#include <windows.h>
#include <86box/keyboard.h>
#include <86box/mouse.h>

View File

@@ -37,7 +37,7 @@
#include <QAbstractNativeEventFilter>
#include <QByteArray>
#include <Windows.h>
#include <windows.h>
#include <memory>