USB: Move to Qt (with *significant* refactoring)

This commit is contained in:
Connor McLaughlin 2022-12-05 01:00:06 +10:00 committed by refractionpcsx2
parent 4ebb5a87b2
commit fc14b8f0da
196 changed files with 8511 additions and 26760 deletions

View File

@ -42,8 +42,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "3rdparty\xz\libl
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "3rdparty\fmt\fmt.vcxproj", "{449AD25E-424A-4714-BABC-68706CDCC33B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsamplerate", "3rdparty\libsamplerate\libsamplerate.vcxproj", "{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libchdr", "3rdparty\libchdr\libchdr.vcxproj", "{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpgd", "3rdparty\jpgd\jpgd.vcxproj", "{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}"
@ -248,18 +246,6 @@ Global
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.Build.0 = Release|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.ActiveCfg = Release|x64
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.Build.0 = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.ActiveCfg = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.Build.0 = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.ActiveCfg = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.Build.0 = Debug|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.ActiveCfg = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.Build.0 = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.ActiveCfg = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.Build.0 = Devel|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.ActiveCfg = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.Build.0 = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.ActiveCfg = Release|x64
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.Build.0 = Release|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.ActiveCfg = Debug|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.Build.0 = Debug|x64
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.ActiveCfg = Debug|x64
@ -434,7 +420,6 @@ Global
{27F17499-A372-4408-8AFA-4F9F4584FBD3} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{12728250-16EC-4DC6-94D7-E21DD88947F8} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{449AD25E-424A-4714-BABC-68706CDCC33B} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}

View File

@ -258,6 +258,10 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
{
}
void Host::SetRelativeMouseMode(bool enabled)
{
}
bool Host::AcquireHostDisplay(RenderAPI api, bool clear_state_on_fail)
{
const std::optional<WindowInfo> wi(GSRunner::GetPlatformWindowInfo());
@ -772,4 +776,4 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
#endif // _WIN32
#endif // _WIN32

View File

@ -117,6 +117,8 @@ target_sources(pcsx2-qt PRIVATE
Settings/SettingsDialog.cpp
Settings/SettingsDialog.h
Settings/SettingsDialog.ui
Settings/USBBindingWidget_DrivingForce.ui
Settings/USBBindingWidget_GTForce.ui
Tools/InputRecording/NewInputRecordingDlg.cpp
Tools/InputRecording/NewInputRecordingDlg.h
Tools/InputRecording/NewInputRecordingDlg.ui

View File

@ -84,17 +84,15 @@ std::optional<WindowInfo> DisplayWidget::getWindowInfo()
return ret;
}
void DisplayWidget::updateRelativeMode(bool master_enable)
void DisplayWidget::updateRelativeMode(bool enabled)
{
bool relative_mode = master_enable && InputManager::HasPointerAxisBinds();
#ifdef _WIN32
// prefer ClipCursor() over warping movement when we're using raw input
bool clip_cursor = relative_mode && false /*InputManager::IsUsingRawInput()*/;
if (m_relative_mouse_enabled == relative_mode && m_clip_mouse_enabled == clip_cursor)
bool clip_cursor = enabled && false /*InputManager::IsUsingRawInput()*/;
if (m_relative_mouse_enabled == enabled && m_clip_mouse_enabled == clip_cursor)
return;
DevCon.WriteLn("updateRelativeMode(): relative=%s, clip=%s", relative_mode ? "yes" : "no", clip_cursor ? "yes" : "no");
DevCon.WriteLn("updateRelativeMode(): relative=%s, clip=%s", enabled ? "yes" : "no", clip_cursor ? "yes" : "no");
if (!clip_cursor && m_clip_mouse_enabled)
{
@ -102,13 +100,13 @@ void DisplayWidget::updateRelativeMode(bool master_enable)
ClipCursor(nullptr);
}
#else
if (m_relative_mouse_enabled == relative_mode)
if (m_relative_mouse_enabled == enabled)
return;
DevCon.WriteLn("updateRelativeMode(): relative=%s", relative_mode ? "yes" : "no");
DevCon.WriteLn("updateRelativeMode(): relative=%s", enabled ? "yes" : "no");
#endif
if (relative_mode)
if (enabled)
{
#ifdef _WIN32
m_relative_mouse_enabled = !clip_cursor;
@ -129,21 +127,22 @@ void DisplayWidget::updateRelativeMode(bool master_enable)
}
void DisplayWidget::updateCursor(bool master_enable)
void DisplayWidget::updateCursor(bool hidden)
{
#ifdef _WIN32
const bool hide = master_enable && (m_should_hide_cursor || m_relative_mouse_enabled || m_clip_mouse_enabled);
#else
const bool hide = master_enable && (m_should_hide_cursor || m_relative_mouse_enabled);
#endif
if (m_cursor_hidden == hide)
if (m_cursor_hidden == hidden)
return;
m_cursor_hidden = hide;
if (hide)
m_cursor_hidden = hidden;
if (hidden)
{
DevCon.WriteLn("updateCursor(): Cursor is now hidden");
setCursor(Qt::BlankCursor);
}
else
{
DevCon.WriteLn("updateCursor(): Cursor is now shown");
unsetCursor();
}
}
void DisplayWidget::handleCloseEvent(QCloseEvent* event)

View File

@ -32,15 +32,13 @@ public:
QPaintEngine* paintEngine() const override;
__fi void setShouldHideCursor(bool hide) { m_should_hide_cursor = hide; }
int scaledWindowWidth() const;
int scaledWindowHeight() const;
std::optional<WindowInfo> getWindowInfo();
void updateRelativeMode(bool master_enable);
void updateCursor(bool master_enable);
void updateRelativeMode(bool enabled);
void updateCursor(bool hidden);
void handleCloseEvent(QCloseEvent* event);
@ -60,7 +58,6 @@ private:
#ifdef _WIN32
bool m_clip_mouse_enabled = false;
#endif
bool m_should_hide_cursor = false;
bool m_cursor_hidden = false;
std::vector<int> m_keys_pressed_with_modifiers;

View File

@ -409,6 +409,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
connect(thread, &EmuThread::onUpdateDisplayRequested, this, &MainWindow::updateDisplay, Qt::BlockingQueuedConnection);
connect(thread, &EmuThread::onDestroyDisplayRequested, this, &MainWindow::destroyDisplay, Qt::BlockingQueuedConnection);
connect(thread, &EmuThread::onResizeDisplayRequested, this, &MainWindow::displayResizeRequested);
connect(thread, &EmuThread::onRelativeMouseModeRequested, this, &MainWindow::relativeMouseModeRequested);
connect(thread, &EmuThread::onVMStarting, this, &MainWindow::onVMStarting);
connect(thread, &EmuThread::onVMStarted, this, &MainWindow::onVMStarted);
connect(thread, &EmuThread::onVMPaused, this, &MainWindow::onVMPaused);
@ -1089,7 +1090,7 @@ bool MainWindow::isRenderingToMain() const
bool MainWindow::shouldHideMouseCursor() const
{
return isRenderingFullscreen() && Host::GetBoolSettingValue("UI", "HideMouseCursor", false);
return (isRenderingFullscreen() && Host::GetBoolSettingValue("UI", "HideMouseCursor", false)) || m_relative_mouse_mode;
}
bool MainWindow::shouldHideMainWindow() const
@ -1250,7 +1251,7 @@ void MainWindow::requestExit()
void MainWindow::checkForSettingChanges()
{
if (m_display_widget)
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused);
updateDisplayWidgetCursor();
updateWindowState();
}
@ -1802,10 +1803,7 @@ void MainWindow::onVMPaused()
m_last_fps_status = m_status_verbose_widget->text();
m_status_verbose_widget->setText(tr("Paused"));
if (m_display_widget)
{
m_display_widget->updateRelativeMode(false);
m_display_widget->updateCursor(false);
}
updateDisplayWidgetCursor();
}
void MainWindow::onVMResumed()
@ -1824,8 +1822,7 @@ void MainWindow::onVMResumed()
m_last_fps_status = QString();
if (m_display_widget)
{
m_display_widget->updateRelativeMode(true);
m_display_widget->updateCursor(true);
updateDisplayWidgetCursor();
m_display_widget->setFocus();
}
}
@ -1842,14 +1839,9 @@ void MainWindow::onVMStopped()
updateInputRecordingActions(false);
if (m_display_widget)
{
m_display_widget->updateRelativeMode(false);
m_display_widget->updateCursor(false);
}
updateDisplayWidgetCursor();
else
{
switchToGameListView();
}
// reload played time
if (m_game_list_widget->isShowingGameList())
@ -2035,9 +2027,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
m_ui.actionStartFullscreenUI->setEnabled(false);
m_ui.actionStartFullscreenUI2->setEnabled(false);
m_display_widget->setShouldHideCursor(shouldHideMouseCursor());
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused);
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
updateDisplayWidgetCursor();
m_display_widget->setFocus();
g_host_display->DoneCurrent();
@ -2083,10 +2073,8 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
container->showNormal();
}
updateDisplayWidgetCursor();
m_display_widget->setFocus();
m_display_widget->setShouldHideCursor(shouldHideMouseCursor());
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused);
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
updateWindowState();
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
@ -2122,10 +2110,8 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
updateWindowTitle();
updateWindowState();
updateDisplayWidgetCursor();
m_display_widget->setFocus();
m_display_widget->setShouldHideCursor(shouldHideMouseCursor());
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused);
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
return m_display_widget;
}
@ -2221,6 +2207,16 @@ void MainWindow::displayResizeRequested(qint32 width, qint32 height)
QtUtils::ResizePotentiallyFixedSizeWindow(this, width, height + extra_height);
}
void MainWindow::relativeMouseModeRequested(bool enabled)
{
if (m_relative_mouse_mode == enabled)
return;
m_relative_mouse_mode = enabled;
if (s_vm_valid && !s_vm_paused)
updateDisplayWidgetCursor();
}
void MainWindow::destroyDisplay()
{
// Now we can safely destroy the display window.
@ -2284,6 +2280,12 @@ void MainWindow::destroyDisplayWidget(bool show_game_list)
updateDisplayRelatedActions(false, false, false);
}
void MainWindow::updateDisplayWidgetCursor()
{
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused && m_relative_mouse_mode);
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused && shouldHideMouseCursor());
}
void MainWindow::focusDisplayWidget()
{
if (!m_display_widget || centralWidget() != m_display_widget)

View File

@ -129,6 +129,7 @@ private Q_SLOTS:
DisplayWidget* createDisplay(bool fullscreen, bool render_to_main);
DisplayWidget* updateDisplay(bool fullscreen, bool render_to_main, bool surfaceless);
void displayResizeRequested(qint32 width, qint32 height);
void relativeMouseModeRequested(bool enabled);
void destroyDisplay();
void focusDisplayWidget();
@ -231,6 +232,7 @@ private:
void restoreDisplayWindowGeometryFromConfig();
void createDisplayWidget(bool fullscreen, bool render_to_main, bool is_exclusive_fullscreen);
void destroyDisplayWidget(bool show_game_list);
void updateDisplayWidgetCursor();
void setDisplayFullscreen(const std::string& fullscreen_mode);
SettingsDialog* getSettingsDialog();
@ -283,6 +285,7 @@ private:
quint32 m_current_game_crc;
bool m_display_created = false;
bool m_relative_mouse_mode = false;
bool m_save_states_invalidated = false;
bool m_was_paused_on_surface_loss = false;
bool m_was_disc_change_request = false;

View File

@ -1486,6 +1486,11 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
emit g_emu_thread->onInputDeviceDisconnected(identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()));
}
void Host::SetRelativeMouseMode(bool enabled)
{
emit g_emu_thread->onRelativeMouseModeRequested(enabled);
}
//////////////////////////////////////////////////////////////////////////
// Hotkeys
//////////////////////////////////////////////////////////////////////////

View File

@ -120,6 +120,7 @@ Q_SIGNALS:
DisplayWidget* onUpdateDisplayRequested(bool fullscreen, bool render_to_main, bool surfaceless);
void onResizeDisplayRequested(qint32 width, qint32 height);
void onDestroyDisplayRequested();
void onRelativeMouseModeRequested(bool enabled);
/// Called when the VM is starting initialization, but has not been completed yet.
void onVMStarting();

View File

@ -15,10 +15,18 @@
#include "PrecompiledHeader.h"
#include <QtCore/QDir>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QScrollArea>
#include <algorithm>
#include "fmt/format.h"
#include "common/StringUtil.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "Settings/ControllerBindingWidgets.h"
#include "Settings/ControllerSettingsDialog.h"
@ -28,9 +36,8 @@
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "common/StringUtil.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "ui_USBBindingWidget_DrivingForce.h"
#include "ui_USBBindingWidget_GTForce.h"
ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port)
: QWidget(parent)
@ -42,8 +49,8 @@ ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSett
populateControllerTypes();
onTypeChanged();
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(m_dialog->getProfileSettingsInterface(),
m_ui.controllerType, m_config_section, "Type", PAD::GetDefaultPadType(port));
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
m_dialog->getProfileSettingsInterface(), m_ui.controllerType, m_config_section, "Type", PAD::GetDefaultPadType(port));
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ControllerBindingWidget::onTypeChanged);
connect(m_ui.bindings, &QPushButton::clicked, this, &ControllerBindingWidget::onBindingsClicked);
@ -106,7 +113,10 @@ void ControllerBindingWidget::onTypeChanged()
if (has_settings)
{
m_settings_widget = new ControllerCustomSettingsWidget(this, m_ui.stackedWidget);
const QString settings_title(tr("%1 Settings").arg(qApp->translate("PAD", cinfo->display_name)));
const gsl::span<const SettingInfo> settings(cinfo->settings, cinfo->num_settings);
m_settings_widget = new ControllerCustomSettingsWidget(
settings, m_config_section, std::string(), settings_title, cinfo->name, getDialog(), m_ui.stackedWidget);
m_ui.stackedWidget->addWidget(m_settings_widget);
}
@ -172,9 +182,7 @@ void ControllerBindingWidget::onAutomaticBindingClicked()
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() {
doDeviceAutomaticBinding(action->data().toString());
});
connect(action, &QAction::triggered, this, [this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
added = true;
}
@ -266,8 +274,7 @@ ControllerMacroWidget::~ControllerMacroWidget() = default;
void ControllerMacroWidget::updateListItem(u32 index)
{
m_ui.portList->item(static_cast<int>(index))
->setText(tr("Macro %1\n%2").arg(index + 1).arg(m_macros[index]->getSummary()));
m_ui.portList->item(static_cast<int>(index))->setText(tr("Macro %1\n%2").arg(index + 1).arg(m_macros[index]->getSummary()));
}
void ControllerMacroWidget::createWidgets(ControllerBindingWidget* parent)
@ -291,8 +298,7 @@ void ControllerMacroWidget::createWidgets(ControllerBindingWidget* parent)
//////////////////////////////////////////////////////////////////////////
ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* parent, ControllerBindingWidget* bwidget,
u32 index)
ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* parent, ControllerBindingWidget* bwidget, u32 index)
: QWidget(parent)
, m_parent(parent)
, m_bwidget(bwidget)
@ -310,8 +316,7 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
}
// load binds (single string joined by &)
const std::string binds_string(
dialog->getStringValue(section.c_str(), fmt::format("Macro{}Binds", index + 1u).c_str(), ""));
const std::string binds_string(dialog->getStringValue(section.c_str(), fmt::format("Macro{}Binds", index + 1u).c_str(), ""));
const std::vector<std::string_view> buttons_split(StringUtil::SplitString(binds_string, '&', true));
for (const std::string_view& button : buttons_split)
@ -335,15 +340,15 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
QListWidgetItem* item = new QListWidgetItem();
item->setText(QString::fromUtf8(bi.display_name));
item->setCheckState((std::find(m_binds.begin(), m_binds.end(), &bi) != m_binds.end()) ? Qt::Checked :
Qt::Unchecked);
item->setCheckState((std::find(m_binds.begin(), m_binds.end(), &bi) != m_binds.end()) ? Qt::Checked : Qt::Unchecked);
m_ui.bindList->addItem(item);
}
m_frequency = dialog->getIntValue(section.c_str(), fmt::format("Macro{}Frequency", index + 1u).c_str(), 0);
updateFrequencyText();
m_ui.trigger->initialize(dialog->getProfileSettingsInterface(), section, fmt::format("Macro{}", index + 1u));
m_ui.trigger->initialize(
dialog->getProfileSettingsInterface(), InputBindingInfo::Type::Macro, section, fmt::format("Macro{}", index + 1u));
connect(m_ui.increaseFrequency, &QAbstractButton::clicked, this, [this]() { modFrequency(1); });
connect(m_ui.decreateFrequency, &QAbstractButton::clicked, this, [this]() { modFrequency(-1); });
@ -368,8 +373,8 @@ QString ControllerMacroEditWidget::getSummary() const
void ControllerMacroEditWidget::onSetFrequencyClicked()
{
bool okay;
int new_freq = QInputDialog::getInt(this, tr("Set Frequency"), tr("Frequency: "), static_cast<int>(m_frequency), 0,
std::numeric_limits<int>::max(), 1, &okay);
int new_freq = QInputDialog::getInt(
this, tr("Set Frequency"), tr("Frequency: "), static_cast<int>(m_frequency), 0, std::numeric_limits<int>::max(), 1, &okay);
if (!okay)
return;
@ -388,9 +393,8 @@ void ControllerMacroEditWidget::modFrequency(s32 delta)
void ControllerMacroEditWidget::updateFrequency()
{
m_bwidget->getDialog()->setIntValue(m_bwidget->getConfigSection().c_str(),
fmt::format("Macro{}Frequency", m_index + 1u).c_str(),
static_cast<s32>(m_frequency));
m_bwidget->getDialog()->setIntValue(
m_bwidget->getConfigSection().c_str(), fmt::format("Macro{}Frequency", m_index + 1u).c_str(), static_cast<s32>(m_frequency));
updateFrequencyText();
}
@ -453,17 +457,21 @@ void ControllerMacroEditWidget::updateBinds()
//////////////////////////////////////////////////////////////////////////
ControllerCustomSettingsWidget::ControllerCustomSettingsWidget(ControllerBindingWidget* parent, QWidget* parent_widget)
ControllerCustomSettingsWidget::ControllerCustomSettingsWidget(gsl::span<const SettingInfo> settings, std::string config_section,
std::string config_prefix, const QString& group_title, const char* translation_ctx, ControllerSettingsDialog* dialog,
QWidget* parent_widget)
: QWidget(parent_widget)
, m_parent(parent)
, m_settings(settings)
, m_config_section(std::move(config_section))
, m_config_prefix(std::move(config_prefix))
, m_dialog(dialog)
{
const PAD::ControllerInfo* cinfo = PAD::GetControllerInfo(parent->getControllerType());
if (!cinfo || cinfo->num_settings == 0)
if (settings.empty())
return;
QGroupBox* gbox = new QGroupBox(tr("%1 Settings").arg(qApp->translate("PAD", cinfo->display_name)), this);
QGroupBox* gbox = new QGroupBox(group_title, this);
QGridLayout* gbox_layout = new QGridLayout(gbox);
createSettingWidgets(parent, gbox, gbox_layout, cinfo);
createSettingWidgets(translation_ctx, gbox, gbox_layout);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
@ -481,26 +489,65 @@ ControllerCustomSettingsWidget::ControllerCustomSettingsWidget(ControllerBinding
ControllerCustomSettingsWidget::~ControllerCustomSettingsWidget() = default;
void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidget* parent, QWidget* widget_parent,
QGridLayout* layout, const PAD::ControllerInfo* cinfo)
static std::tuple<QString, QString> getPrefixAndSuffixForIntFormat(const QString& format)
{
const std::string& section = parent->getConfigSection();
SettingsInterface* sif = parent->getDialog()->getProfileSettingsInterface();
QString prefix, suffix;
QRegularExpression re(QStringLiteral("(.*)%.*d(.*)"));
QRegularExpressionMatch match(re.match(format));
if (match.isValid())
{
prefix = match.captured(1).replace(QStringLiteral("%%"), QStringLiteral("%"));
suffix = match.captured(2).replace(QStringLiteral("%%"), QStringLiteral("%"));
}
return std::tie(prefix, suffix);
}
static std::tuple<QString, QString, int> getPrefixAndSuffixForFloatFormat(const QString& format)
{
QString prefix, suffix;
int decimals = -1;
QRegularExpression re(QStringLiteral("(.*)%.*([0-9]+)f(.*)"));
QRegularExpressionMatch match(re.match(format));
if (match.isValid())
{
prefix = match.captured(1).replace(QStringLiteral("%%"), QStringLiteral("%"));
suffix = match.captured(3).replace(QStringLiteral("%%"), QStringLiteral("%"));
bool decimals_ok;
decimals = match.captured(2).toInt(&decimals_ok);
if (!decimals_ok)
decimals = -1;
}
else
{
re = QRegularExpression(QStringLiteral("(.*)%.*f(.*)"));
match = re.match(format);
prefix = match.captured(1).replace(QStringLiteral("%%"), QStringLiteral("%"));
suffix = match.captured(2).replace(QStringLiteral("%%"), QStringLiteral("%"));
}
return std::tie(prefix, suffix, decimals);
}
void ControllerCustomSettingsWidget::createSettingWidgets(const char* translation_ctx, QWidget* widget_parent, QGridLayout* layout)
{
SettingsInterface* sif = m_dialog->getProfileSettingsInterface();
int current_row = 0;
for (u32 i = 0; i < cinfo->num_settings; i++)
for (const SettingInfo& si : m_settings)
{
const SettingInfo& si = cinfo->settings[i];
std::string key_name = si.name;
std::string key_name = m_config_prefix + si.name;
switch (si.type)
{
case SettingInfo::Type::Boolean:
{
QCheckBox* cb = new QCheckBox(qApp->translate(cinfo->name, si.display_name), widget_parent);
QCheckBox* cb = new QCheckBox(qApp->translate(translation_ctx, si.display_name), widget_parent);
cb->setObjectName(QString::fromUtf8(si.name));
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, cb, section, std::move(key_name),
si.BooleanDefaultValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(
sif, cb, m_config_section, std::move(key_name), si.BooleanDefaultValue());
layout->addWidget(cb, current_row, 0, 1, 4);
current_row++;
}
@ -513,8 +560,14 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
sb->setMinimum(si.IntegerMinValue());
sb->setMaximum(si.IntegerMaxValue());
sb->setSingleStep(si.IntegerStepValue());
SettingWidgetBinder::BindWidgetToIntSetting(sif, sb, section, std::move(key_name), si.IntegerDefaultValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), widget_parent), current_row, 0);
if (si.format)
{
const auto [prefix, suffix] = getPrefixAndSuffixForIntFormat(QString::fromUtf8(si.format));
sb->setPrefix(prefix);
sb->setSuffix(suffix);
}
SettingWidgetBinder::BindWidgetToIntSetting(sif, sb, m_config_section, std::move(key_name), si.IntegerDefaultValue());
layout->addWidget(new QLabel(qApp->translate(translation_ctx, si.display_name), widget_parent), current_row, 0);
layout->addWidget(sb, current_row, 1, 1, 3);
current_row++;
}
@ -525,9 +578,10 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
QComboBox* cb = new QComboBox(widget_parent);
cb->setObjectName(QString::fromUtf8(si.name));
for (u32 i = 0; si.options[i] != nullptr; i++)
cb->addItem(qApp->translate(cinfo->name, si.options[i]));
SettingWidgetBinder::BindWidgetToIntSetting(sif, cb, section, std::move(key_name), si.IntegerDefaultValue(), si.IntegerMinValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), widget_parent), current_row, 0);
cb->addItem(qApp->translate(translation_ctx, si.options[i]));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, cb, m_config_section, std::move(key_name), si.IntegerDefaultValue(), si.IntegerMinValue());
layout->addWidget(new QLabel(qApp->translate(translation_ctx, si.display_name), widget_parent), current_row, 0);
layout->addWidget(cb, current_row, 1, 1, 3);
current_row++;
}
@ -540,8 +594,19 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
sb->setMinimum(si.FloatMinValue());
sb->setMaximum(si.FloatMaxValue());
sb->setSingleStep(si.FloatStepValue());
SettingWidgetBinder::BindWidgetToFloatSetting(sif, sb, section, std::move(key_name), si.FloatDefaultValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), widget_parent), current_row, 0);
#if 0
// We can't use this until we handle multiplier.
if (si.format)
{
const auto [prefix, suffix, decimals] = getPrefixAndSuffixForFloatFormat(QString::fromUtf8(si.format));
sb->setPrefix(prefix);
if (decimals >= 0)
sb->setDecimals(decimals);
sb->setSuffix(suffix);
}
#endif
SettingWidgetBinder::BindWidgetToFloatSetting(sif, sb, m_config_section, std::move(key_name), si.FloatDefaultValue());
layout->addWidget(new QLabel(qApp->translate(translation_ctx, si.display_name), widget_parent), current_row, 0);
layout->addWidget(sb, current_row, 1, 1, 3);
current_row++;
}
@ -551,8 +616,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
{
QLineEdit* le = new QLineEdit(widget_parent);
le->setObjectName(QString::fromUtf8(si.name));
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, section, std::move(key_name), si.StringDefaultValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), widget_parent), current_row, 0);
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, m_config_section, std::move(key_name), si.StringDefaultValue());
layout->addWidget(new QLabel(qApp->translate(translation_ctx, si.display_name), widget_parent), current_row, 0);
layout->addWidget(le, current_row, 1, 1, 3);
current_row++;
}
@ -571,10 +636,10 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
else if (si.options)
{
for (u32 i = 0; si.options[i] != nullptr; i++)
cb->addItem(qApp->translate(cinfo->name, si.options[i]));
cb->addItem(qApp->translate(translation_ctx, si.options[i]));
}
SettingWidgetBinder::BindWidgetToStringSetting(sif, cb, section, std::move(key_name), si.StringDefaultValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), widget_parent), current_row, 0);
SettingWidgetBinder::BindWidgetToStringSetting(sif, cb, m_config_section, std::move(key_name), si.StringDefaultValue());
layout->addWidget(new QLabel(qApp->translate(translation_ctx, si.display_name), widget_parent), current_row, 0);
layout->addWidget(cb, current_row, 1, 1, 3);
current_row++;
}
@ -585,9 +650,9 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
QLineEdit* le = new QLineEdit(widget_parent);
le->setObjectName(QString::fromUtf8(si.name));
QPushButton* browse_button = new QPushButton(tr("Browse..."), widget_parent);
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, section, std::move(key_name), si.StringDefaultValue());
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, m_config_section, std::move(key_name), si.StringDefaultValue());
connect(browse_button, &QPushButton::clicked, [this, le]() {
QString path = QFileDialog::getOpenFileName(this, tr("Select File"));
const QString path(QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Select File"))));
if (!path.isEmpty())
le->setText(path);
});
@ -596,14 +661,14 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
hbox->addWidget(le, 1);
hbox->addWidget(browse_button);
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), widget_parent), current_row, 0);
layout->addWidget(new QLabel(qApp->translate(translation_ctx, si.display_name), widget_parent), current_row, 0);
layout->addLayout(hbox, current_row, 1, 1, 3);
current_row++;
}
break;
}
QLabel* label = new QLabel(si.description ? qApp->translate(cinfo->name, si.description) : QString(), widget_parent);
QLabel* label = new QLabel(si.description ? qApp->translate(translation_ctx, si.description) : QString(), widget_parent);
label->setWordWrap(true);
layout->addWidget(label, current_row++, 0, 1, 4);
@ -613,13 +678,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
void ControllerCustomSettingsWidget::restoreDefaults()
{
const PAD::ControllerInfo* cinfo = PAD::GetControllerInfo(m_parent->getControllerType());
if (!cinfo || cinfo->num_settings == 0)
return;
for (u32 i = 0; i < cinfo->num_settings; i++)
for (const SettingInfo& si : m_settings)
{
const SettingInfo& si = cinfo->settings[i];
const QString key(QString::fromStdString(si.name));
switch (si.type)
@ -664,6 +724,21 @@ void ControllerCustomSettingsWidget::restoreDefaults()
}
break;
case SettingInfo::Type::StringList:
{
QComboBox* widget = findChild<QComboBox*>(QString::fromStdString(si.name));
if (widget)
{
const QString default_value(QString::fromUtf8(si.StringDefaultValue()));
int index = widget->findData(default_value);
if (index < 0)
index = widget->findText(default_value);
if (index >= 0)
widget->setCurrentIndex(index);
}
}
break;
case SettingInfo::Type::Path:
{
QLineEdit* widget = findChild<QLineEdit*>(QString::fromStdString(si.name));
@ -694,26 +769,32 @@ QIcon ControllerBindingWidget_Base::getIcon() const
void ControllerBindingWidget_Base::initBindingWidgets()
{
const std::string& type = getControllerType();
const PAD::ControllerInfo* cinfo = PAD::GetControllerInfo(getControllerType());
if (!cinfo)
return;
const std::string& config_section = getConfigSection();
std::vector<std::string> bindings(PAD::GetControllerBinds(type));
SettingsInterface* sif = getDialog()->getProfileSettingsInterface();
for (std::string& binding : bindings)
for (u32 i = 0; i < cinfo->num_bindings; i++)
{
InputBindingWidget* widget = findChild<InputBindingWidget*>(QString::fromStdString(binding));
if (!widget)
const InputBindingInfo& bi = cinfo->bindings[i];
if (bi.bind_type == InputBindingInfo::Type::Axis || bi.bind_type == InputBindingInfo::Type::HalfAxis ||
bi.bind_type == InputBindingInfo::Type::Button || bi.bind_type == InputBindingInfo::Type::Pointer ||
bi.bind_type == InputBindingInfo::Type::Device)
{
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%.*s)",
binding.c_str(), static_cast<int>(type.size()), type.data());
continue;
}
InputBindingWidget* widget = findChild<InputBindingWidget*>(QString::fromStdString(bi.name));
if (!widget)
{
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%s)", bi.name, cinfo->name);
continue;
}
widget->initialize(sif, config_section, std::move(binding));
widget->initialize(sif, bi.bind_type, config_section, bi.name);
}
}
const PAD::VibrationCapabilities vibe_caps = PAD::GetControllerVibrationCapabilities(type);
switch (vibe_caps)
switch (cinfo->vibration_caps)
{
case PAD::VibrationCapabilities::LargeSmallMotors:
{
@ -763,3 +844,385 @@ ControllerBindingWidget_Base* ControllerBindingWidget_DualShock2::createInstance
}
//////////////////////////////////////////////////////////////////////////
USBDeviceWidget::USBDeviceWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port)
: QWidget(parent)
, m_dialog(dialog)
, m_config_section(StringUtil::StdStringFromFormat("USB%u", port + 1u))
, m_port_number(port)
{
m_ui.setupUi(this);
populateDeviceTypes();
populatePages();
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
m_dialog->getProfileSettingsInterface(), m_ui.deviceType, m_config_section, "Type", "None");
connect(m_ui.deviceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &USBDeviceWidget::onTypeChanged);
connect(m_ui.deviceSubtype, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &USBDeviceWidget::onSubTypeChanged);
connect(m_ui.bindings, &QPushButton::clicked, this, &USBDeviceWidget::onBindingsClicked);
connect(m_ui.settings, &QPushButton::clicked, this, &USBDeviceWidget::onSettingsClicked);
connect(m_ui.automaticBinding, &QPushButton::clicked, this, &USBDeviceWidget::onAutomaticBindingClicked);
connect(m_ui.clearBindings, &QPushButton::clicked, this, &USBDeviceWidget::onClearBindingsClicked);
}
USBDeviceWidget::~USBDeviceWidget() = default;
QIcon USBDeviceWidget::getIcon() const
{
return QIcon::fromTheme("usb-fill");
}
void USBDeviceWidget::populateDeviceTypes()
{
m_ui.deviceType->addItem(qApp->translate("USB", USB::GetDeviceName("None")), QStringLiteral("None"));
for (const auto& [name, display_name] : USB::GetDeviceTypes())
m_ui.deviceType->addItem(QString::fromStdString(display_name), QString::fromStdString(name));
}
void USBDeviceWidget::populatePages()
{
m_device_type = m_dialog->getStringValue(m_config_section.c_str(), "Type", "None");
m_device_subtype = m_dialog->getIntValue(m_config_section.c_str(), fmt::format("{}_subtype", m_device_type).c_str(), 0);
{
QSignalBlocker sb(m_ui.deviceSubtype);
m_ui.deviceSubtype->clear();
for (const std::string& subtype : USB::GetDeviceSubtypes(m_device_type))
m_ui.deviceSubtype->addItem(qApp->translate("USB", subtype.c_str()));
m_ui.deviceSubtype->setCurrentIndex(m_device_subtype);
m_ui.deviceSubtype->setVisible(m_ui.deviceSubtype->count() > 0);
}
if (m_bindings_widget)
{
m_ui.stackedWidget->removeWidget(m_bindings_widget);
delete m_bindings_widget;
m_bindings_widget = nullptr;
}
if (m_settings_widget)
{
m_ui.stackedWidget->removeWidget(m_settings_widget);
delete m_settings_widget;
m_settings_widget = nullptr;
}
const gsl::span<const InputBindingInfo> bindings(USB::GetDeviceBindings(m_device_type, m_device_subtype));
const gsl::span<const SettingInfo> settings(USB::GetDeviceSettings(m_device_type, m_device_subtype));
m_ui.bindings->setEnabled(!bindings.empty());
m_ui.settings->setEnabled(!settings.empty());
if (!bindings.empty())
{
m_bindings_widget = USBBindingWidget::createInstance(m_device_type, m_device_subtype, bindings, this);
if (m_bindings_widget)
{
m_ui.stackedWidget->addWidget(m_bindings_widget);
m_ui.stackedWidget->setCurrentWidget(m_bindings_widget);
}
}
if (!settings.empty())
{
const QString settings_title(tr("Device Settings"));
m_settings_widget = new ControllerCustomSettingsWidget(
settings, m_config_section, m_device_type + "_", settings_title, m_device_type.c_str(), m_dialog, m_ui.stackedWidget);
m_ui.stackedWidget->addWidget(m_settings_widget);
}
updateHeaderToolButtons();
}
void USBDeviceWidget::onTypeChanged()
{
populatePages();
m_dialog->updateListDescription(m_port_number, this);
}
void USBDeviceWidget::onSubTypeChanged(int new_index)
{
m_dialog->setIntValue(m_config_section.c_str(), fmt::format("{}_subtype", m_device_type).c_str(), new_index);
onTypeChanged();
}
void USBDeviceWidget::updateHeaderToolButtons()
{
const QWidget* current_widget = m_ui.stackedWidget->currentWidget();
const QSignalBlocker bindings_sb(m_ui.bindings);
const QSignalBlocker settings_sb(m_ui.settings);
const bool is_bindings = (m_bindings_widget && current_widget == m_bindings_widget);
const bool is_settings = (m_settings_widget && current_widget == m_settings_widget);
m_ui.bindings->setChecked(is_bindings);
m_ui.automaticBinding->setEnabled(is_bindings);
m_ui.clearBindings->setEnabled(is_bindings);
m_ui.settings->setChecked(is_settings);
}
void USBDeviceWidget::onBindingsClicked()
{
if (!m_bindings_widget)
return;
m_ui.stackedWidget->setCurrentWidget(m_bindings_widget);
updateHeaderToolButtons();
}
void USBDeviceWidget::onSettingsClicked()
{
if (!m_settings_widget)
return;
m_ui.stackedWidget->setCurrentWidget(m_settings_widget);
updateHeaderToolButtons();
}
void USBDeviceWidget::onAutomaticBindingClicked()
{
QMenu menu(this);
bool added = false;
for (const QPair<QString, QString>& dev : m_dialog->getDeviceList())
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
added = true;
}
if (!added)
{
QAction* action = menu.addAction(tr("No devices available"));
action->setEnabled(false);
}
menu.exec(QCursor::pos());
}
void USBDeviceWidget::onClearBindingsClicked()
{
if (QMessageBox::question(QtUtils::GetRootWidget(this), tr("Clear Bindings"),
tr("Are you sure you want to clear all bindings for this controller? This action cannot be undone.")) != QMessageBox::Yes)
{
return;
}
if (m_dialog->isEditingGlobalSettings())
{
{
auto lock = Host::GetSettingsLock();
USB::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
}
Host::CommitBaseSettingChanges();
}
else
{
USB::ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
m_dialog->getProfileSettingsInterface()->Save();
}
// force a refresh after clearing
g_emu_thread->applySettings();
onTypeChanged();
}
void USBDeviceWidget::doDeviceAutomaticBinding(const QString& device)
{
std::vector<std::pair<GenericInputBinding, std::string>> mapping = InputManager::GetGenericBindingMapping(device.toStdString());
if (mapping.empty())
{
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Automatic Binding"),
tr("No generic bindings were generated for device '%1'. The controller/source may not support automatic mapping.").arg(device));
return;
}
bool result;
if (m_dialog->isEditingGlobalSettings())
{
{
auto lock = Host::GetSettingsLock();
result = USB::MapDevice(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
}
if (result)
Host::CommitBaseSettingChanges();
}
else
{
result = USB::MapDevice(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
if (result)
{
m_dialog->getProfileSettingsInterface()->Save();
g_emu_thread->reloadInputBindings();
}
}
// force a refresh after mapping
if (result)
{
g_emu_thread->applySettings();
onTypeChanged();
}
}
//////////////////////////////////////////////////////////////////////////
USBBindingWidget::USBBindingWidget(USBDeviceWidget* parent)
: QWidget(parent)
{
}
USBBindingWidget::~USBBindingWidget()
{
}
QIcon USBBindingWidget::getIcon() const
{
//return QIcon::fromTheme("gamepad-line");
return QIcon::fromTheme("artboard-2-line");
}
std::string USBBindingWidget::getBindingKey(const char* binding_name) const
{
return USB::GetConfigBindKey(getDeviceType(), binding_name);
}
void USBBindingWidget::createWidgets(gsl::span<const InputBindingInfo> bindings)
{
QGroupBox* axis_gbox = nullptr;
QGridLayout* axis_layout = nullptr;
QGroupBox* button_gbox = nullptr;
QGridLayout* button_layout = nullptr;
SettingsInterface* sif = getDialog()->getProfileSettingsInterface();
QScrollArea* scrollarea = new QScrollArea(this);
QWidget* scrollarea_widget = new QWidget(scrollarea);
scrollarea->setWidget(scrollarea_widget);
scrollarea->setWidgetResizable(true);
scrollarea->setFrameShape(QFrame::StyledPanel);
scrollarea->setFrameShadow(QFrame::Plain);
// We do axes and buttons separately, so we can figure out how many columns to use.
constexpr int NUM_AXIS_COLUMNS = 2;
int column = 0;
int row = 0;
for (const InputBindingInfo& bi : bindings)
{
if (bi.bind_type == InputBindingInfo::Type::Axis || bi.bind_type == InputBindingInfo::Type::HalfAxis ||
bi.bind_type == InputBindingInfo::Type::Pointer || bi.bind_type == InputBindingInfo::Type::Device)
{
if (!axis_gbox)
{
axis_gbox = new QGroupBox(tr("Axes"), scrollarea_widget);
axis_layout = new QGridLayout(axis_gbox);
}
QGroupBox* gbox = new QGroupBox(qApp->translate("USB", bi.display_name), axis_gbox);
QVBoxLayout* temp = new QVBoxLayout(gbox);
InputBindingWidget* widget = new InputBindingWidget(gbox, sif, bi.bind_type, getConfigSection(), getBindingKey(bi.name));
temp->addWidget(widget);
axis_layout->addWidget(gbox, row, column);
if ((++column) == NUM_AXIS_COLUMNS)
{
column = 0;
row++;
}
}
}
if (axis_gbox)
axis_layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), ++row, 0);
const int num_button_columns = axis_layout ? 2 : 4;
row = 0;
column = 0;
for (const InputBindingInfo& bi : bindings)
{
if (bi.bind_type == InputBindingInfo::Type::Button)
{
if (!button_gbox)
{
button_gbox = new QGroupBox(tr("Buttons"), scrollarea_widget);
button_layout = new QGridLayout(button_gbox);
}
QGroupBox* gbox = new QGroupBox(qApp->translate("USB", bi.display_name), button_gbox);
QVBoxLayout* temp = new QVBoxLayout(gbox);
InputBindingWidget* widget = new InputBindingWidget(gbox, sif, bi.bind_type, getConfigSection(), getBindingKey(bi.name));
temp->addWidget(widget);
button_layout->addWidget(gbox, row, column);
if ((++column) == num_button_columns)
{
column = 0;
row++;
}
}
}
if (button_gbox)
button_layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), ++row, 0);
if (!axis_gbox && !button_gbox)
return;
QHBoxLayout* layout = new QHBoxLayout(scrollarea_widget);
if (axis_gbox)
layout->addWidget(axis_gbox);
if (button_gbox)
layout->addWidget(button_gbox);
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
QHBoxLayout* main_layout = new QHBoxLayout(this);
main_layout->addWidget(scrollarea);
}
void USBBindingWidget::bindWidgets(gsl::span<const InputBindingInfo> bindings)
{
SettingsInterface* sif = getDialog()->getProfileSettingsInterface();
for (const InputBindingInfo& bi : bindings)
{
if (bi.bind_type == InputBindingInfo::Type::Axis || bi.bind_type == InputBindingInfo::Type::HalfAxis ||
bi.bind_type == InputBindingInfo::Type::Button || bi.bind_type == InputBindingInfo::Type::Pointer ||
bi.bind_type == InputBindingInfo::Type::Device)
{
InputBindingWidget* widget = findChild<InputBindingWidget*>(QString::fromUtf8(bi.name));
if (!widget)
{
Console.Error("(USBBindingWidget) No widget found for '%s'.", bi.name);
continue;
}
widget->initialize(sif, bi.bind_type, getConfigSection(), getBindingKey(bi.name));
}
}
}
USBBindingWidget* USBBindingWidget::createInstance(
const std::string& type, u32 subtype, gsl::span<const InputBindingInfo> bindings, USBDeviceWidget* parent)
{
USBBindingWidget* widget = new USBBindingWidget(parent);
bool has_template = false;
if (type == "Pad")
{
if (subtype == 0) // Generic or Driving Force
{
Ui::USBBindingWidget_DrivingForce().setupUi(widget);
has_template = true;
}
else if (subtype == 3) // GT Force
{
Ui::USBBindingWidget_GTForce().setupUi(widget);
has_template = true;
}
}
if (has_template)
widget->bindWidgets(bindings);
else
widget->createWidgets(bindings);
return widget;
}

View File

@ -19,10 +19,13 @@
#include <QtWidgets/QWidget>
#include "gsl/span"
#include "ui_ControllerBindingWidget.h"
#include "ui_ControllerBindingWidget_DualShock2.h"
#include "ui_ControllerMacroWidget.h"
#include "ui_ControllerMacroEditWidget.h"
#include "ui_USBDeviceWidget.h"
class InputBindingWidget;
class ControllerSettingsDialog;
@ -31,6 +34,8 @@ class ControllerMacroWidget;
class ControllerMacroEditWidget;
class ControllerBindingWidget_Base;
class USBBindingWidget;
class ControllerBindingWidget final : public QWidget
{
Q_OBJECT
@ -133,16 +138,20 @@ class ControllerCustomSettingsWidget : public QWidget
Q_OBJECT
public:
ControllerCustomSettingsWidget(ControllerBindingWidget* parent, QWidget* parent_widget);
ControllerCustomSettingsWidget(gsl::span<const SettingInfo> settings, std::string config_section, std::string config_prefix,
const QString& group_title, const char* translation_ctx, ControllerSettingsDialog* dialog, QWidget* parent_widget);
~ControllerCustomSettingsWidget();
void createSettingWidgets(ControllerBindingWidget* parent, QWidget* widget_parent, QGridLayout* layout, const PAD::ControllerInfo* cinfo);
private Q_SLOTS:
void restoreDefaults();
private:
ControllerBindingWidget* m_parent;
void createSettingWidgets(const char* translation_ctx, QWidget* widget_parent, QGridLayout* layout);
gsl::span<const SettingInfo> m_settings;
std::string m_config_section;
std::string m_config_prefix;
ControllerSettingsDialog* m_dialog;
};
//////////////////////////////////////////////////////////////////////////
@ -182,3 +191,71 @@ public:
private:
Ui::ControllerBindingWidget_DualShock2 m_ui;
};
//////////////////////////////////////////////////////////////////////////
class USBDeviceWidget final : public QWidget
{
Q_OBJECT
public:
USBDeviceWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port);
~USBDeviceWidget();
QIcon getIcon() const;
__fi ControllerSettingsDialog* getDialog() const { return m_dialog; }
__fi const std::string& getConfigSection() const { return m_config_section; }
__fi const std::string& getDeviceType() const { return m_device_type; }
__fi u32 getPortNumber() const { return m_port_number; }
private Q_SLOTS:
void onTypeChanged();
void onSubTypeChanged(int new_index);
void onAutomaticBindingClicked();
void onClearBindingsClicked();
void onBindingsClicked();
void onSettingsClicked();
private:
void populateDeviceTypes();
void populatePages();
void updateHeaderToolButtons();
void doDeviceAutomaticBinding(const QString& device);
Ui::USBDeviceWidget m_ui;
ControllerSettingsDialog* m_dialog;
std::string m_config_section;
std::string m_device_type;
u32 m_device_subtype;
u32 m_port_number;
USBBindingWidget* m_bindings_widget = nullptr;
ControllerCustomSettingsWidget* m_settings_widget = nullptr;
};
class USBBindingWidget : public QWidget
{
Q_OBJECT
public:
USBBindingWidget(USBDeviceWidget* parent);
~USBBindingWidget() override;
__fi ControllerSettingsDialog* getDialog() const { return static_cast<USBDeviceWidget*>(parent())->getDialog(); }
__fi const std::string& getConfigSection() const { return static_cast<USBDeviceWidget*>(parent())->getConfigSection(); }
__fi const std::string& getDeviceType() const { return static_cast<USBDeviceWidget*>(parent())->getDeviceType(); }
__fi u32 getPortNumber() const { return static_cast<USBDeviceWidget*>(parent())->getPortNumber(); }
QIcon getIcon() const;
static USBBindingWidget* createInstance(const std::string& type, u32 subtype, gsl::span<const InputBindingInfo> bindings, USBDeviceWidget* parent);
protected:
std::string getBindingKey(const char* binding_name) const;
void createWidgets(gsl::span<const InputBindingInfo> bindings);
void bindWidgets(gsl::span<const InputBindingInfo> bindings);
};

View File

@ -114,7 +114,8 @@ void ControllerSettingsDialog::onNewProfileClicked()
}
const int res = QMessageBox::question(this, tr("Create Input Profile"),
tr("Do you want to copy all bindings from the currently-selected profile to the new profile? Selecting No will create a completely empty profile."),
tr("Do you want to copy all bindings from the currently-selected profile to the new profile? Selecting No will create a completely "
"empty profile."),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
if (res == QMessageBox::Cancel)
return;
@ -140,7 +141,8 @@ void ControllerSettingsDialog::onNewProfileClicked()
if (!temp_si.Save())
{
QMessageBox::critical(this, tr("Error"), tr("Failed to save the new profile to '%1'.").arg(QString::fromStdString(temp_si.GetFileName())));
QMessageBox::critical(
this, tr("Error"), tr("Failed to save the new profile to '%1'.").arg(QString::fromStdString(temp_si.GetFileName())));
return;
}
@ -252,7 +254,7 @@ void ControllerSettingsDialog::onVibrationMotorsEnumerated(const QList<InputBind
for (const InputBindingKey key : motors)
{
const std::string key_str(InputManager::ConvertInputBindingKeyToString(key));
const std::string key_str(InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type::Motor, key));
if (!key_str.empty())
m_vibration_motors.push_back(QString::fromStdString(key_str));
}
@ -380,8 +382,7 @@ void ControllerSettingsDialog::createWidgets()
}
// load mtap settings
const std::array<bool, 2> mtap_enabled = {{getBoolValue("Pad", "MultitapPort1", false),
getBoolValue("Pad", "MultitapPort2", false)}};
const std::array<bool, 2> mtap_enabled = {{getBoolValue("Pad", "MultitapPort1", false), getBoolValue("Pad", "MultitapPort2", false)}};
// we reorder things a little to make it look less silly for mtap
static constexpr const std::array<u32, MAX_PORTS> mtap_port_order = {{0, 2, 3, 4, 1, 5, 6, 7}};
@ -401,14 +402,29 @@ void ControllerSettingsDialog::createWidgets()
const QString display_name(ci ? QString::fromUtf8(ci->display_name) : QStringLiteral("Unknown"));
QListWidgetItem* item = new QListWidgetItem();
item->setText(mtap_enabled[port] ?
(tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setText(mtap_enabled[port] ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setIcon(m_port_bindings[global_slot]->getIcon());
item->setData(Qt::UserRole, QVariant(global_slot));
m_ui.settingsCategory->addItem(item);
}
// USB ports
for (u32 port = 0; port < USB::NUM_PORTS; port++)
{
m_usb_bindings[port] = new USBDeviceWidget(m_ui.settingsContainer, this, port);
m_ui.settingsContainer->addWidget(m_usb_bindings[port]);
const std::string dtype(getStringValue(fmt::format("USB{}", port + 1).c_str(), "Type", "None"));
const QString display_name(qApp->translate("USB", USB::GetDeviceName(dtype)));
QListWidgetItem* item = new QListWidgetItem();
item->setText(tr("USB Port %1\n%2").arg(port + 1).arg(display_name));
item->setIcon(m_usb_bindings[port]->getIcon());
item->setData(Qt::UserRole, QVariant(MAX_PORTS + port));
m_ui.settingsCategory->addItem(item);
}
// only add hotkeys if we're editing global settings
if (!m_profile_interface || m_profile_interface->GetBoolValue("Pad", "UseProfileHotkeyBindings", false))
{
@ -439,14 +455,32 @@ void ControllerSettingsDialog::updateListDescription(u32 global_slot, Controller
const PAD::ControllerInfo* ci = PAD::GetControllerInfo(widget->getControllerType());
const QString display_name(ci ? QString::fromUtf8(ci->display_name) : QStringLiteral("Unknown"));
item->setText(mtap_enabled ?
(tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setIcon(widget->getIcon());
break;
}
}
}
void ControllerSettingsDialog::updateListDescription(u32 port, USBDeviceWidget* widget)
{
for (int i = 0; i < m_ui.settingsCategory->count(); i++)
{
QListWidgetItem* item = m_ui.settingsCategory->item(i);
const QVariant data(item->data(Qt::UserRole));
if (data.type() == QVariant::UInt && data.toUInt() == (MAX_PORTS + port))
{
const std::string dtype(getStringValue(fmt::format("USB{}", port + 1).c_str(), "Type", "None"));
const QString display_name(qApp->translate("USB", USB::GetDeviceName(dtype)));
item->setText(tr("USB Port %1\n%2").arg(port + 1).arg(display_name));
item->setIcon(widget->getIcon());
break;
}
}
}
void ControllerSettingsDialog::refreshProfileList()
{
const std::vector<std::string> names(PAD::GetInputProfileNames());

View File

@ -15,7 +15,8 @@
#pragma once
#include "ui_ControllerSettingsDialog.h"
#include "Frontend/InputManager.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/USB/USB.h"
#include <QtCore/QList>
#include <QtCore/QPair>
#include <QtCore/QString>
@ -27,6 +28,7 @@
class ControllerGlobalSettingsWidget;
class ControllerBindingWidget;
class HotkeySettingsWidget;
class USBDeviceWidget;
class SettingsInterface;
@ -61,6 +63,7 @@ public:
__fi SettingsInterface* getProfileSettingsInterface() { return m_profile_interface.get(); }
void updateListDescription(u32 global_slot, ControllerBindingWidget* widget);
void updateListDescription(u32 port, USBDeviceWidget* widget);
// Helper functions for updating setting values globally or in the profile.
bool getBoolValue(const char* section, const char* key, bool default_value) const;
@ -93,8 +96,6 @@ private Q_SLOTS:
void createWidgets();
private:
static QIcon getIconForType(const std::string& type);
void refreshProfileList();
void switchProfile(const QString& name);
@ -102,6 +103,7 @@ private:
ControllerGlobalSettingsWidget* m_global_settings = nullptr;
std::array<ControllerBindingWidget*, MAX_PORTS> m_port_bindings{};
std::array<USBDeviceWidget*, USB::NUM_PORTS> m_usb_bindings{};
HotkeySettingsWidget* m_hotkey_settings = nullptr;
QList<QPair<QString, QString>> m_device_list;

View File

@ -9,7 +9,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1300</width>
<width>1305</width>
<height>680</height>
</rect>
</property>
@ -33,13 +33,13 @@
</property>
<property name="minimumSize">
<size>
<width>150</width>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<width>170</width>
<height>16777215</height>
</size>
</property>
@ -92,7 +92,8 @@
<string>Load Profile</string>
</property>
<property name="icon">
<iconset theme="folder-open-line"/>
<iconset theme="folder-open-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@ -113,7 +114,8 @@
<string>Restore Defaults</string>
</property>
<property name="icon">
<iconset theme="restart-line"/>
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>

View File

@ -88,7 +88,8 @@ void HotkeySettingsWidget::createButtons()
QLabel* label = new QLabel(qApp->translate("Hotkeys", hotkey->display_name), m_container);
layout->addWidget(label, target_row, 0);
InputBindingWidget* bind = new InputBindingWidget(m_container, m_dialog->getProfileSettingsInterface(), "Hotkeys", hotkey->name);
InputBindingWidget* bind = new InputBindingWidget(
m_container, m_dialog->getProfileSettingsInterface(), InputBindingInfo::Type::Button, "Hotkeys", hotkey->name);
bind->setMinimumWidth(300);
layout->addWidget(bind, target_row, 1);
}

View File

@ -27,17 +27,17 @@
// _BitScanForward()
#include "pcsx2/GS/GSIntrin.h"
InputBindingDialog::InputBindingDialog(SettingsInterface* sif, std::string section_name, std::string key_name,
std::vector<std::string> bindings, QWidget* parent)
InputBindingDialog::InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name,
std::string key_name, std::vector<std::string> bindings, QWidget* parent)
: QDialog(parent)
, m_sif(sif)
, m_bind_type(bind_type)
, m_section_name(std::move(section_name))
, m_key_name(std::move(key_name))
, m_bindings(std::move(bindings))
{
m_ui.setupUi(this);
m_ui.title->setText(
tr("Bindings for %1 %2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
m_ui.title->setText(tr("Bindings for %1 %2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
m_ui.buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
connect(m_ui.addBinding, &QPushButton::clicked, this, &InputBindingDialog::onAddBindingButtonClicked);
@ -159,8 +159,7 @@ void InputBindingDialog::startListeningForInput(u32 timeout_in_seconds)
m_input_listen_timer->setSingleShot(false);
m_input_listen_timer->start(1000);
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this,
&InputBindingDialog::onInputListenTimerTimeout);
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this, &InputBindingDialog::onInputListenTimerTimeout);
m_input_listen_remaining_seconds = timeout_in_seconds;
m_ui.status->setText(tr("Push Button/Axis... [%1]").arg(m_input_listen_remaining_seconds));
m_ui.addBinding->setEnabled(false);
@ -198,8 +197,7 @@ void InputBindingDialog::addNewBinding()
if (m_new_bindings.empty())
return;
const std::string new_binding(
InputManager::ConvertInputBindingKeysToString(m_new_bindings.data(), m_new_bindings.size()));
const std::string new_binding(InputManager::ConvertInputBindingKeysToString(m_bind_type, m_new_bindings.data(), m_new_bindings.size()));
if (!new_binding.empty())
{
if (std::find(m_bindings.begin(), m_bindings.end(), new_binding) != m_bindings.end())
@ -299,8 +297,7 @@ void InputBindingDialog::inputManagerHookCallback(InputBindingKey key, float val
void InputBindingDialog::hookInputManager()
{
InputManager::SetHook([this](InputBindingKey key, float value) {
QMetaObject::invokeMethod(this, "inputManagerHookCallback", Qt::QueuedConnection, Q_ARG(InputBindingKey, key),
Q_ARG(float, value));
QMetaObject::invokeMethod(this, "inputManagerHookCallback", Qt::QueuedConnection, Q_ARG(InputBindingKey, key), Q_ARG(float, value));
return InputInterceptHook::CallbackResult::StopProcessingEvent;
});
}

View File

@ -15,7 +15,8 @@
#pragma once
#include "ui_InputBindingDialog.h"
#include "Frontend/InputManager.h"
#include "pcsx2/Config.h"
#include "pcsx2/Frontend/InputManager.h"
#include <QtWidgets/QDialog>
#include <optional>
#include <string>
@ -28,7 +29,8 @@ class InputBindingDialog : public QDialog
Q_OBJECT
public:
InputBindingDialog(SettingsInterface* sif, std::string section_name, std::string key_name, std::vector<std::string> bindings, QWidget* parent);
InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name,
std::vector<std::string> bindings, QWidget* parent);
~InputBindingDialog();
protected Q_SLOTS:
@ -61,6 +63,7 @@ protected:
Ui::InputBindingDialog m_ui;
SettingsInterface* m_sif;
InputBindingInfo::Type m_bind_type;
std::string m_section_name;
std::string m_key_name;
std::vector<std::string> m_bindings;

View File

@ -40,7 +40,8 @@ InputBindingWidget::InputBindingWidget(QWidget* parent)
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
}
InputBindingWidget::InputBindingWidget(QWidget* parent, SettingsInterface* sif, std::string section_name, std::string key_name)
InputBindingWidget::InputBindingWidget(
QWidget* parent, SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name)
: QPushButton(parent)
{
setMinimumWidth(225);
@ -48,7 +49,7 @@ InputBindingWidget::InputBindingWidget(QWidget* parent, SettingsInterface* sif,
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
initialize(sif, std::move(section_name), std::move(key_name));
initialize(sif, bind_type, std::move(section_name), std::move(key_name));
}
InputBindingWidget::~InputBindingWidget()
@ -61,9 +62,11 @@ bool InputBindingWidget::isMouseMappingEnabled()
return Host::GetBaseBoolSettingValue("UI", "EnableMouseMapping", false);
}
void InputBindingWidget::initialize(SettingsInterface* sif, std::string section_name, std::string key_name)
void InputBindingWidget::initialize(
SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name)
{
m_sif = sif;
m_bind_type = bind_type;
m_section_name = std::move(section_name);
m_key_name = std::move(key_name);
reloadBinding();
@ -223,8 +226,7 @@ void InputBindingWidget::setNewBinding()
if (m_new_bindings.empty())
return;
const std::string new_binding(
InputManager::ConvertInputBindingKeysToString(m_new_bindings.data(), m_new_bindings.size()));
std::string new_binding(InputManager::ConvertInputBindingKeysToString(m_bind_type, m_new_bindings.data(), m_new_bindings.size()));
if (!new_binding.empty())
{
if (m_sif)
@ -265,9 +267,8 @@ void InputBindingWidget::clearBinding()
void InputBindingWidget::reloadBinding()
{
m_bindings = m_sif ?
m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
m_bindings = m_sif ? m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
updateText();
}
@ -306,8 +307,7 @@ void InputBindingWidget::startListeningForInput(u32 timeout_in_seconds)
m_input_listen_timer->setSingleShot(false);
m_input_listen_timer->start(1000);
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this,
&InputBindingWidget::onInputListenTimerTimeout);
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this, &InputBindingWidget::onInputListenTimerTimeout);
m_input_listen_remaining_seconds = timeout_in_seconds;
setText(tr("Push Button/Axis... [%1]").arg(m_input_listen_remaining_seconds));
@ -365,8 +365,7 @@ void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float val
void InputBindingWidget::hookInputManager()
{
InputManager::SetHook([this](InputBindingKey key, float value) {
QMetaObject::invokeMethod(this, "inputManagerHookCallback", Qt::QueuedConnection, Q_ARG(InputBindingKey, key),
Q_ARG(float, value));
QMetaObject::invokeMethod(this, "inputManagerHookCallback", Qt::QueuedConnection, Q_ARG(InputBindingKey, key), Q_ARG(float, value));
return InputInterceptHook::CallbackResult::StopProcessingEvent;
});
}
@ -378,7 +377,7 @@ void InputBindingWidget::unhookInputManager()
void InputBindingWidget::openDialog()
{
InputBindingDialog binding_dialog(m_sif, m_section_name, m_key_name, m_bindings, QtUtils::GetRootWidget(this));
InputBindingDialog binding_dialog(m_sif, m_bind_type, m_section_name, m_key_name, m_bindings, QtUtils::GetRootWidget(this));
binding_dialog.exec();
reloadBinding();
}
@ -388,7 +387,8 @@ InputVibrationBindingWidget::InputVibrationBindingWidget(QWidget* parent)
connect(this, &QPushButton::clicked, this, &InputVibrationBindingWidget::onClicked);
}
InputVibrationBindingWidget::InputVibrationBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, std::string section_name, std::string key_name)
InputVibrationBindingWidget::InputVibrationBindingWidget(
QWidget* parent, ControllerSettingsDialog* dialog, std::string section_name, std::string key_name)
{
setMinimumWidth(225);
setMaximumWidth(225);

View File

@ -16,6 +16,7 @@
#pragma once
#include "common/Pcsx2Defs.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Config.h"
#include <QtWidgets/QPushButton>
#include <optional>
@ -30,12 +31,13 @@ class InputBindingWidget : public QPushButton
public:
InputBindingWidget(QWidget* parent);
InputBindingWidget(QWidget* parent, SettingsInterface* sif, std::string section_name, std::string key_name);
InputBindingWidget(
QWidget* parent, SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name);
~InputBindingWidget();
static bool isMouseMappingEnabled();
void initialize(SettingsInterface* sif, std::string section_name, std::string key_name);
void initialize(SettingsInterface* sif, InputBindingInfo::Type bind_type, std::string section_name, std::string key_name);
public Q_SLOTS:
void clearBinding();
@ -69,6 +71,7 @@ protected:
void unhookInputManager();
SettingsInterface* m_sif = nullptr;
InputBindingInfo::Type m_bind_type = InputBindingInfo::Type::Unknown;
std::string m_section_name;
std::string m_key_name;
std::vector<std::string> m_bindings;
@ -103,6 +106,6 @@ private:
std::string m_section_name;
std::string m_key_name;
std::string m_binding;
ControllerSettingsDialog* m_dialog;
};

View File

@ -0,0 +1,992 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>USBBindingWidget_DrivingForce</class>
<widget class="QWidget" name="USBBindingWidget_DrivingForce">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1102</width>
<height>476</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,0">
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Hints</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>To bind steering for most modern 900 degree wheels, turn the wheel one rotation in the desired direction, then back again to center.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_33">
<property name="title">
<string>Force Feedback</string>
</property>
<layout class="QGridLayout" name="gridLayout_32">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="FFDevice">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>D-Pad</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="3" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Down</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="DPadDown">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Left</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="DPadLeft">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Up</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="DPadUp">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Right</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="DPadRight">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>L1</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="L1">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>L2</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="L2">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<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>
<widget class="QGroupBox" name="groupBox_29">
<property name="title">
<string>Brake</string>
</property>
<layout class="QGridLayout" name="gridLayout_30">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Brake">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_21">
<property name="title">
<string>Steering Left</string>
</property>
<layout class="QGridLayout" name="gridLayout_21">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="SteeringLeft">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_24">
<property name="title">
<string>Steering Right</string>
</property>
<layout class="QGridLayout" name="gridLayout_24">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="SteeringRight">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<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>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>266</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>266</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../resources/resources.qrc">:/images/DrivingForce.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox_35">
<property name="title">
<string>Select</string>
</property>
<layout class="QGridLayout" name="gridLayout_35">
<item row="0" column="0">
<widget class="InputBindingWidget" name="Select">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_23">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Start</string>
</property>
<layout class="QGridLayout" name="gridLayout_23">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Start">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<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>
</layout>
</item>
<item row="1" column="2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_16">
<property name="title">
<string>Face Buttons</string>
</property>
<layout class="QGridLayout" name="gridLayout_16">
<item row="2" column="2" colspan="2">
<widget class="QGroupBox" name="groupBox_20">
<property name="title">
<string>Circle</string>
</property>
<layout class="QGridLayout" name="gridLayout_20">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Circle">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_17">
<property name="title">
<string>Cross</string>
</property>
<layout class="QGridLayout" name="gridLayout_17">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Cross">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_19">
<property name="title">
<string>Triangle</string>
</property>
<layout class="QGridLayout" name="gridLayout_19">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Triangle">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_18">
<property name="title">
<string>Square</string>
</property>
<layout class="QGridLayout" name="gridLayout_18">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Square">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_28">
<property name="title">
<string>R1</string>
</property>
<layout class="QGridLayout" name="gridLayout_29">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="R1">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_27">
<property name="title">
<string>R2</string>
</property>
<layout class="QGridLayout" name="gridLayout_28">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="R2">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_7">
<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>
<widget class="QGroupBox" name="groupBox_32">
<property name="title">
<string>Accelerator</string>
</property>
<layout class="QGridLayout" name="gridLayout_31">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Throttle">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>InputBindingWidget</class>
<extends>QPushButton</extends>
<header>Settings/InputBindingWidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources/resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,683 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>USBBindingWidget_GTForce</class>
<widget class="QWidget" name="USBBindingWidget_GTForce">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1389</width>
<height>521</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>1100</width>
<height>500</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,0">
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Hints</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>To bind steering for most modern 900 degree wheels, turn the wheel one rotation in the desired direction, then back again to center.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_33">
<property name="title">
<string>Force Feedback</string>
</property>
<layout class="QGridLayout" name="gridLayout_32">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="FFDevice">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,0,0,0,0,1">
<item>
<spacer name="verticalSpacer_3">
<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>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>X</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="X">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>A</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="A">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<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>
<widget class="QGroupBox" name="groupBox_29">
<property name="title">
<string>Brake</string>
</property>
<layout class="QGridLayout" name="gridLayout_30">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Brake">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_21">
<property name="title">
<string>Steering Left</string>
</property>
<layout class="QGridLayout" name="gridLayout_21">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="SteeringLeft">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_24">
<property name="title">
<string>Steering Right</string>
</property>
<layout class="QGridLayout" name="gridLayout_24">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="SteeringRight">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<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>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>266</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../resources/resources.qrc">:/images/GTForce.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox_34">
<property name="title">
<string>Left Paddle</string>
</property>
<layout class="QGridLayout" name="gridLayout_34">
<item row="0" column="0">
<widget class="InputBindingWidget" name="MenuDown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_22">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Right Paddle</string>
</property>
<layout class="QGridLayout" name="gridLayout_22">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="MenuUp">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<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>
</layout>
</item>
<item row="1" column="2">
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0,0,0,1">
<item>
<spacer name="verticalSpacer_6">
<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>
<widget class="QGroupBox" name="groupBox_28">
<property name="title">
<string>Y</string>
</property>
<layout class="QGridLayout" name="gridLayout_29">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Y">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_27">
<property name="title">
<string>B</string>
</property>
<layout class="QGridLayout" name="gridLayout_28">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="B">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_7">
<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>
<widget class="QGroupBox" name="groupBox_32">
<property name="title">
<string>Accelerator</string>
</property>
<layout class="QGridLayout" name="gridLayout_31">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="InputBindingWidget" name="Throttle">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>InputBindingWidget</class>
<extends>QPushButton</extends>
<header>Settings/InputBindingWidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources/resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>USBDeviceWidget</class>
<widget class="QWidget" name="USBDeviceWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>833</width>
<height>617</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Device Type</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="deviceType"/>
</item>
<item>
<widget class="QComboBox" name="deviceSubtype"/>
</item>
<item>
<widget class="QToolButton" name="bindings">
<property name="text">
<string>Bindings</string>
</property>
<property name="icon">
<iconset theme="gamepad-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="settings">
<property name="text">
<string>Settings</string>
</property>
<property name="icon">
<iconset theme="checkbox-multiple-blank-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>460</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QToolButton" name="automaticBinding">
<property name="text">
<string>Automatic Mapping</string>
</property>
<property name="icon">
<iconset theme="gamepad-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="clearBindings">
<property name="text">
<string>Clear Mapping</string>
</property>
<property name="icon">
<iconset theme="file-reduce-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget"/>
</item>
</layout>
</widget>
<resources>
<include location="../resources/resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -361,6 +361,11 @@
</QtUi>
</ItemGroup>
<ItemGroup>
<None Include="Settings\USBBindingWidget_DrivingForce.ui" />
<None Include="Settings\USBBindingWidget_GTForce.ui" />
<QtUi Include="Settings\USBDeviceWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerMacroEditWidget.ui">
<FileType>Document</FileType>
</QtUi>
@ -372,4 +377,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="$(SolutionDir)common\vsprops\QtCompile.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>

View File

@ -269,9 +269,6 @@
<ClInclude Include="Settings\MemoryCardConvertWorker.h">
<Filter>Settings</Filter>
</ClInclude>
<ClInclude Include="Tools\InputRecording\InputRecordingViewer.h">
<Filter>Tools\Input Recording</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtMoc Include="MainWindow.h" />
@ -368,6 +365,7 @@
<QtMoc Include="Settings\AchievementSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="Tools\InputRecording\InputRecordingViewer.h" />
</ItemGroup>
<ItemGroup>
<QtResource Include="resources\resources.qrc">
@ -462,10 +460,19 @@
<QtUi Include="Tools\InputRecording\InputRecordingViewer.ui">
<Filter>Tools\Input Recording</Filter>
</QtUi>
<QtUi Include="Settings\USBDeviceWidget.ui">
<Filter>Settings</Filter>
</QtUi>
</ItemGroup>
<ItemGroup>
<None Include="Settings\FolderSettingsWidget.ui">
<Filter>Settings</Filter>
</None>
<None Include="Settings\USBBindingWidget_GTForce.ui">
<Filter>Settings</Filter>
</None>
<None Include="Settings\USBBindingWidget_DrivingForce.ui">
<Filter>Settings</Filter>
</None>
</ItemGroup>
</Project>
</Project>

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0H24V24H0z"/><path d="M12 1l3 5h-2v7.381l3-1.499-.001-.882H15V7h4v4h-1.001L18 13.118l-5 2.5v1.553c1.166.412 2 1.523 2 2.829 0 1.657-1.343 3-3 3s-3-1.343-3-3c0-1.187.69-2.213 1.69-2.7L6 14l-.001-2.268C5.402 11.386 5 10.74 5 10c0-1.105.895-2 2-2s2 .895 2 2c0 .74-.402 1.387-1 1.732V13l3 2.086V6H9l3-5z" fill="#000000"/></svg>

After

Width:  |  Height:  |  Size: 430 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0H24V24H0z"/><path d="M12 1l3 5h-2v7.381l3-1.499-.001-.882H15V7h4v4h-1.001L18 13.118l-5 2.5v1.553c1.166.412 2 1.523 2 2.829 0 1.657-1.343 3-3 3s-3-1.343-3-3c0-1.187.69-2.213 1.69-2.7L6 14l-.001-2.268C5.402 11.386 5 10.74 5 10c0-1.105.895-2 2-2s2 .895 2 2c0 .74-.402 1.387-1 1.732V13l3 2.086V6H9l3-5z" fill="#ffffff"/></svg>

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -50,6 +50,7 @@
<file>icons/black/svg/shut-down-line.svg</file>
<file>icons/black/svg/trophy-line.svg</file>
<file>icons/black/svg/tv-2-line.svg</file>
<file>icons/black/svg/usb-fill.svg</file>
<file>icons/black/svg/volume-up-line.svg</file>
<file>icons/black/svg/window-2-line.svg</file>
<file>icons/discord.png</file>
@ -107,8 +108,11 @@
<file>icons/white/svg/shut-down-line.svg</file>
<file>icons/white/svg/trophy-line.svg</file>
<file>icons/white/svg/tv-2-line.svg</file>
<file>icons/white/svg/usb-fill.svg</file>
<file>icons/white/svg/volume-up-line.svg</file>
<file>icons/white/svg/window-2-line.svg</file>
<file>images/DrivingForce.png</file>
<file>images/GTForce.png</file>
<file>images/dualshock-2.png</file>
</qresource>
</RCC>

View File

@ -439,91 +439,77 @@ endif()
# USBNull
set(pcsx2USBNullSources USB/USBNull.cpp)
set(pcsx2USBNullHeaders USB/USB.h)
set(pcsx2USBNullHeaders USB/USBNull.h)
# USB sources
set(pcsx2USBSources
USB/USB.cpp
USB/deviceproxy.cpp
USB/configuration.cpp
USB/device_init.cpp
USB/qemu-usb/glib.cpp
USB/qemu-usb/vl.cpp
USB/qemu-usb/iov.cpp
USB/qemu-usb/desc.cpp
USB/qemu-usb/core.cpp
USB/qemu-usb/bus.cpp
USB/qemu-usb/usb-ohci.cpp
USB/qemu-usb/core.cpp
USB/qemu-usb/desc.cpp
USB/qemu-usb/hid.cpp
USB/qemu-usb/input-keymap-qcode-to-qnum.cpp
USB/usb-msd/usb-msd.cpp
USB/usb-pad/usb-pad.cpp
USB/usb-pad/usb-pad-ff.cpp
USB/usb-pad/lg/lg_ff.cpp
USB/usb-pad/usb-seamic.cpp
USB/usb-mic/usb-mic-singstar.cpp
USB/usb-mic/usb-mic-logitech.cpp
USB/usb-mic/usb-headset.cpp
USB/qemu-usb/iov.cpp
USB/qemu-usb/usb-ohci.cpp
USB/shared/ringbuffer.cpp
USB/usb-eyetoy/jo_mpeg.cpp
USB/usb-eyetoy/usb-eyetoy-webcam.cpp
USB/usb-hid/usb-hid.cpp
USB/shared/shared_usb.cpp
USB/shared/inifile_usb.cpp
USB/shared/ringbuffer.cpp
USB/usb-lightgun/guncon2.cpp
USB/usb-mic/usb-headset.cpp
USB/usb-mic/usb-mic-logitech.cpp
USB/usb-mic/usb-mic-singstar.cpp
USB/usb-msd/usb-msd.cpp
USB/usb-pad/lg/lg_ff.cpp
USB/usb-pad/usb-pad-ff.cpp
USB/usb-pad/usb-pad.cpp
USB/usb-pad/usb-seamic.cpp
USB/usb-printer/usb-printer.cpp
)
)
# USB headers
set(pcsx2USBHeaders
USB/USB.h
USB/proxybase.h
USB/deviceproxy.h
USB/configuration.h
USB/platcompat.h
USB/helpers.h
USB/readerwriterqueue/readerwriterqueue.h
USB/readerwriterqueue/atomicops.h
USB/qemu-usb/glib.h
USB/qemu-usb/vl.h
USB/qemu-usb/qusb.h
USB/qemu-usb/USBinternal.h
USB/qemu-usb/desc.h
USB/qemu-usb/iov.h
USB/qemu-usb/queue.h
USB/qemu-usb/hid.h
USB/qemu-usb/input-keymap.h
USB/usb-msd/usb-msd.h
USB/usb-pad/usb-pad.h
USB/usb-pad/padproxy.h
USB/usb-pad/lg/lg_ff.h
USB/usb-mic/audio.h
USB/usb-mic/audiodev.h
USB/usb-mic/audiodeviceproxy.h
USB/usb-mic/usb-mic-singstar.h
USB/usb-mic/usb-headset.h
USB/usb-mic/audiodev-noop.h
../3rdparty/jpgd/jpgd.h
../3rdparty/jpgd/jpge.h
USB/usb-eyetoy/jo_mpeg.h
USB/usb-eyetoy/videodeviceproxy.h
USB/usb-eyetoy/videodev.h
USB/usb-eyetoy/usb-eyetoy-webcam.h
USB/usb-eyetoy/ov519.h
USB/usb-hid/hidproxy.h
USB/usb-hid/usb-hid.h
USB/usb-hid/noop.h
USB/shared/shared_usb.h
USB/shared/inifile_usb.h
USB/qemu-usb/iov.h
USB/qemu-usb/queue.h
USB/qemu-usb/qusb.h
USB/readerwriterqueue/atomicops.h
USB/readerwriterqueue/readerwriterqueue.h
USB/shared/ringbuffer.h
USB/usb-eyetoy/jo_mpeg.h
USB/usb-eyetoy/ov519.h
USB/usb-eyetoy/usb-eyetoy-webcam.h
USB/usb-eyetoy/videodev.h
USB/usb-hid/usb-hid.h
USB/usb-lightgun/guncon2.h
USB/usb-mic/audio.h
USB/usb-mic/audiodev-noop.h
USB/usb-mic/audiodev.h
USB/usb-mic/usb-headset.h
USB/usb-mic/usb-mic-singstar.h
USB/usb-msd/usb-msd.h
USB/usb-pad/lg/lg_ff.h
USB/usb-pad/usb-pad.h
USB/usb-printer/usb-printer.h
)
)
if(TARGET PulseAudio::PulseAudio)
list(APPEND pcsx2USBSources USB/usb-mic/audiodev-pulse.cpp)
list(APPEND pcsx2USBHeaders USB/usb-mic/audiodev-pulse.h)
target_link_libraries(PCSX2_FLAGS INTERFACE PulseAudio::PulseAudio)
if(CUBEB_API)
list(APPEND pcsx2USBSources USB/usb-mic/audiodev-cubeb.cpp)
list(APPEND pcsx2USBHeaders USB/usb-mic/audiodev-cubeb.h)
endif()
if(TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static)
list(APPEND pcsx2USBSources USB/usb-pad/usb-pad-sdl-ff.cpp)
list(APPEND pcsx2USBHeaders USB/usb-pad/usb-pad-sdl-ff.h)
endif()
if(PCSX2_CORE)
# Host PAD
set(pcsx2PADSources
@ -887,36 +873,10 @@ if(WIN32)
)
list(APPEND pcsx2USBSources
USB/qemu-usb/input-keymap-win32-to-qcode.cpp
USB/shared/hidapi.cpp
USB/shared/rawinput_usb.cpp
USB/usb-eyetoy/api_init_win32_eyetoy.cpp
USB/usb-eyetoy/cam-windows.cpp
USB/usb-hid/api_init_win32_hid.cpp
USB/usb-hid/raw/rawinput.cpp
USB/usb-mic/api_init_win32_mic.cpp
USB/usb-mic/audiodev-wasapi.cpp
USB/usb-msd/usb-msd-win32.cpp
USB/usb-pad/api_init_win32_pad.cpp
USB/usb-pad/dx/dinput-config.cpp
USB/usb-pad/dx/dinput.cpp
USB/usb-pad/dx/usb-pad-dx.cpp
USB/usb-pad/raw/raw-config.cpp
USB/usb-pad/raw/usb-pad-raw.cpp
USB/Win32/Config_usb.cpp
)
list(APPEND pcsx2USBHeaders
USB/qemu-usb/input-keymap-win32-to-qcode.h
USB/shared/rawinput_usb.h
USB/usb-eyetoy/cam-windows.h
USB/usb-mic/audiodev-wasapi.h
USB/usb-pad/dx/dx.h
USB/usb-pad/dx/usb-pad-dx.h
USB/usb-pad/dx/versionproxy.h
USB/usb-pad/raw/raw-config-res.h
USB/usb-pad/raw/usb-pad-raw.h
USB/Win32/Config_usb.h
USB/Win32/resource_usb.h
)
list(APPEND pcsx2GSSources
@ -936,39 +896,16 @@ if(WIN32)
GS/Renderers/DX12/GSDevice12.h
GS/Renderers/DX12/GSTexture12.h
)
else()
elseif(Linux)
list(APPEND pcsx2USBSources
USB/icon_buzz_24.cpp
USB/linux/config-gtk.cpp
USB/linux/config.cpp
USB/linux/util.cpp
USB/qemu-usb/input-keymap-linux-to-qcode.cpp
USB/usb-eyetoy/api_init_linux.cpp
USB/usb-eyetoy/cam-linux.cpp
USB/usb-hid/api_init_linux.cpp
USB/usb-hid/evdev/evdev-gtk.cpp
USB/usb-mic/api_init_linux.cpp
USB/usb-msd/usb-msd-gtk.cpp
USB/usb-pad/api_init_linux.cpp
USB/usb-pad/evdev/evdev-ff.cpp
USB/usb-pad/evdev/evdev-gtk.cpp
USB/usb-pad/evdev/evdev.cpp
USB/usb-pad/evdev/shared-gtk.cpp
)
list(APPEND pcsx2USBHeaders
USB/gtk.h
USB/icon_buzz_24.h
USB/linux/actualfile.h
USB/linux/config.h
USB/linux/ini.h
USB/linux/util.h
USB/qemu-usb/input-keymap-linux-to-qcode.h
USB/usb-eyetoy/cam-linux.h
USB/usb-hid/evdev/evdev.cpp
USB/usb-hid/evdev/evdev.h
USB/usb-pad/evdev/evdev-ff.h
USB/usb-pad/evdev/evdev.h
USB/usb-pad/evdev/shared.h
)
else()
list(APPEND pcsx2USBSources
USB/usb-eyetoy/cam-noop.cpp
)
endif()
@ -1654,6 +1591,13 @@ if(Windows)
${pcsx2WindowsHeaders})
endif()
if(PCSX2_CORE)
target_sources(PCSX2 PRIVATE ${pcsx2USBSources} ${pcsx2USBHeaders})
target_link_libraries(PCSX2_FLAGS INTERFACE jpgd)
else()
target_sources(PCSX2 PRIVATE ${pcsx2USBNullSources} ${pcsx2USBNullHeaders})
endif()
# MacOSX/BSD
if(UNIX AND NOT Linux)
if(APPLE)
@ -1664,23 +1608,7 @@ if(UNIX AND NOT Linux)
${pcsx2FreeBSDSources})
endif()
target_sources(PCSX2 PRIVATE
${pcsx2LinuxHeaders}
${pcsx2USBNullSources}
${pcsx2USBNullHeaders})
else()
if(NOT PCSX2_CORE)
target_sources(PCSX2 PRIVATE
${pcsx2USBSources}
${pcsx2USBHeaders})
target_link_libraries(PCSX2_FLAGS INTERFACE
jpgd
PkgConfig::SAMPLERATE
)
else()
target_sources(PCSX2 PRIVATE
${pcsx2USBNullSources}
${pcsx2USBNullHeaders})
endif()
${pcsx2LinuxHeaders})
endif()
target_link_libraries(PCSX2_FLAGS INTERFACE
@ -1872,8 +1800,6 @@ function(setup_main_executable target)
${PCSX2_SOURCE_DIR}/GS/GS.rc
${PCSX2_SOURCE_DIR}/PAD/Windows/PAD.rc
${PCSX2_SOURCE_DIR}/SPU2/Windows/SPU2.rc
${PCSX2_SOURCE_DIR}/USB/usb-pad/dx/versionproxy.rc
${PCSX2_SOURCE_DIR}/USB/usb-pad/raw/raw-config.rc
)
endif()
target_sources(${target} PRIVATE

View File

@ -79,7 +79,10 @@ struct InputBindingInfo
Axis,
HalfAxis,
Motor,
Macro
Pointer, // Receive relative mouse movement events, bind_index is offset by the axis.
Keyboard, // Receive host key events, bind_index is offset by the key code.
Device, // Used for special-purpose device selection, e.g. force feedback.
Macro,
};
const char* name;
@ -1109,6 +1112,35 @@ struct Pcsx2Config
}
};
#ifdef PCSX2_CORE
// ------------------------------------------------------------------------
struct USBOptions
{
enum : u32
{
NUM_PORTS = 2
};
struct Port
{
s32 DeviceType;
u32 DeviceSubtype;
bool operator==(const USBOptions::Port& right) const;
bool operator!=(const USBOptions::Port& right) const;
};
std::array<Port, NUM_PORTS> Ports;
USBOptions();
void LoadSave(SettingsWrapper& wrap);
bool operator==(const USBOptions& right) const;
bool operator!=(const USBOptions& right) const;
};
#endif
// ------------------------------------------------------------------------
// Options struct for each memory card.
//
@ -1203,6 +1235,9 @@ struct Pcsx2Config
FramerateOptions Framerate;
SPU2Options SPU2;
DEV9Options DEV9;
#ifdef PCSX2_CORE
USBOptions USB;
#endif
TraceLogFilters Trace;

View File

@ -155,7 +155,7 @@ bool DInputSource::ReloadDevices()
{
const u32 index = static_cast<u32>(m_controllers.size());
m_controllers.push_back(std::move(cd));
Host::OnInputDeviceConnected(GetDeviceIdentifier(index), name);
InputManager::OnInputDeviceConnected(GetDeviceIdentifier(index), name);
changed = true;
}
}
@ -167,7 +167,7 @@ void DInputSource::Shutdown()
{
while (!m_controllers.empty())
{
Host::OnInputDeviceDisconnected(GetDeviceIdentifier(static_cast<u32>(m_controllers.size() - 1)));
InputManager::OnInputDeviceDisconnected(GetDeviceIdentifier(static_cast<u32>(m_controllers.size() - 1)));
m_controllers.pop_back();
}
}
@ -268,7 +268,7 @@ void DInputSource::PollEvents()
if (hr != DI_OK)
{
Host::OnInputDeviceDisconnected(GetDeviceIdentifier(static_cast<u32>(i)));
InputManager::OnInputDeviceDisconnected(GetDeviceIdentifier(static_cast<u32>(i)));
m_controllers.erase(m_controllers.begin() + i);
continue;
}

View File

@ -1301,7 +1301,7 @@ void FullscreenUI::BeginInputBinding(SettingsInterface* bsi, InputBindingInfo::T
// if this key is in our new binding list, it's a "release", and we're done
SettingsInterface* bsi = GetEditingSettingsInterface(game_settings);
const std::string new_binding(InputManager::ConvertInputBindingKeysToString(
s_input_binding_new_bindings.data(), s_input_binding_new_bindings.size()));
s_input_binding_type, s_input_binding_new_bindings.data(), s_input_binding_new_bindings.size()));
bsi->SetStringValue(s_input_binding_section.c_str(), s_input_binding_key.c_str(), new_binding.c_str());
SetSettingsChanged(bsi);
ClearInputBindingVariables();

View File

@ -46,6 +46,7 @@
#ifdef PCSX2_CORE
#include "PAD/Host/PAD.h"
#include "PAD/Host/KeyStatus.h"
#include "USB/USB.h"
#include "Frontend/FullscreenUI.h"
#include "Frontend/ImGuiManager.h"
#include "Frontend/ImGuiFullscreen.h"
@ -482,6 +483,12 @@ void ImGuiManager::DrawInputsOverlay()
num_ports++;
}
for (u32 port = 0; port < USB::NUM_PORTS; port++)
{
if (EmuConfig.USB.Ports[port].DeviceType >= 0 && !USB::GetDeviceBindings(port).empty())
num_ports++;
}
float current_x = margin;
float current_y = display_size.y - margin - ((static_cast<float>(num_ports) * (font->FontSize + spacing)) - spacing);
@ -544,6 +551,59 @@ void ImGuiManager::DrawInputsOverlay()
current_y += font->FontSize + spacing;
}
for (u32 port = 0; port < USB::NUM_PORTS; port++)
{
if (EmuConfig.USB.Ports[port].DeviceType < 0)
continue;
const gsl::span<const InputBindingInfo> bindings(USB::GetDeviceBindings(port));
if (bindings.empty())
continue;
text.clear();
fmt::format_to(std::back_inserter(text), "USB{} |", port + 1u);
for (const InputBindingInfo& bi : bindings)
{
switch (bi.bind_type)
{
case InputBindingInfo::Type::Axis:
case InputBindingInfo::Type::HalfAxis:
{
// axes are always shown
const float value = static_cast<float>(USB::GetDeviceBindValue(port, bi.bind_index));
if (value >= (254.0f / 255.0f))
fmt::format_to(std::back_inserter(text), " {}", bi.name);
else if (value > (1.0f / 255.0f))
fmt::format_to(std::back_inserter(text), " {}: {:.2f}", bi.name, value);
}
break;
case InputBindingInfo::Type::Button:
{
// buttons only shown when active
const float value = static_cast<float>(USB::GetDeviceBindValue(port, bi.bind_index));
if (value >= 0.5f)
fmt::format_to(std::back_inserter(text), " {}", bi.name);
}
break;
case InputBindingInfo::Type::Motor:
case InputBindingInfo::Type::Macro:
case InputBindingInfo::Type::Unknown:
default:
break;
}
}
dl->AddText(font, font->FontSize, ImVec2(current_x + shadow_offset, current_y + shadow_offset), shadow_color, text.c_str(),
text.c_str() + text.length(), 0.0f, &clip_rect);
dl->AddText(
font, font->FontSize, ImVec2(current_x, current_y), text_color, text.c_str(), text.c_str() + text.length(), 0.0f, &clip_rect);
current_y += font->FontSize + spacing;
}
}
#endif

View File

@ -18,6 +18,7 @@
#include "Frontend/InputSource.h"
#include "Frontend/ImGuiManager.h"
#include "PAD/Host/PAD.h"
#include "USB/USB.h"
#include "common/StringUtil.h"
#include "common/Timer.h"
#include "VMManager.h"
@ -107,11 +108,13 @@ namespace InputManager
static void AddHotkeyBindings(SettingsInterface& si);
static void AddPadBindings(SettingsInterface& si, u32 pad, const char* default_type);
static void AddUSBBindings(SettingsInterface& si, u32 port);
static void UpdateContinuedVibration();
static void GenerateRelativeMouseEvents();
static bool DoEventHook(InputBindingKey key, float value);
static bool PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key);
static bool ProcessEvent(InputBindingKey key, float value, bool skip_button_handlers);
template <typename T>
static void UpdateInputSourceState(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock, InputSourceType type);
@ -158,6 +161,11 @@ static std::array<std::array<PointerAxisState, static_cast<u8>(InputPointerAxis:
s_pointer_state;
static std::array<float, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_scale;
using PointerMoveCallback = std::function<void(InputBindingKey key, float value)>;
using KeyboardEventCallback = std::function<void(InputBindingKey key, float value)>;
static std::vector<KeyboardEventCallback> s_keyboard_event_callbacks;
static std::vector<std::pair<u32, PointerMoveCallback>> s_pointer_move_callbacks;
// ------------------------------------------------------------------------
// Binding Parsing
// ------------------------------------------------------------------------
@ -260,43 +268,75 @@ bool InputManager::ParseBindingAndGetSource(const std::string_view& binding, Inp
return false;
}
std::string InputManager::ConvertInputBindingKeyToString(InputBindingKey key)
std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key)
{
if (key.source_type == InputSourceType::Keyboard)
if (binding_type == InputBindingInfo::Type::Pointer || binding_type == InputBindingInfo::Type::Device)
{
const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data));
if (str.has_value() && !str->empty())
return fmt::format("Keyboard/{}", str->c_str());
}
else if (key.source_type == InputSourceType::Pointer)
{
if (key.source_subtype == InputSubclass::PointerButton)
// pointer and device bindings don't have a data part
if (key.source_type == InputSourceType::Keyboard)
{
if (key.data < s_pointer_button_names.size())
return fmt::format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_names[key.data]);
else
return fmt::format("Pointer-{}/Button{}", u32{key.source_index}, key.data);
return "Keyboard";
}
else if (key.source_subtype == InputSubclass::PointerAxis)
else if (key.source_type == InputSourceType::Pointer)
{
return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data],
key.modifier == InputModifier::Negate ? '-' : '+');
return GetPointerDeviceName(key.data);
}
else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)])
{
// This assumes that it always follows the Type/Binding form.
std::string keystr(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key));
std::string::size_type pos = keystr.find('/');
if (pos != std::string::npos)
keystr.erase(pos);
return keystr;
}
}
else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)])
else
{
return s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key);
if (key.source_type == InputSourceType::Keyboard)
{
const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data));
if (str.has_value() && !str->empty())
return fmt::format("Keyboard/{}", str->c_str());
}
else if (key.source_type == InputSourceType::Pointer)
{
if (key.source_subtype == InputSubclass::PointerButton)
{
if (key.data < s_pointer_button_names.size())
return fmt::format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_names[key.data]);
else
return fmt::format("Pointer-{}/Button{}", u32{key.source_index}, key.data);
}
else if (key.source_subtype == InputSubclass::PointerAxis)
{
return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data],
key.modifier == InputModifier::Negate ? '-' : '+');
}
}
else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)])
{
return s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key);
}
}
return {};
}
std::string InputManager::ConvertInputBindingKeysToString(const InputBindingKey* keys, size_t num_keys)
std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys)
{
// can't have a chord of devices/pointers
if (binding_type == InputBindingInfo::Type::Pointer || binding_type == InputBindingInfo::Type::Device)
{
// so only take the first
if (num_keys > 0)
return ConvertInputBindingKeyToString(binding_type, keys[0]);
}
std::stringstream ss;
for (size_t i = 0; i < num_keys; i++)
{
const std::string keystr(ConvertInputBindingKeyToString(keys[i]));
const std::string keystr(ConvertInputBindingKeyToString(binding_type, keys[i]));
if (keystr.empty())
return std::string();
@ -524,6 +564,23 @@ std::optional<InputBindingKey> InputManager::ParsePointerKey(const std::string_v
return std::nullopt;
}
std::optional<u32> InputManager::GetIndexFromPointerBinding(const std::string_view& source)
{
if (!StringUtil::StartsWith(source, "Pointer-"))
return std::nullopt;
const std::optional<s32> pointer_index = StringUtil::FromChars<s32>(source.substr(8));
if (!pointer_index.has_value() || pointer_index.value() < 0)
return std::nullopt;
return static_cast<u32>(pointer_index.value());
}
std::string InputManager::GetPointerDeviceName(u32 pointer_index)
{
return fmt::format("Pointer-{}", pointer_index);
}
// ------------------------------------------------------------------------
// Binding Enumeration
// ------------------------------------------------------------------------
@ -561,19 +618,35 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index, const ch
if (type.empty() || type == "None")
return;
const std::vector<std::string> bind_names = PAD::GetControllerBinds(type);
if (!bind_names.empty())
const PAD::ControllerInfo* cinfo = PAD::GetControllerInfo(type);
if (!cinfo)
return;
for (u32 i = 0; i < cinfo->num_bindings; i++)
{
for (u32 bind_index = 0; bind_index < static_cast<u32>(bind_names.size()); bind_index++)
const InputBindingInfo& bi = cinfo->bindings[i];
switch (bi.bind_type)
{
const std::string& bind_name = bind_names[bind_index];
const std::vector<std::string> bindings(si.GetStringList(section.c_str(), bind_name.c_str()));
if (!bindings.empty())
case InputBindingInfo::Type::Button:
case InputBindingInfo::Type::Axis:
case InputBindingInfo::Type::HalfAxis:
{
// we use axes for all pad bindings to simplify things, and because they are pressure sensitive
AddBindings(bindings,
InputAxisEventHandler{[pad_index, bind_index](float value) { PAD::SetControllerState(pad_index, bind_index, value); }});
const std::vector<std::string> bindings(si.GetStringList(section.c_str(), bi.name));
if (!bindings.empty())
{
// we use axes for all pad bindings to simplify things, and because they are pressure sensitive
AddBindings(bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index](float value) {
PAD::SetControllerState(pad_index, bind_index, value);
}});
}
}
break;
// TODO: Move vibration motors in here.
default:
break;
}
}
@ -589,14 +662,13 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index, const ch
}
}
const PAD::VibrationCapabilities vibcaps = PAD::GetControllerVibrationCapabilities(type);
if (vibcaps != PAD::VibrationCapabilities::NoVibration)
if (cinfo->vibration_caps != PAD::VibrationCapabilities::NoVibration)
{
PadVibrationBinding vib;
vib.pad_index = pad_index;
bool has_any_bindings = false;
switch (vibcaps)
switch (cinfo->vibration_caps)
{
case PAD::VibrationCapabilities::LargeSmallMotors:
{
@ -623,6 +695,65 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index, const ch
}
}
void InputManager::AddUSBBindings(SettingsInterface& si, u32 port)
{
const std::string device(USB::GetConfigDevice(si, port));
if (device.empty() || device == "None")
return;
const std::string section(USBGetConfigSection(port));
const u32 subtype = USB::GetConfigSubType(si, port, device);
for (const InputBindingInfo& bi : USB::GetDeviceBindings(device, subtype))
{
const std::string bind_name(USB::GetConfigBindKey(device, bi.name));
switch (bi.bind_type)
{
case InputBindingInfo::Type::Button:
case InputBindingInfo::Type::Axis:
case InputBindingInfo::Type::HalfAxis:
{
// normal bindings
const std::vector<std::string> bindings(si.GetStringList(section.c_str(), bind_name.c_str()));
if (!bindings.empty())
{
AddBindings(bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index](
float value) { USB::SetDeviceBindValue(port, bind_index, value); }});
}
}
break;
case InputBindingInfo::Type::Keyboard:
{
// set up to receive keyboard events
s_keyboard_event_callbacks.push_back([port, base = static_cast<u32>(bi.bind_index)](InputBindingKey key, float value) {
USB::SetDeviceBindValue(port, base + key.data, value);
});
}
break;
case InputBindingInfo::Type::Pointer:
{
const std::vector<std::string> bindings(si.GetStringList(section.c_str(), bind_name.c_str()));
for (const std::string& binding : bindings)
{
const std::optional<u32> key(GetIndexFromPointerBinding(binding));
if (!key.has_value())
continue;
s_pointer_move_callbacks.emplace_back(key.value(), [port, base = bi.bind_index](InputBindingKey key, float value) {
USB::SetDeviceBindValue(port, base + key.data, value);
});
}
}
break;
default:
break;
}
}
}
// ------------------------------------------------------------------------
// Event Handling
// ------------------------------------------------------------------------
@ -639,8 +770,7 @@ bool InputManager::HasAnyBindingsForSource(InputBindingKey key)
for (const auto& it : s_binding_map)
{
const InputBindingKey& okey = it.first;
if (okey.source_type == key.source_type && okey.source_index == key.source_index &&
okey.source_subtype == key.source_subtype)
if (okey.source_type == key.source_type && okey.source_index == key.source_index && okey.source_subtype == key.source_subtype)
{
return true;
}
@ -661,7 +791,11 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi
// If imgui ate the event, don't fire our handlers.
const bool skip_button_handlers = PreprocessEvent(key, value, generic_key);
return ProcessEvent(key, value, skip_button_handlers);
}
bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_button_handlers)
{
// find all the bindings associated with this key
const InputBindingKey masked_key = key.MaskDirection();
const auto range = s_binding_map.equal_range(masked_key);
@ -718,8 +852,7 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi
binding->current_mask = new_mask;
// Workaround for multi-key bindings that share the same keys.
if (binding->num_keys > 1 && new_full_state && prev_full_state != new_full_state &&
range.first != range.second)
if (binding->num_keys > 1 && new_full_state && prev_full_state != new_full_state && range.first != range.second)
{
// Because the binding map isn't ordered, we could iterate in the order of Shift+F1 and then
// F1, which would mean that F1 wouldn't get cancelled and still activate. So, to handle this
@ -777,6 +910,9 @@ bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInpu
{
if (ImGuiManager::ProcessHostKeyEvent(key, value))
return true;
for (const KeyboardEventCallback& kbc : s_keyboard_event_callbacks)
kbc(key, value);
}
else if (key.source_type == InputSourceType::Pointer && key.source_subtype == InputSubclass::PointerButton)
{
@ -810,44 +946,66 @@ void InputManager::GenerateRelativeMouseEvents()
if (value != state.last_value)
{
state.last_value = value;
InvokeEvents(key, value, GenericInputBinding::Unknown);
ProcessEvent(key, value, false);
}
if (delta != 0.0f)
{
for (const std::pair<u32, PointerMoveCallback>& pmc : s_pointer_move_callbacks)
{
if (pmc.first == device)
pmc.second(key, delta);
}
}
}
}
}
std::pair<float, float> InputManager::GetPointerAbsolutePosition(u32 index)
{
return std::make_pair(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::X)],
s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::Y)]);
}
void InputManager::UpdatePointerAbsolutePosition(u32 index, float x, float y)
{
const float dx = x - std::exchange(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::X)], x);
const float dy = y - std::exchange(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::Y)], y);
if (dx != 0.0f)
UpdatePointerRelativeDelta(index, InputPointerAxis::X, dx);
s_pointer_state[index][static_cast<u8>(InputPointerAxis::X)].delta.fetch_add(
static_cast<s32>(dx * 65536.0f), std::memory_order_release);
if (dy != 0.0f)
UpdatePointerRelativeDelta(index, InputPointerAxis::Y, dy);
s_pointer_state[index][static_cast<u8>(InputPointerAxis::Y)].delta.fetch_add(
static_cast<s32>(dy * 65536.0f), std::memory_order_release);
ImGuiManager::UpdateMousePosition(x, y);
if (index == 0)
ImGuiManager::UpdateMousePosition(x, y);
}
void InputManager::UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis, float d, bool raw_input)
{
s_host_pointer_positions[index][static_cast<u8>(axis)] += d;
s_pointer_state[index][static_cast<u8>(axis)].delta.fetch_add(static_cast<s32>(d * 65536.0f), std::memory_order_release);
if (index == 0 && axis <= InputPointerAxis::Y)
ImGuiManager::UpdateMousePosition(s_host_pointer_positions[0][0], s_host_pointer_positions[0][1]);
}
bool InputManager::HasPointerAxisBinds()
void InputManager::OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name)
{
std::unique_lock lock(s_binding_map_write_lock);
for (const auto& it : s_binding_map)
{
const InputBindingKey& key = it.first;
if (key.source_type == InputSourceType::Pointer && key.source_subtype == InputSubclass::PointerAxis &&
key.data >= static_cast<u32>(InputPointerAxis::X) && key.data <= static_cast<u32>(InputPointerAxis::Y))
{
return true;
}
}
if (VMManager::HasValidVM())
USB::InputDeviceConnected(identifier);
return false;
Host::OnInputDeviceConnected(identifier, device_name);
}
void InputManager::OnInputDeviceDisconnected(const std::string_view& identifier)
{
if (VMManager::HasValidVM())
USB::InputDeviceDisconnected(identifier);
Host::OnInputDeviceDisconnected(identifier);
}
// ------------------------------------------------------------------------
@ -1017,6 +1175,8 @@ void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& bind
s_binding_map.clear();
s_pad_vibration_array.clear();
s_keyboard_event_callbacks.clear();
s_pointer_move_callbacks.clear();
// Hotkeys use the base configuration, except if the custom hotkeys option is enabled.
const bool use_profile_hotkeys = si.GetBoolValue("Pad", "UseProfileHotkeyBindings", false);
@ -1035,6 +1195,26 @@ void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& bind
1.0f /
std::max(si.GetFloatValue("Pad", fmt::format("Pointer{}Scale", s_pointer_axis_names[axis]).c_str(), default_scale), 1.0f);
}
for (u32 port = 0; port < USB::NUM_PORTS; port++)
AddUSBBindings(binding_si, port);
// Check for relative mode bindings, and enable if there's anything using it.
bool has_relative_mode_bindings = !s_pointer_move_callbacks.empty();
if (!has_relative_mode_bindings)
{
for (const auto& it : s_binding_map)
{
const InputBindingKey& key = it.first;
if (key.source_type == InputSourceType::Pointer && key.source_subtype == InputSubclass::PointerAxis &&
key.data >= static_cast<u32>(InputPointerAxis::X) && key.data <= static_cast<u32>(InputPointerAxis::Y))
{
has_relative_mode_bindings = true;
break;
}
}
}
Host::SetRelativeMouseMode(has_relative_mode_bindings);
}
// ------------------------------------------------------------------------

View File

@ -166,6 +166,7 @@ namespace InputManager
/// Maximum number of host mouse devices.
static constexpr u32 MAX_POINTER_DEVICES = 1;
static constexpr u32 MAX_POINTER_BUTTONS = 3;
/// Returns a pointer to the external input source class, if present.
InputSource* GetInputSourceInterface(InputSourceType type);
@ -179,6 +180,12 @@ namespace InputManager
/// Parses an input class string.
std::optional<InputSourceType> ParseInputSourceString(const std::string_view& str);
/// Parses a pointer device string, i.e. tells you which pointer is specified.
std::optional<u32> GetIndexFromPointerBinding(const std::string_view& str);
/// Returns the device name for a pointer index (e.g. Pointer-0).
std::string GetPointerDeviceName(u32 pointer_index);
/// Converts a key code from a human-readable string to an identifier.
std::optional<u32> ConvertHostKeyboardStringToCode(const std::string_view& str);
@ -199,10 +206,10 @@ namespace InputManager
std::optional<InputBindingKey> ParseInputBindingKey(const std::string_view& binding);
/// Converts a input key to a string.
std::string ConvertInputBindingKeyToString(InputBindingKey key);
std::string ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key);
/// Converts a chord of binding keys to a string.
std::string ConvertInputBindingKeysToString(const InputBindingKey* keys, size_t num_keys);
std::string ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, const InputBindingKey* keys, size_t num_keys);
/// Returns a list of all hotkeys.
std::vector<const HotkeyInfo*> GetHotkeyList();
@ -266,14 +273,20 @@ namespace InputManager
/// The pad vibration state will internally remain, so that when emulation is unpaused, the effect resumes.
void PauseVibration();
/// Reads absolute pointer position.
std::pair<float, float> GetPointerAbsolutePosition(u32 index);
/// Updates absolute pointer position. Can call from UI thread, use when the host only reports absolute coordinates.
void UpdatePointerAbsolutePosition(u32 index, float x, float y);
/// Updates relative pointer position. Can call from the UI thread, use when host supports relative coordinate reporting.
void UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis, float d, bool raw_input = false);
/// Returns true if any bindings are present which require relative mouse movement.
bool HasPointerAxisBinds();
/// Called when a new input device is connected.
void OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name);
/// Called when an input device is disconnected.
void OnInputDeviceDisconnected(const std::string_view& identifier);
} // namespace InputManager
namespace Host
@ -286,4 +299,7 @@ namespace Host
/// Called when an input device is disconnected.
void OnInputDeviceDisconnected(const std::string_view& identifier);
/// Enables relative mouse mode in the host.
void SetRelativeMouseMode(bool enabled);
} // namespace Host

View File

@ -610,7 +610,7 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
m_controllers.push_back(std::move(cd));
Host::OnInputDeviceConnected(StringUtil::StdStringFromFormat("SDL-%d", player_id), name);
InputManager::OnInputDeviceConnected(StringUtil::StdStringFromFormat("SDL-%d", player_id), name);
return true;
}
@ -620,7 +620,7 @@ bool SDLInputSource::CloseDevice(int joystick_index)
if (it == m_controllers.end())
return false;
Host::OnInputDeviceDisconnected(StringUtil::StdStringFromFormat("SDL-%d", it->player_id));
InputManager::OnInputDeviceDisconnected(StringUtil::StdStringFromFormat("SDL-%d", it->player_id));
if (it->haptic)
SDL_HapticClose(it->haptic);

View File

@ -397,16 +397,15 @@ void XInputSource::HandleControllerConnection(u32 index)
cd.last_state = {};
cd.last_state_scp = {};
Host::OnInputDeviceConnected(
InputManager::OnInputDeviceConnected(
StringUtil::StdStringFromFormat("XInput-%u", index), StringUtil::StdStringFromFormat("XInput Controller %u", index));
}
void XInputSource::HandleControllerDisconnection(u32 index)
{
Console.WriteLn("XInput controller %u disconnected.", index);
InputManager::OnInputDeviceDisconnected(StringUtil::StdStringFromFormat("XInput-%u", index));
m_controllers[index] = {};
Host::OnInputDeviceDisconnected(StringUtil::StdStringFromFormat("XInput-%u", index));
}
void XInputSource::CheckForStateChanges(u32 index, const XINPUT_STATE& new_state)

View File

@ -20,6 +20,7 @@
#include "SaveState.h"
#include "pcsx2/Config.h"
#include "pcsx2/GS/config.h"
#include "gsl/span"
#include <map>
@ -87,6 +88,10 @@ void GSgetInternalResolution(int* width, int* height);
void GSgetStats(std::string& info);
void GSgetTitleStats(std::string& info);
/// Converts window position to normalized display coordinates (0..1). A value less than 0 or greater than 1 is
/// returned if the position lies outside the display area.
void GSTranslateWindowToDisplayCoordinates(float window_x, float window_y, float* display_x, float* display_y);
void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config);
void GSSwitchRenderer(GSRendererType new_renderer);
void GSResetAPIState();

View File

@ -71,9 +71,15 @@ static std::mutex s_screenshot_threads_mutex;
std::unique_ptr<GSRenderer> g_gs_renderer;
// Since we read this on the EE thread, we can't put it in the renderer, because
// we might be switching while the other thread reads it.
static GSVector4 s_last_draw_rect;
GSRenderer::GSRenderer()
: m_shader_time_start(Common::Timer::GetCurrentValue())
{
s_last_draw_rect = GSVector4::zero();
}
GSRenderer::~GSRenderer() = default;
@ -686,6 +692,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
draw_rect = CalculateDrawDstRect(g_host_display->GetWindowWidth(), g_host_display->GetWindowHeight(),
src_rect, current->GetSize(), g_host_display->GetDisplayAlignment(), g_host_display->UsesLowerLeftOrigin(),
GetVideoMode() == GSVideoMode::SDTV_480P || (GSConfig.PCRTCOverscan && GSConfig.PCRTCOffsets));
s_last_draw_rect = draw_rect;
if (GSConfig.CASMode != GSCASMode::Disabled)
{
@ -924,6 +931,7 @@ void GSRenderer::PresentCurrentFrame()
const GSVector4 draw_rect(CalculateDrawDstRect(g_host_display->GetWindowWidth(), g_host_display->GetWindowHeight(),
src_rect, current->GetSize(), g_host_display->GetDisplayAlignment(), g_host_display->UsesLowerLeftOrigin(),
GetVideoMode() == GSVideoMode::SDTV_480P || (GSConfig.PCRTCOverscan && GSConfig.PCRTCOffsets)));
s_last_draw_rect = draw_rect;
const u64 current_time = Common::Timer::GetCurrentValue();
const float shader_time = static_cast<float>(Common::Timer::ConvertValueToSeconds(current_time - m_shader_time_start));
@ -937,6 +945,23 @@ void GSRenderer::PresentCurrentFrame()
g_gs_device->RestoreAPIState();
}
void GSTranslateWindowToDisplayCoordinates(float window_x, float window_y, float* display_x, float* display_y)
{
const float draw_width = s_last_draw_rect.z - s_last_draw_rect.x;
const float draw_height = s_last_draw_rect.w - s_last_draw_rect.y;
const float rel_x = window_x - s_last_draw_rect.x;
const float rel_y = window_y - s_last_draw_rect.y;
if (rel_x < 0 || rel_x > draw_width || rel_y < 0 || rel_y > draw_height)
{
*display_x = -1.0f;
*display_y = -1.0f;
return;
}
*display_x = rel_x / draw_width;
*display_y = rel_y / draw_height;
}
#ifndef PCSX2_CORE
bool GSRenderer::BeginCapture(std::string& filename)

View File

@ -21,6 +21,12 @@
#include "Gif_Unit.h"
#include "SPU2/spu2.h"
#ifdef PCSX2_CORE
#include "USB/USB.h"
#else
#include "USB/USBNull.h"
#endif
#include "fmt/core.h"
using namespace R5900;
@ -78,7 +84,7 @@ void hwReset()
vif1Reset();
gif_fifo.init();
rcntInit();
USBreset();
}
__fi uint intcInterrupt()

View File

@ -24,7 +24,11 @@
#include "Common.h"
#include "SPU2/spu2.h"
#include "DEV9/DEV9.h"
#ifdef PCSX2_CORE
#include "USB/USB.h"
#else
#include "USB/USBNull.h"
#endif
#include "IopHw.h"
#include "IopDma.h"
#include "CDVD/CDVD.h"

View File

@ -15,7 +15,11 @@
#include "PrecompiledHeader.h"
#include "DEV9/DEV9.h"
#ifdef PCSX2_CORE
#include "USB/USB.h"
#else
#include "USB/USBNull.h"
#endif
#include "IopHw.h"
#include "IopDma.h"
#include "Common.h"

View File

@ -600,12 +600,6 @@ void PAD::CopyConfiguration(SettingsInterface* dest_si, const SettingsInterface&
}
}
PAD::VibrationCapabilities PAD::GetControllerVibrationCapabilities(const std::string_view& type)
{
const ControllerInfo* info = GetControllerInfo(type);
return info ? info->vibration_caps : VibrationCapabilities::NoVibration;
}
static u32 TryMapGenericMapping(SettingsInterface& si, const std::string& section,
const InputManager::GenericInputBindingMapping& mapping, GenericInputBinding generic_name,
const char* bind_name)

View File

@ -106,9 +106,6 @@ namespace PAD
/// Returns the list of binds for the specified controller type.
std::vector<std::string> GetControllerBinds(const std::string_view& type);
/// Returns the vibration configuration for the specified controller type.
VibrationCapabilities GetControllerVibrationCapabilities(const std::string_view& type);
/// Returns general information for the specified controller type.
const ControllerInfo* GetControllerInfo(ControllerType type);
const ControllerInfo* GetControllerInfo(const std::string_view& name);

View File

@ -26,7 +26,10 @@
#include "CDVD/CDVDcommon.h"
#include "MemoryCardFile.h"
#ifndef PCSX2_CORE
#ifdef PCSX2_CORE
#include "USB/USB.h"
#else
#include "USB/USBNull.h"
#include "gui/AppConfig.h"
#include "GS/GS.h"
#endif
@ -1077,6 +1080,62 @@ void Pcsx2Config::FramerateOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapEntry(SlomoScalar);
}
#ifdef PCSX2_CORE
Pcsx2Config::USBOptions::USBOptions()
{
for (u32 i = 0; i < static_cast<u32>(Ports.size()); i++)
{
Ports[i].DeviceType = -1;
Ports[i].DeviceSubtype = 0;
}
}
void Pcsx2Config::USBOptions::LoadSave(SettingsWrapper& wrap)
{
for (u32 i = 0; i < static_cast<u32>(Ports.size()); i++)
{
const std::string section(USBGetConfigSection(i));
std::string device = USB::DeviceTypeIndexToName(Ports[i].DeviceType);
wrap.Entry(section.c_str(), "Type", device, device);
if (wrap.IsLoading())
Ports[i].DeviceType = USB::DeviceTypeNameToIndex(device);
const std::string subtype_key(fmt::format("{}_subtype", USB::DeviceTypeIndexToName(Ports[i].DeviceType)));
wrap.Entry(section.c_str(), subtype_key.c_str(), Ports[i].DeviceSubtype);
}
}
bool Pcsx2Config::USBOptions::Port::operator==(const USBOptions::Port& right) const
{
return OpEqu(DeviceType) && OpEqu(DeviceSubtype);
}
bool Pcsx2Config::USBOptions::Port::operator!=(const USBOptions::Port& right) const
{
return !this->operator==(right);
}
bool Pcsx2Config::USBOptions::operator==(const USBOptions& right) const
{
for (u32 i = 0; i < static_cast<u32>(Ports.size()); i++)
{
if (!OpEqu(Ports[i]))
return false;
}
return true;
}
bool Pcsx2Config::USBOptions::operator!=(const USBOptions& right) const
{
return !this->operator==(right);
}
#endif
#ifdef ENABLE_ACHIEVEMENTS
Pcsx2Config::AchievementsOptions::AchievementsOptions()
@ -1197,6 +1256,9 @@ void Pcsx2Config::LoadSave(SettingsWrapper& wrap)
Debugger.LoadSave(wrap);
Trace.LoadSave(wrap);
#ifdef PCSX2_CORE
USB.LoadSave(wrap);
#endif
#ifdef ENABLE_ACHIEVEMENTS
Achievements.LoadSave(wrap);

View File

@ -38,7 +38,6 @@
#include "Elfheader.h"
#include "CDVD/CDVD.h"
#include "USB/USB.h"
#include "Patch.h"
#include "GameDatabase.h"
@ -120,9 +119,6 @@ void cpuReset()
g_GameStarted = false;
g_GameLoading = false;
// Probably not the right place, but it has to be done when the ram is actually initialized
USBsetRAM(iopMem->Main);
// FIXME: LastELF should be reset on media changes as well as on CPU resets, in
// the very unlikely case that a user swaps to another media source that "looks"
// the same (identical ELF names) but is actually different (devs actually could

View File

@ -40,14 +40,15 @@
#include "GS.h"
#include "GS/GS.h"
#include "SPU2/spu2.h"
#include "USB/USB.h"
#include "PAD/Gamepad.h"
#ifndef PCSX2_CORE
#include "gui/App.h"
#include "gui/ConsoleLogger.h"
#include "gui/SysThreads.h"
#include "USB/USBNull.h"
#else
#include "USB/USB.h"
#include "VMManager.h"
#endif
@ -424,7 +425,7 @@ static int SysState_MTGSFreeze(FreezeAction mode, freezeData* fP)
static constexpr SysState_Component SPU2{ "SPU2", SPU2freeze };
static constexpr SysState_Component PAD_{ "PAD", PADfreeze };
static constexpr SysState_Component USB{ "USB", USBfreeze };
static constexpr SysState_Component USB_{ "USB", USBfreeze };
static constexpr SysState_Component GS{ "GS", SysState_MTGSFreeze };
@ -644,8 +645,8 @@ public:
virtual ~SavestateEntry_USB() = default;
const char* GetFilename() const { return "USB.bin"; }
void FreezeIn(zip_file_t* zf) const { return SysState_ComponentFreezeIn(zf, USB); }
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, USB); }
void FreezeIn(zip_file_t* zf) const { return SysState_ComponentFreezeIn(zf, USB_); }
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, USB_); }
bool IsRequired() const { return false; }
};
@ -726,7 +727,7 @@ static const std::unique_ptr<BaseSavestateEntry> SavestateEntries[] = {
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_VU0prog),
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_VU1prog),
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_SPU2),
#ifndef PCSX2_CORE
#ifdef PCSX2_CORE
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_USB),
#endif
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_PAD),

File diff suppressed because it is too large Load Diff

View File

@ -15,32 +15,85 @@
#pragma once
#include <cstdio>
#include <cstring>
#include <optional>
#include <string>
#include <limits.h>
#include <string_view>
#include <utility>
#include <vector>
#include "gsl/span"
#include "Config.h"
#include "SaveState.h"
class SettingsInterface;
namespace USB
{
enum : u32
{
NUM_PORTS = 2,
};
s32 DeviceTypeNameToIndex(const std::string_view& device);
const char* DeviceTypeIndexToName(s32 device);
std::vector<std::pair<std::string, std::string>> GetDeviceTypes();
const char* GetDeviceName(const std::string_view& device);
std::vector<std::string> GetDeviceSubtypes(const std::string_view& device);
gsl::span<const InputBindingInfo> GetDeviceBindings(const std::string_view& device, u32 subtype);
gsl::span<const SettingInfo> GetDeviceSettings(const std::string_view& device, u32 subtype);
gsl::span<const InputBindingInfo> GetDeviceBindings(u32 port);
float GetDeviceBindValue(u32 port, u32 bind_index);
void SetDeviceBindValue(u32 port, u32 bind_index, float value);
/// Called when a new input device is connected.
void InputDeviceConnected(const std::string_view& identifier);
/// Called when an input device is disconnected.
void InputDeviceDisconnected(const std::string_view& identifier);
std::string GetConfigDevice(const SettingsInterface& si, u32 port);
u32 GetConfigSubType(const SettingsInterface& si, u32 port, const std::string_view& devname);
/// Returns the configuration key for the specified bind and device type.
std::string GetConfigBindKey(const std::string_view& device, const std::string_view& bind_name);
/// Performs automatic controller mapping with the provided list of generic mappings.
bool MapDevice(SettingsInterface& si, u32 port, const std::vector<std::pair<GenericInputBinding, std::string>>& mapping);
/// Clears all bindings for a given port.
void ClearPortBindings(SettingsInterface& si, u32 port);
/// Identifies any device/subtype changes and recreates devices.
void CheckForConfigChanges(const Pcsx2Config& old_config);
/// Reads a device-specific configuration boolean.
bool GetConfigBool(SettingsInterface& si, u32 port, const char* devname, const char* key, bool default_value);
/// Reads a device-specific configuration integer.
s32 GetConfigInt(SettingsInterface& si, u32 port, const char* devname, const char* key, s32 default_value);
/// Reads a device-specific configuration floating-point value.
float GetConfigFloat(SettingsInterface& si, u32 port, const char* devname, const char* key, float default_value);
/// Reads a device-specific configuration string.
std::string GetConfigString(SettingsInterface& si, u32 port, const char* devname, const char* key, const char* default_value = "");
} // namespace USB
std::string USBGetConfigSection(int port);
struct WindowInfo;
// ---------------------------------------------------------------------
#define USBdefs
extern u8* ram;
// ---------------------------------------------------------------------
void USBconfigure();
void DestroyDevices();
void CreateDevices();
s32 USBinit();
void USBasync(u32 cycles);
void USBshutdown();
void USBclose();
s32 USBopen(const WindowInfo& wi);
bool USBopen();
void USBreset();
s32 USBfreeze(FreezeAction mode, freezeData* data);
u8 USBread8(u32 addr);
@ -51,12 +104,3 @@ void USBwrite16(u32 addr, u16 value);
void USBwrite32(u32 addr, u32 value);
void USBsetRAM(void* mem);
extern FILE* usbLog;
s64 get_clock();
/* usb-pad-raw.cpp */
#if _WIN32
#include "common/RedtapeWindows.h"
extern HWND gsWnd;
#endif

View File

@ -15,19 +15,15 @@
#include "PrecompiledHeader.h"
#include "USB.h"
u8* ram = nullptr;
#include "USBNull.h"
void USBconfigure() {}
void DestroyDevices() {}
void CreateDevices() {}
s32 USBinit() { return 0; }
void USBasync(u32 cycles) {}
void USBshutdown() {}
void USBclose() {}
void USBreset() {}
s32 USBopen(const WindowInfo& wi) { return 0; }
s32 USBfreeze(FreezeAction mode, freezeData* data) { return 0; }
@ -37,8 +33,3 @@ u32 USBread32(u32 addr) { return 0; }
void USBwrite8(u32 addr, u8 value) {}
void USBwrite16(u32 addr, u16 value) {}
void USBwrite32(u32 addr, u32 value) {}
void USBsetRAM(void* mem) { ram = static_cast<u8*>(mem); }
FILE* usbLog = nullptr;
s64 get_clock() { return 0; };

View File

@ -14,7 +14,29 @@
*/
#pragma once
#include <string>
bool file_exists(std::string path);
bool dir_exists(std::string path);
#include <cstdio>
#include <cstring>
#include <string>
#include <limits.h>
#include "SaveState.h"
struct WindowInfo;
void USBconfigure();
s32 USBinit();
void USBasync(u32 cycles);
void USBshutdown();
void USBclose();
void USBreset();
s32 USBopen(const WindowInfo& wi);
s32 USBfreeze(FreezeAction mode, freezeData* data);
u8 USBread8(u32 addr);
u16 USBread16(u32 addr);
u32 USBread32(u32 addr);
void USBwrite8(u32 addr, u8 value);
void USBwrite16(u32 addr, u16 value);
void USBwrite32(u32 addr, u32 value);

View File

@ -1,272 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "gui/AppCoreThread.h"
#include "USB/USB.h"
#include "resource_usb.h"
#include "Config_usb.h"
#include "USB/deviceproxy.h"
#include "USB/usb-pad/padproxy.h"
#include "USB/usb-mic/audiodeviceproxy.h"
#include "USB/configuration.h"
#include "USB/shared/inifile_usb.h"
HINSTANCE hInstUSB;
void SysMessageA(const char* fmt, ...)
{
va_list list;
char tmp[512];
va_start(list, fmt);
vsprintf_s(tmp, 512, fmt, list);
va_end(list);
MessageBoxA(0, tmp, "USB Msg", 0);
}
void SysMessageW(const wchar_t* fmt, ...)
{
va_list list;
wchar_t tmp[512];
va_start(list, fmt);
vswprintf_s(tmp, 512, fmt, list);
va_end(list);
MessageBoxW(0, tmp, L"USB Msg", 0);
}
void SelChangedAPI(HWND hW, int port)
{
int sel = SendDlgItemMessage(hW, port ? IDC_COMBO_API1_USB : IDC_COMBO_API2_USB, CB_GETCURSEL, 0, 0);
int devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1_USB : IDC_COMBO2_USB, CB_GETCURSEL, 0, 0);
if (devtype == 0)
return;
devtype--;
auto& rd = RegisterDevice::instance();
auto devName = rd.Name(devtype);
auto apis = rd.Device(devtype)->ListAPIs();
auto it = apis.begin();
std::advance(it, sel);
changedAPIs[std::make_pair(port, devName)] = *it;
}
void SelChangedSubtype(HWND hW, int port)
{
int sel = SendDlgItemMessage(hW, port ? IDC_COMBO_WHEEL_TYPE1_USB : IDC_COMBO_WHEEL_TYPE2_USB, CB_GETCURSEL, 0, 0);
int devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1_USB : IDC_COMBO2_USB, CB_GETCURSEL, 0, 0);
if (devtype == 0)
return;
devtype--;
auto& rd = RegisterDevice::instance();
auto devName = rd.Name(devtype);
changedSubtype[std::make_pair(port, devName)] = sel;
}
void PopulateAPIs(HWND hW, int port)
{
SendDlgItemMessage(hW, port ? IDC_COMBO_API1_USB : IDC_COMBO_API2_USB, CB_RESETCONTENT, 0, 0);
int devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1_USB : IDC_COMBO2_USB, CB_GETCURSEL, 0, 0);
if (devtype == 0)
return;
devtype--;
auto& rd = RegisterDevice::instance();
auto dev = rd.Device(devtype);
auto devName = rd.Name(devtype);
auto apis = dev->ListAPIs();
std::string selApi = GetSelectedAPI(std::make_pair(port, devName));
std::string var;
std::wstring tmp;
if (!LoadSetting(nullptr, port, rd.Name(devtype), N_DEVICE_API, tmp))
{
if (apis.begin() != apis.end())
{
selApi = *apis.begin();
changedAPIs[std::make_pair(port, devName)] = selApi;
}
}
var = wstr_to_str(tmp);
int i = 0, sel = 0;
for (auto& api : apis)
{
auto name = dev->LongAPIName(api);
if (!name)
continue;
SendDlgItemMessageW(hW, port ? IDC_COMBO_API1_USB : IDC_COMBO_API2_USB, CB_ADDSTRING, 0, (LPARAM)name);
if (api == var)
sel = i;
i++;
}
SendDlgItemMessage(hW, port ? IDC_COMBO_API1_USB : IDC_COMBO_API2_USB, CB_SETCURSEL, sel, 0);
}
void PopulateSubType(HWND hW, int port)
{
SendDlgItemMessage(hW, port ? IDC_COMBO_WHEEL_TYPE1_USB : IDC_COMBO_WHEEL_TYPE2_USB, CB_RESETCONTENT, 0, 0);
int devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1_USB : IDC_COMBO2_USB, CB_GETCURSEL, 0, 0);
if (devtype == 0)
return;
devtype--;
auto& rd = RegisterDevice::instance();
auto dev = rd.Device(devtype);
auto devName = rd.Name(devtype);
int sel = 0;
if (!LoadSetting(nullptr, port, dev->TypeName(), N_DEV_SUBTYPE, sel))
{
changedSubtype[std::make_pair(port, devName)] = sel;
}
for (auto subtype : dev->SubTypes())
{
SendDlgItemMessageA(hW, port ? IDC_COMBO_WHEEL_TYPE1_USB : IDC_COMBO_WHEEL_TYPE2_USB, CB_ADDSTRING, 0, (LPARAM)subtype.c_str());
}
SendDlgItemMessage(hW, port ? IDC_COMBO_WHEEL_TYPE1_USB : IDC_COMBO_WHEEL_TYPE2_USB, CB_SETCURSEL, sel, 0);
}
BOOL CALLBACK ConfigureDlgProcUSB(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int port;
switch (uMsg)
{
case WM_INITDIALOG:
LoadConfig();
CheckDlgButton(hW, IDC_LOGGING_USB, conf.Log);
//Selected emulated devices.
SendDlgItemMessageA(hW, IDC_COMBO1_USB, CB_ADDSTRING, 0, (LPARAM) "None");
SendDlgItemMessageA(hW, IDC_COMBO2_USB, CB_ADDSTRING, 0, (LPARAM) "None");
{
auto& rd = RegisterDevice::instance();
int i = 0, p1 = 0, p2 = 0;
for (auto& name : rd.Names())
{
i++; //jump over "None"
auto dev = rd.Device(name);
SendDlgItemMessageW(hW, IDC_COMBO1_USB, CB_ADDSTRING, 0, (LPARAM)dev->Name());
SendDlgItemMessageW(hW, IDC_COMBO2_USB, CB_ADDSTRING, 0, (LPARAM)dev->Name());
//Port 1 aka device/player 1
if (conf.Port[1] == name)
p1 = i;
//Port 0 aka device/player 2
if (conf.Port[0] == name)
p2 = i;
}
SendDlgItemMessage(hW, IDC_COMBO1_USB, CB_SETCURSEL, p1, 0);
SendDlgItemMessage(hW, IDC_COMBO2_USB, CB_SETCURSEL, p2, 0);
PopulateAPIs(hW, 0);
PopulateAPIs(hW, 1);
PopulateSubType(hW, 0);
PopulateSubType(hW, 1);
}
return TRUE;
break;
case WM_COMMAND:
switch (HIWORD(wParam))
{
case CBN_SELCHANGE:
switch (LOWORD(wParam))
{
case IDC_COMBO_API1_USB:
case IDC_COMBO_API2_USB:
port = (LOWORD(wParam) == IDC_COMBO_API1_USB) ? 1 : 0;
SelChangedAPI(hW, port);
break;
case IDC_COMBO1_USB:
case IDC_COMBO2_USB:
port = (LOWORD(wParam) == IDC_COMBO1_USB) ? 1 : 0;
PopulateAPIs(hW, port);
PopulateSubType(hW, port);
break;
case IDC_COMBO_WHEEL_TYPE1_USB:
case IDC_COMBO_WHEEL_TYPE2_USB:
port = (LOWORD(wParam) == IDC_COMBO_WHEEL_TYPE1_USB) ? 1 : 0;
SelChangedSubtype(hW, port);
break;
}
break;
case BN_CLICKED:
switch (LOWORD(wParam))
{
case IDC_CONFIGURE1_USB:
case IDC_CONFIGURE2_USB:
{
LRESULT devtype, apitype;
port = (LOWORD(wParam) == IDC_CONFIGURE1_USB) ? 1 : 0;
devtype = SendDlgItemMessage(hW, port ? IDC_COMBO1_USB : IDC_COMBO2_USB, CB_GETCURSEL, 0, 0);
apitype = SendDlgItemMessage(hW, port ? IDC_COMBO_API1_USB : IDC_COMBO_API2_USB, CB_GETCURSEL, 0, 0);
if (devtype > 0)
{
devtype--;
auto device = RegisterDevice::instance().Device(devtype);
if (device)
{
auto list = device->ListAPIs();
auto it = list.begin();
std::advance(it, apitype);
if (it == list.end())
break;
std::string api = *it;
Win32Handles handles(hInstUSB, hW);
if (device->Configure(port, api, &handles) == RESULT_FAILED)
SysMessage(TEXT("Some settings may not have been saved!\n"));
}
}
}
break;
case IDCANCEL:
EndDialog(hW, TRUE);
return TRUE;
case IDOK:
conf.Log = IsDlgButtonChecked(hW, IDC_LOGGING_USB);
{
auto& regInst = RegisterDevice::instance();
int i;
//device type
i = SendDlgItemMessage(hW, IDC_COMBO1_USB, CB_GETCURSEL, 0, 0);
conf.Port[1] = regInst.Name(i - 1);
i = SendDlgItemMessage(hW, IDC_COMBO2_USB, CB_GETCURSEL, 0, 0);
conf.Port[0] = regInst.Name(i - 1);
}
SaveConfig();
CreateDevices();
EndDialog(hW, RESULT_OK);
return TRUE;
}
}
}
return FALSE;
}
void USBconfigure()
{
ScopedCoreThreadPause paused_core;
USBsetSettingsDir();
RegisterDevice::Register();
DialogBox(hInstUSB,
MAKEINTRESOURCE(IDD_CONFIG_USB),
GetActiveWindow(),
(DLGPROC)ConfigureDlgProcUSB);
paused_core.AllowResume();
}

View File

@ -1,45 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WIN32_H
#define WIN32_H
#include <commctrl.h>
typedef struct Win32Handles
{
HINSTANCE hInst;
HWND hWnd;
Win32Handles(HINSTANCE i, HWND w)
: hInst(i)
, hWnd(w)
{
}
} Win32Handles;
#define CHECKED_SET_MAX_INT(var, hDlg, nIDDlgItem, bSigned, min, max) \
do \
{ \
/*CheckControlTextIsNumber(GetDlgItem(hDlg, nIDDlgItem), bSigned, 0);*/ \
var = GetDlgItemInt(hDlg, nIDDlgItem, NULL, bSigned); \
if (var < min) \
var = min; \
else if (var > max) \
{ \
var = max; \
SetDlgItemInt(hDlg, nIDDlgItem, var, bSigned); \
SendMessage(GetDlgItem(hDlg, nIDDlgItem), EM_SETSEL, -2, -2); \
} \
} while (0)
#endif

View File

@ -1,206 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource_usb.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "WinResrc.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Anglais (États-Unis) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DLGMSD_USB DIALOGEX 0, 0, 316, 74
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "USB Mass Storage Device"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,204,54,50,14
PUSHBUTTON "Cancel",IDCANCEL,258,54,50,14
GROUPBOX "Image file path",IDC_STATIC_USB,6,6,300,36
EDITTEXT IDC_EDIT1_USB,12,18,234,14,ES_AUTOHSCROLL,WS_EX_ACCEPTFILES
PUSHBUTTON "Browse",IDC_BUTTON1_USB,252,18,50,14
END
IDD_CONFIG_USB DIALOGEX 0, 0, 257, 205
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "USB Settings"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,194,184,50,14
DEFPUSHBUTTON "OK",IDOK,138,184,50,14
GROUPBOX "Device type",IDC_STATIC_USB,6,6,246,48
LTEXT "Port 1:",IDC_STATIC_USB,19,19,23,8
COMBOBOX IDC_COMBO1_USB,48,17,198,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Port 2:",IDC_STATIC_USB,19,37,23,8
COMBOBOX IDC_COMBO2_USB,48,35,198,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Device API",IDC_STATIC_USB,6,54,246,48
LTEXT "Port 1:",IDC_STATIC_USB,19,67,23,8
COMBOBOX IDC_COMBO_API1_USB,48,65,144,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "Configure",IDC_CONFIGURE1_USB,198,65,49,14
LTEXT "Port 2:",IDC_STATIC_USB,19,85,23,8
COMBOBOX IDC_COMBO_API2_USB,48,83,144,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "Configure",IDC_CONFIGURE2_USB,198,83,49,14
CONTROL "Enable Logging (for developer use only)",IDC_LOGGING_USB, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,105,144,12
GROUPBOX "Emulated device",IDC_STATIC_USB,6,131,246,48
LTEXT "Port 1:",IDC_STATIC_USB,19,144,23,8
COMBOBOX IDC_COMBO_WHEEL_TYPE1_USB,48,142,198,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Port 2:",IDC_STATIC_USB,19,162,23,8
COMBOBOX IDC_COMBO_WHEEL_TYPE2_USB,48,160,198,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_DLGWASAPI_USB DIALOGEX 0, 0, 287, 230
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "WASAPI Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,174,210,50,14
PUSHBUTTON "Cancel",IDCANCEL,228,210,50,14
GROUPBOX "Audio Input",IDC_STATIC_USB,6,6,270,54
LTEXT "Player 1:",IDC_STATIC_USB,12,18,30,8
LTEXT "Player 2:",IDC_STATIC_USB,12,36,30,8
COMBOBOX IDC_COMBO1_USB,48,18,216,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO2_USB,48,36,216,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "1 ms",IDC_STATIC_USB,18,138,16,8
LTEXT "1000 ms",IDC_STATIC_USB,240,138,28,8
GROUPBOX "Input Buffering",IDC_STATIC_USB,6,108,270,46
CONTROL "",IDC_SLIDER1_USB,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,18,121,252,15
EDITTEXT IDC_BUFFER1_USB,122,138,40,12,ES_AUTOHSCROLL | ES_NUMBER
GROUPBOX "Audio Output",IDC_STATIC_USB,6,66,270,36
COMBOBOX IDC_COMBO3_USB,48,78,216,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "1 ms",IDC_STATIC_USB,18,186,16,8
LTEXT "1000 ms",IDC_STATIC_USB,240,186,28,8
GROUPBOX "Output Buffering",IDC_STATIC_USB,6,156,270,46
CONTROL "",IDC_SLIDER2_USB,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,18,169,252,15
EDITTEXT IDC_BUFFER2_USB,122,186,40,12,ES_AUTOHSCROLL | ES_NUMBER
END
IDD_DLG_EYETOY_USB DIALOGEX 0, 0, 309, 49
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "EyeToy Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Device:",IDC_STATIC_USB,7,8,27,8
COMBOBOX IDC_COMBO1_USB,40,7,262,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,198,28,50,14
PUSHBUTTON "Cancel",IDCANCEL,252,28,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_DLGMIC_USB AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_CONFIG_USB AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_DLGWASAPI_USB AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_DLG_EYETOY_USB AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DLGMSD_USB, DIALOG
BEGIN
END
IDD_CONFIG_USB, DIALOG
BEGIN
END
IDD_DLGWASAPI_USB, DIALOG
BEGIN
END
IDD_DLG_EYETOY_USB, DIALOG
BEGIN
END
END
#endif // APSTUDIO_INVOKED
#endif // Anglais (États-Unis) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Espagnol (Argentine) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS)
LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource_usb.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""WinResrc.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Espagnol (Argentine) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -1,19 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <initguid.h>
#include <propsys.h>
#include <functiondiscoverykeys_devpkey.h>

View File

@ -1,41 +0,0 @@
//{{NO_DEPENDENCIES}}
// fichier Include Microsoft Visual C++.
// Utilisé par USBDialog.rc
//
#define IDC_CONFIGURE1_USB 3
#define IDC_CONFIGURE2_USB 4
#define IDD_CONFDLG_USB 101
#define IDD_CONFIG_USB 101
#define IDD_DLGMSD_USB 106
#define IDD_DLGWASAPI_USB 107
#define IDD_DLG_EYETOY_USB 108
#define IDC_LOGGING_USB 1007
#define IDC_COMBO1_USB 1008
#define IDC_COMBO2_USB 1009
#define IDC_LIST1_USB 1010
#define IDC_COMBO_API1_USB 1010
#define IDC_COMBO3_USB 1010
#define IDC_COMBO_FFB_USB 1011
#define IDC_COMBO_API2_USB 1011
#define IDC_BUTTON1_USB 1012
#define IDC_DFP_PASS_USB 1013
#define IDC_EDIT1_USB 1015
#define IDC_COMBO_WHEEL_TYPE1_USB 1037
#define IDC_COMBO_WHEEL_TYPE2_USB 1038
#define IDC_SLIDER1_USB 1039
#define IDC_BUFFER1_USB 1040
#define IDC_COMBOMICAPI_USB 1041
#define IDC_SLIDER2_USB 1041
#define IDC_BUFFER2_USB 1042
#define IDC_STATIC_USB -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1042
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,278 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "deviceproxy.h"
#include "configuration.h"
#include "shared/inifile_usb.h"
#include "platcompat.h"
#include "Config.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "gui/StringHelpers.h"
#include <map>
#include <vector>
std::map<std::pair<int, std::string>, std::string> changedAPIs;
std::map<std::pair<int, std::string>, int> changedSubtype;
wxString iniFileUSB(L"USB.ini");
static TSTDSTRING usb_path;
TSTDSTRING IniPath; // default path, just in case
TSTDSTRING LogDir;
CIniFile ciniFile;
bool USBpathSet = false;
void USBsetSettingsDir()
{
if(!USBpathSet)
{
IniPath = StringUtil::UTF8StringToWxString(Path::Combine(EmuFolders::Settings, "USB.ini")); // default path, just in case
USBpathSet = true;
}
}
void USBsetLogDir(const char* dir)
{
#ifdef _WIN32
LogDir = str_to_wstr(dir);
#else
LogDir = dir;
#endif
}
std::string GetSelectedAPI(const std::pair<int, std::string>& pair)
{
USBsetSettingsDir();
auto it = changedAPIs.find(pair);
if (it != changedAPIs.end())
return it->second;
return std::string();
}
int GetSelectedSubtype(const std::pair<int, std::string>& pair)
{
auto it = changedSubtype.find(pair);
if (it != changedSubtype.end())
return it->second;
return 0;
}
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, TSTDSTRING& value)
{
USBsetSettingsDir();
CIniKey* key;
#ifdef _WIN32
auto sect = ciniFile.GetSection(section);
if (sect && (key = sect->GetKey(param)))
{
value = key->GetValue();
return true;
}
#else
auto sect = ciniFile.GetSection(str_to_wstr(section));
if (sect && (key = sect->GetKey(str_to_wstr(param))))
{
value = wstr_to_str(key->GetValue());
return true;
}
#endif
return false;
}
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t& value)
{
USBsetSettingsDir();
CIniKey* key;
#ifdef _WIN32
auto sect = ciniFile.GetSection(section);
if (sect && (key = sect->GetKey(param)))
{
try
{
value = std::stoi(key->GetValue());
return true;
}
#else
auto sect = ciniFile.GetSection(str_to_wstr(section));
if (sect && (key = sect->GetKey(str_to_wstr(param))))
{
try
{
value = std::stoi(key->GetValue());
return true;
}
#endif
catch (std::exception& err)
{
DevCon.WriteLn("%s\n", err.what());
}
}
return false;
}
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, const TSTDSTRING& value)
{
USBsetSettingsDir();
#ifdef _WIN32
ciniFile.SetKeyValue(section, param, value);
#else
ciniFile.SetKeyValue(str_to_wstr(section), str_to_wstr(param), str_to_wstr(value));
#endif
return true;
}
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t value)
{
USBsetSettingsDir();
#ifdef _WIN32
ciniFile.SetKeyValue(section, param, TSTDTOSTRING(value));
#else
ciniFile.SetKeyValue(str_to_wstr(section), str_to_wstr(param), str_to_wstr(TSTDTOSTRING(value)));
#endif
return true;
}
void SaveConfig()
{
USBsetSettingsDir();
#ifdef _WIN32
SaveSetting(L"MAIN", L"log", conf.Log);
#else
SaveSetting("MAIN", "log", conf.Log);
#endif
#ifdef _WIN32
SaveSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, str_to_wstr(conf.Port[0]));
SaveSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, str_to_wstr(conf.Port[1]));
#else
SaveSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, conf.Port[0]);
SaveSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, conf.Port[1]);
#endif
for (auto& k : changedAPIs)
{
#ifdef _WIN32
SaveSetting(nullptr, k.first.first, k.first.second, N_DEVICE_API, str_to_wstr(k.second));
#else
SaveSetting(nullptr, k.first.first, k.first.second, N_DEVICE_API, k.second);
#endif
}
for (auto& k : changedSubtype)
{
SaveSetting(nullptr, k.first.first, k.first.second, N_DEV_SUBTYPE, k.second);
}
#ifdef _WIN32
bool ret = ciniFile.Save(IniPath);
#else
[[maybe_unused]]bool ret = ciniFile.Save(str_to_wstr(IniPath));
#endif
}
void LoadConfig()
{
USBsetSettingsDir();
static bool loaded = false;
if (loaded)
return;
loaded = true;
#ifdef _WIN32
ciniFile.Load(IniPath);
LoadSetting(L"MAIN", L"log", conf.Log);
#else
ciniFile.Load(str_to_wstr(IniPath));
LoadSetting("MAIN", "log", conf.Log);
#endif
#ifdef _WIN32
std::wstring tmp;
LoadSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, tmp);
conf.Port[0] = wstr_to_str(tmp);
LoadSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, tmp);
conf.Port[1] = wstr_to_str(tmp);
#else
LoadSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, conf.Port[0]);
LoadSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, conf.Port[1]);
#endif
auto& instance = RegisterDevice::instance();
for (int i = 0; i < 2; i++)
{
std::string api;
#ifdef _WIN32
LoadSetting(nullptr, i, conf.Port[i], N_DEVICE_API, tmp);
api = wstr_to_str(tmp);
#else
LoadSetting(nullptr, i, conf.Port[i], N_DEVICE_API, api);
#endif
auto dev = instance.Device(conf.Port[i]);
if (dev)
{
if (!dev->IsValidAPI(api))
{
api = "<invalid>";
const auto& apis = dev->ListAPIs();
if (!apis.empty())
api = *apis.begin();
}
}
if (api.size())
changedAPIs[std::make_pair(i, conf.Port[i])] = api;
int subtype = 0;
LoadSetting(nullptr, i, conf.Port[i], N_DEV_SUBTYPE, subtype);
changedSubtype[std::make_pair(i, conf.Port[i])] = subtype;
}
}
void ClearSection(const TCHAR* section)
{
USBsetSettingsDir();
#ifdef _WIN32
auto s = ciniFile.GetSection(section);
#else
auto s = ciniFile.GetSection(str_to_wstr(section));
#endif
if (s)
{
s->RemoveAllKeys();
}
}
void RemoveSection(const char* dev_type, int port, const std::string& key)
{
USBsetSettingsDir();
TSTDSTRING tkey;
tkey.assign(key.begin(), key.end());
TSTDSTRINGSTREAM section;
if (dev_type)
section << dev_type << TEXT(" ");
section << tkey << TEXT(" ") << port;
TSTDSTRING str = section.str();
#ifdef _WIN32
ciniFile.RemoveSection(section.str());
#else
ciniFile.RemoveSection(str_to_wstr(section.str()));
#endif
}

View File

@ -1,162 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platcompat.h"
#include <wx/string.h>
#include <vector>
#include <string>
#include <map>
#include <sstream>
#define RESULT_CANCELED 0
#define RESULT_OK 1
#define RESULT_FAILED 2
// freeze modes:
#define FREEZE_LOAD 0
#define FREEZE_SAVE 1
#define FREEZE_SIZE 2
// Device-level config related defines
#define S_DEVICE_API TEXT("Device API")
#define S_WHEEL_TYPE TEXT("Wheel type")
#define S_CONFIG_PATH TEXT("Path")
#define N_DEVICE_API TEXT("device_api")
#define N_DEVICES TEXT("devices")
#define N_DEVICE TEXT("device")
#define N_WHEEL_PT TEXT("wheel_pt")
#define N_DEVICE_PORT0 TEXT("port_0")
#define N_DEVICE_PORT1 TEXT("port_1")
#define N_DEVICE_PORT "port"
#define N_DEV_SUBTYPE TEXT("subtype")
#define N_CONFIG_PATH TEXT("path")
#define PLAYER_TWO_PORT 0
#define PLAYER_ONE_PORT 1
#define USB_PORT PLAYER_ONE_PORT
struct Config
{
int Log;
std::string Port[2];
Config();
};
extern Config conf;
void SaveConfig();
void LoadConfig();
void ClearSection(const TCHAR* section);
void RemoveSection(const char* dev_type, int port, const std::string& key);
extern TSTDSTRING IniPath;
extern TSTDSTRING LogDir;
extern std::map<std::pair<int /*port*/, std::string /*devname*/>, std::string> changedAPIs;
extern std::map<std::pair<int /*port*/, std::string /*devname*/>, int> changedSubtype;
std::string GetSelectedAPI(const std::pair<int /*port*/, std::string /*devname*/>& pair);
int GetSelectedSubtype(const std::pair<int, std::string>& pair);
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, TSTDSTRING& value);
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t& value);
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, const TSTDSTRING& value);
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t value);
#ifdef _UNICODE
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, std::string& value);
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, const std::string& value);
#endif
void USBsetSettingsDir();
void USBsetLogDir(const char* dir);
template <typename Type>
bool LoadSetting(const char* dev_type, int port, const std::string& key, const TCHAR* name, Type& var)
{
bool ret = false;
if (key.empty())
{
return false;
}
TSTDSTRING tkey;
tkey.assign(key.begin(), key.end());
TSTDSTRINGSTREAM section;
if (dev_type)
section << dev_type << TEXT(" ");
section << tkey << TEXT(" ") << port;
TSTDSTRING str = section.str();
ret = LoadSettingValue(IniPath, str, name, var);
return ret;
}
template <typename Type>
bool LoadSetting(const TCHAR* section, const TCHAR* key, Type& var)
{
bool ret = false;
ret = LoadSettingValue(IniPath, section, key, var);
return ret;
}
/**
*
* [devices]
* portX = pad
*
* [pad X]
* api = joydev
*
* [joydev X]
* button0 = 1
* button1 = 2
* ...
*
* */
template <typename Type>
bool SaveSetting(const char* dev_type, int port, const std::string& key, const TCHAR* name, const Type var)
{
bool ret = false;
if (key.empty())
{
return false;
}
TSTDSTRING tkey;
tkey.assign(key.begin(), key.end());
TSTDSTRINGSTREAM section;
if (dev_type)
section << dev_type << TEXT(" ");
section << tkey << TEXT(" ") << port;
TSTDSTRING str = section.str();
ret = SaveSettingValue(IniPath, str, name, var);
return ret;
}
template <typename Type>
bool SaveSetting(const TCHAR* section, const TCHAR* key, const Type var)
{
bool ret = false;
ret = SaveSettingValue(IniPath, section, key, var);
return ret;
}

View File

@ -1,62 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "deviceproxy.h"
#include "usb-eyetoy/usb-eyetoy-webcam.h"
#include "usb-hid/usb-hid.h"
#include "usb-mic/usb-headset.h"
#include "usb-mic/usb-mic-singstar.h"
#include "usb-msd/usb-msd.h"
#include "usb-pad/usb-pad.h"
#include "usb-printer/usb-printer.h"
void RegisterDevice::Register()
{
auto& inst = RegisterDevice::instance();
if (inst.Map().size()) // FIXME Don't clear proxies, singstar keeps a copy to uninit audio
return;
inst.Add(DEVTYPE_PAD, new DeviceProxy<usb_pad::PadDevice>());
inst.Add(DEVTYPE_MSD, new DeviceProxy<usb_msd::MsdDevice>());
inst.Add(DEVTYPE_SINGSTAR, new DeviceProxy<usb_mic::SingstarDevice>());
inst.Add(DEVTYPE_LOGITECH_MIC, new DeviceProxy<usb_mic::LogitechMicDevice>());
inst.Add(DEVTYPE_LOGITECH_HEADSET, new DeviceProxy<usb_mic::HeadsetDevice>());
inst.Add(DEVTYPE_HIDKBD, new DeviceProxy<usb_hid::HIDKbdDevice>());
inst.Add(DEVTYPE_HIDMOUSE, new DeviceProxy<usb_hid::HIDMouseDevice>());
inst.Add(DEVTYPE_RBKIT, new DeviceProxy<usb_pad::RBDrumKitDevice>());
inst.Add(DEVTYPE_BUZZ, new DeviceProxy<usb_pad::BuzzDevice>());
#ifdef _WIN32
inst.Add(DEVTYPE_GAMETRAK, new DeviceProxy<usb_pad::GametrakDevice>());
inst.Add(DEVTYPE_REALPLAY, new DeviceProxy<usb_pad::RealPlayDevice>());
#endif
inst.Add(DEVTYPE_EYETOY, new DeviceProxy<usb_eyetoy::EyeToyWebCamDevice>());
inst.Add(DEVTYPE_BEATMANIA_DADADA, new DeviceProxy<usb_hid::BeatManiaDevice>());
inst.Add(DEVTYPE_SEGA_SEAMIC, new DeviceProxy<usb_pad::SeamicDevice>());
inst.Add(DEVTYPE_PRINTER, new DeviceProxy<usb_printer::PrinterDevice>());
inst.Add(DEVTYPE_KEYBOARDMANIA, new DeviceProxy<usb_pad::KeyboardmaniaDevice>());
RegisterAPIs();
}
void RegisterDevice::Unregister()
{
/*for (auto& i: registerDeviceMap)
delete i.second;*/
registerDeviceMap.clear();
delete registerDevice;
registerDevice = nullptr;
UnregisterAPIs();
}

View File

@ -15,25 +15,85 @@
#include "PrecompiledHeader.h"
#include "deviceproxy.h"
#include "usb-pad/padproxy.h"
#include "usb-mic/audiodeviceproxy.h"
#include "usb-hid/hidproxy.h"
#include "usb-eyetoy/videodeviceproxy.h"
#include "usb-eyetoy/usb-eyetoy-webcam.h"
#include "usb-hid/usb-hid.h"
#include "usb-mic/usb-headset.h"
#include "usb-mic/usb-mic-singstar.h"
#include "usb-msd/usb-msd.h"
#include "usb-pad/usb-pad.h"
#include "usb-printer/usb-printer.h"
#include "usb-lightgun/guncon2.h"
RegisterDevice* RegisterDevice::registerDevice = nullptr;
void RegisterAPIs()
DeviceProxy::~DeviceProxy() = default;
std::vector<std::string> DeviceProxy::SubTypes() const
{
usb_pad::RegisterPad::Register();
usb_mic::RegisterAudioDevice::Register();
usb_hid::RegisterUsbHID::Register();
usb_eyetoy::RegisterVideoDevice::Register();
return {};
}
void UnregisterAPIs()
gsl::span<const InputBindingInfo> DeviceProxy::Bindings(u32 subtype) const
{
usb_pad::RegisterPad::instance().Clear();
usb_mic::RegisterAudioDevice::instance().Clear();
usb_hid::RegisterUsbHID::instance().Clear();
usb_eyetoy::RegisterVideoDevice::instance().Clear();
return {};
}
gsl::span<const SettingInfo> DeviceProxy::Settings(u32 subtype) const
{
return {};
}
float DeviceProxy::GetBindingValue(const USBDevice* dev, u32 bind) const
{
return 0.0f;
}
void DeviceProxy::SetBindingValue(USBDevice* dev, u32 bind, float value) const
{
}
bool DeviceProxy::Freeze(USBDevice* dev, StateWrapper& sw) const
{
return false;
}
void DeviceProxy::UpdateSettings(USBDevice* dev, SettingsInterface& si) const
{
}
void DeviceProxy::InputDeviceConnected(USBDevice* dev, const std::string_view& identifier) const
{
}
void DeviceProxy::InputDeviceDisconnected(USBDevice* dev, const std::string_view& identifier) const
{
}
void RegisterDevice::Register()
{
auto& inst = RegisterDevice::instance();
if (inst.Map().size()) // FIXME Don't clear proxies, singstar keeps a copy to uninit audio
return;
inst.Add(DEVTYPE_PAD, new usb_pad::PadDevice());
inst.Add(DEVTYPE_MSD, new usb_msd::MsdDevice());
inst.Add(DEVTYPE_SINGSTAR, new usb_mic::SingstarDevice());
inst.Add(DEVTYPE_LOGITECH_MIC, new usb_mic::LogitechMicDevice());
inst.Add(DEVTYPE_LOGITECH_HEADSET, new usb_mic::HeadsetDevice());
inst.Add(DEVTYPE_HIDKBD, new usb_hid::HIDKbdDevice());
inst.Add(DEVTYPE_HIDMOUSE, new usb_hid::HIDMouseDevice());
inst.Add(DEVTYPE_RBKIT, new usb_pad::RBDrumKitDevice());
inst.Add(DEVTYPE_BUZZ, new usb_pad::BuzzDevice());
inst.Add(DEVTYPE_EYETOY, new usb_eyetoy::EyeToyWebCamDevice());
inst.Add(DEVTYPE_BEATMANIA_DADADA, new usb_hid::BeatManiaDevice());
inst.Add(DEVTYPE_SEGA_SEAMIC, new usb_pad::SeamicDevice());
inst.Add(DEVTYPE_PRINTER, new usb_printer::PrinterDevice());
inst.Add(DEVTYPE_KEYBOARDMANIA, new usb_pad::KeyboardmaniaDevice());
inst.Add(DEVTYPE_GUNCON2, new usb_lightgun::GunCon2Device());
}
void RegisterDevice::Unregister()
{
registerDeviceMap.clear();
delete registerDevice;
registerDevice = nullptr;
}

View File

@ -13,26 +13,27 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEVICEPROXY_H
#define DEVICEPROXY_H
#include "configuration.h"
#pragma once
#include <memory>
#include <string>
#include <string_view>
#include <map>
#include <list>
#include <algorithm>
#include <iterator>
//#include <memory>
#include "helpers.h"
#include "proxybase.h"
#include <memory>
#include "gsl/span"
#include "qemu-usb/USBinternal.h"
#include "Config.h"
#include "SaveState.h"
void RegisterAPIs();
void UnregisterAPIs();
class StateWrapper;
// also map key/array index
enum DeviceType
enum DeviceType : s32
{
DEVTYPE_NONE = -1,
DEVTYPE_PAD = 0,
@ -44,160 +45,35 @@ enum DeviceType
DEVTYPE_HIDMOUSE,
DEVTYPE_RBKIT,
DEVTYPE_BUZZ,
DEVTYPE_GAMETRAK,
DEVTYPE_REALPLAY,
DEVTYPE_EYETOY,
DEVTYPE_BEATMANIA_DADADA,
DEVTYPE_SEGA_SEAMIC,
DEVTYPE_PRINTER,
DEVTYPE_KEYBOARDMANIA,
DEVTYPE_GUNCON2
};
struct SelectDeviceName
{
template <typename S>
std::string operator()(const std::pair<const DeviceType, S>& x) const
{
return x.second->TypeName();
}
};
class DeviceError : public std::runtime_error
class DeviceProxy
{
public:
DeviceError(const char* msg)
: std::runtime_error(msg)
{
}
virtual ~DeviceError() {}
};
virtual ~DeviceProxy();
class DeviceProxyBase
{
public:
DeviceProxyBase(){};
virtual ~DeviceProxyBase() {}
virtual USBDevice* CreateDevice(int port) = 0;
virtual const TCHAR* Name() const = 0;
virtual const char* Name() const = 0;
virtual const char* TypeName() const = 0;
virtual int Configure(int port, const std::string& api, void* data) = 0;
virtual std::list<std::string> ListAPIs() = 0;
virtual const TCHAR* LongAPIName(const std::string& name) = 0;
virtual int Freeze(FreezeAction mode, USBDevice* dev, void* data) = 0;
virtual std::vector<std::string> SubTypes() = 0;
virtual std::vector<std::string> SubTypes() const;
virtual gsl::span<const InputBindingInfo> Bindings(u32 subtype) const;
virtual gsl::span<const SettingInfo> Settings(u32 subtype) const;
virtual bool IsValidAPI(const std::string& api)
{
const std::list<std::string>& apis = ListAPIs();
auto it = std::find(apis.begin(), apis.end(), api);
if (it != apis.end())
return true;
return false;
}
};
virtual USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const = 0;
template <class T>
class DeviceProxy : public DeviceProxyBase
{
public:
DeviceProxy() {}
virtual ~DeviceProxy()
{
}
virtual USBDevice* CreateDevice(int port)
{
return T::CreateDevice(port);
}
virtual const TCHAR* Name() const
{
return T::Name();
}
virtual const char* TypeName() const
{
return T::TypeName();
}
virtual int Configure(int port, const std::string& api, void* data)
{
return T::Configure(port, api, data);
}
virtual std::list<std::string> ListAPIs()
{
return T::ListAPIs();
}
virtual const TCHAR* LongAPIName(const std::string& name)
{
return T::LongAPIName(name);
}
virtual int Freeze(FreezeAction mode, USBDevice* dev, void* data)
{
return T::Freeze(mode, dev, data);
}
virtual std::vector<std::string> SubTypes()
{
return T::SubTypes();
}
};
virtual float GetBindingValue(const USBDevice* dev, u32 bind) const;
virtual void SetBindingValue(USBDevice* dev, u32 bind, float value) const;
template <class T>
class RegisterProxy
{
RegisterProxy(const RegisterProxy&) = delete;
RegisterProxy() {}
virtual bool Freeze(USBDevice* dev, StateWrapper& sw) const;
virtual void UpdateSettings(USBDevice* dev, SettingsInterface& si) const;
public:
typedef std::map<std::string, std::unique_ptr<T>> RegisterProxyMap;
static RegisterProxy& instance()
{
static RegisterProxy registerProxy;
return registerProxy;
}
virtual ~RegisterProxy()
{
Clear();
}
void Clear()
{
registerProxyMap.clear();
}
void Add(const std::string& name, T* creator)
{
registerProxyMap[name] = std::unique_ptr<T>(creator);
}
T* Proxy(const std::string& name)
{
return registerProxyMap[name].get();
}
std::list<std::string> Names() const
{
std::list<std::string> nameList;
std::transform(
registerProxyMap.begin(), registerProxyMap.end(),
std::back_inserter(nameList),
SelectKey());
return nameList;
}
std::string Name(int idx) const
{
auto it = registerProxyMap.begin();
std::advance(it, idx);
if (it != registerProxyMap.end())
return std::string(it->first);
return std::string();
}
const RegisterProxyMap& Map() const
{
return registerProxyMap;
}
private:
RegisterProxyMap registerProxyMap;
virtual void InputDeviceConnected(USBDevice* dev, const std::string_view& identifier) const;
virtual void InputDeviceDisconnected(USBDevice* dev, const std::string_view& identifier) const;
};
class RegisterDevice
@ -207,7 +83,7 @@ class RegisterDevice
static RegisterDevice* registerDevice;
public:
typedef std::map<DeviceType, std::unique_ptr<DeviceProxyBase>> RegisterDeviceMap;
typedef std::map<DeviceType, std::unique_ptr<DeviceProxy>> RegisterDeviceMap;
static RegisterDevice& instance()
{
if (!registerDevice)
@ -220,18 +96,13 @@ public:
static void Register();
void Unregister();
void Add(DeviceType key, DeviceProxyBase* creator)
void Add(DeviceType key, DeviceProxy* creator)
{
registerDeviceMap[key] = std::unique_ptr<DeviceProxyBase>(creator);
registerDeviceMap[key] = std::unique_ptr<DeviceProxy>(creator);
}
DeviceProxyBase* Device(const std::string& name)
DeviceProxy* Device(const std::string_view& name)
{
//return registerDeviceMap[name];
/*for (auto& k : registerDeviceMap)
if(k.first.name == name)
return k.second;
return nullptr;*/
auto proxy = std::find_if(registerDeviceMap.begin(),
registerDeviceMap.end(),
[&name](const RegisterDeviceMap::value_type& val) -> bool {
@ -242,7 +113,7 @@ public:
return nullptr;
}
DeviceProxyBase* Device(int index)
DeviceProxy* Device(int index)
{
auto it = registerDeviceMap.begin();
std::advance(it, index);
@ -251,7 +122,7 @@ public:
return nullptr;
}
DeviceType Index(const std::string& name)
DeviceType Index(const std::string_view& name)
{
auto proxy = std::find_if(registerDeviceMap.begin(),
registerDeviceMap.end(),
@ -263,25 +134,6 @@ public:
return DEVTYPE_NONE;
}
std::list<std::string> Names() const
{
std::list<std::string> nameList;
std::transform(
registerDeviceMap.begin(), registerDeviceMap.end(),
std::back_inserter(nameList),
SelectDeviceName());
return nameList;
}
std::string Name(int index) const
{
auto it = registerDeviceMap.begin();
std::advance(it, index);
if (it != registerDeviceMap.end())
return it->second->TypeName();
return std::string();
}
const RegisterDeviceMap& Map() const
{
return registerDeviceMap;
@ -290,5 +142,3 @@ public:
private:
RegisterDeviceMap registerDeviceMap;
};
#endif

View File

@ -1,19 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gtk/gtk.h>
GtkWidget* new_combobox(const char* label, GtkWidget* vbox, bool scrollable = false); // linux/config-gtk.cpp

View File

@ -1,28 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HELPERS_H
#define HELPERS_H
struct SelectKey
{
template <typename F, typename S>
F operator()(const std::pair<const F, S>& x) const
{
return x.first;
}
};
#endif

View File

@ -1,85 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
// clang-format off
#include "icon_buzz_24.h"
const unsigned char icon_buzz_24[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xa6, 0xf5,
0xfd, 0xff, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xfd,
0xfd, 0xff, 0xfd, 0xf6, 0xa6, 0x39, 0x00, 0x00, 0x00,
0x00, 0x00, 0x50, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xd6, 0x50, 0x00, 0x00, 0x00, 0x1e, 0xce,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xce, 0x1e, 0x00, 0x00, 0x8b, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00,
0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x5e, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x5e, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0x5e, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x5e, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
0x00, 0x8b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x1e, 0xce,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xce, 0x1e, 0x00, 0x00, 0x00, 0x50, 0xd6, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0x50, 0x00, 0x00,
0x00, 0x00, 0x00, 0x39, 0xa6, 0xf0, 0xfd, 0xff, 0xfe,
0xfe, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xfd,
0xf0, 0xa6, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// clang-format on

View File

@ -1,17 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
extern const unsigned char icon_buzz_24[];

View File

@ -1,152 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h> // errno
#include <fcntl.h> // open()
#include <stdio.h> // rename()
#include <string.h> // strerror()
#include <sys/stat.h> // stat64(), open(), fstat()
#include <sys/types.h> // stat64(), open(), fstat(), lseek64()
#include <unistd.h> // stat64(), fstat(), lseek64(), read(), close(), write()
// unlink()
//#include "logfile.h"
#include "actualfile.h"
int IsActualFile(const char *filename) {
int retval;
struct stat64 filestat;
errno = 0;
retval = stat64(filename, &filestat);
if((retval < 0) || (errno != 0)) {
return(-1); // Name doesn't exist.
} // ENDIF- Trouble getting stat on a file?
if(S_ISREG(filestat.st_mode) == 0) return(-2); // Not a regular file.
return(0); // Yep, that's a file.
} // END IsActualFile()
void ActualFileDelete(const char *filename) {
unlink(filename);
} // END ActualFileDelete()
void ActualFileRename(const char *origname, const char *newname) {
rename(origname, newname);
return;
} // END ActualFileRename()
ACTUALHANDLE ActualFileOpenForRead(const char *filename) {
int newhandle;
if(filename == NULL) return(-1);
errno = 0;
newhandle = open(filename, O_RDONLY | O_LARGEFILE);
if((newhandle < 0) || (errno != 0)) {
return(-1);
} // ENDIF- Error? Abort
return(newhandle);
} // END ActualFileOpenForRead()
off64_t ActualFileSize(ACTUALHANDLE handle) {
int retval;
struct stat64 filestat;
errno = 0;
retval = fstat64(handle, &filestat);
if((retval < 0) || (errno != 0)) return(-1); // Name doesn't exist.
return(filestat.st_size);
} // END ActualFileSize()
int ActualFileSeek(ACTUALHANDLE handle, off64_t position) {
off64_t moved;
if(handle < 0) return(-1);
if(position < 0) return(-1); // Maybe... position = 0?
errno = 0;
moved = lseek64(handle, position, SEEK_SET);
if(errno != 0) {
return(-1);
} // ENDIF- Error? Abort
return(0);
} // END ActualFileSeek()
int ActualFileRead(ACTUALHANDLE handle, int bytes, char *buffer) {
int retval;
if(handle == ACTUALHANDLENULL) return(-1);
if(bytes < 1) return(-1);
if(buffer == NULL) return(-1);
errno = 0;
retval = read(handle, buffer, bytes);
if((retval < 0) || (errno != 0)) {
// return(-1);
} // ENDIF- Error? Abort
return(retval); // Send back how many bytes read
} // END ActualFileRead()
void ActualFileClose(ACTUALHANDLE handle) {
if(handle < 0) return;
errno = 0;
close(handle);
return;
} // END ActualFileClose()
ACTUALHANDLE ActualFileOpenForWrite(const char *filename) {
int newhandle;
if(filename == NULL) return(-1);
errno = 0;
newhandle = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
if((newhandle < 0) || (errno != 0)) {
return(-1);
} // ENDIF- Error? Abort
return(newhandle);
} // END ActualFileOpenForWrite()
int ActualFileWrite(ACTUALHANDLE handle, int bytes, char *buffer) {
int retval;
if(handle < 0) return(-1);
if(bytes < 1) return(-1);
if(buffer == NULL) return(-1);
errno = 0;
retval = write(handle, buffer, bytes);
if((retval < 0) || (errno != 0)) {
// return(-1);
} // ENDIF- Error? Abort
return(retval); // Send back how many bytes written
} // END ActualFileWrite()

View File

@ -1,42 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTUALFILE_H
#define ACTUALFILE_H
#include <sys/types.h> // off64_t
#define ACTUALHANDLE int
#define ACTUALHANDLENULL -1
// #define VERBOSE_FUNCTION_ACTUALFILE
// #define VERBOSE_WARNING_ACTUALFILE
extern int IsActualFile(const char* filename);
extern void ActualFileDelete(const char* filename);
extern void ActualFileRename(const char* origname, const char* newname);
extern ACTUALHANDLE ActualFileOpenForRead(const char* filename);
extern off64_t ActualFileSize(ACTUALHANDLE handle);
extern int ActualFileSeek(ACTUALHANDLE handle, off64_t position);
extern int ActualFileRead(ACTUALHANDLE handle, int bytes, char* buffer);
extern void ActualFileClose(ACTUALHANDLE handle);
extern ACTUALHANDLE ActualFileOpenForWrite(const char* filename);
extern int ActualFileWrite(ACTUALHANDLE handle, int bytes, char* buffer);
#endif /* ACTUALFILE_H */

View File

@ -1,345 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
#include <map>
#include <vector>
#include <string>
#include "gui/AppCoreThread.h"
#include "USB/gtk.h"
#include "USB/configuration.h"
#include "USB/deviceproxy.h"
#include "USB/usb-pad/padproxy.h"
#include "USB/usb-mic/audiodeviceproxy.h"
#include "config.h"
#include "USB/USB.h"
struct SettingsCB
{
int player;
std::string device;
std::string api;
GtkComboBox* combo;
GtkComboBox* subtype;
};
gboolean run_msg_dialog(gpointer data)
{
GtkWidget* dialog = (GtkWidget*)data;
gtk_widget_show_all(dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
return FALSE;
}
static void populateApiWidget(SettingsCB* settingsCB, const std::string& device)
{
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(settingsCB->combo)));
auto dev = RegisterDevice::instance().Device(device);
GtkComboBox* widget = settingsCB->combo;
if (dev)
{
int port = 1 - settingsCB->player;
std::string api;
auto it = changedAPIs.find(std::make_pair(port, device));
if (it == changedAPIs.end())
{
LoadSetting(nullptr, port, device, N_DEVICE_API, api);
if (!dev->IsValidAPI(api))
api.clear();
}
else
api = it->second;
settingsCB->api = api;
int i = 0;
for (auto& it : dev->ListAPIs())
{
auto name = dev->LongAPIName(it);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), name);
if (api.size() && api == it)
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), i);
else
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), 0);
i++;
}
}
}
static void populateSubtypeWidget(SettingsCB* settingsCB, const std::string& device)
{
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(settingsCB->subtype)));
auto dev = RegisterDevice::instance().Device(device);
GtkComboBox* widget = settingsCB->subtype;
if (dev)
{
int port = 1 - settingsCB->player;
int sel = 0;
if (!LoadSetting(nullptr, port, device, N_DEV_SUBTYPE, sel))
{
changedSubtype[std::make_pair(port, device)] = sel;
}
for (auto subtype : dev->SubTypes())
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), subtype.c_str());
}
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), sel);
}
}
static void deviceChanged(GtkComboBox* widget, gpointer data)
{
SettingsCB* settingsCB = (SettingsCB*)data;
gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
int player = settingsCB->player;
std::string s;
if (active > 0)
s = RegisterDevice::instance().Name(active - 1);
settingsCB->device = s;
populateApiWidget(settingsCB, s);
populateSubtypeWidget(settingsCB, s);
if (player == 0)
conf.Port[1] = s;
else
conf.Port[0] = s;
}
static void apiChanged(GtkComboBox* widget, gpointer data)
{
SettingsCB* settingsCB = (SettingsCB*)data;
int player = settingsCB->player;
gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
auto& name = settingsCB->device;
auto dev = RegisterDevice::instance().Device(name);
if (dev)
{
auto apis = dev->ListAPIs();
auto it = apis.begin();
std::advance(it, active);
if (it != apis.end())
{
int port = 1 - player;
auto pair = std::make_pair(port, name);
auto itAPI = changedAPIs.find(pair);
if (itAPI != changedAPIs.end())
itAPI->second = *it;
else
changedAPIs[pair] = *it;
settingsCB->api = *it;
}
}
}
static void subtypeChanged(GtkComboBox* widget, gpointer data)
{
SettingsCB* settingsCB = (SettingsCB*)data;
int player = settingsCB->player;
gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
auto& name = settingsCB->device;
auto dev = RegisterDevice::instance().Device(name);
if (dev)
{
int port = 1 - player;
changedSubtype[std::make_pair(port, name)] = active;
}
}
static void configureApi(GtkWidget* widget, gpointer data)
{
SettingsCB* settingsCB = (SettingsCB*)data;
int player = settingsCB->player;
auto& name = settingsCB->device;
auto dev = RegisterDevice::instance().Device(name);
if (dev)
{
int port = 1 - player;
auto& api = settingsCB->api;
GtkWidget* dlg = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "dlg"));
[[maybe_unused]]int res = dev->Configure(port, api, dlg);
}
}
GtkWidget* new_combobox(const char* label, GtkWidget* vbox, bool scrollable)
{
GtkWidget *rs_hbox, *rs_label, *rs_cb;
rs_hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), rs_hbox, FALSE, TRUE, 0);
rs_label = gtk_label_new(label);
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_label, FALSE, TRUE, 5);
gtk_label_set_justify(GTK_LABEL(rs_label), GTK_JUSTIFY_RIGHT);
rs_cb = gtk_combo_box_text_new();
if (!scrollable)
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_cb, TRUE, TRUE, 5);
else
{
GtkWidget* sw = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(sw), rs_cb);
gtk_box_pack_start(GTK_BOX(rs_hbox), sw, TRUE, TRUE, 5);
}
return rs_cb;
}
static GtkWidget* new_frame(const char* label, GtkWidget* box)
{
GtkWidget* ro_frame = gtk_frame_new(NULL);
gtk_box_pack_start(GTK_BOX(box), ro_frame, TRUE, FALSE, 0);
GtkWidget* ro_label = gtk_label_new(label);
gtk_frame_set_label_widget(GTK_FRAME(ro_frame), ro_label);
gtk_label_set_use_markup(GTK_LABEL(ro_label), TRUE);
GtkWidget* vbox = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(ro_frame), vbox);
return vbox;
}
void USBconfigure()
{
ScopedCoreThreadPause paused_core;
USBsetSettingsDir();
RegisterDevice::Register();
LoadConfig();
SettingsCB settingsCB[2];
settingsCB[0].player = 0;
settingsCB[1].player = 1;
const char* players[] = {"Player 1:", "Player 2:"};
GtkWidget *rs_cb, *vbox;
// Create the dialog window
GtkWidget* dlg = gtk_dialog_new_with_buttons(
"USB Settings", NULL, GTK_DIALOG_MODAL,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE);
GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
GtkWidget* main_vbox = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(dlg_area_box), main_vbox);
/*** Device type ***/
vbox = new_frame("Select device type:", main_vbox);
std::string devs[2] = {conf.Port[1], conf.Port[0]};
/*** Devices' Comboboxes ***/
for (int ply = 0; ply < 2; ply++)
{
settingsCB[ply].device = devs[ply];
rs_cb = new_combobox(players[ply], vbox);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), "None");
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), 0);
auto devices = RegisterDevice::instance().Names();
int idx = 0;
for (auto& device : devices)
{
auto deviceProxy = RegisterDevice::instance().Device(device);
if (!deviceProxy)
{
continue;
}
auto name = deviceProxy->Name();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), name);
idx++;
if (devs[ply] == device)
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), idx);
}
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(deviceChanged), (gpointer)&settingsCB[ply]);
}
/*** APIs ***/
vbox = new_frame("Select device API:", main_vbox);
/*** API Comboboxes ***/
for (int ply = 0; ply < 2; ply++)
{
rs_cb = new_combobox(players[ply], vbox);
settingsCB[ply].combo = GTK_COMBO_BOX(rs_cb);
//gtk_combo_box_set_active (GTK_COMBO_BOX (rs_cb), sel_idx);
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(apiChanged), (gpointer)&settingsCB[ply]);
GtkWidget* hbox = gtk_widget_get_parent(rs_cb);
GtkWidget* button = gtk_button_new_with_label("Configure");
gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_icon_name("gtk-preferences", GTK_ICON_SIZE_BUTTON));
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
g_signal_connect(button, "clicked", G_CALLBACK(configureApi), (gpointer)&settingsCB[ply]);
g_object_set_data(G_OBJECT(button), "dlg", dlg);
populateApiWidget(&settingsCB[ply], devs[ply]);
}
/** Emulated device / Wheel type **/
vbox = new_frame("Emulated device:", main_vbox);
for (int ply = 0; ply < 2; ply++)
{
rs_cb = new_combobox(players[ply], vbox);
settingsCB[ply].subtype = GTK_COMBO_BOX(rs_cb);
g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(subtypeChanged), (gpointer)&settingsCB[ply]);
populateSubtypeWidget(&settingsCB[ply], devs[ply]);
}
gtk_widget_show_all(dlg);
// Modal loop
gint result = gtk_dialog_run(GTK_DIALOG(dlg));
gtk_widget_destroy(dlg);
// Wait for all gtk events to be consumed ...
while (gtk_events_pending())
gtk_main_iteration_do(FALSE);
if (result == GTK_RESPONSE_OK)
{
SaveConfig();
CreateDevices();
}
// ClearAPIs();
paused_core.AllowResume();
}
void CALLBACK USBabout()
{
}

View File

@ -1,31 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "USB/configuration.h"
#include "USB/deviceproxy.h"
#include "USB/usb-pad/padproxy.h"
#include "USB/usb-mic/audiodeviceproxy.h"
#include "common/Console.h"
void SysMessage_stderr(const char* fmt, ...)
{
va_list arglist;
va_start(arglist, fmt);
Console.Warning(fmt, arglist);
va_end(arglist);
}

View File

@ -1,21 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LINUXCONFIG_H
#define LINUXCONFIG_H
#include <sstream>
#include <string>
#endif

View File

@ -1,594 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stddef.h> // NULL
#include <stdio.h> // sprintf()
#include <stdarg.h> // va_start(), va_end(), vsprintf()
//#include "logfile.h"
#include "actualfile.h"
#include "ini.h"
//#define VERBOSE_FUNCTION_INI 1
const char INIext[] = ".ini";
const char INInewext[] = ".new";
// Returns: position where new extensions should be added.
int INIRemoveExt(const char *argname, char *tempname) {
int i;
int j;
int k;
i = 0;
while((i <= INIMAXLEN) && (*(argname + i) != 0)) {
*(tempname + i) = *(argname + i);
i++;
} // ENDWHILE- Copying the argument name into a temporary area;
*(tempname + i) = 0; // And 0-terminate
k = i;
k--;
j = 0;
while((j <= INIMAXLEN) && (INIext[j] != 0)) j++;
j--;
while((j >= 0) && (*(tempname + k) == INIext[j])) {
k--;
j--;
} // ENDWHILE- Comparing the ending characters to the INI ext.
if(j < 0) {
k++;
i = k;
*(tempname + i) = 0; // 0-terminate, cutting off ".ini"
} // ENDIF- Do we have a match? Then remove the end chars.
return(i);
} // END INIRemoveExt()
void INIAddInExt(char *tempname, int temppos) {
int i;
i = 0;
while((i + temppos < INIMAXLEN) && (INIext[i] != 0)) {
*(tempname + temppos + i) = INIext[i];
i++;
} // ENDWHILE- Attaching extenstion to filename
*(tempname + temppos + i) = 0; // And 0-terminate
} // END INIAddInExt()
void INIAddOutExt(char *tempname, int temppos) {
int i;
i = 0;
while((i + temppos < INIMAXLEN) && (INInewext[i] != 0)) {
*(tempname + temppos + i) = INInewext[i];
i++;
} // ENDWHILE- Attaching extenstion to filename
*(tempname + temppos + i) = 0; // And 0-terminate
} // END INIAddInExt()
// Returns number of bytes read to get line (0 means end-of-file)
int INIReadLine(ACTUALHANDLE infile, char *buffer) {
int charcount = 0;
int i = 0;
char tempin[2] = {0};
int retflag = 0;
while((i < INIMAXLEN) && (retflag < 2)) {
const int retval = ActualFileRead(infile, 1, tempin);
charcount++;
if(retval != 1) {
retflag = 2;
charcount--;
} else if(tempin[0] == '\n') {
retflag = 2;
} else if(tempin[0] >= ' ') {
*(buffer + i) = tempin[0];
i++;
} // ENDLONGIF- How do we react to the next character?
} // ENDWHILE- Loading up on characters until an End-of-Line appears
*(buffer + i) = 0; // And 0-terminate
return(charcount);
} // END INIReadLine()
// Note: Do we need to back-skip a char if something other \n follows \r?
// Returns: number of bytes to get to start of section (or -1)
int INIFindSection(ACTUALHANDLE infile, const char *section) {
int charcount = 0;
int retflag = 0;
char scanbuffer[INIMAXLEN+1];
while(retflag == 0) {
const int retval = INIReadLine(infile, scanbuffer);
if(retval == 0) return(-1); // EOF? Stop here.
if(scanbuffer[0] == '[') {
int i = 0;
while((i < INIMAXLEN) &&
(*(section + i) != 0) &&
(*(section + i) == scanbuffer[i + 1])) i++;
if((i < INIMAXLEN - 2) && (*(section + i) == 0)) {
if((scanbuffer[i + 1] == ']') && (scanbuffer[i + 2] == 0)) {
retflag = 1;
} // ENDIF- End marks look good? Return successful.
} // ENDIF- Do we have a section match?
} // ENDIF- Does this look like a section header?
if(retflag == 0) charcount += retval;
} // ENDWHILE- Scanning lines for the correct [Section] header.
return(charcount);
} // END INIFindSection()
// Returns: number of bytes to get to start of keyword (or -1)
int INIFindKeyword(ACTUALHANDLE infile, const char *keyword, char *buffer) {
int charcount = 0;
int retflag = 0;
char scanbuffer[INIMAXLEN+1];
while(retflag == 0) {
int retval = INIReadLine(infile, scanbuffer);
if(retval == 0) return(-1); // EOF? Stop here.
if(scanbuffer[0] == '[') return(-1); // New section? Stop here.
int i = 0;
while((i < INIMAXLEN) &&
(*(keyword + i) != 0) &&
(*(keyword + i) == scanbuffer[i])) i++;
if((i < INIMAXLEN - 2) && (*(keyword + i) == 0)) {
if(scanbuffer[i] == '=') {
retflag = 1;
if(buffer != NULL) {
i++;
int j = 0;
while((i < INIMAXLEN) && (scanbuffer[i] != 0)) {
*(buffer + j) = scanbuffer[i];
i++;
j++;
} // ENDWHILE- Copying the value out to the outbound buffer.
*(buffer + j) = 0; // And 0-terminate.
} // ENDIF- Return the value as well?
} // ENDIF- End marks look good? Return successful.
} // ENDIF- Do we have a section match?
if(retflag == 0) charcount += retval;
} // ENDWHILE- Scanning lines for the correct [Section] header.
return(charcount);
} // END INIFindKeyWord()
// Returns: number of bytes left to write... (from charcount back)
int INICopy(ACTUALHANDLE infile, ACTUALHANDLE outfile, int charcount) {
char buffer[4096];
int chunk = 4096;
int i = charcount;
chunk = 4096;
if(i < chunk) chunk = i;
while(chunk > 0) {
int retval = ActualFileRead(infile, chunk, buffer);
if(retval <= 0) return(i); // Trouble? Stop here.
if(retval < chunk) chunk = retval; // Short block? Note it.
retval = ActualFileWrite(outfile, chunk, buffer);
if(retval <= 0) return(i); // Trouble? Stop here.
i -= retval;
if(retval < chunk) return(i); // Short block written? Stop here.
chunk = 4096;
if(i < chunk) chunk = i;
} // ENDWHILE- Copying a section of file across, one chunk at a time.
return(0);
} // END INICopyToPos()
int INISaveString(const char *file, const char *section, const char *keyword, const char *value) {
char inname[INIMAXLEN+1];
char outname[INIMAXLEN+1];
int filepos;
ACTUALHANDLE infile;
ACTUALHANDLE outfile;
int i;
int retval;
char templine[INIMAXLEN+1];
if(file == NULL) return(-1);
if(section == NULL) return(-1);
if(keyword == NULL) return(-1);
if(value == NULL) return(-1);
filepos = INIRemoveExt(file, inname);
for(i = 0; i <= filepos; i++) outname[i] = inname[i];
INIAddInExt(inname, filepos);
INIAddOutExt(outname, filepos);
filepos = 0;
infile = ActualFileOpenForRead(inname);
if(infile == ACTUALHANDLENULL) {
outfile = ActualFileOpenForWrite(inname);
if(outfile == ACTUALHANDLENULL) return(-1); // Just a bad name? Abort.
sprintf(templine, "[%s]\r\n", section);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
if(retval < i) {
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(inname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
sprintf(templine, "%s=%s\r\n", keyword, value);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
if(retval < i) {
ActualFileDelete(inname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
return(0);
} // ENDIF- No input file? Create a brand new .ini file then.
retval = INIFindSection(infile, section);
if(retval < 0) {
outfile = ActualFileOpenForWrite(outname);
if(outfile == ACTUALHANDLENULL) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't open a temp file? Abort
ActualFileSeek(infile, 0); // Move ini to beginning of file...
INICopy(infile, outfile, 0x0FFFFFFF); // Copy the whole file out...
sprintf(templine, "\r\n[%s]\r\n", section);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
if(retval < i) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
sprintf(templine, "%s=%s\r\n", keyword, value);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
if(retval < i) {
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
ActualFileDelete(inname);
ActualFileRename(outname, inname);
return(0);
} // ENDIF- Couldn't find the section? Make a new one!
filepos = retval;
ActualFileSeek(infile, filepos);
filepos += INIReadLine(infile, templine); // Get section line's byte count
retval = INIFindKeyword(infile, keyword, NULL);
if(retval < 0) {
ActualFileSeek(infile, filepos);
retval = INIReadLine(infile, templine);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0) && (templine[i] != '=')) i++;
while((retval > 0) && (templine[i] == '=')) {
filepos += retval;
retval = INIReadLine(infile, templine);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0) && (templine[i] != '=')) i++;
} // ENDWHILE- skimming to the bottom of the section
outfile = ActualFileOpenForWrite(outname);
if(outfile == ACTUALHANDLENULL) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't open a temp file? Abort
ActualFileSeek(infile, 0);
retval = INICopy(infile, outfile, filepos);
if(retval > 0) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing everything up to keyword? Abort.
sprintf(templine, "%s=%s\r\n", keyword, value);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
if(retval < i) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
} else {
filepos += retval; // Position just before old version of keyword
outfile = ActualFileOpenForWrite(outname);
if(outfile == ACTUALHANDLENULL) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't open a temp file? Abort
ActualFileSeek(infile, 0);
retval = INICopy(infile, outfile, filepos);
if(retval > 0) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing everything up to keyword? Abort.
INIReadLine(infile, templine); // Read past old keyword/value...
// Replace with new value
sprintf(templine, "%s=%s\r\n", keyword, value);
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
if(retval < i) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
} // ENDIF- Need to add a new keyword?
INICopy(infile, outfile, 0xFFFFFFF); // Write out rest of file
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(inname);
ActualFileRename(outname, inname);
return(0);
} // END INISaveString()
int INILoadString(const char *file, const char *section, const char *keyword, char *buffer) {
char inname[INIMAXLEN+1];
int filepos;
ACTUALHANDLE infile;
int retval;
if(file == NULL) return(-1);
if(section == NULL) return(-1);
if(keyword == NULL) return(-1);
if(buffer == NULL) return(-1);
filepos = INIRemoveExt(file, inname);
INIAddInExt(inname, filepos);
filepos = 0;
infile = ActualFileOpenForRead(inname);
if(infile == ACTUALHANDLENULL) return(-1);
retval = INIFindSection(infile, section);
if(retval < 0) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Didn't find it? Abort.
retval = INIFindKeyword(infile, keyword, buffer);
if(retval < 0) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Didn't find it? Abort.
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(0);
} // END INILoadString()
int INIRemove(const char *file, const char *section, const char *keyword) {
char inname[INIMAXLEN+1];
char outname[INIMAXLEN+1];
int filepos;
ACTUALHANDLE infile;
ACTUALHANDLE outfile;
char templine[INIMAXLEN+1];
int i;
int retval;
if(file == NULL) return(-1);
if(section == NULL) return(-1);
filepos = INIRemoveExt(file, inname);
for(i = 0; i <= filepos; i++) outname[i] = inname[i];
INIAddInExt(inname, filepos);
INIAddOutExt(outname, filepos);
infile = ActualFileOpenForRead(inname);
if(infile == ACTUALHANDLENULL) return(-1);
retval = INIFindSection(infile, section);
if(retval == -1) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't even find the section? Abort
filepos = retval;
if(keyword == NULL) {
outfile = ActualFileOpenForWrite(outname);
if(outfile == ACTUALHANDLENULL) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't open a temp file? Abort
ActualFileSeek(infile, 0);
retval = INICopy(infile, outfile, filepos);
if(retval > 0) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing everything up to the section? Abort.
templine[0] = 0;
retval = 1;
while((retval > 0) && (templine[0] != '[')) {
retval = INIReadLine(infile, templine);
} // ENDWHILE- Read to the start of the next section... or EOF.
if(templine[0] == '[') {
i = 0;
while((i < INIMAXLEN) && (templine[i] != 0)) i++;
retval = ActualFileWrite(outfile, i, templine);
if(retval < i) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing it out? Abort.
} // ENDIF- Are there other sections after this one? Save them then.
} else {
filepos = retval;
ActualFileSeek(infile, filepos);
filepos += INIReadLine(infile, templine); // Get section line's byte count
retval = INIFindKeyword(infile, keyword, NULL);
if(retval == -1) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't find the keyword? Abort
filepos += retval;
outfile = ActualFileOpenForWrite(outname);
if(outfile == ACTUALHANDLENULL) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
return(-1);
} // ENDIF- Couldn't open a temp file? Abort
ActualFileSeek(infile, 0);
retval = INICopy(infile, outfile, filepos);
if(retval > 0) {
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(outname);
return(-1);
} // ENDIF- Trouble writing everything up to keyword? Abort.
INIReadLine(infile, templine); // Read (and discard) the keyword line
} // ENDIF- Wipe out the whole section? Or just a keyword?
INICopy(infile, outfile, 0xFFFFFFF); // Write out rest of file
ActualFileClose(infile);
infile = ACTUALHANDLENULL;
ActualFileClose(outfile);
outfile = ACTUALHANDLENULL;
ActualFileDelete(inname);
ActualFileRename(outname, inname);
return(0);
} // END INIRemove()
int INISaveUInt(const char *file, const char *section, const char *keyword, unsigned int value) {
char numvalue[INIMAXLEN+1];
sprintf(numvalue, "%u", value);
return(INISaveString(file, section, keyword, numvalue));
} // END INISaveUInt()
int INILoadUInt(const char *file, const char *section, const char *keyword, unsigned int *buffer) {
char numvalue[INIMAXLEN+1];
int retval;
unsigned int value;
// unsigned int sign; // Not needed in unsigned numbers
int pos;
if(buffer == NULL) return(-1);
*(buffer) = 0;
retval = INILoadString(file, section, keyword, numvalue);
if(retval < 0) return(retval);
value = 0;
// sign = 1; // Start positive
pos = 0;
// Note: skip leading spaces? (Shouldn't have to, I hope)
// if(numvalue[pos] == '-') {
// pos++;
// sign = -1;
// } // ENDIF- Negative sign check
while((pos < INIMAXLEN) && (numvalue[pos] != 0)) {
if(value > (0xFFFFFFFF / 10)) return(-1); // Overflow?
if((numvalue[pos] >= '0') && (numvalue[pos] <= '9')) {
value *= 10;
value += numvalue[pos] - '0';
pos++;
} else {
numvalue[pos] = 0;
} // ENDIF- Add a digit in? Or stop searching for digits?
} // ENDWHILE- Adding digits of info to our ever-increasing value
// value *= sign
*(buffer) = value;
return(0);
} // END INILoadUInt()

View File

@ -1,61 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INI_H
#define INI_H
// #ifndef __LINUX__
// #ifdef __linux__
// #define __LINUX__
// #endif /* __linux__ */
// #endif /* No __LINUX__ */
// #define CDVDdefs
// File format:
// [section]
// keyword=value
// file - Name of the INI file
// section - Section within the file
// keyword - Identifier for a value
// value - value to store with a keyword in a section in the file
// buffer - place to retrieve the value of a keyword
// return values: 0 = success, -1 = failure
// #define VERBOSE_FUNCTION_INI
#define INIMAXLEN 255
#if __cplusplus
extern "C" {
#endif
extern int INISaveString(const char* file, const char* section, const char* keyword, const char* value);
extern int INILoadString(const char* file, const char* section, const char* keyword, char* buffer);
extern int INISaveUInt(const char* file, const char* section, const char* keyword, unsigned int value);
extern int INILoadUInt(const char* file, const char* section, const char* keyword, unsigned int* buffer);
// NULL in the keyword below removes the whole section.
extern int INIRemove(const char* file, const char* section, const char* keyword);
#if __cplusplus
}
#endif
#endif /* INI_H */

View File

@ -1,31 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "util.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
bool file_exists(std::string path)
{
struct stat s;
return !stat(path.c_str(), &s) && !S_ISDIR(s.st_mode);
}
bool dir_exists(std::string path)
{
struct stat s;
return !stat(path.c_str(), &s) && S_ISDIR(s.st_mode);
}

View File

@ -1,132 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Annoying defines
// ---------------------------------------------------------------------
// make sure __POSIX__ is defined for all systems where we assume POSIX
// compliance
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__)
#if !defined(__POSIX__)
#define __POSIX__ 1
#endif
#endif
#ifndef EXPORT_C_
#ifdef _MSC_VER
#define EXPORT_C_(type) extern "C" type CALLBACK
#elif defined(__i386__)
#define EXPORT_C_(type) extern "C" __attribute__((stdcall, visibility("default"))) type
#else
#define EXPORT_C_(type) extern "C" __attribute__((visibility("default"))) type
//#define EXPORT_C_(type) extern "C" __attribute__((stdcall,visibility("default"))) type
#endif
#endif
#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#define wfopen _wfopen
#define fseeko64 _fseeki64
#define ftello64 _ftelli64
#define TSTDSTRING std::wstring
#define TSTDSTRINGSTREAM std::wstringstream
#define TSTDTOSTRING std::to_wstring
//FIXME narrow string fmt
#define SFMTs "S"
#define __builtin_constant_p(p) false
void SysMessageW(const wchar_t* fmt, ...);
#define SysMessage SysMessageW
#else //_WIN32
#define MAX_PATH PATH_MAX
#define __inline inline
//#ifndef TEXT
//#define TEXT(x) L##x
//#endif
//FIXME narrow string fmt
#define SFMTs "s"
#define TEXT(val) val
#define TCHAR char
#define wfopen fopen
#define TSTDSTRING std::string
#define TSTDSTRINGSTREAM std::stringstream
#define TSTDTOSTRING std::to_string
void SysMessage(const char* fmt, ...);
#endif //_WIN32
#if __MINGW32__
#define DBL_EPSILON 2.2204460492503131e-16
#define FLT_EPSILON 1.1920928955078125e-7f
template <size_t size>
errno_t mbstowcs_s(
size_t* pReturnValue,
wchar_t (&wcstr)[size],
const char* mbstr,
size_t count)
{
return mbstowcs_s(pReturnValue, wcstr, size, mbstr, count);
}
template <size_t size>
errno_t wcstombs_s(
size_t* pReturnValue,
char (&mbstr)[size],
const wchar_t* wcstr,
size_t count)
{
return wcstombs_s(pReturnValue, mbstr, size, wcstr, count);
}
#endif //__MINGW32__
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])))
#endif
#include <cstddef>
template <class T, std::size_t N>
constexpr std::size_t countof(const T (&)[N]) noexcept
{
return N;
}
template <class T>
constexpr std::size_t countof(const T N)
{
return N.size();
}
//TODO Idk, used only in desc.h and struct USBDescriptor should be already packed anyway
#if defined(_WIN32) && !defined(__MINGW32__)
#define PACK(def, name) __pragma(pack(push, 1)) def name __pragma(pack(pop))
#elif defined(__clang__)
#define PACK(def, name) def __attribute__((packed)) name
#else
#define PACK(def, name) def __attribute__((gcc_struct, packed)) name
#endif

View File

@ -1,25 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
//TODO Maybe too much inheritance?
class ProxyBase
{
public:
ProxyBase() {}
virtual ~ProxyBase() {}
virtual const TCHAR* Name() const = 0;
virtual int Configure(int port, const char* dev_type, void* data) = 0;
};

View File

@ -13,10 +13,9 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef USBINTERNAL_H
#define USBINTERNAL_H
#pragma once
#include "vl.h"
#include "USB/qemu-usb/qusb.h"
/* Dump packet contents. */
//#define DEBUG_PACKET
@ -28,8 +27,8 @@
#define OHCI_MAX_PORTS 15 // status regs from 0x0c54 but usb snooping
// reg is at 0x0c80, so only 11 ports?
extern int64_t usb_frame_time;
extern int64_t usb_bit_time;
extern int64_t g_usb_frame_time;
extern int64_t g_usb_bit_time;
typedef struct OHCIPort
{
@ -42,7 +41,6 @@ typedef uint32_t target_phys_addr_t;
typedef struct OHCIState
{
target_phys_addr_t mem_base;
int mem;
uint32_t num_ports;
uint64_t eof_timer;
@ -106,7 +104,7 @@ struct ohci_hcca
const typeof(((type *) 0)->member) *__mptr = (ptr); \
(type *) ((char *) __mptr - offsetof(type, member));})
*/
#define CONTAINER_OF(p, type, field) ((type*)((char*)p - ((ptrdiff_t) & ((type*)0)->field)))
#define USB_CONTAINER_OF(p, type, field) ((type*)((char*)p - ((ptrdiff_t) & ((type*)0)->field)))
#define HCCA_WRITEBACK_OFFSET 128 //offsetof(struct ohci_hcca, frame)
#define HCCA_WRITEBACK_SIZE 8 /* frame, pad, done */
@ -306,4 +304,3 @@ void ohci_hard_reset(OHCIState* ohci);
void ohci_soft_reset(OHCIState* ohci);
int ohci_bus_start(OHCIState* ohci);
void ohci_bus_stop(OHCIState* ohci);
#endif

View File

@ -14,8 +14,8 @@
*/
#include "PrecompiledHeader.h"
#include "USBinternal.h"
#include "vl.h"
#include "USB/qemu-usb/USBinternal.h"
#include "USB/qemu-usb/qusb.h"
#define USB_DEVICE_GET_CLASS(p) (&p->klass)

View File

@ -25,10 +25,9 @@
*/
#include "PrecompiledHeader.h"
#include "USB/platcompat.h"
#include "vl.h"
#include "iov.h"
//#include "trace.h"
#include "USB/qemu-usb/qusb.h"
#include "USB/qemu-usb/iov.h"
#include <utility>
void usb_pick_speed(USBPort* port)
{
@ -39,9 +38,8 @@ void usb_pick_speed(USBPort* port)
USB_SPEED_LOW,
};
USBDevice* udev = port->dev;
int i;
for (i = 0; i < (int)ARRAY_SIZE(speeds); i++)
for (u32 i = 0; i < std::size(speeds); i++)
{
if ((udev->speedmask & (1 << speeds[i])) &&
(port->speedmask & (1 << speeds[i])))
@ -568,7 +566,7 @@ void usb_cancel_packet(USBPacket* p)
void usb_packet_init(USBPacket* p)
{
qemu_iovec_init(&p->iov, 1);
qemu_iovec_init(&p->iov);
}
static const char* usb_packet_state_name(USBPacketState state)
@ -581,7 +579,7 @@ static const char* usb_packet_state_name(USBPacketState state)
/*[USB_PACKET_COMPLETE] =*/"complete",
/*[USB_PACKET_CANCELED] =*/"canceled",
};
if (state < ARRAY_SIZE(name))
if (static_cast<u32>(state) < std::size(name))
{
return name[state];
}

View File

@ -14,10 +14,8 @@
*/
#include "PrecompiledHeader.h"
#include "vl.h"
#include "desc.h"
#include "glib.h"
//#include "trace.h"
#include "USB/qemu-usb/qusb.h"
#include "USB/qemu-usb/desc.h"
/* ------------------------------------------------------------------ */

View File

@ -15,12 +15,11 @@
#pragma once
#include <wchar.h>
#include <cstdint>
#include <vector>
#include "USB/platcompat.h"
/* binary representation */
PACK(
#pragma pack(push, 1)
typedef struct USBDescriptor {
uint8_t bLength;
uint8_t bDescriptorType;
@ -124,8 +123,8 @@ PACK(
} u;
} cap;
} u;
},
USBDescriptor);
} USBDescriptor;
#pragma pack(pop)
struct USBDescID
{

View File

@ -1,160 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "glib.h"
#include <cstdlib>
#include <cstring>
#define SIZE_OVERFLOWS(a, b) (G_UNLIKELY((b) > 0 && (a) > G_MAXSIZE / (b)))
/**
* g_malloc:
* @n_bytes: the number of bytes to allocate
*
* Allocates @n_bytes bytes of memory.
* If @n_bytes is 0 it returns %NULL.
*
* Returns: a pointer to the allocated memory
*/
void* my_g_malloc(size_t n_bytes)
{
if (G_LIKELY(n_bytes))
{
void* mem;
mem = malloc(n_bytes);
//TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
if (mem)
return mem;
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
// G_STRLOC, n_bytes);
}
//TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
return NULL;
}
/**
* g_malloc0:
* @n_bytes: the number of bytes to allocate
*
* Allocates @n_bytes bytes of memory, initialized to 0's.
* If @n_bytes is 0 it returns %NULL.
*
* Returns: a pointer to the allocated memory
*/
void* my_g_malloc0(size_t n_bytes)
{
if (G_LIKELY(n_bytes))
{
void* mem;
mem = calloc(1, n_bytes);
//TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0));
if (mem)
return mem;
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
// G_STRLOC, n_bytes);
}
//TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0));
return NULL;
}
/**
* g_malloc_n:
* @n_blocks: the number of blocks to allocate
* @n_block_bytes: the size of each block in bytes
*
* This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
* but care is taken to detect possible overflow during multiplication.
*
* Since: 2.24
* Returns: a pointer to the allocated memory
*/
void* my_g_malloc_n(size_t n_blocks,
size_t n_block_bytes)
{
if (SIZE_OVERFLOWS(n_blocks, n_block_bytes))
{
//g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
// G_STRLOC, n_blocks, n_block_bytes);
}
return my_g_malloc(n_blocks * n_block_bytes);
}
/**
* g_realloc:
* @mem: (nullable): the memory to reallocate
* @n_bytes: new size of the memory in bytes
*
* Reallocates the memory pointed to by @mem, so that it now has space for
* @n_bytes bytes of memory. It returns the new address of the memory, which may
* have been moved. @mem may be %NULL, in which case it's considered to
* have zero-length. @n_bytes may be 0, in which case %NULL will be returned
* and @mem will be freed unless it is %NULL.
*
* Returns: the new address of the allocated memory
*/
void* my_g_realloc(void* mem,
size_t n_bytes)
{
if (G_LIKELY(n_bytes))
{
void* newmem = realloc(mem, n_bytes);
//TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0));
if (newmem)
return newmem;
//g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
// G_STRLOC, n_bytes);
}
if (mem)
free(mem);
//TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0));
return NULL;
}
/**
* g_realloc_n:
* @mem: (nullable): the memory to reallocate
* @n_blocks: the number of blocks to allocate
* @n_block_bytes: the size of each block in bytes
*
* This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
* but care is taken to detect possible overflow during multiplication.
*
* Since: 2.24
* Returns: the new address of the allocated memory
*/
void* my_g_realloc_n(void* mem,
size_t n_blocks,
size_t n_block_bytes)
{
if (SIZE_OVERFLOWS(n_blocks, n_block_bytes))
{
//g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
// G_STRLOC, n_blocks, n_block_bytes);
}
return my_g_realloc(mem, n_blocks * n_block_bytes);
}

View File

@ -1,47 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLIB_H
#define GLIB_H
#include <cstddef>
#include <cstdint>
#define G_MAXSIZE G_MAXUINT64
#define G_MAXUINT64 0xffffffffffffffffUL
#define G_MAXUINT32 ((uint32_t)0xffffffff)
void* my_g_malloc0(size_t n_bytes);
void* my_g_malloc(size_t n_bytes);
void* my_g_malloc_n(size_t n_blocks,
size_t n_block_bytes);
void* my_g_realloc_n(void* mem,
size_t n_blocks,
size_t n_block_bytes);
#define my_g_free free
#define G_LIKELY(expr) (expr)
#define G_UNLIKELY(expr) (expr)
#define my_G_NEW(struct_type, n_structs, func) \
((struct_type*)my_g_##func##_n((n_structs), sizeof(struct_type)))
#define my_G_RENEW(struct_type, mem, n_structs, func) \
((struct_type*)my_g_##func##_n(mem, (n_structs), sizeof(struct_type)))
#define my_g_new(struct_type, n_structs) my_G_NEW(struct_type, n_structs, malloc)
#define my_g_renew(struct_type, mem, n_structs) my_G_RENEW(struct_type, mem, n_structs, realloc)
#endif

View File

@ -748,14 +748,14 @@ int hid_keyboard_poll(HIDState* hs, uint8_t* buf, int len)
buf[1] = 0;
if (hs->kbd.keys > 6)
{
memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, std::min(8, len) - 2);
}
else
{
memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
memcpy(buf + 2, hs->kbd.key, std::min(8, len) - 2);
}
return MIN(8, len);
return std::min(8, len);
}
int hid_keyboard_write(HIDState* hs, uint8_t* buf, int len)

View File

@ -13,9 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_HID_H
#define QEMU_HID_H
#include "vl.h"
#pragma once
#include <cstdint>
/* include/ui/console.h */
/* keyboard/mouse support */
@ -343,5 +342,3 @@ void hid_pointer_activate(HIDState* hs);
int hid_pointer_poll(HIDState* hs, uint8_t* buf, int len);
int hid_keyboard_poll(HIDState* hs, uint8_t* buf, int len);
int hid_keyboard_write(HIDState* hs, uint8_t* buf, int len);
#endif /* QEMU_HID_H */

View File

@ -1,544 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "input-keymap-linux-to-qcode.h"
const QKeyCode qemu_input_map_linux_to_qcode[] = {
Q_KEY_CODE_UNMAPPED, /* linux:0 (KEY_RESERVED) -> linux:0 (KEY_RESERVED) -> qcode:Q_KEY_CODE_UNMAPPED (unmapped) */
Q_KEY_CODE_ESC, /* linux:1 (KEY_ESC) -> linux:1 (KEY_ESC) -> qcode:Q_KEY_CODE_ESC (esc) */
Q_KEY_CODE_1, /* linux:2 (KEY_1) -> linux:2 (KEY_1) -> qcode:Q_KEY_CODE_1 (1) */
Q_KEY_CODE_2, /* linux:3 (KEY_2) -> linux:3 (KEY_2) -> qcode:Q_KEY_CODE_2 (2) */
Q_KEY_CODE_3, /* linux:4 (KEY_3) -> linux:4 (KEY_3) -> qcode:Q_KEY_CODE_3 (3) */
Q_KEY_CODE_4, /* linux:5 (KEY_4) -> linux:5 (KEY_4) -> qcode:Q_KEY_CODE_4 (4) */
Q_KEY_CODE_5, /* linux:6 (KEY_5) -> linux:6 (KEY_5) -> qcode:Q_KEY_CODE_5 (5) */
Q_KEY_CODE_6, /* linux:7 (KEY_6) -> linux:7 (KEY_6) -> qcode:Q_KEY_CODE_6 (6) */
Q_KEY_CODE_7, /* linux:8 (KEY_7) -> linux:8 (KEY_7) -> qcode:Q_KEY_CODE_7 (7) */
Q_KEY_CODE_8, /* linux:9 (KEY_8) -> linux:9 (KEY_8) -> qcode:Q_KEY_CODE_8 (8) */
Q_KEY_CODE_9, /* linux:10 (KEY_9) -> linux:10 (KEY_9) -> qcode:Q_KEY_CODE_9 (9) */
Q_KEY_CODE_0, /* linux:11 (KEY_0) -> linux:11 (KEY_0) -> qcode:Q_KEY_CODE_0 (0) */
Q_KEY_CODE_MINUS, /* linux:12 (KEY_MINUS) -> linux:12 (KEY_MINUS) -> qcode:Q_KEY_CODE_MINUS (minus) */
Q_KEY_CODE_EQUAL, /* linux:13 (KEY_EQUAL) -> linux:13 (KEY_EQUAL) -> qcode:Q_KEY_CODE_EQUAL (equal) */
Q_KEY_CODE_BACKSPACE, /* linux:14 (KEY_BACKSPACE) -> linux:14 (KEY_BACKSPACE) -> qcode:Q_KEY_CODE_BACKSPACE (backspace) */
Q_KEY_CODE_TAB, /* linux:15 (KEY_TAB) -> linux:15 (KEY_TAB) -> qcode:Q_KEY_CODE_TAB (tab) */
Q_KEY_CODE_Q, /* linux:16 (KEY_Q) -> linux:16 (KEY_Q) -> qcode:Q_KEY_CODE_Q (q) */
Q_KEY_CODE_W, /* linux:17 (KEY_W) -> linux:17 (KEY_W) -> qcode:Q_KEY_CODE_W (w) */
Q_KEY_CODE_E, /* linux:18 (KEY_E) -> linux:18 (KEY_E) -> qcode:Q_KEY_CODE_E (e) */
Q_KEY_CODE_R, /* linux:19 (KEY_R) -> linux:19 (KEY_R) -> qcode:Q_KEY_CODE_R (r) */
Q_KEY_CODE_T, /* linux:20 (KEY_T) -> linux:20 (KEY_T) -> qcode:Q_KEY_CODE_T (t) */
Q_KEY_CODE_Y, /* linux:21 (KEY_Y) -> linux:21 (KEY_Y) -> qcode:Q_KEY_CODE_Y (y) */
Q_KEY_CODE_U, /* linux:22 (KEY_U) -> linux:22 (KEY_U) -> qcode:Q_KEY_CODE_U (u) */
Q_KEY_CODE_I, /* linux:23 (KEY_I) -> linux:23 (KEY_I) -> qcode:Q_KEY_CODE_I (i) */
Q_KEY_CODE_O, /* linux:24 (KEY_O) -> linux:24 (KEY_O) -> qcode:Q_KEY_CODE_O (o) */
Q_KEY_CODE_P, /* linux:25 (KEY_P) -> linux:25 (KEY_P) -> qcode:Q_KEY_CODE_P (p) */
Q_KEY_CODE_BRACKET_LEFT, /* linux:26 (KEY_LEFTBRACE) -> linux:26 (KEY_LEFTBRACE) -> qcode:Q_KEY_CODE_BRACKET_LEFT (bracket_left) */
Q_KEY_CODE_BRACKET_RIGHT, /* linux:27 (KEY_RIGHTBRACE) -> linux:27 (KEY_RIGHTBRACE) -> qcode:Q_KEY_CODE_BRACKET_RIGHT (bracket_right) */
Q_KEY_CODE_RET, /* linux:28 (KEY_ENTER) -> linux:28 (KEY_ENTER) -> qcode:Q_KEY_CODE_RET (ret) */
Q_KEY_CODE_CTRL, /* linux:29 (KEY_LEFTCTRL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
Q_KEY_CODE_A, /* linux:30 (KEY_A) -> linux:30 (KEY_A) -> qcode:Q_KEY_CODE_A (a) */
Q_KEY_CODE_S, /* linux:31 (KEY_S) -> linux:31 (KEY_S) -> qcode:Q_KEY_CODE_S (s) */
Q_KEY_CODE_D, /* linux:32 (KEY_D) -> linux:32 (KEY_D) -> qcode:Q_KEY_CODE_D (d) */
Q_KEY_CODE_F, /* linux:33 (KEY_F) -> linux:33 (KEY_F) -> qcode:Q_KEY_CODE_F (f) */
Q_KEY_CODE_G, /* linux:34 (KEY_G) -> linux:34 (KEY_G) -> qcode:Q_KEY_CODE_G (g) */
Q_KEY_CODE_H, /* linux:35 (KEY_H) -> linux:35 (KEY_H) -> qcode:Q_KEY_CODE_H (h) */
Q_KEY_CODE_J, /* linux:36 (KEY_J) -> linux:36 (KEY_J) -> qcode:Q_KEY_CODE_J (j) */
Q_KEY_CODE_K, /* linux:37 (KEY_K) -> linux:37 (KEY_K) -> qcode:Q_KEY_CODE_K (k) */
Q_KEY_CODE_L, /* linux:38 (KEY_L) -> linux:38 (KEY_L) -> qcode:Q_KEY_CODE_L (l) */
Q_KEY_CODE_SEMICOLON, /* linux:39 (KEY_SEMICOLON) -> linux:39 (KEY_SEMICOLON) -> qcode:Q_KEY_CODE_SEMICOLON (semicolon) */
Q_KEY_CODE_APOSTROPHE, /* linux:40 (KEY_APOSTROPHE) -> linux:40 (KEY_APOSTROPHE) -> qcode:Q_KEY_CODE_APOSTROPHE (apostrophe) */
Q_KEY_CODE_GRAVE_ACCENT, /* linux:41 (KEY_GRAVE) -> linux:41 (KEY_GRAVE) -> qcode:Q_KEY_CODE_GRAVE_ACCENT (grave_accent) */
Q_KEY_CODE_SHIFT, /* linux:42 (KEY_LEFTSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
Q_KEY_CODE_BACKSLASH, /* linux:43 (KEY_BACKSLASH) -> linux:43 (KEY_BACKSLASH) -> qcode:Q_KEY_CODE_BACKSLASH (backslash) */
Q_KEY_CODE_Z, /* linux:44 (KEY_Z) -> linux:44 (KEY_Z) -> qcode:Q_KEY_CODE_Z (z) */
Q_KEY_CODE_X, /* linux:45 (KEY_X) -> linux:45 (KEY_X) -> qcode:Q_KEY_CODE_X (x) */
Q_KEY_CODE_C, /* linux:46 (KEY_C) -> linux:46 (KEY_C) -> qcode:Q_KEY_CODE_C (c) */
Q_KEY_CODE_V, /* linux:47 (KEY_V) -> linux:47 (KEY_V) -> qcode:Q_KEY_CODE_V (v) */
Q_KEY_CODE_B, /* linux:48 (KEY_B) -> linux:48 (KEY_B) -> qcode:Q_KEY_CODE_B (b) */
Q_KEY_CODE_N, /* linux:49 (KEY_N) -> linux:49 (KEY_N) -> qcode:Q_KEY_CODE_N (n) */
Q_KEY_CODE_M, /* linux:50 (KEY_M) -> linux:50 (KEY_M) -> qcode:Q_KEY_CODE_M (m) */
Q_KEY_CODE_COMMA, /* linux:51 (KEY_COMMA) -> linux:51 (KEY_COMMA) -> qcode:Q_KEY_CODE_COMMA (comma) */
Q_KEY_CODE_DOT, /* linux:52 (KEY_DOT) -> linux:52 (KEY_DOT) -> qcode:Q_KEY_CODE_DOT (dot) */
Q_KEY_CODE_SLASH, /* linux:53 (KEY_SLASH) -> linux:53 (KEY_SLASH) -> qcode:Q_KEY_CODE_SLASH (slash) */
Q_KEY_CODE_SHIFT_R, /* linux:54 (KEY_RIGHTSHIFT) -> linux:54 (KEY_RIGHTSHIFT) -> qcode:Q_KEY_CODE_SHIFT_R (shift_r) */
Q_KEY_CODE_KP_MULTIPLY, /* linux:55 (KEY_KPASTERISK) -> linux:55 (KEY_KPASTERISK) -> qcode:Q_KEY_CODE_KP_MULTIPLY (kp_multiply) */
Q_KEY_CODE_ALT, /* linux:56 (KEY_LEFTALT) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
Q_KEY_CODE_SPC, /* linux:57 (KEY_SPACE) -> linux:57 (KEY_SPACE) -> qcode:Q_KEY_CODE_SPC (spc) */
Q_KEY_CODE_CAPS_LOCK, /* linux:58 (KEY_CAPSLOCK) -> linux:58 (KEY_CAPSLOCK) -> qcode:Q_KEY_CODE_CAPS_LOCK (caps_lock) */
Q_KEY_CODE_F1, /* linux:59 (KEY_F1) -> linux:59 (KEY_F1) -> qcode:Q_KEY_CODE_F1 (f1) */
Q_KEY_CODE_F2, /* linux:60 (KEY_F2) -> linux:60 (KEY_F2) -> qcode:Q_KEY_CODE_F2 (f2) */
Q_KEY_CODE_F3, /* linux:61 (KEY_F3) -> linux:61 (KEY_F3) -> qcode:Q_KEY_CODE_F3 (f3) */
Q_KEY_CODE_F4, /* linux:62 (KEY_F4) -> linux:62 (KEY_F4) -> qcode:Q_KEY_CODE_F4 (f4) */
Q_KEY_CODE_F5, /* linux:63 (KEY_F5) -> linux:63 (KEY_F5) -> qcode:Q_KEY_CODE_F5 (f5) */
Q_KEY_CODE_F6, /* linux:64 (KEY_F6) -> linux:64 (KEY_F6) -> qcode:Q_KEY_CODE_F6 (f6) */
Q_KEY_CODE_F7, /* linux:65 (KEY_F7) -> linux:65 (KEY_F7) -> qcode:Q_KEY_CODE_F7 (f7) */
Q_KEY_CODE_F8, /* linux:66 (KEY_F8) -> linux:66 (KEY_F8) -> qcode:Q_KEY_CODE_F8 (f8) */
Q_KEY_CODE_F9, /* linux:67 (KEY_F9) -> linux:67 (KEY_F9) -> qcode:Q_KEY_CODE_F9 (f9) */
Q_KEY_CODE_F10, /* linux:68 (KEY_F10) -> linux:68 (KEY_F10) -> qcode:Q_KEY_CODE_F10 (f10) */
Q_KEY_CODE_NUM_LOCK, /* linux:69 (KEY_NUMLOCK) -> linux:69 (KEY_NUMLOCK) -> qcode:Q_KEY_CODE_NUM_LOCK (num_lock) */
Q_KEY_CODE_SCROLL_LOCK, /* linux:70 (KEY_SCROLLLOCK) -> linux:70 (KEY_SCROLLLOCK) -> qcode:Q_KEY_CODE_SCROLL_LOCK (scroll_lock) */
Q_KEY_CODE_KP_7, /* linux:71 (KEY_KP7) -> linux:71 (KEY_KP7) -> qcode:Q_KEY_CODE_KP_7 (kp_7) */
Q_KEY_CODE_KP_8, /* linux:72 (KEY_KP8) -> linux:72 (KEY_KP8) -> qcode:Q_KEY_CODE_KP_8 (kp_8) */
Q_KEY_CODE_KP_9, /* linux:73 (KEY_KP9) -> linux:73 (KEY_KP9) -> qcode:Q_KEY_CODE_KP_9 (kp_9) */
Q_KEY_CODE_KP_SUBTRACT, /* linux:74 (KEY_KPMINUS) -> linux:74 (KEY_KPMINUS) -> qcode:Q_KEY_CODE_KP_SUBTRACT (kp_subtract) */
Q_KEY_CODE_KP_4, /* linux:75 (KEY_KP4) -> linux:75 (KEY_KP4) -> qcode:Q_KEY_CODE_KP_4 (kp_4) */
Q_KEY_CODE_KP_5, /* linux:76 (KEY_KP5) -> linux:76 (KEY_KP5) -> qcode:Q_KEY_CODE_KP_5 (kp_5) */
Q_KEY_CODE_KP_6, /* linux:77 (KEY_KP6) -> linux:77 (KEY_KP6) -> qcode:Q_KEY_CODE_KP_6 (kp_6) */
Q_KEY_CODE_KP_ADD, /* linux:78 (KEY_KPPLUS) -> linux:78 (KEY_KPPLUS) -> qcode:Q_KEY_CODE_KP_ADD (kp_add) */
Q_KEY_CODE_KP_1, /* linux:79 (KEY_KP1) -> linux:79 (KEY_KP1) -> qcode:Q_KEY_CODE_KP_1 (kp_1) */
Q_KEY_CODE_KP_2, /* linux:80 (KEY_KP2) -> linux:80 (KEY_KP2) -> qcode:Q_KEY_CODE_KP_2 (kp_2) */
Q_KEY_CODE_KP_3, /* linux:81 (KEY_KP3) -> linux:81 (KEY_KP3) -> qcode:Q_KEY_CODE_KP_3 (kp_3) */
Q_KEY_CODE_KP_0, /* linux:82 (KEY_KP0) -> linux:82 (KEY_KP0) -> qcode:Q_KEY_CODE_KP_0 (kp_0) */
Q_KEY_CODE_KP_DECIMAL, /* linux:83 (KEY_KPDOT) -> linux:83 (KEY_KPDOT) -> qcode:Q_KEY_CODE_KP_DECIMAL (kp_decimal) */
Q_KEY_CODE_UNMAPPED, /* linux:84 (unnamed) -> linux:84 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:85 (KEY_ZENKAKUHANKAKU) -> linux:85 (KEY_ZENKAKUHANKAKU) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_LESS, /* linux:86 (KEY_102ND) -> linux:86 (KEY_102ND) -> qcode:Q_KEY_CODE_LESS (less) */
Q_KEY_CODE_F11, /* linux:87 (KEY_F11) -> linux:87 (KEY_F11) -> qcode:Q_KEY_CODE_F11 (f11) */
Q_KEY_CODE_F12, /* linux:88 (KEY_F12) -> linux:88 (KEY_F12) -> qcode:Q_KEY_CODE_F12 (f12) */
Q_KEY_CODE_RO, /* linux:89 (KEY_RO) -> linux:89 (KEY_RO) -> qcode:Q_KEY_CODE_RO (ro) */
Q_KEY_CODE_UNMAPPED, /* linux:90 (KEY_KATAKANA) -> linux:90 (KEY_KATAKANA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_HIRAGANA, /* linux:91 (KEY_HIRAGANA) -> linux:91 (KEY_HIRAGANA) -> qcode:Q_KEY_CODE_HIRAGANA (hiragana) */
Q_KEY_CODE_HENKAN, /* linux:92 (KEY_HENKAN) -> linux:92 (KEY_HENKAN) -> qcode:Q_KEY_CODE_HENKAN (henkan) */
Q_KEY_CODE_KATAKANAHIRAGANA, /* linux:93 (KEY_KATAKANAHIRAGANA) -> linux:93 (KEY_KATAKANAHIRAGANA) -> qcode:Q_KEY_CODE_KATAKANAHIRAGANA (katakanahiragana) */
Q_KEY_CODE_MUHENKAN, /* linux:94 (KEY_MUHENKAN) -> linux:94 (KEY_MUHENKAN) -> qcode:Q_KEY_CODE_MUHENKAN (muhenkan) */
Q_KEY_CODE_UNMAPPED, /* linux:95 (KEY_KPJPCOMMA) -> linux:95 (KEY_KPJPCOMMA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_KP_ENTER, /* linux:96 (KEY_KPENTER) -> linux:96 (KEY_KPENTER) -> qcode:Q_KEY_CODE_KP_ENTER (kp_enter) */
Q_KEY_CODE_CTRL_R, /* linux:97 (KEY_RIGHTCTRL) -> linux:97 (KEY_RIGHTCTRL) -> qcode:Q_KEY_CODE_CTRL_R (ctrl_r) */
Q_KEY_CODE_KP_DIVIDE, /* linux:98 (KEY_KPSLASH) -> linux:98 (KEY_KPSLASH) -> qcode:Q_KEY_CODE_KP_DIVIDE (kp_divide) */
Q_KEY_CODE_SYSRQ, /* linux:99 (KEY_SYSRQ) -> linux:99 (KEY_SYSRQ) -> qcode:Q_KEY_CODE_SYSRQ (sysrq) */
Q_KEY_CODE_ALT_R, /* linux:100 (KEY_RIGHTALT) -> linux:100 (KEY_RIGHTALT) -> qcode:Q_KEY_CODE_ALT_R (alt_r) */
Q_KEY_CODE_LF, /* linux:101 (KEY_LINEFEED) -> linux:101 (KEY_LINEFEED) -> qcode:Q_KEY_CODE_LF (lf) */
Q_KEY_CODE_HOME, /* linux:102 (KEY_HOME) -> linux:102 (KEY_HOME) -> qcode:Q_KEY_CODE_HOME (home) */
Q_KEY_CODE_UP, /* linux:103 (KEY_UP) -> linux:103 (KEY_UP) -> qcode:Q_KEY_CODE_UP (up) */
Q_KEY_CODE_PGUP, /* linux:104 (KEY_PAGEUP) -> linux:104 (KEY_PAGEUP) -> qcode:Q_KEY_CODE_PGUP (pgup) */
Q_KEY_CODE_LEFT, /* linux:105 (KEY_LEFT) -> linux:105 (KEY_LEFT) -> qcode:Q_KEY_CODE_LEFT (left) */
Q_KEY_CODE_RIGHT, /* linux:106 (KEY_RIGHT) -> linux:106 (KEY_RIGHT) -> qcode:Q_KEY_CODE_RIGHT (right) */
Q_KEY_CODE_END, /* linux:107 (KEY_END) -> linux:107 (KEY_END) -> qcode:Q_KEY_CODE_END (end) */
Q_KEY_CODE_DOWN, /* linux:108 (KEY_DOWN) -> linux:108 (KEY_DOWN) -> qcode:Q_KEY_CODE_DOWN (down) */
Q_KEY_CODE_PGDN, /* linux:109 (KEY_PAGEDOWN) -> linux:109 (KEY_PAGEDOWN) -> qcode:Q_KEY_CODE_PGDN (pgdn) */
Q_KEY_CODE_INSERT, /* linux:110 (KEY_INSERT) -> linux:110 (KEY_INSERT) -> qcode:Q_KEY_CODE_INSERT (insert) */
Q_KEY_CODE_DELETE, /* linux:111 (KEY_DELETE) -> linux:111 (KEY_DELETE) -> qcode:Q_KEY_CODE_DELETE (delete) */
Q_KEY_CODE_UNMAPPED, /* linux:112 (KEY_MACRO) -> linux:112 (KEY_MACRO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_AUDIOMUTE, /* linux:113 (KEY_MUTE) -> linux:113 (KEY_MUTE) -> qcode:Q_KEY_CODE_AUDIOMUTE (audiomute) */
Q_KEY_CODE_VOLUMEDOWN, /* linux:114 (KEY_VOLUMEDOWN) -> linux:114 (KEY_VOLUMEDOWN) -> qcode:Q_KEY_CODE_VOLUMEDOWN (volumedown) */
Q_KEY_CODE_VOLUMEUP, /* linux:115 (KEY_VOLUMEUP) -> linux:115 (KEY_VOLUMEUP) -> qcode:Q_KEY_CODE_VOLUMEUP (volumeup) */
Q_KEY_CODE_POWER, /* linux:116 (KEY_POWER) -> linux:116 (KEY_POWER) -> qcode:Q_KEY_CODE_POWER (power) */
Q_KEY_CODE_KP_EQUALS, /* linux:117 (KEY_KPEQUAL) -> linux:117 (KEY_KPEQUAL) -> qcode:Q_KEY_CODE_KP_EQUALS (kp_equals) */
Q_KEY_CODE_UNMAPPED, /* linux:118 (KEY_KPPLUSMINUS) -> linux:118 (KEY_KPPLUSMINUS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_PAUSE, /* linux:119 (KEY_PAUSE) -> linux:119 (KEY_PAUSE) -> qcode:Q_KEY_CODE_PAUSE (pause) */
Q_KEY_CODE_UNMAPPED, /* linux:120 (KEY_SCALE) -> linux:120 (KEY_SCALE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_KP_COMMA, /* linux:121 (KEY_KPCOMMA) -> linux:121 (KEY_KPCOMMA) -> qcode:Q_KEY_CODE_KP_COMMA (kp_comma) */
Q_KEY_CODE_UNMAPPED, /* linux:122 (KEY_HANGEUL) -> linux:122 (KEY_HANGEUL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:123 (KEY_HANJA) -> linux:123 (KEY_HANJA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_YEN, /* linux:124 (KEY_YEN) -> linux:124 (KEY_YEN) -> qcode:Q_KEY_CODE_YEN (yen) */
Q_KEY_CODE_META_L, /* linux:125 (KEY_LEFTMETA) -> linux:125 (KEY_LEFTMETA) -> qcode:Q_KEY_CODE_META_L (meta_l) */
Q_KEY_CODE_META_R, /* linux:126 (KEY_RIGHTMETA) -> linux:126 (KEY_RIGHTMETA) -> qcode:Q_KEY_CODE_META_R (meta_r) */
Q_KEY_CODE_COMPOSE, /* linux:127 (KEY_COMPOSE) -> linux:127 (KEY_COMPOSE) -> qcode:Q_KEY_CODE_COMPOSE (compose) */
Q_KEY_CODE_STOP, /* linux:128 (KEY_STOP) -> linux:128 (KEY_STOP) -> qcode:Q_KEY_CODE_STOP (stop) */
Q_KEY_CODE_AGAIN, /* linux:129 (KEY_AGAIN) -> linux:129 (KEY_AGAIN) -> qcode:Q_KEY_CODE_AGAIN (again) */
Q_KEY_CODE_PROPS, /* linux:130 (KEY_PROPS) -> linux:130 (KEY_PROPS) -> qcode:Q_KEY_CODE_PROPS (props) */
Q_KEY_CODE_UNDO, /* linux:131 (KEY_UNDO) -> linux:131 (KEY_UNDO) -> qcode:Q_KEY_CODE_UNDO (undo) */
Q_KEY_CODE_FRONT, /* linux:132 (KEY_FRONT) -> linux:132 (KEY_FRONT) -> qcode:Q_KEY_CODE_FRONT (front) */
Q_KEY_CODE_COPY, /* linux:133 (KEY_COPY) -> linux:133 (KEY_COPY) -> qcode:Q_KEY_CODE_COPY (copy) */
Q_KEY_CODE_OPEN, /* linux:134 (KEY_OPEN) -> linux:134 (KEY_OPEN) -> qcode:Q_KEY_CODE_OPEN (open) */
Q_KEY_CODE_PASTE, /* linux:135 (KEY_PASTE) -> linux:135 (KEY_PASTE) -> qcode:Q_KEY_CODE_PASTE (paste) */
Q_KEY_CODE_FIND, /* linux:136 (KEY_FIND) -> linux:136 (KEY_FIND) -> qcode:Q_KEY_CODE_FIND (find) */
Q_KEY_CODE_CUT, /* linux:137 (KEY_CUT) -> linux:137 (KEY_CUT) -> qcode:Q_KEY_CODE_CUT (cut) */
Q_KEY_CODE_HELP, /* linux:138 (KEY_HELP) -> linux:138 (KEY_HELP) -> qcode:Q_KEY_CODE_HELP (help) */
Q_KEY_CODE_MENU, /* linux:139 (KEY_MENU) -> linux:139 (KEY_MENU) -> qcode:Q_KEY_CODE_MENU (menu) */
Q_KEY_CODE_CALCULATOR, /* linux:140 (KEY_CALC) -> linux:140 (KEY_CALC) -> qcode:Q_KEY_CODE_CALCULATOR (calculator) */
Q_KEY_CODE_UNMAPPED, /* linux:141 (KEY_SETUP) -> linux:141 (KEY_SETUP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_SLEEP, /* linux:142 (KEY_SLEEP) -> linux:142 (KEY_SLEEP) -> qcode:Q_KEY_CODE_SLEEP (sleep) */
Q_KEY_CODE_WAKE, /* linux:143 (KEY_WAKEUP) -> linux:143 (KEY_WAKEUP) -> qcode:Q_KEY_CODE_WAKE (wake) */
Q_KEY_CODE_UNMAPPED, /* linux:144 (KEY_FILE) -> linux:144 (KEY_FILE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:145 (KEY_SENDFILE) -> linux:145 (KEY_SENDFILE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:146 (KEY_DELETEFILE) -> linux:146 (KEY_DELETEFILE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:147 (KEY_XFER) -> linux:147 (KEY_XFER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:148 (KEY_PROG1) -> linux:148 (KEY_PROG1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:149 (KEY_PROG2) -> linux:149 (KEY_PROG2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:150 (KEY_WWW) -> linux:150 (KEY_WWW) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:151 (KEY_MSDOS) -> linux:151 (KEY_MSDOS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:152 (KEY_SCREENLOCK) -> linux:152 (KEY_SCREENLOCK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:153 (KEY_DIRECTION) -> linux:153 (KEY_DIRECTION) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:154 (KEY_CYCLEWINDOWS) -> linux:154 (KEY_CYCLEWINDOWS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_MAIL, /* linux:155 (KEY_MAIL) -> linux:155 (KEY_MAIL) -> qcode:Q_KEY_CODE_MAIL (mail) */
Q_KEY_CODE_AC_BOOKMARKS, /* linux:156 (KEY_BOOKMARKS) -> linux:156 (KEY_BOOKMARKS) -> qcode:Q_KEY_CODE_AC_BOOKMARKS (ac_bookmarks) */
Q_KEY_CODE_COMPUTER, /* linux:157 (KEY_COMPUTER) -> linux:157 (KEY_COMPUTER) -> qcode:Q_KEY_CODE_COMPUTER (computer) */
Q_KEY_CODE_AC_BACK, /* linux:158 (KEY_BACK) -> linux:158 (KEY_BACK) -> qcode:Q_KEY_CODE_AC_BACK (ac_back) */
Q_KEY_CODE_AC_FORWARD, /* linux:159 (KEY_FORWARD) -> linux:159 (KEY_FORWARD) -> qcode:Q_KEY_CODE_AC_FORWARD (ac_forward) */
Q_KEY_CODE_UNMAPPED, /* linux:160 (KEY_CLOSECD) -> linux:160 (KEY_CLOSECD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:161 (KEY_EJECTCD) -> linux:161 (KEY_EJECTCD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:162 (KEY_EJECTCLOSECD) -> linux:162 (KEY_EJECTCLOSECD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_AUDIONEXT, /* linux:163 (KEY_NEXTSONG) -> linux:163 (KEY_NEXTSONG) -> qcode:Q_KEY_CODE_AUDIONEXT (audionext) */
Q_KEY_CODE_AUDIOPLAY, /* linux:164 (KEY_PLAYPAUSE) -> linux:164 (KEY_PLAYPAUSE) -> qcode:Q_KEY_CODE_AUDIOPLAY (audioplay) */
Q_KEY_CODE_AUDIOPREV, /* linux:165 (KEY_PREVIOUSSONG) -> linux:165 (KEY_PREVIOUSSONG) -> qcode:Q_KEY_CODE_AUDIOPREV (audioprev) */
Q_KEY_CODE_AUDIOSTOP, /* linux:166 (KEY_STOPCD) -> linux:166 (KEY_STOPCD) -> qcode:Q_KEY_CODE_AUDIOSTOP (audiostop) */
Q_KEY_CODE_UNMAPPED, /* linux:167 (KEY_RECORD) -> linux:167 (KEY_RECORD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:168 (KEY_REWIND) -> linux:168 (KEY_REWIND) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:169 (KEY_PHONE) -> linux:169 (KEY_PHONE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:170 (KEY_ISO) -> linux:170 (KEY_ISO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:171 (KEY_CONFIG) -> linux:171 (KEY_CONFIG) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_AC_HOME, /* linux:172 (KEY_HOMEPAGE) -> linux:172 (KEY_HOMEPAGE) -> qcode:Q_KEY_CODE_AC_HOME (ac_home) */
Q_KEY_CODE_AC_REFRESH, /* linux:173 (KEY_REFRESH) -> linux:173 (KEY_REFRESH) -> qcode:Q_KEY_CODE_AC_REFRESH (ac_refresh) */
Q_KEY_CODE_UNMAPPED, /* linux:174 (KEY_EXIT) -> linux:174 (KEY_EXIT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:175 (KEY_MOVE) -> linux:175 (KEY_MOVE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:176 (KEY_EDIT) -> linux:176 (KEY_EDIT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:177 (KEY_SCROLLUP) -> linux:177 (KEY_SCROLLUP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:178 (KEY_SCROLLDOWN) -> linux:178 (KEY_SCROLLDOWN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:179 (KEY_KPLEFTPAREN) -> linux:179 (KEY_KPLEFTPAREN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:180 (KEY_KPRIGHTPAREN) -> linux:180 (KEY_KPRIGHTPAREN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:181 (KEY_NEW) -> linux:181 (KEY_NEW) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:182 (KEY_REDO) -> linux:182 (KEY_REDO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:183 (KEY_F13) -> linux:183 (KEY_F13) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:184 (KEY_F14) -> linux:184 (KEY_F14) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:185 (KEY_F15) -> linux:185 (KEY_F15) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:186 (KEY_F16) -> linux:186 (KEY_F16) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:187 (KEY_F17) -> linux:187 (KEY_F17) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:188 (KEY_F18) -> linux:188 (KEY_F18) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:189 (KEY_F19) -> linux:189 (KEY_F19) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:190 (KEY_F20) -> linux:190 (KEY_F20) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:191 (KEY_F21) -> linux:191 (KEY_F21) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:192 (KEY_F22) -> linux:192 (KEY_F22) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:193 (KEY_F23) -> linux:193 (KEY_F23) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:194 (KEY_F24) -> linux:194 (KEY_F24) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:195 (unnamed) -> linux:195 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:196 (unnamed) -> linux:196 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:197 (unnamed) -> linux:197 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:198 (unnamed) -> linux:198 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:199 (unnamed) -> linux:199 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:200 (KEY_PLAYCD) -> linux:200 (KEY_PLAYCD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:201 (KEY_PAUSECD) -> linux:201 (KEY_PAUSECD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:202 (KEY_PROG3) -> linux:202 (KEY_PROG3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:203 (KEY_PROG4) -> linux:203 (KEY_PROG4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:204 (KEY_DASHBOARD) -> linux:204 (KEY_DASHBOARD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:205 (KEY_SUSPEND) -> linux:205 (KEY_SUSPEND) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:206 (KEY_CLOSE) -> linux:206 (KEY_CLOSE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:207 (KEY_PLAY) -> linux:207 (KEY_PLAY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:208 (KEY_FASTFORWARD) -> linux:208 (KEY_FASTFORWARD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:209 (KEY_BASSBOOST) -> linux:209 (KEY_BASSBOOST) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:210 (KEY_PRINT) -> linux:210 (KEY_PRINT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:211 (KEY_HP) -> linux:211 (KEY_HP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:212 (KEY_CAMERA) -> linux:212 (KEY_CAMERA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:213 (KEY_SOUND) -> linux:213 (KEY_SOUND) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:214 (KEY_QUESTION) -> linux:214 (KEY_QUESTION) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:215 (KEY_EMAIL) -> linux:215 (KEY_EMAIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:216 (KEY_CHAT) -> linux:216 (KEY_CHAT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:217 (KEY_SEARCH) -> linux:217 (KEY_SEARCH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:218 (KEY_CONNECT) -> linux:218 (KEY_CONNECT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:219 (KEY_FINANCE) -> linux:219 (KEY_FINANCE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:220 (KEY_SPORT) -> linux:220 (KEY_SPORT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:221 (KEY_SHOP) -> linux:221 (KEY_SHOP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:222 (KEY_ALTERASE) -> linux:222 (KEY_ALTERASE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:223 (KEY_CANCEL) -> linux:223 (KEY_CANCEL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:224 (KEY_BRIGHTNESSDOWN) -> linux:224 (KEY_BRIGHTNESSDOWN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:225 (KEY_BRIGHTNESSUP) -> linux:225 (KEY_BRIGHTNESSUP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_MEDIASELECT, /* linux:226 (KEY_MEDIA) -> linux:226 (KEY_MEDIA) -> qcode:Q_KEY_CODE_MEDIASELECT (mediaselect) */
Q_KEY_CODE_UNMAPPED, /* linux:227 (KEY_SWITCHVIDEOMODE) -> linux:227 (KEY_SWITCHVIDEOMODE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:228 (KEY_KBDILLUMTOGGLE) -> linux:228 (KEY_KBDILLUMTOGGLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:229 (KEY_KBDILLUMDOWN) -> linux:229 (KEY_KBDILLUMDOWN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:230 (KEY_KBDILLUMUP) -> linux:230 (KEY_KBDILLUMUP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:231 (KEY_SEND) -> linux:231 (KEY_SEND) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:232 (KEY_REPLY) -> linux:232 (KEY_REPLY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:233 (KEY_FORWARDMAIL) -> linux:233 (KEY_FORWARDMAIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:234 (KEY_SAVE) -> linux:234 (KEY_SAVE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:235 (KEY_DOCUMENTS) -> linux:235 (KEY_DOCUMENTS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:236 (KEY_BATTERY) -> linux:236 (KEY_BATTERY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:237 (KEY_BLUETOOTH) -> linux:237 (KEY_BLUETOOTH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:238 (KEY_WLAN) -> linux:238 (KEY_WLAN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:239 (KEY_UWB) -> linux:239 (KEY_UWB) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:240 (KEY_UNKNOWN) -> linux:240 (KEY_UNKNOWN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:241 (KEY_VIDEO_NEXT) -> linux:241 (KEY_VIDEO_NEXT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:242 (KEY_VIDEO_PREV) -> linux:242 (KEY_VIDEO_PREV) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:243 (KEY_BRIGHTNESS_CYCLE) -> linux:243 (KEY_BRIGHTNESS_CYCLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:244 (KEY_BRIGHTNESS_ZERO) -> linux:244 (KEY_BRIGHTNESS_ZERO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:245 (KEY_DISPLAY_OFF) -> linux:245 (KEY_DISPLAY_OFF) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:246 (KEY_WIMAX) -> linux:246 (KEY_WIMAX) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:247 (unnamed) -> linux:247 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:248 (unnamed) -> linux:248 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:249 (unnamed) -> linux:249 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:250 (unnamed) -> linux:250 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:251 (unnamed) -> linux:251 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:252 (unnamed) -> linux:252 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:253 (unnamed) -> linux:253 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:254 (unnamed) -> linux:254 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:255 (unnamed) -> linux:255 (unnamed) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:256 (BTN_0) -> linux:256 (BTN_0) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:257 (BTN_1) -> linux:257 (BTN_1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:258 (BTN_2) -> linux:258 (BTN_2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:259 (BTN_3) -> linux:259 (BTN_3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:260 (BTN_4) -> linux:260 (BTN_4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:261 (BTN_5) -> linux:261 (BTN_5) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:262 (BTN_6) -> linux:262 (BTN_6) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:263 (BTN_7) -> linux:263 (BTN_7) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:264 (BTN_8) -> linux:264 (BTN_8) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:265 (BTN_9) -> linux:265 (BTN_9) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:266 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:267 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:268 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:269 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:270 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:271 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:272 (BTN_LEFT) -> linux:272 (BTN_LEFT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:273 (BTN_RIGHT) -> linux:273 (BTN_RIGHT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:274 (BTN_MIDDLE) -> linux:274 (BTN_MIDDLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:275 (BTN_SIDE) -> linux:275 (BTN_SIDE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:276 (BTN_EXTRA) -> linux:276 (BTN_EXTRA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:277 (BTN_FORWARD) -> linux:277 (BTN_FORWARD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:278 (BTN_BACK) -> linux:278 (BTN_BACK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:279 (BTN_TASK) -> linux:279 (BTN_TASK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:280 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:281 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:282 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:283 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:284 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:285 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:286 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:287 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:288 (BTN_TRIGGER) -> linux:288 (BTN_TRIGGER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:289 (BTN_THUMB) -> linux:289 (BTN_THUMB) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:290 (BTN_THUMB2) -> linux:290 (BTN_THUMB2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:291 (BTN_TOP) -> linux:291 (BTN_TOP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:292 (BTN_TOP2) -> linux:292 (BTN_TOP2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:293 (BTN_PINKIE) -> linux:293 (BTN_PINKIE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:294 (BTN_BASE) -> linux:294 (BTN_BASE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:295 (BTN_BASE2) -> linux:295 (BTN_BASE2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:296 (BTN_BASE3) -> linux:296 (BTN_BASE3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:297 (BTN_BASE4) -> linux:297 (BTN_BASE4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:298 (BTN_BASE5) -> linux:298 (BTN_BASE5) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:299 (BTN_BASE6) -> linux:299 (BTN_BASE6) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:300 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:301 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:302 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:303 (BTN_DEAD) -> linux:303 (BTN_DEAD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:304 (BTN_A) -> linux:304 (BTN_A) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:305 (BTN_B) -> linux:305 (BTN_B) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:306 (BTN_C) -> linux:306 (BTN_C) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:307 (BTN_X) -> linux:307 (BTN_X) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:308 (BTN_Y) -> linux:308 (BTN_Y) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:309 (BTN_Z) -> linux:309 (BTN_Z) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:310 (BTN_TL) -> linux:310 (BTN_TL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:311 (BTN_TR) -> linux:311 (BTN_TR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:312 (BTN_TL2) -> linux:312 (BTN_TL2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:313 (BTN_TR2) -> linux:313 (BTN_TR2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:314 (BTN_SELECT) -> linux:314 (BTN_SELECT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:315 (BTN_START) -> linux:315 (BTN_START) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:316 (BTN_MODE) -> linux:316 (BTN_MODE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:317 (BTN_THUMBL) -> linux:317 (BTN_THUMBL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:318 (BTN_THUMBR) -> linux:318 (BTN_THUMBR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:319 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:320 (BTN_TOOL_PEN) -> linux:320 (BTN_TOOL_PEN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:321 (BTN_TOOL_RUBBER) -> linux:321 (BTN_TOOL_RUBBER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:322 (BTN_TOOL_BRUSH) -> linux:322 (BTN_TOOL_BRUSH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:323 (BTN_TOOL_PENCIL) -> linux:323 (BTN_TOOL_PENCIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:324 (BTN_TOOL_AIRBRUSH) -> linux:324 (BTN_TOOL_AIRBRUSH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:325 (BTN_TOOL_FINGER) -> linux:325 (BTN_TOOL_FINGER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:326 (BTN_TOOL_MOUSE) -> linux:326 (BTN_TOOL_MOUSE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:327 (BTN_TOOL_LENS) -> linux:327 (BTN_TOOL_LENS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:328 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:329 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:330 (BTN_TOUCH) -> linux:330 (BTN_TOUCH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:331 (BTN_STYLUS) -> linux:331 (BTN_STYLUS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:332 (BTN_STYLUS2) -> linux:332 (BTN_STYLUS2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:333 (BTN_TOOL_DOUBLETAP) -> linux:333 (BTN_TOOL_DOUBLETAP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:334 (BTN_TOOL_TRIPLETAP) -> linux:334 (BTN_TOOL_TRIPLETAP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:335 (BTN_TOOL_QUADTAP) -> linux:335 (BTN_TOOL_QUADTAP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:336 (BTN_GEAR_DOWN) -> linux:336 (BTN_GEAR_DOWN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:337 (BTN_GEAR_UP) -> linux:337 (BTN_GEAR_UP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:338 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:339 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:340 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:341 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:342 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:343 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:344 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:345 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:346 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:347 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:348 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:349 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:350 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:351 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:352 (KEY_OK) -> linux:352 (KEY_OK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:353 (KEY_SELECT) -> linux:353 (KEY_SELECT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:354 (KEY_GOTO) -> linux:354 (KEY_GOTO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:355 (KEY_CLEAR) -> linux:355 (KEY_CLEAR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:356 (KEY_POWER2) -> linux:356 (KEY_POWER2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:357 (KEY_OPTION) -> linux:357 (KEY_OPTION) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:358 (KEY_INFO) -> linux:358 (KEY_INFO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:359 (KEY_TIME) -> linux:359 (KEY_TIME) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:360 (KEY_VENDOR) -> linux:360 (KEY_VENDOR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:361 (KEY_ARCHIVE) -> linux:361 (KEY_ARCHIVE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:362 (KEY_PROGRAM) -> linux:362 (KEY_PROGRAM) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:363 (KEY_CHANNEL) -> linux:363 (KEY_CHANNEL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:364 (KEY_FAVORITES) -> linux:364 (KEY_FAVORITES) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:365 (KEY_EPG) -> linux:365 (KEY_EPG) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:366 (KEY_PVR) -> linux:366 (KEY_PVR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:367 (KEY_MHP) -> linux:367 (KEY_MHP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:368 (KEY_LANGUAGE) -> linux:368 (KEY_LANGUAGE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:369 (KEY_TITLE) -> linux:369 (KEY_TITLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:370 (KEY_SUBTITLE) -> linux:370 (KEY_SUBTITLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:371 (KEY_ANGLE) -> linux:371 (KEY_ANGLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:372 (KEY_ZOOM) -> linux:372 (KEY_ZOOM) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:373 (KEY_MODE) -> linux:373 (KEY_MODE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:374 (KEY_KEYBOARD) -> linux:374 (KEY_KEYBOARD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:375 (KEY_SCREEN) -> linux:375 (KEY_SCREEN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:376 (KEY_PC) -> linux:376 (KEY_PC) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:377 (KEY_TV) -> linux:377 (KEY_TV) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:378 (KEY_TV2) -> linux:378 (KEY_TV2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:379 (KEY_VCR) -> linux:379 (KEY_VCR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:380 (KEY_VCR2) -> linux:380 (KEY_VCR2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:381 (KEY_SAT) -> linux:381 (KEY_SAT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:382 (KEY_SAT2) -> linux:382 (KEY_SAT2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:383 (KEY_CD) -> linux:383 (KEY_CD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:384 (KEY_TAPE) -> linux:384 (KEY_TAPE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:385 (KEY_RADIO) -> linux:385 (KEY_RADIO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:386 (KEY_TUNER) -> linux:386 (KEY_TUNER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:387 (KEY_PLAYER) -> linux:387 (KEY_PLAYER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:388 (KEY_TEXT) -> linux:388 (KEY_TEXT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:389 (KEY_DVD) -> linux:389 (KEY_DVD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:390 (KEY_AUX) -> linux:390 (KEY_AUX) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:391 (KEY_MP3) -> linux:391 (KEY_MP3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:392 (KEY_AUDIO) -> linux:392 (KEY_AUDIO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:393 (KEY_VIDEO) -> linux:393 (KEY_VIDEO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:394 (KEY_DIRECTORY) -> linux:394 (KEY_DIRECTORY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:395 (KEY_LIST) -> linux:395 (KEY_LIST) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:396 (KEY_MEMO) -> linux:396 (KEY_MEMO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:397 (KEY_CALENDAR) -> linux:397 (KEY_CALENDAR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:398 (KEY_RED) -> linux:398 (KEY_RED) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:399 (KEY_GREEN) -> linux:399 (KEY_GREEN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:400 (KEY_YELLOW) -> linux:400 (KEY_YELLOW) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:401 (KEY_BLUE) -> linux:401 (KEY_BLUE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:402 (KEY_CHANNELUP) -> linux:402 (KEY_CHANNELUP) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:403 (KEY_CHANNELDOWN) -> linux:403 (KEY_CHANNELDOWN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:404 (KEY_FIRST) -> linux:404 (KEY_FIRST) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:405 (KEY_LAST) -> linux:405 (KEY_LAST) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:406 (KEY_AB) -> linux:406 (KEY_AB) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:407 (KEY_NEXT) -> linux:407 (KEY_NEXT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:408 (KEY_RESTART) -> linux:408 (KEY_RESTART) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:409 (KEY_SLOW) -> linux:409 (KEY_SLOW) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:410 (KEY_SHUFFLE) -> linux:410 (KEY_SHUFFLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:411 (KEY_BREAK) -> linux:411 (KEY_BREAK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:412 (KEY_PREVIOUS) -> linux:412 (KEY_PREVIOUS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:413 (KEY_DIGITS) -> linux:413 (KEY_DIGITS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:414 (KEY_TEEN) -> linux:414 (KEY_TEEN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:415 (KEY_TWEN) -> linux:415 (KEY_TWEN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:416 (KEY_VIDEOPHONE) -> linux:416 (KEY_VIDEOPHONE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:417 (KEY_GAMES) -> linux:417 (KEY_GAMES) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:418 (KEY_ZOOMIN) -> linux:418 (KEY_ZOOMIN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:419 (KEY_ZOOMOUT) -> linux:419 (KEY_ZOOMOUT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:420 (KEY_ZOOMRESET) -> linux:420 (KEY_ZOOMRESET) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:421 (KEY_WORDPROCESSOR) -> linux:421 (KEY_WORDPROCESSOR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:422 (KEY_EDITOR) -> linux:422 (KEY_EDITOR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:423 (KEY_SPREADSHEET) -> linux:423 (KEY_SPREADSHEET) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:424 (KEY_GRAPHICSEDITOR) -> linux:424 (KEY_GRAPHICSEDITOR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:425 (KEY_PRESENTATION) -> linux:425 (KEY_PRESENTATION) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:426 (KEY_DATABASE) -> linux:426 (KEY_DATABASE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:427 (KEY_NEWS) -> linux:427 (KEY_NEWS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:428 (KEY_VOICEMAIL) -> linux:428 (KEY_VOICEMAIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:429 (KEY_ADDRESSBOOK) -> linux:429 (KEY_ADDRESSBOOK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:430 (KEY_MESSENGER) -> linux:430 (KEY_MESSENGER) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:431 (KEY_DISPLAYTOGGLE) -> linux:431 (KEY_DISPLAYTOGGLE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:432 (KEY_SPELLCHECK) -> linux:432 (KEY_SPELLCHECK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:433 (KEY_LOGOFF) -> linux:433 (KEY_LOGOFF) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:434 (KEY_DOLLAR) -> linux:434 (KEY_DOLLAR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:435 (KEY_EURO) -> linux:435 (KEY_EURO) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:436 (KEY_FRAMEBACK) -> linux:436 (KEY_FRAMEBACK) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:437 (KEY_FRAMEFORWARD) -> linux:437 (KEY_FRAMEFORWARD) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:438 (KEY_CONTEXT_MENU) -> linux:438 (KEY_CONTEXT_MENU) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:439 (KEY_MEDIA_REPEAT) -> linux:439 (KEY_MEDIA_REPEAT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:440 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:441 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:442 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:443 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:444 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:445 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:446 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:447 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:448 (KEY_DEL_EOL) -> linux:448 (KEY_DEL_EOL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:449 (KEY_DEL_EOS) -> linux:449 (KEY_DEL_EOS) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:450 (KEY_INS_LINE) -> linux:450 (KEY_INS_LINE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:451 (KEY_DEL_LINE) -> linux:451 (KEY_DEL_LINE) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:452 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:453 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:454 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:455 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:456 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:457 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:458 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:459 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:460 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:461 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:462 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:463 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:464 (KEY_FN) -> linux:464 (KEY_FN) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:465 (KEY_FN_ESC) -> linux:465 (KEY_FN_ESC) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:466 (KEY_FN_F1) -> linux:466 (KEY_FN_F1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:467 (KEY_FN_F2) -> linux:467 (KEY_FN_F2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:468 (KEY_FN_F3) -> linux:468 (KEY_FN_F3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:469 (KEY_FN_F4) -> linux:469 (KEY_FN_F4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:470 (KEY_FN_F5) -> linux:470 (KEY_FN_F5) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:471 (KEY_FN_F6) -> linux:471 (KEY_FN_F6) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:472 (KEY_FN_F7) -> linux:472 (KEY_FN_F7) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:473 (KEY_FN_F8) -> linux:473 (KEY_FN_F8) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:474 (KEY_FN_F9) -> linux:474 (KEY_FN_F9) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:475 (KEY_FN_F10) -> linux:475 (KEY_FN_F10) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:476 (KEY_FN_F11) -> linux:476 (KEY_FN_F11) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:477 (KEY_FN_F12) -> linux:477 (KEY_FN_F12) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:478 (KEY_FN_1) -> linux:478 (KEY_FN_1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:479 (KEY_FN_2) -> linux:479 (KEY_FN_2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:480 (KEY_FN_D) -> linux:480 (KEY_FN_D) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:481 (KEY_FN_E) -> linux:481 (KEY_FN_E) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:482 (KEY_FN_F) -> linux:482 (KEY_FN_F) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:483 (KEY_FN_S) -> linux:483 (KEY_FN_S) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:484 (KEY_FN_B) -> linux:484 (KEY_FN_B) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:485 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:486 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:487 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:488 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:489 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:490 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:491 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:492 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:493 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:494 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:495 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:496 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:497 (KEY_BRL_DOT1) -> linux:497 (KEY_BRL_DOT1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:498 (KEY_BRL_DOT2) -> linux:498 (KEY_BRL_DOT2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:499 (KEY_BRL_DOT3) -> linux:499 (KEY_BRL_DOT3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:500 (KEY_BRL_DOT4) -> linux:500 (KEY_BRL_DOT4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:501 (KEY_BRL_DOT5) -> linux:501 (KEY_BRL_DOT5) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:502 (KEY_BRL_DOT6) -> linux:502 (KEY_BRL_DOT6) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:503 (KEY_BRL_DOT7) -> linux:503 (KEY_BRL_DOT7) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:504 (KEY_BRL_DOT8) -> linux:504 (KEY_BRL_DOT8) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:505 (KEY_BRL_DOT9) -> linux:505 (KEY_BRL_DOT9) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:506 (KEY_BRL_DOT10) -> linux:506 (KEY_BRL_DOT10) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:507 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:508 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:509 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:510 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:511 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:512 (KEY_NUMERIC_0) -> linux:512 (KEY_NUMERIC_0) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:513 (KEY_NUMERIC_1) -> linux:513 (KEY_NUMERIC_1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:514 (KEY_NUMERIC_2) -> linux:514 (KEY_NUMERIC_2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:515 (KEY_NUMERIC_3) -> linux:515 (KEY_NUMERIC_3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:516 (KEY_NUMERIC_4) -> linux:516 (KEY_NUMERIC_4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:517 (KEY_NUMERIC_5) -> linux:517 (KEY_NUMERIC_5) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:518 (KEY_NUMERIC_6) -> linux:518 (KEY_NUMERIC_6) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:519 (KEY_NUMERIC_7) -> linux:519 (KEY_NUMERIC_7) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:520 (KEY_NUMERIC_8) -> linux:520 (KEY_NUMERIC_8) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:521 (KEY_NUMERIC_9) -> linux:521 (KEY_NUMERIC_9) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:522 (KEY_NUMERIC_STAR) -> linux:522 (KEY_NUMERIC_STAR) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:523 (KEY_NUMERIC_POUND) -> linux:523 (KEY_NUMERIC_POUND) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* linux:524 (KEY_RFKILL) -> linux:524 (KEY_RFKILL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
};
const size_t qemu_input_map_linux_to_qcode_len = sizeof(qemu_input_map_linux_to_qcode) / sizeof(qemu_input_map_linux_to_qcode[0]);

View File

@ -1,18 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "hid.h"
extern const QKeyCode qemu_input_map_linux_to_qcode[];
extern const size_t qemu_input_map_linux_to_qcode_len;

View File

@ -17,7 +17,7 @@
#include "input-keymap.h"
//TODO how much does std::map kill perf if any?
const std::map<const QKeyCode, unsigned short> qemu_input_map_qcode_to_qnum = {
static const std::map<const QKeyCode, unsigned short> qemu_input_map_qcode_to_qnum = {
{Q_KEY_CODE_0, 0xb}, /* qcode:Q_KEY_CODE_0 (0) -> linux:11 (KEY_0) -> qnum:11 */
{Q_KEY_CODE_1, 0x2}, /* qcode:Q_KEY_CODE_1 (1) -> linux:2 (KEY_1) -> qnum:2 */
{Q_KEY_CODE_2, 0x3}, /* qcode:Q_KEY_CODE_2 (2) -> linux:3 (KEY_2) -> qnum:3 */

View File

@ -1,276 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is auto-generated from keymaps.csv on 2018-12-22 15:48
* To re-generate, run:
* keymap-gen --lang=stdc++ --varname=qemu_input_map_win32_to_qcode code-map keymaps.csv win32 qcode
*/
#include "PrecompiledHeader.h"
#include "input-keymap-win32-to-qcode.h"
const std::array<QKeyCode, 252> qemu_input_map_win32_to_qcode = {
Q_KEY_CODE_UNMAPPED, /* win32:0 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:1 (VK_LBUTTON) -> linux:256 (BTN_0) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:2 (VK_RBUTTON) -> linux:257 (BTN_1) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:3 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:4 (VK_MBUTTON) -> linux:258 (BTN_2) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:5 (VK_XBUTTON1) -> linux:259 (BTN_3) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:6 (VK_XBUTTON2) -> linux:260 (BTN_4) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:7 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_BACKSPACE, /* win32:8 (VK_BACK) -> linux:14 (KEY_BACKSPACE) -> qcode:Q_KEY_CODE_BACKSPACE (backspace) */
Q_KEY_CODE_TAB, /* win32:9 (VK_TAB) -> linux:15 (KEY_TAB) -> qcode:Q_KEY_CODE_TAB (tab) */
Q_KEY_CODE_UNMAPPED, /* win32:10 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:11 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:12 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_RET, /* win32:13 (VK_RETURN) -> linux:28 (KEY_ENTER) -> qcode:Q_KEY_CODE_RET (ret) */
Q_KEY_CODE_UNMAPPED, /* win32:14 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:15 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_SHIFT, /* win32:16 (VK_LSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
Q_KEY_CODE_CTRL, /* win32:17 (VK_CONTROL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
Q_KEY_CODE_ALT, /* win32:18 (VK_MENU) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
Q_KEY_CODE_PAUSE, /* win32:19 (VK_PAUSE) -> linux:119 (KEY_PAUSE) -> qcode:Q_KEY_CODE_PAUSE (pause) */
Q_KEY_CODE_CAPS_LOCK, /* win32:20 (VK_CAPITAL) -> linux:58 (KEY_CAPSLOCK) -> qcode:Q_KEY_CODE_CAPS_LOCK (caps_lock) */
Q_KEY_CODE_UNMAPPED, /* win32:21 (VK_HANGEUL) -> linux:122 (KEY_HANGEUL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:22 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:23 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:24 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:25 (VK_HANJA) -> linux:123 (KEY_HANJA) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:26 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_ESC, /* win32:27 (VK_ESCAPE) -> linux:1 (KEY_ESC) -> qcode:Q_KEY_CODE_ESC (esc) */
Q_KEY_CODE_UNMAPPED, /* win32:28 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:29 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:30 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:31 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_SPC, /* win32:32 (VK_SPACE) -> linux:57 (KEY_SPACE) -> qcode:Q_KEY_CODE_SPC (spc) */
Q_KEY_CODE_PGUP, /* win32:33 (VK_PRIOR) -> linux:104 (KEY_PAGEUP) -> qcode:Q_KEY_CODE_PGUP (pgup) */
Q_KEY_CODE_PGDN, /* win32:34 (VK_NEXT) -> linux:109 (KEY_PAGEDOWN) -> qcode:Q_KEY_CODE_PGDN (pgdn) */
Q_KEY_CODE_END, /* win32:35 (VK_END) -> linux:107 (KEY_END) -> qcode:Q_KEY_CODE_END (end) */
Q_KEY_CODE_HOME, /* win32:36 (VK_HOME) -> linux:102 (KEY_HOME) -> qcode:Q_KEY_CODE_HOME (home) */
Q_KEY_CODE_LEFT, /* win32:37 (VK_LEFT) -> linux:105 (KEY_LEFT) -> qcode:Q_KEY_CODE_LEFT (left) */
Q_KEY_CODE_UP, /* win32:38 (VK_UP) -> linux:103 (KEY_UP) -> qcode:Q_KEY_CODE_UP (up) */
Q_KEY_CODE_RIGHT, /* win32:39 (VK_RIGHT) -> linux:106 (KEY_RIGHT) -> qcode:Q_KEY_CODE_RIGHT (right) */
Q_KEY_CODE_DOWN, /* win32:40 (VK_DOWN) -> linux:108 (KEY_DOWN) -> qcode:Q_KEY_CODE_DOWN (down) */
Q_KEY_CODE_UNMAPPED, /* win32:41 (VK_SELECT) -> linux:353 (KEY_SELECT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:42 (VK_PRINT) -> linux:210 (KEY_PRINT) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:43 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_SYSRQ, /* win32:44 (VK_SNAPSHOT) -> linux:99 (KEY_SYSRQ) -> qcode:Q_KEY_CODE_SYSRQ (sysrq) */
Q_KEY_CODE_INSERT, /* win32:45 (VK_INSERT) -> linux:110 (KEY_INSERT) -> qcode:Q_KEY_CODE_INSERT (insert) */
Q_KEY_CODE_DELETE, /* win32:46 (VK_DELETE) -> linux:111 (KEY_DELETE) -> qcode:Q_KEY_CODE_DELETE (delete) */
Q_KEY_CODE_HELP, /* win32:47 (VK_HELP) -> linux:138 (KEY_HELP) -> qcode:Q_KEY_CODE_HELP (help) */
Q_KEY_CODE_0, /* win32:48 (VK_0) -> linux:11 (KEY_0) -> qcode:Q_KEY_CODE_0 (0) */
Q_KEY_CODE_1, /* win32:49 (VK_1) -> linux:2 (KEY_1) -> qcode:Q_KEY_CODE_1 (1) */
Q_KEY_CODE_2, /* win32:50 (VK_2) -> linux:3 (KEY_2) -> qcode:Q_KEY_CODE_2 (2) */
Q_KEY_CODE_3, /* win32:51 (VK_3) -> linux:4 (KEY_3) -> qcode:Q_KEY_CODE_3 (3) */
Q_KEY_CODE_4, /* win32:52 (VK_4) -> linux:5 (KEY_4) -> qcode:Q_KEY_CODE_4 (4) */
Q_KEY_CODE_5, /* win32:53 (VK_5) -> linux:6 (KEY_5) -> qcode:Q_KEY_CODE_5 (5) */
Q_KEY_CODE_6, /* win32:54 (VK_6) -> linux:7 (KEY_6) -> qcode:Q_KEY_CODE_6 (6) */
Q_KEY_CODE_7, /* win32:55 (VK_7) -> linux:8 (KEY_7) -> qcode:Q_KEY_CODE_7 (7) */
Q_KEY_CODE_8, /* win32:56 (VK_8) -> linux:9 (KEY_8) -> qcode:Q_KEY_CODE_8 (8) */
Q_KEY_CODE_9, /* win32:57 (VK_9) -> linux:10 (KEY_9) -> qcode:Q_KEY_CODE_9 (9) */
Q_KEY_CODE_UNMAPPED, /* win32:58 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:59 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:60 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:61 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:62 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:63 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:64 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_A, /* win32:65 (VK_A) -> linux:30 (KEY_A) -> qcode:Q_KEY_CODE_A (a) */
Q_KEY_CODE_B, /* win32:66 (VK_B) -> linux:48 (KEY_B) -> qcode:Q_KEY_CODE_B (b) */
Q_KEY_CODE_C, /* win32:67 (VK_C) -> linux:46 (KEY_C) -> qcode:Q_KEY_CODE_C (c) */
Q_KEY_CODE_D, /* win32:68 (VK_D) -> linux:32 (KEY_D) -> qcode:Q_KEY_CODE_D (d) */
Q_KEY_CODE_E, /* win32:69 (VK_E) -> linux:18 (KEY_E) -> qcode:Q_KEY_CODE_E (e) */
Q_KEY_CODE_F, /* win32:70 (VK_F) -> linux:33 (KEY_F) -> qcode:Q_KEY_CODE_F (f) */
Q_KEY_CODE_G, /* win32:71 (VK_G) -> linux:34 (KEY_G) -> qcode:Q_KEY_CODE_G (g) */
Q_KEY_CODE_H, /* win32:72 (VK_H) -> linux:35 (KEY_H) -> qcode:Q_KEY_CODE_H (h) */
Q_KEY_CODE_I, /* win32:73 (VK_I) -> linux:23 (KEY_I) -> qcode:Q_KEY_CODE_I (i) */
Q_KEY_CODE_J, /* win32:74 (VK_J) -> linux:36 (KEY_J) -> qcode:Q_KEY_CODE_J (j) */
Q_KEY_CODE_K, /* win32:75 (VK_K) -> linux:37 (KEY_K) -> qcode:Q_KEY_CODE_K (k) */
Q_KEY_CODE_L, /* win32:76 (VK_L) -> linux:38 (KEY_L) -> qcode:Q_KEY_CODE_L (l) */
Q_KEY_CODE_M, /* win32:77 (VK_M) -> linux:50 (KEY_M) -> qcode:Q_KEY_CODE_M (m) */
Q_KEY_CODE_N, /* win32:78 (VK_N) -> linux:49 (KEY_N) -> qcode:Q_KEY_CODE_N (n) */
Q_KEY_CODE_O, /* win32:79 (VK_O) -> linux:24 (KEY_O) -> qcode:Q_KEY_CODE_O (o) */
Q_KEY_CODE_P, /* win32:80 (VK_P) -> linux:25 (KEY_P) -> qcode:Q_KEY_CODE_P (p) */
Q_KEY_CODE_Q, /* win32:81 (VK_Q) -> linux:16 (KEY_Q) -> qcode:Q_KEY_CODE_Q (q) */
Q_KEY_CODE_R, /* win32:82 (VK_R) -> linux:19 (KEY_R) -> qcode:Q_KEY_CODE_R (r) */
Q_KEY_CODE_S, /* win32:83 (VK_S) -> linux:31 (KEY_S) -> qcode:Q_KEY_CODE_S (s) */
Q_KEY_CODE_T, /* win32:84 (VK_T) -> linux:20 (KEY_T) -> qcode:Q_KEY_CODE_T (t) */
Q_KEY_CODE_U, /* win32:85 (VK_U) -> linux:22 (KEY_U) -> qcode:Q_KEY_CODE_U (u) */
Q_KEY_CODE_V, /* win32:86 (VK_V) -> linux:47 (KEY_V) -> qcode:Q_KEY_CODE_V (v) */
Q_KEY_CODE_W, /* win32:87 (VK_W) -> linux:17 (KEY_W) -> qcode:Q_KEY_CODE_W (w) */
Q_KEY_CODE_X, /* win32:88 (VK_X) -> linux:45 (KEY_X) -> qcode:Q_KEY_CODE_X (x) */
Q_KEY_CODE_Y, /* win32:89 (VK_Y) -> linux:21 (KEY_Y) -> qcode:Q_KEY_CODE_Y (y) */
Q_KEY_CODE_Z, /* win32:90 (VK_Z) -> linux:44 (KEY_Z) -> qcode:Q_KEY_CODE_Z (z) */
Q_KEY_CODE_META_L, /* win32:91 (VK_LWIN) -> linux:125 (KEY_LEFTMETA) -> qcode:Q_KEY_CODE_META_L (meta_l) */
Q_KEY_CODE_META_R, /* win32:92 (VK_RWIN) -> linux:126 (KEY_RIGHTMETA) -> qcode:Q_KEY_CODE_META_R (meta_r) */
Q_KEY_CODE_COMPOSE, /* win32:93 (VK_APPS) -> linux:127 (KEY_COMPOSE) -> qcode:Q_KEY_CODE_COMPOSE (compose) */
Q_KEY_CODE_UNMAPPED, /* win32:94 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_SLEEP, /* win32:95 (VK_SLEEP) -> linux:142 (KEY_SLEEP) -> qcode:Q_KEY_CODE_SLEEP (sleep) */
Q_KEY_CODE_KP_0, /* win32:96 (VK_NUMPAD0) -> linux:82 (KEY_KP0) -> qcode:Q_KEY_CODE_KP_0 (kp_0) */
Q_KEY_CODE_KP_1, /* win32:97 (VK_NUMPAD1) -> linux:79 (KEY_KP1) -> qcode:Q_KEY_CODE_KP_1 (kp_1) */
Q_KEY_CODE_KP_2, /* win32:98 (VK_NUMPAD2) -> linux:80 (KEY_KP2) -> qcode:Q_KEY_CODE_KP_2 (kp_2) */
Q_KEY_CODE_KP_3, /* win32:99 (VK_NUMPAD3) -> linux:81 (KEY_KP3) -> qcode:Q_KEY_CODE_KP_3 (kp_3) */
Q_KEY_CODE_KP_4, /* win32:100 (VK_NUMPAD4) -> linux:75 (KEY_KP4) -> qcode:Q_KEY_CODE_KP_4 (kp_4) */
Q_KEY_CODE_KP_5, /* win32:101 (VK_NUMPAD5) -> linux:76 (KEY_KP5) -> qcode:Q_KEY_CODE_KP_5 (kp_5) */
Q_KEY_CODE_KP_6, /* win32:102 (VK_NUMPAD6) -> linux:77 (KEY_KP6) -> qcode:Q_KEY_CODE_KP_6 (kp_6) */
Q_KEY_CODE_KP_7, /* win32:103 (VK_NUMPAD7) -> linux:71 (KEY_KP7) -> qcode:Q_KEY_CODE_KP_7 (kp_7) */
Q_KEY_CODE_KP_8, /* win32:104 (VK_NUMPAD8) -> linux:72 (KEY_KP8) -> qcode:Q_KEY_CODE_KP_8 (kp_8) */
Q_KEY_CODE_KP_9, /* win32:105 (VK_NUMPAD9) -> linux:73 (KEY_KP9) -> qcode:Q_KEY_CODE_KP_9 (kp_9) */
Q_KEY_CODE_KP_MULTIPLY, /* win32:106 (VK_MULTIPLY) -> linux:55 (KEY_KPASTERISK) -> qcode:Q_KEY_CODE_KP_MULTIPLY (kp_multiply) */
Q_KEY_CODE_KP_ADD, /* win32:107 (VK_ADD) -> linux:78 (KEY_KPPLUS) -> qcode:Q_KEY_CODE_KP_ADD (kp_add) */
Q_KEY_CODE_KP_COMMA, /* win32:108 (VK_SEPARATOR??) -> linux:121 (KEY_KPCOMMA) -> qcode:Q_KEY_CODE_KP_COMMA (kp_comma) */
Q_KEY_CODE_KP_SUBTRACT, /* win32:109 (VK_SUBTRACT) -> linux:74 (KEY_KPMINUS) -> qcode:Q_KEY_CODE_KP_SUBTRACT (kp_subtract) */
Q_KEY_CODE_KP_DECIMAL, /* win32:110 (VK_DECIMAL) -> linux:83 (KEY_KPDOT) -> qcode:Q_KEY_CODE_KP_DECIMAL (kp_decimal) */
Q_KEY_CODE_KP_DIVIDE, /* win32:111 (VK_DIVIDE) -> linux:98 (KEY_KPSLASH) -> qcode:Q_KEY_CODE_KP_DIVIDE (kp_divide) */
Q_KEY_CODE_F1, /* win32:112 (VK_F1) -> linux:59 (KEY_F1) -> qcode:Q_KEY_CODE_F1 (f1) */
Q_KEY_CODE_F2, /* win32:113 (VK_F2) -> linux:60 (KEY_F2) -> qcode:Q_KEY_CODE_F2 (f2) */
Q_KEY_CODE_F3, /* win32:114 (VK_F3) -> linux:61 (KEY_F3) -> qcode:Q_KEY_CODE_F3 (f3) */
Q_KEY_CODE_F4, /* win32:115 (VK_F4) -> linux:62 (KEY_F4) -> qcode:Q_KEY_CODE_F4 (f4) */
Q_KEY_CODE_F5, /* win32:116 (VK_F5) -> linux:63 (KEY_F5) -> qcode:Q_KEY_CODE_F5 (f5) */
Q_KEY_CODE_F6, /* win32:117 (VK_F6) -> linux:64 (KEY_F6) -> qcode:Q_KEY_CODE_F6 (f6) */
Q_KEY_CODE_F7, /* win32:118 (VK_F7) -> linux:65 (KEY_F7) -> qcode:Q_KEY_CODE_F7 (f7) */
Q_KEY_CODE_F8, /* win32:119 (VK_F8) -> linux:66 (KEY_F8) -> qcode:Q_KEY_CODE_F8 (f8) */
Q_KEY_CODE_F9, /* win32:120 (VK_F9) -> linux:67 (KEY_F9) -> qcode:Q_KEY_CODE_F9 (f9) */
Q_KEY_CODE_F10, /* win32:121 (VK_F10) -> linux:68 (KEY_F10) -> qcode:Q_KEY_CODE_F10 (f10) */
Q_KEY_CODE_F11, /* win32:122 (VK_F11) -> linux:87 (KEY_F11) -> qcode:Q_KEY_CODE_F11 (f11) */
Q_KEY_CODE_F12, /* win32:123 (VK_F12) -> linux:88 (KEY_F12) -> qcode:Q_KEY_CODE_F12 (f12) */
Q_KEY_CODE_UNMAPPED, /* win32:124 (VK_F13) -> linux:183 (KEY_F13) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:125 (VK_F14) -> linux:184 (KEY_F14) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:126 (VK_F15) -> linux:185 (KEY_F15) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:127 (VK_F16) -> linux:186 (KEY_F16) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:128 (VK_F17) -> linux:187 (KEY_F17) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:129 (VK_F18) -> linux:188 (KEY_F18) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:130 (VK_F19) -> linux:189 (KEY_F19) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:131 (VK_F20) -> linux:190 (KEY_F20) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:132 (VK_F21) -> linux:191 (KEY_F21) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:133 (VK_F22) -> linux:192 (KEY_F22) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:134 (VK_F23) -> linux:193 (KEY_F23) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:135 (VK_F24) -> linux:194 (KEY_F24) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:136 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:137 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:138 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:139 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:140 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:141 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:142 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:143 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_NUM_LOCK, /* win32:144 (VK_NUMLOCK) -> linux:69 (KEY_NUMLOCK) -> qcode:Q_KEY_CODE_NUM_LOCK (num_lock) */
Q_KEY_CODE_SCROLL_LOCK, /* win32:145 (VK_SCROLL) -> linux:70 (KEY_SCROLLLOCK) -> qcode:Q_KEY_CODE_SCROLL_LOCK (scroll_lock) */
Q_KEY_CODE_UNMAPPED, /* win32:146 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:147 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:148 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:149 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:150 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:151 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:152 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:153 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:154 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:155 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:156 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:157 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:158 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:159 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_SHIFT, /* win32:160 (VK_LSHIFT) -> linux:42 (KEY_LEFTSHIFT) -> qcode:Q_KEY_CODE_SHIFT (shift) */
Q_KEY_CODE_SHIFT_R, /* win32:161 (VK_RSHIFT) -> linux:54 (KEY_RIGHTSHIFT) -> qcode:Q_KEY_CODE_SHIFT_R (shift_r) */
Q_KEY_CODE_CTRL, /* win32:162 (VK_CONTROL) -> linux:29 (KEY_LEFTCTRL) -> qcode:Q_KEY_CODE_CTRL (ctrl) */
Q_KEY_CODE_CTRL_R, /* win32:163 (VK_RCONTROL) -> linux:97 (KEY_RIGHTCTRL) -> qcode:Q_KEY_CODE_CTRL_R (ctrl_r) */
Q_KEY_CODE_ALT, /* win32:164 (VK_MENU) -> linux:56 (KEY_LEFTALT) -> qcode:Q_KEY_CODE_ALT (alt) */
Q_KEY_CODE_ALT_R, /* win32:165 (VK_RMENU) -> linux:100 (KEY_RIGHTALT) -> qcode:Q_KEY_CODE_ALT_R (alt_r) */
Q_KEY_CODE_AC_BACK, /* win32:166 (VK_BROWSER_BACK) -> linux:158 (KEY_BACK) -> qcode:Q_KEY_CODE_AC_BACK (ac_back) */
Q_KEY_CODE_AC_FORWARD, /* win32:167 (VK_BROWSER_FORWARD) -> linux:159 (KEY_FORWARD) -> qcode:Q_KEY_CODE_AC_FORWARD (ac_forward) */
Q_KEY_CODE_AC_REFRESH, /* win32:168 (VK_BROWSER_REFRESH) -> linux:173 (KEY_REFRESH) -> qcode:Q_KEY_CODE_AC_REFRESH (ac_refresh) */
Q_KEY_CODE_STOP, /* win32:169 (VK_BROWSER_STOP) -> linux:128 (KEY_STOP) -> qcode:Q_KEY_CODE_STOP (stop) */
Q_KEY_CODE_UNMAPPED, /* win32:170 (VK_BROWSER_SEARCH) -> linux:217 (KEY_SEARCH) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:171 (VK_BROWSER_FAVOURITES) -> linux:364 (KEY_FAVORITES) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_AC_HOME, /* win32:172 (VK_BROWSER_HOME) -> linux:172 (KEY_HOMEPAGE) -> qcode:Q_KEY_CODE_AC_HOME (ac_home) */
Q_KEY_CODE_AUDIOMUTE, /* win32:173 (VK_VOLUME_MUTE) -> linux:113 (KEY_MUTE) -> qcode:Q_KEY_CODE_AUDIOMUTE (audiomute) */
Q_KEY_CODE_VOLUMEDOWN, /* win32:174 (VK_VOLUME_DOWN) -> linux:114 (KEY_VOLUMEDOWN) -> qcode:Q_KEY_CODE_VOLUMEDOWN (volumedown) */
Q_KEY_CODE_VOLUMEUP, /* win32:175 (VK_VOLUME_UP) -> linux:115 (KEY_VOLUMEUP) -> qcode:Q_KEY_CODE_VOLUMEUP (volumeup) */
Q_KEY_CODE_AUDIONEXT, /* win32:176 (VK_MEDIA_NEXT_TRACK) -> linux:163 (KEY_NEXTSONG) -> qcode:Q_KEY_CODE_AUDIONEXT (audionext) */
Q_KEY_CODE_AUDIOPREV, /* win32:177 (VK_MEDIA_PREV_TRACK) -> linux:165 (KEY_PREVIOUSSONG) -> qcode:Q_KEY_CODE_AUDIOPREV (audioprev) */
Q_KEY_CODE_AUDIOSTOP, /* win32:178 (VK_MEDIA_STOP) -> linux:166 (KEY_STOPCD) -> qcode:Q_KEY_CODE_AUDIOSTOP (audiostop) */
Q_KEY_CODE_AUDIOPLAY, /* win32:179 (VK_MEDIA_PLAY_PAUSE) -> linux:164 (KEY_PLAYPAUSE) -> qcode:Q_KEY_CODE_AUDIOPLAY (audioplay) */
Q_KEY_CODE_UNMAPPED, /* win32:180 (VK_LAUNCH_MAIL) -> linux:215 (KEY_EMAIL) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:181 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:182 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:183 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:184 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:185 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_SEMICOLON, /* win32:186 (VK_OEM_1) -> linux:39 (KEY_SEMICOLON) -> qcode:Q_KEY_CODE_SEMICOLON (semicolon) */
Q_KEY_CODE_EQUAL, /* win32:187 (VK_OEM_PLUS) -> linux:13 (KEY_EQUAL) -> qcode:Q_KEY_CODE_EQUAL (equal) */
Q_KEY_CODE_COMMA, /* win32:188 (VK_OEM_COMMA) -> linux:51 (KEY_COMMA) -> qcode:Q_KEY_CODE_COMMA (comma) */
Q_KEY_CODE_MINUS, /* win32:189 (VK_OEM_MINUS) -> linux:12 (KEY_MINUS) -> qcode:Q_KEY_CODE_MINUS (minus) */
Q_KEY_CODE_DOT, /* win32:190 (VK_OEM_PERIOD) -> linux:52 (KEY_DOT) -> qcode:Q_KEY_CODE_DOT (dot) */
Q_KEY_CODE_SLASH, /* win32:191 (VK_OEM_2) -> linux:53 (KEY_SLASH) -> qcode:Q_KEY_CODE_SLASH (slash) */
Q_KEY_CODE_GRAVE_ACCENT, /* win32:192 (VK_OEM_3) -> linux:41 (KEY_GRAVE) -> qcode:Q_KEY_CODE_GRAVE_ACCENT (grave_accent) */
Q_KEY_CODE_UNMAPPED, /* win32:193 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:194 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:195 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:196 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:197 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:198 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:199 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:200 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:201 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:202 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:203 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:204 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:205 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:206 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:207 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:208 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:209 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:210 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:211 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:212 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:213 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:214 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:215 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:216 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:217 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:218 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_BRACKET_LEFT, /* win32:219 (VK_OEM_4) -> linux:26 (KEY_LEFTBRACE) -> qcode:Q_KEY_CODE_BRACKET_LEFT (bracket_left) */
Q_KEY_CODE_BACKSLASH, /* win32:220 (VK_OEM_5) -> linux:43 (KEY_BACKSLASH) -> qcode:Q_KEY_CODE_BACKSLASH (backslash) */
Q_KEY_CODE_BRACKET_RIGHT, /* win32:221 (VK_OEM_6) -> linux:27 (KEY_RIGHTBRACE) -> qcode:Q_KEY_CODE_BRACKET_RIGHT (bracket_right) */
Q_KEY_CODE_APOSTROPHE, /* win32:222 (VK_OEM_7) -> linux:40 (KEY_APOSTROPHE) -> qcode:Q_KEY_CODE_APOSTROPHE (apostrophe) */
Q_KEY_CODE_UNMAPPED, /* win32:223 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:224 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_LESS, /* win32:225 (VK_OEM_102) -> linux:86 (KEY_102ND) -> qcode:Q_KEY_CODE_LESS (less) */
Q_KEY_CODE_UNMAPPED, /* win32:226 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:227 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:228 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:229 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:230 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:231 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:232 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:233 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:234 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:235 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:236 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:237 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:238 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:239 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:240 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:241 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:242 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:243 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:244 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:245 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:246 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:247 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:248 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:249 (unnamed) -> linux:None (unnamed) -> qcode:None (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:250 (VK_PLAY) -> linux:207 (KEY_PLAY) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
Q_KEY_CODE_UNMAPPED, /* win32:251 (VK_ZOOM) -> linux:372 (KEY_ZOOM) -> qcode:Q_KEY_CODE_UNMAPPED (unnamed) */
};

View File

@ -1,24 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file is auto-generated from keymaps.csv on 2018-12-22 15:48
* Database checksum sha256(ef8f29f4e4294479e2789aa61e410c4b0464d4f0ad16bcc1526086a4f123bc10)
* To re-generate, run:
* keymap-gen --lang=stdc++ --varname=qemu_input_map_win32_to_qcode code-map keymaps.csv win32 qcode
*/
#include <array>
#include "hid.h"
extern const std::array<QKeyCode, 252> qemu_input_map_win32_to_qcode;

View File

@ -13,10 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <map>
#include "hid.h"
extern const std::map<const QKeyCode, unsigned short> qemu_input_map_qcode_to_qnum;
int qemu_input_qcode_to_number(const QKeyCode value);
int qemu_input_key_value_to_number(const KeyValue* value);
int qemu_input_key_value_to_scancode(const KeyValue* value, bool down, int* codes);

View File

@ -17,15 +17,14 @@
*/
#include "PrecompiledHeader.h"
#include "vl.h"
//#include "qemu-common.h"
#include "iov.h"
#include "glib.h"
//#include "qemu/sockets.h"
//#include "qemu/cutils.h"
#include "USB/qemu-usb/iov.h"
#include <algorithm>
#include <cassert>
#include <cstring>
size_t iov_from_buf_full(const struct iovec* iov, unsigned int iov_cnt,
// TODO(Stenzek): Rewrite this stuff to LGPL.
size_t iov_from_buf(const struct usb_iovec* iov, unsigned int iov_cnt,
size_t offset, const void* buf, size_t bytes)
{
size_t done;
@ -34,7 +33,7 @@ size_t iov_from_buf_full(const struct iovec* iov, unsigned int iov_cnt,
{
if (offset < iov[i].iov_len)
{
size_t len = MIN(iov[i].iov_len - offset, bytes - done);
size_t len = std::min(iov[i].iov_len - offset, bytes - done);
memcpy((char*)iov[i].iov_base + offset, (char*)buf + done, len);
done += len;
offset = 0;
@ -48,7 +47,7 @@ size_t iov_from_buf_full(const struct iovec* iov, unsigned int iov_cnt,
return done;
}
size_t iov_to_buf_full(const struct iovec* iov, const unsigned int iov_cnt,
size_t iov_to_buf(const struct usb_iovec* iov, const unsigned int iov_cnt,
size_t offset, void* buf, size_t bytes)
{
size_t done;
@ -57,7 +56,7 @@ size_t iov_to_buf_full(const struct iovec* iov, const unsigned int iov_cnt,
{
if (offset < iov[i].iov_len)
{
size_t len = MIN(iov[i].iov_len - offset, bytes - done);
size_t len = std::min(iov[i].iov_len - offset, bytes - done);
memcpy((char*)buf + done, (char*)iov[i].iov_base + offset, len);
done += len;
offset = 0;
@ -71,7 +70,7 @@ size_t iov_to_buf_full(const struct iovec* iov, const unsigned int iov_cnt,
return done;
}
size_t iov_memset(const struct iovec* iov, const unsigned int iov_cnt,
size_t iov_memset(const struct usb_iovec* iov, const unsigned int iov_cnt,
size_t offset, int fillc, size_t bytes)
{
size_t done;
@ -80,7 +79,7 @@ size_t iov_memset(const struct iovec* iov, const unsigned int iov_cnt,
{
if (offset < iov[i].iov_len)
{
size_t len = MIN(iov[i].iov_len - offset, bytes - done);
size_t len = std::min(iov[i].iov_len - offset, bytes - done);
memset((char*)iov[i].iov_base + offset, fillc, len);
done += len;
offset = 0;
@ -94,67 +93,17 @@ size_t iov_memset(const struct iovec* iov, const unsigned int iov_cnt,
return done;
}
size_t iov_size(const struct iovec* iov, const unsigned int iov_cnt)
{
size_t len;
unsigned int i;
len = 0;
for (i = 0; i < iov_cnt; i++)
{
len += iov[i].iov_len;
}
return len;
}
unsigned iov_copy(struct iovec* dst_iov, unsigned int dst_iov_cnt,
const struct iovec* iov, unsigned int iov_cnt,
size_t offset, size_t bytes)
{
size_t len;
unsigned int i, j;
for (i = 0, j = 0;
i < iov_cnt && j < dst_iov_cnt && (offset || bytes); i++)
{
if (offset >= iov[i].iov_len)
{
offset -= iov[i].iov_len;
continue;
}
len = MIN(bytes, iov[i].iov_len - offset);
dst_iov[j].iov_base = (char*)iov[i].iov_base + offset;
dst_iov[j].iov_len = len;
j++;
bytes -= len;
offset = 0;
}
assert(offset == 0);
return j;
}
/* io vectors */
void qemu_iovec_init(QEMUIOVector* qiov, int alloc_hint)
void qemu_iovec_init(QEMUIOVector* qiov)
{
qiov->iov = my_g_new(struct iovec, alloc_hint);
qiov->iov = (struct usb_iovec*)std::malloc(sizeof(usb_iovec));
qiov->niov = 0;
qiov->nalloc = alloc_hint;
qiov->nalloc = 1;
qiov->size = 0;
}
void qemu_iovec_init_external(QEMUIOVector* qiov, struct iovec* iov, int niov)
{
int i;
qiov->iov = iov;
qiov->niov = niov;
qiov->nalloc = -1;
qiov->size = 0;
for (i = 0; i < niov; i++)
qiov->size += iov[i].iov_len;
}
void qemu_iovec_add(QEMUIOVector* qiov, void* base, size_t len)
{
assert(qiov->nalloc != -1);
@ -162,7 +111,7 @@ void qemu_iovec_add(QEMUIOVector* qiov, void* base, size_t len)
if (qiov->niov == qiov->nalloc)
{
qiov->nalloc = 2 * qiov->nalloc + 1;
qiov->iov = my_g_renew(struct iovec, qiov->iov, qiov->nalloc);
qiov->iov = (struct usb_iovec*)std::realloc(qiov->iov, sizeof(usb_iovec) * qiov->nalloc);
}
qiov->iov[qiov->niov].iov_base = base;
qiov->iov[qiov->niov].iov_len = len;
@ -170,90 +119,12 @@ void qemu_iovec_add(QEMUIOVector* qiov, void* base, size_t len)
++qiov->niov;
}
/*
* Concatenates (partial) iovecs from src_iov to the end of dst.
* It starts copying after skipping `soffset' bytes at the
* beginning of src and adds individual vectors from src to
* dst copies up to `sbytes' bytes total, or up to the end
* of src_iov if it comes first. This way, it is okay to specify
* very large value for `sbytes' to indicate "up to the end
* of src".
* Only vector pointers are processed, not the actual data buffers.
*/
size_t qemu_iovec_concat_iov(QEMUIOVector* dst,
struct iovec* src_iov, unsigned int src_cnt,
size_t soffset, size_t sbytes)
{
unsigned int i;
size_t done;
if (!sbytes)
{
return 0;
}
assert(dst->nalloc != -1);
for (i = 0, done = 0; done < sbytes && i < src_cnt; i++)
{
if (soffset < src_iov[i].iov_len)
{
size_t len = MIN(src_iov[i].iov_len - soffset, sbytes - done);
qemu_iovec_add(dst, (char*)src_iov[i].iov_base + soffset, len);
done += len;
soffset = 0;
}
else
{
soffset -= src_iov[i].iov_len;
}
}
assert(soffset == 0); /* offset beyond end of src */
return done;
}
/*
* Concatenates (partial) iovecs from src to the end of dst.
* It starts copying after skipping `soffset' bytes at the
* beginning of src and adds individual vectors from src to
* dst copies up to `sbytes' bytes total, or up to the end
* of src if it comes first. This way, it is okay to specify
* very large value for `sbytes' to indicate "up to the end
* of src".
* Only vector pointers are processed, not the actual data buffers.
*/
void qemu_iovec_concat(QEMUIOVector* dst,
QEMUIOVector* src, size_t soffset, size_t sbytes)
{
qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes);
}
/*
* Check if the contents of the iovecs are all zero
*/
/*bool qemu_iovec_is_zero(QEMUIOVector *qiov)
{
int i;
for (i = 0; i < qiov->niov; i++) {
size_t offs = QEMU_ALIGN_DOWN(qiov->iov[i].iov_len, 4 * sizeof(long));
uint8_t *ptr = (uint8_t *)qiov->iov[i].iov_base;
if (offs && !buffer_is_zero(qiov->iov[i].iov_base, offs)) {
return false;
}
for (; offs < qiov->iov[i].iov_len; offs++) {
if (ptr[offs]) {
return false;
}
}
}
return true;
}*/
void qemu_iovec_destroy(QEMUIOVector* qiov)
{
assert(qiov->nalloc != -1);
qemu_iovec_reset(qiov);
my_g_free(qiov->iov);
std::free(qiov->iov);
qiov->nalloc = 0;
qiov->iov = NULL;
}
@ -265,161 +136,3 @@ void qemu_iovec_reset(QEMUIOVector* qiov)
qiov->niov = 0;
qiov->size = 0;
}
size_t qemu_iovec_to_buf(QEMUIOVector* qiov, size_t offset,
void* buf, size_t bytes)
{
return iov_to_buf(qiov->iov, qiov->niov, offset, buf, bytes);
}
size_t qemu_iovec_from_buf(QEMUIOVector* qiov, size_t offset,
const void* buf, size_t bytes)
{
return iov_from_buf(qiov->iov, qiov->niov, offset, buf, bytes);
}
size_t qemu_iovec_memset(QEMUIOVector* qiov, size_t offset,
int fillc, size_t bytes)
{
return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes);
}
/**
* Check that I/O vector contents are identical
*
* The IO vectors must have the same structure (same length of all parts).
* A typical usage is to compare vectors created with qemu_iovec_clone().
*
* @a: I/O vector
* @b: I/O vector
* @ret: Offset to first mismatching byte or -1 if match
*/
ssize_t qemu_iovec_compare(QEMUIOVector* a, QEMUIOVector* b)
{
int i;
ssize_t offset = 0;
assert(a->niov == b->niov);
for (i = 0; i < a->niov; i++)
{
size_t len = 0;
uint8_t* p = (uint8_t*)a->iov[i].iov_base;
uint8_t* q = (uint8_t*)b->iov[i].iov_base;
assert(a->iov[i].iov_len == b->iov[i].iov_len);
while (len < a->iov[i].iov_len && *p++ == *q++)
{
len++;
}
offset += len;
if (len != a->iov[i].iov_len)
{
return offset;
}
}
return -1;
}
typedef struct
{
int src_index;
struct iovec* src_iov;
void* dest_base;
} IOVectorSortElem;
static int sortelem_cmp_src_base(const void* a, const void* b)
{
const IOVectorSortElem* elem_a = (const IOVectorSortElem*)a;
const IOVectorSortElem* elem_b = (const IOVectorSortElem*)b;
/* Don't overflow */
if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base)
{
return -1;
}
else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base)
{
return 1;
}
else
{
return 0;
}
}
static int sortelem_cmp_src_index(const void* a, const void* b)
{
const IOVectorSortElem* elem_a = (const IOVectorSortElem*)a;
const IOVectorSortElem* elem_b = (const IOVectorSortElem*)b;
return elem_a->src_index - elem_b->src_index;
}
size_t iov_discard_front(struct iovec** iov, unsigned int* iov_cnt,
size_t bytes)
{
size_t total = 0;
struct iovec* cur;
for (cur = *iov; *iov_cnt > 0; cur++)
{
if (cur->iov_len > bytes)
{
cur->iov_base = (uint8_t*)cur->iov_base + bytes;
cur->iov_len -= bytes;
total += bytes;
break;
}
bytes -= cur->iov_len;
total += cur->iov_len;
*iov_cnt -= 1;
}
*iov = cur;
return total;
}
size_t iov_discard_back(struct iovec* iov, unsigned int* iov_cnt,
size_t bytes)
{
size_t total = 0;
struct iovec* cur;
if (*iov_cnt == 0)
{
return 0;
}
cur = iov + (*iov_cnt - 1);
while (*iov_cnt > 0)
{
if (cur->iov_len > bytes)
{
cur->iov_len -= bytes;
total += bytes;
break;
}
bytes -= cur->iov_len;
total += cur->iov_len;
cur--;
*iov_cnt -= 1;
}
return total;
}
void qemu_iovec_discard_back(QEMUIOVector* qiov, size_t bytes)
{
unsigned int niov = qiov->niov;
assert(qiov->size >= bytes);
assert(iov_discard_back(qiov->iov, &niov, bytes) == bytes);
qiov->niov = niov;
qiov->size -= bytes;
}

View File

@ -11,24 +11,13 @@
* the COPYING file in the top-level directory.
*/
#include "USB/platcompat.h"
#pragma once
#ifndef IOV_H
#define IOV_H
#if !defined(_BITS_UIO_H) && !defined(__iovec_defined) /* /usr/include/bits/uio.h */
struct iovec
struct usb_iovec
{
void* iov_base;
size_t iov_len;
};
#endif
/**
* count and return data size, in bytes, of an iovec
* starting at `iov' of `iov_cnt' number of elements.
*/
size_t iov_size(const struct iovec* iov, const unsigned int iov_cnt);
/**
* Copy from single continuous buffer to scatter-gather vector of buffers
@ -47,43 +36,11 @@ size_t iov_size(const struct iovec* iov, const unsigned int iov_cnt);
* such "large" value is -1 (sinice size_t is unsigned),
* so specifying `-1' as `bytes' means 'up to the end of iovec'.
*/
size_t iov_from_buf_full(const struct iovec* iov, unsigned int iov_cnt,
size_t iov_from_buf(const struct usb_iovec* iov, unsigned int iov_cnt,
size_t offset, const void* buf, size_t bytes);
size_t iov_to_buf_full(const struct iovec* iov, const unsigned int iov_cnt,
size_t iov_to_buf(const struct usb_iovec* iov, const unsigned int iov_cnt,
size_t offset, void* buf, size_t bytes);
static inline size_t
iov_from_buf(const struct iovec* iov, unsigned int iov_cnt,
size_t offset, const void* buf, size_t bytes)
{
if (__builtin_constant_p(bytes) && iov_cnt &&
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset)
{
memcpy((char*)iov[0].iov_base + offset, buf, bytes);
return bytes;
}
else
{
return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
}
}
static inline size_t
iov_to_buf(const struct iovec* iov, const unsigned int iov_cnt,
size_t offset, void* buf, size_t bytes)
{
if (__builtin_constant_p(bytes) && iov_cnt &&
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset)
{
memcpy(buf, (char*)iov[0].iov_base + offset, bytes);
return bytes;
}
else
{
return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
}
}
/**
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
* starting at byte offset `start', to value `fillc', repeating it
@ -94,91 +51,18 @@ iov_to_buf(const struct iovec* iov, const unsigned int iov_cnt,
* min(size, iov_size(iov) - offset).
* Again, it is okay to use large value for `bytes' to mean "up to the end".
*/
size_t iov_memset(const struct iovec* iov, const unsigned int iov_cnt,
size_t iov_memset(const struct usb_iovec* iov, const unsigned int iov_cnt,
size_t offset, int fillc, size_t bytes);
/*
* Send/recv data from/to iovec buffers directly
*
* `offset' bytes in the beginning of iovec buffer are skipped and
* next `bytes' bytes are used, which must be within data of iovec.
*
* r = iov_send_recv(sockfd, iov, iovcnt, offset, bytes, true);
*
* is logically equivalent to
*
* char *buf = malloc(bytes);
* iov_to_buf(iov, iovcnt, offset, buf, bytes);
* r = send(sockfd, buf, bytes, 0);
* free(buf);
*
* For iov_send_recv() _whole_ area being sent or received
* should be within the iovec, not only beginning of it.
*/
ssize_t iov_send_recv(int sockfd, const struct iovec* iov, unsigned iov_cnt,
size_t offset, size_t bytes, bool do_send);
#define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \
iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
#define iov_send(sockfd, iov, iov_cnt, offset, bytes) \
iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
/**
* Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements
* in file `fp', prefixing each line with `prefix' and processing not more
* than `limit' data bytes.
*/
void iov_hexdump(const struct iovec* iov, const unsigned int iov_cnt,
FILE* fp, const char* prefix, size_t limit);
/*
* Partial copy of vector from iov to dst_iov (data is not copied).
* dst_iov overlaps iov at a specified offset.
* size of dst_iov is at most bytes. dst vector count is returned.
*/
unsigned iov_copy(struct iovec* dst_iov, unsigned int dst_iov_cnt,
const struct iovec* iov, unsigned int iov_cnt,
size_t offset, size_t bytes);
/*
* Remove a given number of bytes from the front or back of a vector.
* This may update iov and/or iov_cnt to exclude iovec elements that are
* no longer required.
*
* The number of bytes actually discarded is returned. This number may be
* smaller than requested if the vector is too small.
*/
size_t iov_discard_front(struct iovec** iov, unsigned int* iov_cnt,
size_t bytes);
size_t iov_discard_back(struct iovec* iov, unsigned int* iov_cnt,
size_t bytes);
typedef struct QEMUIOVector
{
struct iovec* iov;
struct usb_iovec* iov;
int niov;
int nalloc;
size_t size;
} QEMUIOVector;
void qemu_iovec_init(QEMUIOVector* qiov, int alloc_hint);
void qemu_iovec_init_external(QEMUIOVector* qiov, struct iovec* iov, int niov);
void qemu_iovec_init(QEMUIOVector* qiov);
void qemu_iovec_add(QEMUIOVector* qiov, void* base, size_t len);
void qemu_iovec_concat(QEMUIOVector* dst,
QEMUIOVector* src, size_t soffset, size_t sbytes);
size_t qemu_iovec_concat_iov(QEMUIOVector* dst,
struct iovec* src_iov, unsigned int src_cnt,
size_t soffset, size_t sbytes);
bool qemu_iovec_is_zero(QEMUIOVector* qiov);
void qemu_iovec_destroy(QEMUIOVector* qiov);
void qemu_iovec_reset(QEMUIOVector* qiov);
size_t qemu_iovec_to_buf(QEMUIOVector* qiov, size_t offset,
void* buf, size_t bytes);
size_t qemu_iovec_from_buf(QEMUIOVector* qiov, size_t offset,
const void* buf, size_t bytes);
size_t qemu_iovec_memset(QEMUIOVector* qiov, size_t offset,
int fillc, size_t bytes);
ssize_t qemu_iovec_compare(QEMUIOVector* a, QEMUIOVector* b);
void qemu_iovec_clone(QEMUIOVector* dest, const QEMUIOVector* src, void* buf);
void qemu_iovec_discard_back(QEMUIOVector* qiov, size_t bytes);
#endif

View File

@ -22,8 +22,9 @@
* THE SOFTWARE.
*/
#include "iov.h"
#include "queue.h"
#pragma once
#include "USB/qemu-usb/iov.h"
#include "USB/qemu-usb/queue.h"
#define USB_TOKEN_SETUP 0x2d
#define USB_TOKEN_IN 0x69 /* device -> host */
@ -388,9 +389,6 @@ typedef struct USBDeviceClass
int streams);
void (*free_streams)(USBDevice* dev, USBEndpoint** eps, int nr_eps);
int (*open)(USBDevice* dev);
void (*close)(USBDevice* dev);
const char* product_desc;
const USBDesc* usb_desc;
bool attached_settable;

View File

@ -1,594 +0,0 @@
/*
* QEMU USB HUB emulation
*
* Copyright (c) 2005 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "vl.h"
//#define DEBUG
#define MAX_PORTS 8
typedef struct USBHubPort
{
USBPort port;
uint16_t wPortStatus;
uint16_t wPortChange;
} USBHubPort;
typedef struct USBHubState
{
USBDevice dev;
int nb_ports;
USBHubPort ports[MAX_PORTS];
} USBHubState;
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
#define PORT_STAT_CONNECTION 0x0001
#define PORT_STAT_ENABLE 0x0002
#define PORT_STAT_SUSPEND 0x0004
#define PORT_STAT_OVERCURRENT 0x0008
#define PORT_STAT_RESET 0x0010
#define PORT_STAT_POWER 0x0100
#define PORT_STAT_LOW_SPEED 0x0200
#define PORT_STAT_HIGH_SPEED 0x0400
#define PORT_STAT_TEST 0x0800
#define PORT_STAT_INDICATOR 0x1000
#define PORT_STAT_C_CONNECTION 0x0001
#define PORT_STAT_C_ENABLE 0x0002
#define PORT_STAT_C_SUSPEND 0x0004
#define PORT_STAT_C_OVERCURRENT 0x0008
#define PORT_STAT_C_RESET 0x0010
#define PORT_CONNECTION 0
#define PORT_ENABLE 1
#define PORT_SUSPEND 2
#define PORT_OVERCURRENT 3
#define PORT_RESET 4
#define PORT_POWER 8
#define PORT_LOWSPEED 9
#define PORT_HIGHSPEED 10
#define PORT_C_CONNECTION 16
#define PORT_C_ENABLE 17
#define PORT_C_SUSPEND 18
#define PORT_C_OVERCURRENT 19
#define PORT_C_RESET 20
#define PORT_TEST 21
#define PORT_INDICATOR 22
/* same as Linux kernel root hubs */
static const uint8_t qemu_hub_dev_descriptor[] = {
0x12, /* u8 bLength; */
0x01, /* u8 bDescriptorType; Device */
0x10, 0x01, /* u16 bcdUSB; v1.1 */
0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* u8 bDeviceSubClass; */
0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
0x08, /* u8 bMaxPacketSize0; 8 Bytes */
0x00, 0x00, /* u16 idVendor; */
0x00, 0x00, /* u16 idProduct; */
0x01, 0x01, /* u16 bcdDevice */
0x03, /* u8 iManufacturer; */
0x02, /* u8 iProduct; */
0x01, /* u8 iSerialNumber; */
0x01 /* u8 bNumConfigurations; */
};
/* XXX: patch interrupt size */
static const uint8_t qemu_hub_config_descriptor[] = {
/* one configuration */
0x09, /* u8 bLength; */
0x02, /* u8 bDescriptorType; Configuration */
0x19, 0x00, /* u16 wTotalLength; */
0x01, /* u8 bNumInterfaces; (1) */
0x01, /* u8 bConfigurationValue; */
0x00, /* u8 iConfiguration; */
0xc0, /* u8 bmAttributes;
Bit 7: must be set,
6: Self-powered,
5: Remote wakeup,
4..0: resvd */
0x00, /* u8 MaxPower; */
/* USB 1.1:
* USB 2.0, single TT organization (mandatory):
* one interface, protocol 0
*
* USB 2.0, multiple TT organization (optional):
* two interfaces, protocols 1 (like single TT)
* and 2 (multiple TT mode) ... config is
* sometimes settable
* NOT IMPLEMENTED
*/
/* one interface */
0x09, /* u8 if_bLength; */
0x04, /* u8 if_bDescriptorType; Interface */
0x00, /* u8 if_bInterfaceNumber; */
0x00, /* u8 if_bAlternateSetting; */
0x01, /* u8 if_bNumEndpoints; */
0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
0x00, /* u8 if_bInterfaceSubClass; */
0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
0x00, /* u8 if_iInterface; */
/* one endpoint (status change endpoint) */
0x07, /* u8 ep_bLength; */
0x05, /* u8 ep_bDescriptorType; Endpoint */
0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* u8 ep_bmAttributes; Interrupt */
0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
};
static const uint8_t qemu_hub_hub_descriptor[] =
{
0x00, /* u8 bLength; patched in later */
0x29, /* u8 bDescriptorType; Hub-descriptor */
0x00, /* u8 bNbrPorts; (patched later) */
0x0a, /* u16 wHubCharacteristics; */
0x00, /* (per-port OC, no power switching) */
0x01, /* u8 bPwrOn2pwrGood; 2ms */
0x00 /* u8 bHubContrCurrent; 0 mA */
/* DeviceRemovable and PortPwrCtrlMask patched in later */
};
static void usb_hub_attach(USBPort* port1, USBDevice* dev)
{
USBHubState* s = (USBHubState*)port1->opaque;
USBHubPort* port = (USBHubPort*)&s->ports[port1->index];
if (dev)
{
if (port->port.dev)
usb_attach(port1, NULL);
port->wPortStatus |= PORT_STAT_CONNECTION;
port->wPortChange |= PORT_STAT_C_CONNECTION;
if (dev->speed == USB_SPEED_LOW)
port->wPortStatus |= PORT_STAT_LOW_SPEED;
else
port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
port->port.dev = dev;
/* send the attach message */
dev->handle_packet(dev,
USB_MSG_ATTACH, 0, 0, NULL, 0);
}
else
{
dev = port->port.dev;
if (dev)
{
port->wPortStatus &= ~PORT_STAT_CONNECTION;
port->wPortChange |= PORT_STAT_C_CONNECTION;
if (port->wPortStatus & PORT_STAT_ENABLE)
{
port->wPortStatus &= ~PORT_STAT_ENABLE;
port->wPortChange |= PORT_STAT_C_ENABLE;
}
/* send the detach message */
dev->handle_packet(dev,
USB_MSG_DETACH, 0, 0, NULL, 0);
port->port.dev = NULL;
}
}
}
static void usb_hub_handle_reset(USBDevice* dev)
{
/* XXX: do it */
}
static int usb_hub_handle_control(USBDevice* dev, int request, int value,
int index, int length, uint8_t* data)
{
USBHubState* s = (USBHubState*)dev;
int ret;
switch (request)
{
case DeviceRequest | USB_REQ_GET_STATUS:
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
(dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
data[1] = 0x00;
ret = 2;
break;
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP)
{
dev->remote_wakeup = 0;
}
else
{
goto fail;
}
ret = 0;
break;
case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
if (value == 0 && index != 0x81)
{ /* clear ep halt */
goto fail;
}
ret = 0;
break;
case DeviceOutRequest | USB_REQ_SET_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP)
{
dev->remote_wakeup = 1;
}
else
{
goto fail;
}
ret = 0;
break;
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
dev->addr = value;
ret = 0;
break;
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch (value >> 8)
{
case USB_DT_DEVICE:
memcpy(data, qemu_hub_dev_descriptor,
sizeof(qemu_hub_dev_descriptor));
ret = sizeof(qemu_hub_dev_descriptor);
break;
case USB_DT_CONFIG:
memcpy(data, qemu_hub_config_descriptor,
sizeof(qemu_hub_config_descriptor));
/* status change endpoint size based on number
* of ports */
data[22] = (s->nb_ports + 1 + 7) / 8;
ret = sizeof(qemu_hub_config_descriptor);
break;
case USB_DT_STRING:
switch (value & 0xff)
{
case 0:
/* language ids */
data[0] = 4;
data[1] = 3;
data[2] = 0x09;
data[3] = 0x04;
ret = 4;
break;
case 1:
/* serial number */
ret = set_usb_string(data, "314159");
break;
case 2:
/* product description */
ret = set_usb_string(data, "QEMU USB Hub");
break;
case 3:
/* vendor description */
ret = set_usb_string(data, "PCSX2/QEMU");
break;
default:
goto fail;
}
break;
default:
goto fail;
}
break;
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
data[0] = 1;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
ret = 0;
break;
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
/* usb specific requests */
case GetHubStatus:
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
ret = 4;
break;
case GetPortStatus:
{
unsigned int n = index - 1;
USBHubPort* port;
if (n >= s->nb_ports)
goto fail;
port = &s->ports[n];
data[0] = port->wPortStatus;
data[1] = port->wPortStatus >> 8;
data[2] = port->wPortChange;
data[3] = port->wPortChange >> 8;
ret = 4;
}
break;
case SetHubFeature:
case ClearHubFeature:
if (value == 0 || value == 1)
{
}
else
{
goto fail;
}
ret = 0;
break;
case SetPortFeature:
{
unsigned int n = index - 1;
USBHubPort* port;
USBDevice* dev;
if (n >= s->nb_ports)
goto fail;
port = &s->ports[n];
dev = port->port.dev;
switch (value)
{
case PORT_SUSPEND:
port->wPortStatus |= PORT_STAT_SUSPEND;
break;
case PORT_RESET:
if (dev)
{
dev->handle_packet(dev,
USB_MSG_RESET, 0, 0, NULL, 0);
port->wPortChange |= PORT_STAT_C_RESET;
/* set enable bit */
port->wPortStatus |= PORT_STAT_ENABLE;
}
break;
case PORT_POWER:
break;
default:
goto fail;
}
ret = 0;
}
break;
case ClearPortFeature:
{
unsigned int n = index - 1;
USBHubPort* port;
USBDevice* dev;
if (n >= s->nb_ports)
goto fail;
port = &s->ports[n];
dev = port->port.dev;
switch (value)
{
case PORT_ENABLE:
port->wPortStatus &= ~PORT_STAT_ENABLE;
break;
case PORT_C_ENABLE:
port->wPortChange &= ~PORT_STAT_C_ENABLE;
break;
case PORT_SUSPEND:
port->wPortStatus &= ~PORT_STAT_SUSPEND;
break;
case PORT_C_SUSPEND:
port->wPortChange &= ~PORT_STAT_C_SUSPEND;
break;
case PORT_C_CONNECTION:
port->wPortChange &= ~PORT_STAT_C_CONNECTION;
break;
case PORT_C_OVERCURRENT:
port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
break;
case PORT_C_RESET:
port->wPortChange &= ~PORT_STAT_C_RESET;
break;
default:
goto fail;
}
ret = 0;
}
break;
case GetHubDescriptor:
{
unsigned int n, limit, var_hub_size = 0;
memcpy(data, qemu_hub_hub_descriptor,
sizeof(qemu_hub_hub_descriptor));
data[2] = s->nb_ports;
/* fill DeviceRemovable bits */
limit = ((s->nb_ports + 1 + 7) / 8) + 7;
for (n = 7; n < limit; n++)
{
data[n] = 0x00;
var_hub_size++;
}
/* fill PortPwrCtrlMask bits */
limit = limit + ((s->nb_ports + 7) / 8);
for (; n < limit; n++)
{
data[n] = 0xff;
var_hub_size++;
}
ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
data[0] = ret;
break;
}
default:
fail:
ret = USB_RET_STALL;
break;
}
return ret;
}
static int usb_hub_handle_data(USBDevice* dev, int pid,
uint8_t devep, uint8_t* data, int len)
{
int ret = 0;
switch (pid)
{
case USB_TOKEN_IN:
if (devep == 1)
{
USBHubState* s = (USBHubState*)dev;
unsigned int status;
int i, n;
n = (s->nb_ports + 1 + 7) / 8;
if (len == 1)
{ /* FreeBSD workaround */
n = 1;
}
else if (n > len)
{
return USB_RET_BABBLE;
}
status = 0;
for (i = 0; i < s->nb_ports; i++)
{
USBHubPort* port = &s->ports[i];
if (port->wPortChange)
status |= (1 << (i + 1));
}
if (status != 0)
{
for (i = 0; i < n; i++)
{
data[i] = status >> (8 * i);
}
ret = n;
}
else
{
ret = USB_RET_NAK; /* usb11 11.13.1 */
}
}
else
{
goto fail;
}
break;
case USB_TOKEN_OUT:
default:
fail:
ret = USB_RET_STALL;
break;
}
return ret;
}
static int usb_hub_broadcast_packet(USBHubState* s, int pid,
uint8_t devaddr, uint8_t devep,
uint8_t* data, int len)
{
for (int i = 0; i < s->nb_ports; i++)
{
USBHubPort* port = &s->ports[i];
USBDevice* dev = port->port.dev;
if (dev && (port->wPortStatus & PORT_STAT_ENABLE))
{
int ret = dev->handle_packet(dev, pid,
devaddr, devep,
data, len);
if (ret != USB_RET_NODEV)
{
return ret;
}
}
}
return USB_RET_NODEV;
}
static int usb_hub_handle_packet(USBDevice* dev, int pid,
uint8_t devaddr, uint8_t devep,
uint8_t* data, int len)
{
USBHubState* s = (USBHubState*)dev;
if (dev->state == USB_STATE_DEFAULT &&
dev->addr != 0 &&
devaddr != dev->addr &&
(pid == USB_TOKEN_SETUP ||
pid == USB_TOKEN_OUT ||
pid == USB_TOKEN_IN))
{
/* broadcast the packet to the devices */
return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
}
return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
}
static void usb_hub_handle_destroy(USBDevice* dev)
{
USBHubState* s = (USBHubState*)dev;
free(s);
}
USBDevice* usb_hub_init(int nb_ports)
{
if (nb_ports > MAX_PORTS)
return NULL;
USBHubState* s = (USBHubState*)qemu_mallocz(sizeof(USBHubState));
if (!s)
return NULL;
s->dev.speed = USB_SPEED_FULL;
s->dev.handle_packet = usb_hub_handle_packet;
/* generic USB device init */
s->dev.handle_reset = usb_hub_handle_reset;
s->dev.handle_control = usb_hub_handle_control;
s->dev.handle_data = usb_hub_handle_data;
s->dev.handle_destroy = usb_hub_handle_destroy;
strncpy(s->dev.devname, "QEMU USB Hub", sizeof(s->dev.devname));
s->nb_ports = nb_ports;
for (int i = 0; i < s->nb_ports; i++)
{
USBHubPort* port = &s->ports[i];
port->port.opaque = s;
port->port.index = i;
port->port.attach = usb_hub_attach;
port->wPortStatus = PORT_STAT_POWER;
port->wPortChange = 0;
}
return (USBDevice*)s;
}

View File

@ -29,19 +29,20 @@
//typedef CPUReadMemoryFunc
#include "PrecompiledHeader.h"
#include "vl.h"
#include "queue.h"
#include "USBinternal.h"
#include "USB/qemu-usb/qusb.h"
#include "USB/qemu-usb/queue.h"
#include "USB/qemu-usb/USBinternal.h"
#include "IopMem.h"
#define DMA_DIRECTION_TO_DEVICE 0
#define DMA_DIRECTION_FROM_DEVICE 1
#define ED_LINK_LIMIT 32
int64_t last_cycle = 0;
extern int64_t g_usb_last_cycle;
#define MIN_IRQ_INTERVAL 64 /* hack */
extern int64_t get_clock();
extern int get_ticks_per_second();
extern int64_t usb_get_clock();
extern int usb_get_ticks_per_second();
extern void usbIrq(int);
//#define DEBUG_PACKET
@ -49,6 +50,27 @@ extern void usbIrq(int);
static void ohci_async_cancel_device(OHCIState* ohci, USBDevice* dev);
static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
union
{
uint64_t ll;
struct
{
uint32_t low, high;
} l;
} u, res;
uint64_t rl, rh;
u.ll = a;
rl = (uint64_t)u.l.low * (uint64_t)b;
rh = (uint64_t)u.l.high * (uint64_t)b;
rh += (rl >> 32);
res.l.high = rh / c;
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
return res.ll;
}
/* Update IRQ levels */
static inline void ohci_intr_update(OHCIState* ohci)
{
@ -61,10 +83,10 @@ static inline void ohci_intr_update(OHCIState* ohci)
if (level)
{
if ((get_clock() - last_cycle) > MIN_IRQ_INTERVAL)
if ((usb_get_clock() - g_usb_last_cycle) > MIN_IRQ_INTERVAL)
{
usbIrq(1);
last_cycle = get_clock();
g_usb_last_cycle = usb_get_clock();
}
}
}
@ -334,68 +356,43 @@ void ohci_hard_reset(OHCIState* ohci)
ohci_roothub_reset(ohci);
}
#define le32_to_cpu(x) (x)
#define cpu_to_le32(x) (x)
#define le16_to_cpu(x) (x)
#define cpu_to_le16(x) (x)
/* Get an array of dwords from main memory */
static inline int get_dwords(uint32_t addr, uint32_t* buf, int num)
__fi static int get_dwords(uint32_t addr, uint32_t* buf, uint32_t num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
if (cpu_physical_memory_rw(addr, (uint8_t*)buf, sizeof(*buf), 0))
return 0;
*buf = le32_to_cpu(*buf);
}
if ((addr + (num * sizeof(uint32_t))) > sizeof(iopMem->Main))
return 0;
std::memcpy(buf, iopMem->Main + addr, num * sizeof(uint32_t));
return 1;
}
/* Get an array of words from main memory */
static inline int get_words(uint32_t addr, uint16_t* buf, int num)
__fi static int get_words(uint32_t addr, uint16_t* buf, uint32_t num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
if (cpu_physical_memory_rw(addr, (uint8_t*)buf, sizeof(*buf), 0))
return 0;
*buf = le16_to_cpu(*buf);
}
if ((addr + (num * sizeof(uint16_t))) > sizeof(iopMem->Main))
return 0;
std::memcpy(buf, iopMem->Main + addr, num * sizeof(uint16_t));
return 1;
}
/* Put an array of dwords in to main memory */
static inline int put_dwords(uint32_t addr, uint32_t* buf, int num)
__fi static int put_dwords(uint32_t addr, uint32_t* buf, uint32_t num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
uint32_t tmp = cpu_to_le32(*buf);
if (cpu_physical_memory_rw(addr, (uint8_t*)&tmp, sizeof(tmp), 1))
return 0;
}
if ((addr + (num * sizeof(uint32_t))) > sizeof(iopMem->Main))
return 0;
std::memcpy(iopMem->Main + addr, buf, num * sizeof(uint32_t));
return 1;
}
/* Put an array of dwords in to main memory */
static inline int put_words(uint32_t addr, uint16_t* buf, int num)
__fi static int put_words(uint32_t addr, uint16_t* buf, uint32_t num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
uint16_t tmp = cpu_to_le16(*buf);
if (cpu_physical_memory_rw(addr, (uint8_t*)&tmp, sizeof(tmp), 1))
return 0;
}
if ((addr + (num * sizeof(uint16_t))) > sizeof(iopMem->Main))
return 0;
std::memcpy(iopMem->Main + addr, buf, num * sizeof(uint16_t));
return 1;
}
@ -436,31 +433,35 @@ static inline int ohci_put_iso_td(OHCIState* ohci, uint32_t addr, struct ohci_is
put_words(addr + 16, td->offset, 8);
}
static inline int ohci_put_hcca(OHCIState* ohci,
struct ohci_hcca* hcca)
{
cpu_physical_memory_write(ohci->hcca + HCCA_WRITEBACK_OFFSET,
(uint8_t*)hcca + HCCA_WRITEBACK_OFFSET,
HCCA_WRITEBACK_SIZE);
return 1;
}
/* Read/Write the contents of a TD from/to main memory. */
static int ohci_copy_td(OHCIState* ohci, struct ohci_td* td, uint8_t* buf, uint32_t len, int write)
{
uint32_t ptr, n;
ptr = td->cbp;
n = 0x1000 - (ptr & 0xfff);
if (n > len)
n = len;
if (cpu_physical_memory_rw(ptr, buf, n, write))
n = std::min<uint32_t>(0x1000 - (ptr & 0xfff), len);
if ((ptr + n) > sizeof(iopMem->Main))
return 1;
if (write)
std::memcpy(iopMem->Main + ptr, buf, len);
else
std::memcpy(buf, iopMem->Main + ptr, len);
if (n == len)
return 0;
ptr = td->be & ~0xfffu;
buf += n;
cpu_physical_memory_rw(ptr, buf, len - n, write);
len -= n;
if ((ptr + n) > sizeof(iopMem->Main))
return 1;
if (write)
std::memcpy(iopMem->Main + ptr, buf, len);
else
std::memcpy(buf, iopMem->Main + ptr, len);
return 0;
}
@ -471,16 +472,30 @@ static int ohci_copy_iso_td(OHCIState* ohci, uint32_t start_addr, uint32_t end_a
uint32_t ptr, n;
ptr = start_addr;
n = 0x1000 - (ptr & 0xfff);
if (n > len)
n = len;
if (cpu_physical_memory_rw(ptr, buf, n, write))
n = std::min<uint32_t>(0x1000 - (ptr & 0xfff), len);
if ((ptr + n) > sizeof(iopMem->Main))
return 1;
if (write)
std::memcpy(iopMem->Main + ptr, buf, len);
else
std::memcpy(buf, iopMem->Main + ptr, len);
if (n == len)
return 0;
ptr = end_addr & ~0xfffu;
buf += n;
cpu_physical_memory_rw(ptr, buf, len - n, write);
len -= n;
if ((ptr + n) > sizeof(iopMem->Main))
return 1;
if (write)
std::memcpy(iopMem->Main + ptr, buf, len);
else
std::memcpy(buf, iopMem->Main + ptr, len);
return 0;
}
@ -488,7 +503,7 @@ static void ohci_process_lists(OHCIState* ohci, int completion);
static void ohci_async_complete_packet(USBPort* port, USBPacket* packet)
{
OHCIState* ohci = CONTAINER_OF(packet, OHCIState, usb_packet);
OHCIState* ohci = USB_CONTAINER_OF(packet, OHCIState, usb_packet);
//trace_usb_ohci_async_complete();
ohci->async_complete = true;
@ -733,7 +748,7 @@ static int ohci_service_iso_td(OHCIState* ohci, struct ohci_ed* ed,
}
else
{
if (ret > (ssize_t)len)
if (ret > static_cast<s32>(len))
{
//trace_usb_ohci_iso_td_data_overrun(ret, len);
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
@ -1136,8 +1151,8 @@ static int ohci_service_ed_list(OHCIState* ohci, uint32_t head, int completion)
/* Generate a SOF event, and set a timer for EOF */
static void ohci_sof(OHCIState* ohci)
{
ohci->sof_time = get_clock();
ohci->eof_timer = usb_frame_time;
ohci->sof_time = usb_get_clock();
ohci->eof_timer = g_usb_frame_time;
ohci_set_interrupt(ohci, OHCI_INTR_SF);
}
@ -1170,9 +1185,14 @@ static void ohci_process_lists(OHCIState* ohci, int completion)
void ohci_frame_boundary(void* opaque)
{
OHCIState* ohci = (OHCIState*)opaque;
struct ohci_hcca hcca;
cpu_physical_memory_read(ohci->hcca, (uint8_t*)&hcca, sizeof(hcca));
if (ohci->hcca + sizeof(ohci_hcca) > sizeof(iopMem->Main))
{
Console.Error("ohci->hcca pointer is out of range.");
return;
}
ohci_hcca* hcca = reinterpret_cast<ohci_hcca*>(iopMem->Main + ohci->hcca);
/* Process all the lists at the end of the frame */
/* if reset bit was set, don't process possibly invalid descriptors */
@ -1183,7 +1203,7 @@ void ohci_frame_boundary(void* opaque)
if (ohci->ctl & OHCI_CTL_PLE)
{
const int n = ohci->frame_number & 0x1f;
ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
ohci_service_ed_list(ohci, hcca->intr[n], 0);
}
/* Cancel all pending packets if either of the lists has been disabled. */
@ -1210,7 +1230,7 @@ void ohci_frame_boundary(void* opaque)
/* Increment frame number and take care of endianness. */
ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
hcca.frame = cpu_to_le16(ohci->frame_number);
hcca->frame = ohci->frame_number;
if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD))
{
@ -1218,7 +1238,7 @@ void ohci_frame_boundary(void* opaque)
abort();
if (ohci->intr & ohci->intr_status)
ohci->done |= 1;
hcca.done = cpu_to_le32(ohci->done);
hcca->done = ohci->done;
ohci->done = 0;
ohci->done_count = 7;
ohci_set_interrupt(ohci, OHCI_INTR_WD);
@ -1229,9 +1249,6 @@ void ohci_frame_boundary(void* opaque)
/* Do SOF stuff here */
ohci_sof(ohci);
/* Writeback HCCA */
ohci_put_hcca(ohci, &hcca);
}
/* Start sending SOF tokens across the USB bus, lists are processed in
@ -1361,13 +1378,13 @@ static uint32_t ohci_get_frame_remaining(OHCIState* ohci)
/* Being in USB operational state guarnatees sof_time was
* set already.
*/
tks = get_clock() - ohci->sof_time;
tks = usb_get_clock() - ohci->sof_time;
/* avoid muldiv if possible */
if (tks >= usb_frame_time)
if (tks >= g_usb_frame_time)
return (ohci->frt << 31);
tks = muldiv64(1, tks, usb_bit_time);
tks = muldiv64(1, tks, g_usb_bit_time);
fr = (uint16_t)(ohci->fi - tks);
return (ohci->frt << 31) | fr;
@ -1717,26 +1734,26 @@ OHCIState* ohci_create(uint32_t base, int ports)
return NULL;
int i;
const int ticks_per_sec = get_ticks_per_second();
const int ticks_per_sec = usb_get_ticks_per_second();
memset(ohci, 0, sizeof(OHCIState));
ohci->mem_base = base;
if (usb_frame_time == 0)
if (g_usb_frame_time == 0)
{
#if OHCI_TIME_WARP
usb_frame_time = ticks_per_sec;
usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ / 1000);
g_usb_frame_time = ticks_per_sec;
g_usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ / 1000);
#else
usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
g_usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
if (ticks_per_sec >= USB_HZ)
{
usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
g_usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
}
else
{
usb_bit_time = 1;
g_usb_bit_time = 1;
}
#endif
}

View File

@ -1,43 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "vl.h"
/* compute with 96 bit intermediate result: (a*b)/c */
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
union
{
uint64_t ll;
struct
{
#ifdef WORDS_BIGENDIAN
uint32_t high, low;
#else
uint32_t low, high;
#endif
} l;
} u, res;
uint64_t rl, rh;
u.ll = a;
rl = (uint64_t)u.l.low * (uint64_t)b;
rh = (uint64_t)u.l.high * (uint64_t)b;
rh += (rl >> 32);
res.l.high = rh / c;
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
return res.ll;
}

View File

@ -1,79 +0,0 @@
/*
* QEMU System Emulator header
*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef VL_H
#define VL_H
/* we put basic includes here to avoid repeating them in device drivers */
#include <cstdlib>
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <cstdint>
#include <cstddef>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <cassert>
#include <cerrno>
#include <fcntl.h>
#include <sys/stat.h>
#if !defined(_MSC_VER)
#define inline __inline
#endif
#include "qusb.h"
#ifndef glue
#define xglue(x, y) x##y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/* vl.c */
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
int cpu_physical_memory_rw(uint32_t addr, uint8_t* buf,
size_t len, int is_write);
inline int cpu_physical_memory_read(uint32_t addr,
uint8_t* buf, size_t len)
{
return cpu_physical_memory_rw(addr, buf, len, 0);
}
inline int cpu_physical_memory_write(uint32_t addr,
const uint8_t* buf, size_t len)
{
return cpu_physical_memory_rw(addr, (uint8_t*)buf, len, 1);
}
#endif /* VL_H */

View File

@ -1,75 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <windows.h>
#include <setupapi.h>
#include "hidapi.h"
_HidD_GetHidGuid HidD_GetHidGuid = NULL;
_HidD_GetAttributes HidD_GetAttributes = NULL;
_HidD_GetPreparsedData HidD_GetPreparsedData = NULL;
_HidP_GetCaps HidP_GetCaps = NULL;
_HidD_FreePreparsedData HidD_FreePreparsedData = NULL;
_HidD_GetFeature HidD_GetFeature = NULL;
_HidD_SetFeature HidD_SetFeature = NULL;
_HidP_GetSpecificButtonCaps HidP_GetSpecificButtonCaps = NULL;
_HidP_GetButtonCaps HidP_GetButtonCaps = NULL;
_HidP_GetUsages HidP_GetUsages = NULL;
_HidP_GetValueCaps HidP_GetValueCaps = NULL;
_HidP_GetUsageValue HidP_GetUsageValue = NULL;
_HidD_GetProductString HidD_GetProductString = NULL;
static HMODULE hModHid = 0;
int InitHid()
{
if (hModHid)
{
return 1;
}
hModHid = LoadLibraryA("hid.dll");
if (hModHid)
{
if ((HidD_GetHidGuid = (_HidD_GetHidGuid)GetProcAddress(hModHid, "HidD_GetHidGuid")) &&
(HidD_GetAttributes = (_HidD_GetAttributes)GetProcAddress(hModHid, "HidD_GetAttributes")) &&
(HidD_GetPreparsedData = (_HidD_GetPreparsedData)GetProcAddress(hModHid, "HidD_GetPreparsedData")) &&
(HidP_GetCaps = (_HidP_GetCaps)GetProcAddress(hModHid, "HidP_GetCaps")) &&
(HidD_FreePreparsedData = (_HidD_FreePreparsedData)GetProcAddress(hModHid, "HidD_FreePreparsedData")) &&
(HidP_GetSpecificButtonCaps = (_HidP_GetSpecificButtonCaps)GetProcAddress(hModHid, "HidP_GetSpecificButtonCaps")) &&
(HidP_GetButtonCaps = (_HidP_GetButtonCaps)GetProcAddress(hModHid, "HidP_GetButtonCaps")) &&
(HidP_GetUsages = (_HidP_GetUsages)GetProcAddress(hModHid, "HidP_GetUsages")) &&
(HidP_GetValueCaps = (_HidP_GetValueCaps)GetProcAddress(hModHid, "HidP_GetValueCaps")) &&
(HidP_GetUsageValue = (_HidP_GetUsageValue)GetProcAddress(hModHid, "HidP_GetUsageValue")) &&
(HidD_GetProductString = (_HidD_GetProductString)GetProcAddress(hModHid, "HidD_GetProductString")) &&
(HidD_GetFeature = (_HidD_GetFeature)GetProcAddress(hModHid, "HidD_GetFeature")) &&
(HidD_SetFeature = (_HidD_SetFeature)GetProcAddress(hModHid, "HidD_SetFeature")))
{
//pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
return 1;
}
UninitHid();
}
return 0;
}
void UninitHid()
{
if (hModHid)
{
FreeLibrary(hModHid);
hModHid = 0;
}
}

View File

@ -1,476 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HIDAPI_H
#define HIDAPI_H
#include <pshpack4.h>
#define NTSTATUS int
typedef USHORT USAGE, *PUSAGE;
#define HID_USAGE_PAGE_GENERIC ((USAGE)0x01)
#define HID_USAGE_PAGE_SIMULATION ((USAGE)0x02)
#define HID_USAGE_PAGE_VR ((USAGE)0x03)
#define HID_USAGE_PAGE_SPORT ((USAGE)0x04)
#define HID_USAGE_PAGE_GAME ((USAGE)0x05)
#define HID_USAGE_PAGE_KEYBOARD ((USAGE)0x07)
#define HID_USAGE_PAGE_LED ((USAGE)0x08)
#define HID_USAGE_PAGE_BUTTON ((USAGE)0x09)
#define HID_USAGE_PAGE_ORDINAL ((USAGE)0x0A)
#define HID_USAGE_PAGE_TELEPHONY ((USAGE)0x0B)
#define HID_USAGE_PAGE_CONSUMER ((USAGE)0x0C)
#define HID_USAGE_PAGE_DIGITIZER ((USAGE)0x0D)
#define HID_USAGE_PAGE_UNICODE ((USAGE)0x10)
#define HID_USAGE_PAGE_ALPHANUMERIC ((USAGE)0x14)
//
// Usages from Generic Desktop Page (0x01)
//
#define HID_USAGE_GENERIC_POINTER ((USAGE)0x01)
#define HID_USAGE_GENERIC_MOUSE ((USAGE)0x02)
#define HID_USAGE_GENERIC_JOYSTICK ((USAGE)0x04)
#define HID_USAGE_GENERIC_GAMEPAD ((USAGE)0x05)
#define HID_USAGE_GENERIC_KEYBOARD ((USAGE)0x06)
#define HID_USAGE_GENERIC_KEYPAD ((USAGE)0x07)
#define HID_USAGE_GENERIC_SYSTEM_CTL ((USAGE)0x80)
#define HID_USAGE_GENERIC_X ((USAGE)0x30)
#define HID_USAGE_GENERIC_Y ((USAGE)0x31)
#define HID_USAGE_GENERIC_Z ((USAGE)0x32)
#define HID_USAGE_GENERIC_RX ((USAGE)0x33)
#define HID_USAGE_GENERIC_RY ((USAGE)0x34)
#define HID_USAGE_GENERIC_RZ ((USAGE)0x35)
#define HID_USAGE_GENERIC_SLIDER ((USAGE)0x36)
#define HID_USAGE_GENERIC_DIAL ((USAGE)0x37)
#define HID_USAGE_GENERIC_WHEEL ((USAGE)0x38)
#define HID_USAGE_GENERIC_HATSWITCH ((USAGE)0x39)
#define HID_USAGE_GENERIC_COUNTED_BUFFER ((USAGE)0x3A)
#define HID_USAGE_GENERIC_BYTE_COUNT ((USAGE)0x3B)
#define HID_USAGE_GENERIC_MOTION_WAKEUP ((USAGE)0x3C)
#define HID_USAGE_GENERIC_VX ((USAGE)0x40)
#define HID_USAGE_GENERIC_VY ((USAGE)0x41)
#define HID_USAGE_GENERIC_VZ ((USAGE)0x42)
#define HID_USAGE_GENERIC_VBRX ((USAGE)0x43)
#define HID_USAGE_GENERIC_VBRY ((USAGE)0x44)
#define HID_USAGE_GENERIC_VBRZ ((USAGE)0x45)
#define HID_USAGE_GENERIC_VNO ((USAGE)0x46)
#define HID_USAGE_GENERIC_SYSCTL_POWER ((USAGE)0x81)
#define HID_USAGE_GENERIC_SYSCTL_SLEEP ((USAGE)0x82)
#define HID_USAGE_GENERIC_SYSCTL_WAKE ((USAGE)0x83)
#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU ((USAGE)0x84)
#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU ((USAGE)0x85)
#define HID_USAGE_GENERIC_SYSCTL_APP_MENU ((USAGE)0x86)
#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU ((USAGE)0x87)
#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT ((USAGE)0x88)
#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT ((USAGE)0x89)
#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT ((USAGE)0x8A)
#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT ((USAGE)0x8B)
#define HID_USAGE_GENERIC_SYSCTL_MENU_UP ((USAGE)0x8C)
#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN ((USAGE)0x8D)
//
// Usages from Simulation Controls Page (0x02)
//
#define HID_USAGE_SIMULATION_RUDDER ((USAGE)0xBA)
#define HID_USAGE_SIMULATION_THROTTLE ((USAGE)0xBB)
//
// Virtual Reality Controls Page (0x03)
//
//
// Sport Controls Page (0x04)
//
//
// Game Controls Page (0x05)
//
//
// Keyboard/Keypad Page (0x07)
//
// Error "keys"
#define HID_USAGE_KEYBOARD_NOEVENT ((USAGE)0x00)
#define HID_USAGE_KEYBOARD_ROLLOVER ((USAGE)0x01)
#define HID_USAGE_KEYBOARD_POSTFAIL ((USAGE)0x02)
#define HID_USAGE_KEYBOARD_UNDEFINED ((USAGE)0x03)
// Letters
#define HID_USAGE_KEYBOARD_aA ((USAGE)0x04)
#define HID_USAGE_KEYBOARD_zZ ((USAGE)0x1D)
// Numbers
#define HID_USAGE_KEYBOARD_ONE ((USAGE)0x1E)
#define HID_USAGE_KEYBOARD_ZERO ((USAGE)0x27)
// Modifier Keys
#define HID_USAGE_KEYBOARD_LCTRL ((USAGE)0xE0)
#define HID_USAGE_KEYBOARD_LSHFT ((USAGE)0xE1)
#define HID_USAGE_KEYBOARD_LALT ((USAGE)0xE2)
#define HID_USAGE_KEYBOARD_LGUI ((USAGE)0xE3)
#define HID_USAGE_KEYBOARD_RCTRL ((USAGE)0xE4)
#define HID_USAGE_KEYBOARD_RSHFT ((USAGE)0xE5)
#define HID_USAGE_KEYBOARD_RALT ((USAGE)0xE6)
#define HID_USAGE_KEYBOARD_RGUI ((USAGE)0xE7)
#define HID_USAGE_KEYBOARD_SCROLL_LOCK ((USAGE)0x47)
#define HID_USAGE_KEYBOARD_NUM_LOCK ((USAGE)0x53)
#define HID_USAGE_KEYBOARD_CAPS_LOCK ((USAGE)0x39)
// Funtion keys
#define HID_USAGE_KEYBOARD_F1 ((USAGE)0x3A)
#define HID_USAGE_KEYBOARD_F12 ((USAGE)0x45)
#define HID_USAGE_KEYBOARD_RETURN ((USAGE)0x28)
#define HID_USAGE_KEYBOARD_ESCAPE ((USAGE)0x29)
#define HID_USAGE_KEYBOARD_DELETE ((USAGE)0x2A)
#define HID_USAGE_KEYBOARD_PRINT_SCREEN ((USAGE)0x46)
// and hundreds more...
//
// LED Page (0x08)
//
#define HID_USAGE_LED_NUM_LOCK ((USAGE)0x01)
#define HID_USAGE_LED_CAPS_LOCK ((USAGE)0x02)
#define HID_USAGE_LED_SCROLL_LOCK ((USAGE)0x03)
#define HID_USAGE_LED_COMPOSE ((USAGE)0x04)
#define HID_USAGE_LED_KANA ((USAGE)0x05)
#define HID_USAGE_LED_POWER ((USAGE)0x06)
#define HID_USAGE_LED_SHIFT ((USAGE)0x07)
#define HID_USAGE_LED_DO_NOT_DISTURB ((USAGE)0x08)
#define HID_USAGE_LED_MUTE ((USAGE)0x09)
#define HID_USAGE_LED_TONE_ENABLE ((USAGE)0x0A)
#define HID_USAGE_LED_HIGH_CUT_FILTER ((USAGE)0x0B)
#define HID_USAGE_LED_LOW_CUT_FILTER ((USAGE)0x0C)
#define HID_USAGE_LED_EQUALIZER_ENABLE ((USAGE)0x0D)
#define HID_USAGE_LED_SOUND_FIELD_ON ((USAGE)0x0E)
#define HID_USAGE_LED_SURROUND_FIELD_ON ((USAGE)0x0F)
#define HID_USAGE_LED_REPEAT ((USAGE)0x10)
#define HID_USAGE_LED_STEREO ((USAGE)0x11)
#define HID_USAGE_LED_SAMPLING_RATE_DETECT ((USAGE)0x12)
#define HID_USAGE_LED_SPINNING ((USAGE)0x13)
#define HID_USAGE_LED_CAV ((USAGE)0x14)
#define HID_USAGE_LED_CLV ((USAGE)0x15)
#define HID_USAGE_LED_RECORDING_FORMAT_DET ((USAGE)0x16)
#define HID_USAGE_LED_OFF_HOOK ((USAGE)0x17)
#define HID_USAGE_LED_RING ((USAGE)0x18)
#define HID_USAGE_LED_MESSAGE_WAITING ((USAGE)0x19)
#define HID_USAGE_LED_DATA_MODE ((USAGE)0x1A)
#define HID_USAGE_LED_BATTERY_OPERATION ((USAGE)0x1B)
#define HID_USAGE_LED_BATTERY_OK ((USAGE)0x1C)
#define HID_USAGE_LED_BATTERY_LOW ((USAGE)0x1D)
#define HID_USAGE_LED_SPEAKER ((USAGE)0x1E)
#define HID_USAGE_LED_HEAD_SET ((USAGE)0x1F)
#define HID_USAGE_LED_HOLD ((USAGE)0x20)
#define HID_USAGE_LED_MICROPHONE ((USAGE)0x21)
#define HID_USAGE_LED_COVERAGE ((USAGE)0x22)
#define HID_USAGE_LED_NIGHT_MODE ((USAGE)0x23)
#define HID_USAGE_LED_SEND_CALLS ((USAGE)0x24)
#define HID_USAGE_LED_CALL_PICKUP ((USAGE)0x25)
#define HID_USAGE_LED_CONFERENCE ((USAGE)0x26)
#define HID_USAGE_LED_STAND_BY ((USAGE)0x27)
#define HID_USAGE_LED_CAMERA_ON ((USAGE)0x28)
#define HID_USAGE_LED_CAMERA_OFF ((USAGE)0x29)
#define HID_USAGE_LED_ON_LINE ((USAGE)0x2A)
#define HID_USAGE_LED_OFF_LINE ((USAGE)0x2B)
#define HID_USAGE_LED_BUSY ((USAGE)0x2C)
#define HID_USAGE_LED_READY ((USAGE)0x2D)
#define HID_USAGE_LED_PAPER_OUT ((USAGE)0x2E)
#define HID_USAGE_LED_PAPER_JAM ((USAGE)0x2F)
#define HID_USAGE_LED_REMOTE ((USAGE)0x30)
#define HID_USAGE_LED_FORWARD ((USAGE)0x31)
#define HID_USAGE_LED_REVERSE ((USAGE)0x32)
#define HID_USAGE_LED_STOP ((USAGE)0x33)
#define HID_USAGE_LED_REWIND ((USAGE)0x34)
#define HID_USAGE_LED_FAST_FORWARD ((USAGE)0x35)
#define HID_USAGE_LED_PLAY ((USAGE)0x36)
#define HID_USAGE_LED_PAUSE ((USAGE)0x37)
#define HID_USAGE_LED_RECORD ((USAGE)0x38)
#define HID_USAGE_LED_ERROR ((USAGE)0x39)
#define HID_USAGE_LED_SELECTED_INDICATOR ((USAGE)0x3A)
#define HID_USAGE_LED_IN_USE_INDICATOR ((USAGE)0x3B)
#define HID_USAGE_LED_MULTI_MODE_INDICATOR ((USAGE)0x3C)
#define HID_USAGE_LED_INDICATOR_ON ((USAGE)0x3D)
#define HID_USAGE_LED_INDICATOR_FLASH ((USAGE)0x3E)
#define HID_USAGE_LED_INDICATOR_SLOW_BLINK ((USAGE)0x3F)
#define HID_USAGE_LED_INDICATOR_FAST_BLINK ((USAGE)0x40)
#define HID_USAGE_LED_INDICATOR_OFF ((USAGE)0x41)
#define HID_USAGE_LED_FLASH_ON_TIME ((USAGE)0x42)
#define HID_USAGE_LED_SLOW_BLINK_ON_TIME ((USAGE)0x43)
#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME ((USAGE)0x44)
#define HID_USAGE_LED_FAST_BLINK_ON_TIME ((USAGE)0x45)
#define HID_USAGE_LED_FAST_BLINK_OFF_TIME ((USAGE)0x46)
#define HID_USAGE_LED_INDICATOR_COLOR ((USAGE)0x47)
#define HID_USAGE_LED_RED ((USAGE)0x48)
#define HID_USAGE_LED_GREEN ((USAGE)0x49)
#define HID_USAGE_LED_AMBER ((USAGE)0x4A)
#define HID_USAGE_LED_GENERIC_INDICATOR ((USAGE)0x3B)
//
// Button Page (0x09)
//
// There is no need to label these usages.
//
//
// Ordinal Page (0x0A)
//
// There is no need to label these usages.
//
//
// Telephony Device Page (0x0B)
//
#define HID_USAGE_TELEPHONY_PHONE ((USAGE)0x01)
#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE ((USAGE)0x02)
#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS ((USAGE)0x03)
#define HID_USAGE_TELEPHONY_HANDSET ((USAGE)0x04)
#define HID_USAGE_TELEPHONY_HEADSET ((USAGE)0x05)
#define HID_USAGE_TELEPHONY_KEYPAD ((USAGE)0x06)
#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON ((USAGE)0x07)
// BUGBUG defined in ntstatus.h
#ifndef FACILITY_HID_ERROR_CODE
#define FACILITY_HID_ERROR_CODE 0x11
#endif
#define HIDP_ERROR_CODES(SEV, CODE) \
((NTSTATUS)(((SEV) << 28) | (FACILITY_HID_ERROR_CODE << 16) | (CODE)))
#define HIDP_STATUS_SUCCESS (HIDP_ERROR_CODES(0x0, 0))
#define HIDP_STATUS_NULL (HIDP_ERROR_CODES(0x8, 1))
#define HIDP_STATUS_INVALID_PREPARSED_DATA (HIDP_ERROR_CODES(0xC, 1))
#define HIDP_STATUS_INVALID_REPORT_TYPE (HIDP_ERROR_CODES(0xC, 2))
#define HIDP_STATUS_INVALID_REPORT_LENGTH (HIDP_ERROR_CODES(0xC, 3))
#define HIDP_STATUS_USAGE_NOT_FOUND (HIDP_ERROR_CODES(0xC, 4))
#define HIDP_STATUS_VALUE_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC, 5))
#define HIDP_STATUS_BAD_LOG_PHY_VALUES (HIDP_ERROR_CODES(0xC, 6))
#define HIDP_STATUS_BUFFER_TOO_SMALL (HIDP_ERROR_CODES(0xC, 7))
#define HIDP_STATUS_INTERNAL_ERROR (HIDP_ERROR_CODES(0xC, 8))
#define HIDP_STATUS_I8242_TRANS_UNKNOWN (HIDP_ERROR_CODES(0xC, 9))
#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID (HIDP_ERROR_CODES(0xC, 0xA))
#define HIDP_STATUS_NOT_VALUE_ARRAY (HIDP_ERROR_CODES(0xC, 0xB))
#define HIDP_STATUS_IS_VALUE_ARRAY (HIDP_ERROR_CODES(0xC, 0xC))
#define HIDP_STATUS_DATA_INDEX_NOT_FOUND (HIDP_ERROR_CODES(0xC, 0xD))
#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC, 0xE))
#define HIDP_STATUS_BUTTON_NOT_PRESSED (HIDP_ERROR_CODES(0xC, 0xF))
#define HIDP_STATUS_REPORT_DOES_NOT_EXIST (HIDP_ERROR_CODES(0xC, 0x10))
#define HIDP_STATUS_NOT_IMPLEMENTED (HIDP_ERROR_CODES(0xC, 0x20))
typedef enum _HIDP_REPORT_TYPE
{
HidP_Input,
HidP_Output,
HidP_Feature
} HIDP_REPORT_TYPE;
typedef struct _USAGE_AND_PAGE
{
USAGE Usage;
USAGE UsagePage;
} USAGE_AND_PAGE, *PUSAGE_AND_PAGE;
typedef struct _HIDP_BUTTON_CAPS
{
USAGE UsagePage;
UCHAR ReportID;
BOOLEAN IsAlias;
USHORT BitField;
USHORT LinkCollection; // A unique internal index pointer
USAGE LinkUsage;
USAGE LinkUsagePage;
BOOLEAN IsRange;
BOOLEAN IsStringRange;
BOOLEAN IsDesignatorRange;
BOOLEAN IsAbsolute;
ULONG Reserved[10];
union
{
struct
{
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct
{
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
USHORT DataIndex, Reserved4;
} NotRange;
};
} HIDP_BUTTON_CAPS, *PHIDP_BUTTON_CAPS;
typedef struct _HIDP_VALUE_CAPS
{
USAGE UsagePage;
UCHAR ReportID;
BOOLEAN IsAlias;
USHORT BitField;
USHORT LinkCollection; // A unique internal index pointer
USAGE LinkUsage;
USAGE LinkUsagePage;
BOOLEAN IsRange;
BOOLEAN IsStringRange;
BOOLEAN IsDesignatorRange;
BOOLEAN IsAbsolute;
BOOLEAN HasNull; // Does this channel have a null report union
UCHAR Reserved;
USHORT BitSize; // How many bits are devoted to this value?
USHORT ReportCount; // See Note below. Usually set to 1.
USHORT Reserved2[5];
ULONG UnitsExp;
ULONG Units;
LONG LogicalMin, LogicalMax;
LONG PhysicalMin, PhysicalMax;
union
{
struct
{
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct
{
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
USHORT DataIndex, Reserved4;
} NotRange;
};
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
typedef struct _HIDD_ATTRIBUTES
{
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
//
// Vendor ids of this hid device
//
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
//
// Additional fields will be added to the end of this structure.
//
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
typedef PUCHAR PHIDP_REPORT_DESCRIPTOR;
typedef struct _HIDP_PREPARSED_DATA* PHIDP_PREPARSED_DATA;
typedef struct _HIDP_CAPS
{
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberLinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
} HIDP_CAPS, *PHIDP_CAPS;
typedef struct _HIDP_DATA
{
USHORT DataIndex;
USHORT Reserved;
union
{
ULONG RawValue; // for values
BOOLEAN On; // for buttons MUST BE TRUE for buttons.
};
} HIDP_DATA, *PHIDP_DATA;
typedef BOOLEAN(__stdcall* _HidD_GetAttributes)(HANDLE HidDeviceObject, HIDD_ATTRIBUTES* Attributes);
typedef void(__stdcall* _HidD_GetHidGuid)(GUID* HidGuid);
typedef BOOLEAN(__stdcall* _HidD_GetPreparsedData)(HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA* PreparsedData);
typedef NTSTATUS(__stdcall* _HidP_GetCaps)(PHIDP_PREPARSED_DATA PreparsedData, HIDP_CAPS* caps);
typedef BOOLEAN(__stdcall* _HidD_FreePreparsedData)(PHIDP_PREPARSED_DATA PreparsedData);
typedef BOOLEAN(__stdcall* _HidD_GetFeature)(HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
typedef BOOLEAN(__stdcall* _HidD_SetFeature)(HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
typedef NTSTATUS(__stdcall* _HidP_GetSpecificButtonCaps)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS(__stdcall* _HidP_GetButtonCaps)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS(__stdcall* _HidP_GetUsages)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE* UsageList, ULONG* UsageLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
typedef NTSTATUS(__stdcall* _HidP_GetValueCaps)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS(__stdcall* _HidP_GetUsageValue)(HIDP_REPORT_TYPE ReportType, USAGE UsagePage, USHORT LinkCollection, USAGE Usage, PULONG UsageValue, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
typedef BOOLEAN(__stdcall* _HidD_GetProductString)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
//#define HidP_GetButtonCaps(_Type_, _Caps_, _Len_, _Data_) \
// HidP_GetSpecificButtonCaps(_Type_, 0, 0, 0, _Caps_, _Len_, _Data_)
extern _HidD_GetHidGuid HidD_GetHidGuid;
extern _HidD_GetAttributes HidD_GetAttributes;
extern _HidD_GetPreparsedData HidD_GetPreparsedData;
extern _HidP_GetCaps HidP_GetCaps;
extern _HidD_FreePreparsedData HidD_FreePreparsedData;
extern _HidD_GetFeature HidD_GetFeature;
extern _HidD_SetFeature HidD_SetFeature;
extern _HidP_GetSpecificButtonCaps HidP_GetSpecificButtonCaps;
extern _HidP_GetButtonCaps HidP_GetButtonCaps;
extern _HidP_GetUsages HidP_GetUsages;
extern _HidP_GetValueCaps HidP_GetValueCaps;
extern _HidP_GetUsageValue HidP_GetUsageValue;
extern _HidD_GetProductString HidD_GetProductString;
void UninitHid();
int InitHid();
#include <poppack.h>
#endif

Some files were not shown because too many files have changed in this diff Show More