diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 0fd342e55..30b6f53a8 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -64,10 +64,10 @@ static int keydelay[512]; #endif static scancode *scan_table; /* scancode table for keyboard */ -static uint8_t caps_lock = 0; -static uint8_t num_lock = 0; -static uint8_t scroll_lock = 0; -static uint8_t shift = 0; +static volatile uint8_t caps_lock = 0; +static volatile uint8_t num_lock = 0; +static volatile uint8_t scroll_lock = 0; +static uint8_t shift = 0; static int key5576mode = 0; @@ -310,13 +310,16 @@ keyboard_input(int down, uint16_t scan) shift &= ~0x80; break; case 0x03a: /* Caps Lock */ - caps_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + caps_lock ^= 1; break; case 0x045: - num_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + num_lock ^= 1; break; case 0x046: - scroll_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + scroll_lock ^= 1; break; default: diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e61b8547a..605f51e90 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -3476,6 +3476,7 @@ keyboard_at_bat(void *priv) keyboard_scan = 1; + keyboard_update_states(0, 0, 0); kbc_at_dev_queue_add(dev, 0xaa, 0); } else { bat_counter--; @@ -3510,6 +3511,7 @@ keyboard_at_write(void *priv) switch (dev->command) { case 0xed: /* Set/reset LEDs */ kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_update_states(!!(val & 0x4), !!(val & 0x2), val & 0x1); keyboard_at_log("%s: Set/reset LEDs [%02X]\n", dev->name, val); break; @@ -3767,6 +3769,7 @@ keyboard_at_init(const device_t *info) keyboard_send = add_data_kbd; SavedKbd = dev; + keyboard_update_states(0, 0, 0); inv_cmd_response = (dev->type & FLAG_PS2) ? 0xfe : 0xfa; @@ -3785,6 +3788,8 @@ keyboard_at_close(void *priv) /* Disable the scancode maps. */ keyboard_set_table(NULL); + keyboard_update_states(0, 0, 0); + SavedKbd = NULL; free(dev); diff --git a/src/qt/icons/caps_lock_off.ico b/src/qt/icons/caps_lock_off.ico new file mode 100644 index 000000000..6895c735c Binary files /dev/null and b/src/qt/icons/caps_lock_off.ico differ diff --git a/src/qt/icons/caps_lock_on.ico b/src/qt/icons/caps_lock_on.ico new file mode 100644 index 000000000..2cfd48aad Binary files /dev/null and b/src/qt/icons/caps_lock_on.ico differ diff --git a/src/qt/icons/kana_lock_off.ico b/src/qt/icons/kana_lock_off.ico new file mode 100644 index 000000000..27c9b88c2 Binary files /dev/null and b/src/qt/icons/kana_lock_off.ico differ diff --git a/src/qt/icons/kana_lock_on.ico b/src/qt/icons/kana_lock_on.ico new file mode 100644 index 000000000..ec171b52b Binary files /dev/null and b/src/qt/icons/kana_lock_on.ico differ diff --git a/src/qt/icons/num_lock_off.ico b/src/qt/icons/num_lock_off.ico new file mode 100644 index 000000000..5b14da1d4 Binary files /dev/null and b/src/qt/icons/num_lock_off.ico differ diff --git a/src/qt/icons/num_lock_on.ico b/src/qt/icons/num_lock_on.ico new file mode 100644 index 000000000..0dd08d7ae Binary files /dev/null and b/src/qt/icons/num_lock_on.ico differ diff --git a/src/qt/icons/scroll_lock_off.ico b/src/qt/icons/scroll_lock_off.ico new file mode 100644 index 000000000..85cb09ec6 Binary files /dev/null and b/src/qt/icons/scroll_lock_off.ico differ diff --git a/src/qt/icons/scroll_lock_on.ico b/src/qt/icons/scroll_lock_on.ico new file mode 100644 index 000000000..33476406a Binary files /dev/null and b/src/qt/icons/scroll_lock_on.ico differ diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 1fb9b3fb5..905a100f4 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -186,6 +186,43 @@ MainWindow::MainWindow(QWidget *parent) ui->menuEGA_S_VGA_settings->menuAction()->setMenuRole(QAction::NoRole); ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); + + num_icon = QIcon(":/settings/qt/icons/num_lock_on.ico"); + num_icon_off = QIcon(":/settings/qt/icons/num_lock_off.ico"); + scroll_icon = QIcon(":/settings/qt/icons/scroll_lock_on.ico"); + scroll_icon_off = QIcon(":/settings/qt/icons/scroll_lock_off.ico"); + caps_icon = QIcon(":/settings/qt/icons/caps_lock_on.ico"); + caps_icon_off = QIcon(":/settings/qt/icons/caps_lock_off.ico"); + /* TODO: Add Kana indicator here after the keyboard type work is done. */ + + num_label = new QLabel; + num_label->setPixmap(num_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(num_label); + + caps_label = new QLabel; + caps_label->setPixmap(caps_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(caps_label); + + scroll_label = new QLabel; + scroll_label->setPixmap(scroll_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(scroll_label); + + QTimer* ledKeyboardTimer = new QTimer(this); + ledKeyboardTimer->setTimerType(Qt::CoarseTimer); + ledKeyboardTimer->setInterval(1); + connect(ledKeyboardTimer, &QTimer::timeout, this, [this] () { + uint8_t caps, num, scroll; + keyboard_get_states(&caps, &num, &scroll); + + if (num_label->isVisible()) + num_label->setPixmap(num ? this->num_icon.pixmap(QSize(16, 16)) : this->num_icon_off.pixmap(QSize(16, 16))); + if (caps_label->isVisible()) + caps_label->setPixmap(caps ? this->caps_icon.pixmap(QSize(16, 16)) : this->caps_icon_off.pixmap(QSize(16, 16))); + if (scroll_label->isVisible()) + scroll_label->setPixmap(scroll ? this->scroll_icon.pixmap(QSize(16, 16)) : this->scroll_icon_off.pixmap(QSize(16, 16))); + }); + ledKeyboardTimer->start(); + #ifdef Q_OS_WINDOWS util::setWin11RoundedCorners(this->winId(), (hide_status_bar ? false : true)); #endif @@ -213,6 +250,9 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::hardResetCompleted, this, [this]() { ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); #ifdef USE_WACOM @@ -1455,6 +1495,10 @@ MainWindow::refreshMediaMenu() status->refresh(ui->statusbar); ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); ui->actionACPI_Shutdown->setEnabled(!!acpi_enabled); + + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); } void diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 5811ac36a..421b9ce15 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include #include @@ -189,6 +191,10 @@ private: friend class RendererStack; // For UI variable access by non-primary renderer windows. friend class WindowsRawInputFilter; // Needed to reload renderers on style sheet changes. + QLabel *caps_label, *scroll_label, *num_label; + QIcon caps_icon, scroll_icon, num_icon; + QIcon caps_icon_off, scroll_icon_off, num_icon_off; + bool isShowMessage = false; }; diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index bc553ac61..a5963c152 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -34,6 +34,14 @@ qt/icons/86Box-green.ico qt/icons/86Box-red.ico qt/icons/86Box-yellow.ico + qt/icons/caps_lock_off.ico + qt/icons/caps_lock_on.ico + qt/icons/kana_lock_off.ico + qt/icons/kana_lock_on.ico + qt/icons/num_lock_off.ico + qt/icons/num_lock_on.ico + qt/icons/scroll_lock_off.ico + qt/icons/scroll_lock_on.ico qt/icons/acpi_shutdown.ico