summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/CMakeLists.txt5
-rw-r--r--gui/init.cpp159
-rw-r--r--gui/init.hpp3
-rw-r--r--gui/keyboard.cpp50
-rw-r--r--gui/keyboard.h10
-rw-r--r--gui/lang/nl_NL.ts4
-rw-r--r--gui/lang/ru_RU.ts4
-rw-r--r--gui/lang/stub.ts4
-rw-r--r--gui/lang/zh_CN.ts4
-rw-r--r--gui/mapping-dialog.cpp30
-rw-r--r--gui/process_detector.cpp20
-rw-r--r--gui/process_detector.h2
-rw-r--r--gui/settings.cpp2
-rw-r--r--gui/settings.hpp2
14 files changed, 183 insertions, 116 deletions
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
index cb5e2bdc..db2f0b9e 100644
--- a/gui/CMakeLists.txt
+++ b/gui/CMakeLists.txt
@@ -5,7 +5,6 @@ target_link_libraries(${self}
opentrack-logic
opentrack-spline
opentrack-pose-widget
- opentrack-version
)
# for process detector
@@ -15,3 +14,7 @@ elseif(LINUX)
otr_pkgconfig(${self} libprocps)
endif()
+if(NOT APPLE AND NOT WIN32)
+ target_compile_definitions(${self} PRIVATE -DOTR_X11_THREADS)
+ otr_pkgconfig(${self} x11)
+endif()
diff --git a/gui/init.cpp b/gui/init.cpp
index 4609d535..77d90212 100644
--- a/gui/init.cpp
+++ b/gui/init.cpp
@@ -1,5 +1,3 @@
-#include "init.hpp"
-
/* Copyright (c) 2013-2017 Stanislaw Halik
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -7,14 +5,12 @@
* copyright notice and this permission notice appear in all copies.
*/
-#if defined(Q_CREATOR_RUN)
-# pragma clang diagnostic ignored "-Wmain"
-#endif
-
+#include "init.hpp"
#include "migration/migration.hpp"
#include "options/options.hpp"
using namespace options;
#include "compat/library-path.hpp"
+#include "compat/arch.hpp"
#include <memory>
#include <cstdlib>
@@ -30,86 +26,129 @@ using namespace options;
#include <QFile>
#include <QFileDialog>
#include <QString>
-#include <QSysInfo>
+#include <QOperatingSystemVersion>
+#include <QMutex>
#include <QDebug>
-#if /* denormal control */ \
- /* GNU */ defined __x86_64__ || defined __SSE3__ || \
- /* MSVC */ defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
-
-# if defined __GNUG__ && defined __SSE2__ && !defined __SSE3__ && !defined __x86_64__
-# undef OTR_DENORM_DAZ
-# include <emmintrin.h>
-# else
-# define OTR_DENORM_DAZ
-# include <pmmintrin.h>
-# endif
-# include <cfloat>
+#include <cfloat>
+#include <cfenv>
-# ifdef __APPLE__
-# include <fenv.h>
-# endif
+#ifdef __MINGW32__
+extern "C" __declspec(dllimport) unsigned __cdecl _controlfp(unsigned, unsigned);
+#endif
static void set_fp_mask()
{
-#ifdef OTR_DENORM_DAZ
+#if defined OTR_ARCH_DENORM_DAZ
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
-#endif
+#elif defined OTR_ARCH_DENORM_FTZ
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
- //_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
+#endif
+
+#ifdef OTR_ARCH_FPU_MASK
_MM_SET_EXCEPTION_MASK(_MM_MASK_MASK);
+#endif
#ifdef __APPLE__
fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
#endif
-}
-#else
-static inline void set_fp_mask() {}
+
+#ifdef _WIN32
+# ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wreserved-id-macro"
+# endif
+# ifndef _DN_FLUSH
+# define _DN_FLUSH 0x01000000
+# endif
+# ifndef _MCW_DN
+# define _MCW_DN 0x03000000
+# endif
+# ifdef __clang__
+# pragma clang diagnostic pop
+# endif
+ _controlfp(_DN_FLUSH, _MCW_DN);
#endif
+}
-static void set_qt_style()
+#ifdef OTR_X11_THREADS
+#include <X11/Xlib.h>
+static void enable_x11_threads()
{
-#if defined _WIN32
- if (QSysInfo::WindowsVersion == QSysInfo::WV_XP)
- return;
+ (void)XInitThreads();
+}
#endif
+static void set_qt_style()
+{
#if defined _WIN32 || defined __APPLE__
// our layouts on OSX make some control wrongly sized -sh 20160908
{
- const char* const preferred[] { "fusion", "windowsvista", "macintosh" };
+ const char* const preferred[] {
+#ifdef __APPLE__
+ "macintosh", "fusion", "windowsvista", "windows",
+#else
+ "fusion", "windowsvista", "windows", "windowsxp",
+#endif
+ };
for (const char* style_name : preferred)
- {
- QStyle* s = QStyleFactory::create(style_name);
- if (s)
+ if (QStyle* s = QStyleFactory::create(style_name); s != nullptr)
{
QApplication::setStyle(s);
break;
}
- }
}
#endif
}
+#include <string>
+
#ifdef _WIN32
+# include <windows.h>
+# include <malloc.h>
+#else
+# include <alloca.h>
+#endif
static void qdebug_to_console(QtMsgType, const QMessageLogContext& ctx, const QString &msg)
{
- const unsigned short* const str_ = msg.utf16();
- const auto str = reinterpret_cast<wchar_t const*>(str_);
- static_assert(sizeof(*str_) == sizeof(*str));
-
- std::fflush(stderr);
- if (ctx.function)
- std::fprintf(stderr, "[%s:%d%s]: %ls\n", ctx.file, ctx.line, ctx.function, str);
- else if (ctx.file)
- std::fprintf(stderr, "[%s:%d]: %ls\n", ctx.file, ctx.line, str);
+#ifdef _WIN32
+ static_assert(sizeof(wchar_t) == sizeof(decltype(*msg.utf16())));
+
+ if (IsDebuggerPresent())
+ {
+ static QMutex lock;
+ QMutexLocker l(&lock);
+
+ const wchar_t* const bytes = (const wchar_t*)msg.utf16();
+
+ OutputDebugStringW(bytes);
+ OutputDebugStringW(L"\n");
+ }
else
- std::fprintf(stderr, "%ls\n", str);
- std::fflush(stderr);
+#endif
+ {
+#if defined _WIN32 && 1
+ const wchar_t* const bytes = (const wchar_t*)msg.utf16();
+#else
+ unsigned len = (unsigned)msg.size()+1;
+ wchar_t* const bytes = (wchar_t*)alloca(len * sizeof(wchar_t));
+ bytes[len-1] = 0;
+ (void)msg.toWCharArray(bytes);
+#endif
+ {
+ if (ctx.file)
+ std::fprintf(stderr, "[%s:%d]: %ls\n", ctx.file, ctx.line, bytes);
+ else
+ std::fprintf(stderr, "%ls\n", bytes);
+ }
+ std::fflush(stderr);
+ }
}
+#ifdef _WIN32
+
static void add_win32_path()
{
// see https://software.intel.com/en-us/articles/limitation-to-the-length-of-the-system-path-variable
@@ -160,14 +199,13 @@ static void add_win32_path()
}
}
-#include <windows.h>
-
static void attach_parent_console()
{
- std::fflush(stdin);
- std::fflush(stderr);
+ if (GetConsoleWindow() != nullptr)
+ return;
- (void)qInstallMessageHandler(qdebug_to_console);
+ fflush(stdin);
+ fflush(stderr);
if (AttachConsole(ATTACH_PARENT_PROCESS))
{
@@ -176,7 +214,7 @@ static void attach_parent_console()
_wfreopen(L"CON", L"r", stdin);
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
- freopen("CON", "w", stderr);
+ freopen("CON", "r", stdin);
// skip prompt in cmd.exe window
fprintf(stderr, "\n");
@@ -200,12 +238,17 @@ static int run_window(std::unique_ptr<QWidget> main_window)
return status;
}
-int otr_main(int argc, char** argv, std::function<QWidget*()> const& make_main_window)
+int otr_main(int argc, char** argv, std::function<std::unique_ptr<QWidget>()> const& make_main_window)
{
set_fp_mask();
+#ifdef OTR_X11_THREADS
+ enable_x11_threads();
+#endif
+#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QCoreApplication::setAttribute(Qt::AA_X11InitThreads, true);
+#endif
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication app(argc, argv);
@@ -214,6 +257,8 @@ int otr_main(int argc, char** argv, std::function<QWidget*()> const& make_main_w
attach_parent_console();
#endif
+ (void)qInstallMessageHandler(qdebug_to_console);
+
QDir::setCurrent(OPENTRACK_BASE_PATH);
set_qt_style();
@@ -241,7 +286,7 @@ int otr_main(int argc, char** argv, std::function<QWidget*()> const& make_main_w
}
}
- int ret = run_window(std::unique_ptr<QWidget>(make_main_window()));
+ int ret = run_window(make_main_window());
#if 0
// msvc crashes in Qt plugin system's dtor
diff --git a/gui/init.hpp b/gui/init.hpp
index 7c437bcb..4274f437 100644
--- a/gui/init.hpp
+++ b/gui/init.hpp
@@ -3,9 +3,10 @@
#include "export.hpp"
#include <functional>
+#include <memory>
#include <QWidget>
-OTR_GUI_EXPORT int otr_main(int argc, char** argv, std::function<QWidget*()> const& make_main_window);
+OTR_GUI_EXPORT int otr_main(int argc, char** argv, std::function<std::unique_ptr<QWidget>()> const& make_main_window);
// XXX TODO need split MainWindow into mixins each implementing part of the functionality
diff --git a/gui/keyboard.cpp b/gui/keyboard.cpp
index dbc3ab3a..90849bab 100644
--- a/gui/keyboard.cpp
+++ b/gui/keyboard.cpp
@@ -1,39 +1,43 @@
+#undef NDEBUG
+#include <cassert>
+
#include "keyboard.h"
#include <QDebug>
#ifdef _WIN32
-auto keyboard_listener::make_token()
+
+void keyboard_listener::receive_key(const Key& k)
{
- return [this](const Key& k) {
- if(!k.guid.isEmpty())
- {
- int mods = 0;
- if (k.alt) mods |= Qt::AltModifier;
- if (k.shift) mods |= Qt::ShiftModifier;
- if (k.ctrl) mods |= Qt::ControlModifier;
- emit joystick_button_pressed(k.guid, k.keycode | mods, k.held);
- }
- else
- {
- Qt::KeyboardModifiers m;
- QKeySequence k_;
- if (win_key::to_qt(k, k_, m))
- emit key_pressed({ int(m) | int(k_) });
- }
- };
+ if(!k.guid.isEmpty())
+ {
+ int mods = 0;
+ if (k.alt) mods |= Qt::AltModifier;
+ if (k.shift) mods |= Qt::ShiftModifier;
+ if (k.ctrl) mods |= Qt::ControlModifier;
+
+ emit joystick_button_pressed(k.guid, k.keycode | mods, k.held);
+ }
+ else
+ {
+ Qt::KeyboardModifiers m;
+ QKeySequence k_;
+
+ if (win_key::to_qt(k, k_, m))
+ for (unsigned i = 0; i < (unsigned)k_.count(); i++)
+ emit key_pressed(QKeySequence(int(m) | k_[i]));
+ }
}
#endif
-keyboard_listener::keyboard_listener(QWidget* parent) :
- QDialog(parent)
-#ifdef _WIN32
- , token(make_token())
-#endif
+keyboard_listener::keyboard_listener(QWidget* parent) : QDialog(parent)
{
ui.setupUi(this);
setFocusPolicy(Qt::StrongFocus);
+#ifdef _WIN32
+ (void)token;
+#endif
}
#if !defined _WIN32
diff --git a/gui/keyboard.h b/gui/keyboard.h
index 0a06a3af..ea35d372 100644
--- a/gui/keyboard.h
+++ b/gui/keyboard.h
@@ -22,13 +22,17 @@
class OTR_GUI_EXPORT keyboard_listener : public QDialog
{
Q_OBJECT
- Ui_keyboard_listener ui;
+
#ifdef _WIN32
- auto make_token();
- KeybindingWorker::Token token;
+ void receive_key(const Key& k);
+
+ KeybindingWorker::Token token{[this](const Key& k) {receive_key(k);}};
#else
void keyPressEvent(QKeyEvent* event) override;
#endif
+
+ Ui_keyboard_listener ui;
+
public:
keyboard_listener(QWidget* parent = nullptr);
signals:
diff --git a/gui/lang/nl_NL.ts b/gui/lang/nl_NL.ts
index 64ee0621..60b84189 100644
--- a/gui/lang/nl_NL.ts
+++ b/gui/lang/nl_NL.ts
@@ -121,6 +121,10 @@ Press &quot;clear calibration&quot; to remove any calibration data pertaining to
<source>%1°</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1 cm</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>options_dialog</name>
diff --git a/gui/lang/ru_RU.ts b/gui/lang/ru_RU.ts
index 8e3ca4a7..d40b4775 100644
--- a/gui/lang/ru_RU.ts
+++ b/gui/lang/ru_RU.ts
@@ -121,6 +121,10 @@ Press &quot;clear calibration&quot; to remove any calibration data pertaining to
<source>%1°</source>
<translation></translation>
</message>
+ <message>
+ <source>%1 cm</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>options_dialog</name>
diff --git a/gui/lang/stub.ts b/gui/lang/stub.ts
index 932f4348..b383a0d8 100644
--- a/gui/lang/stub.ts
+++ b/gui/lang/stub.ts
@@ -121,6 +121,10 @@ Press &quot;clear calibration&quot; to remove any calibration data pertaining to
<source>%1°</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1 cm</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>options_dialog</name>
diff --git a/gui/lang/zh_CN.ts b/gui/lang/zh_CN.ts
index 45414302..fa2d512c 100644
--- a/gui/lang/zh_CN.ts
+++ b/gui/lang/zh_CN.ts
@@ -122,6 +122,10 @@ Press &quot;clear calibration&quot; to remove any calibration data pertaining to
<source>%1°</source>
<translation></translation>
</message>
+ <message>
+ <source>%1 cm</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>options_dialog</name>
diff --git a/gui/mapping-dialog.cpp b/gui/mapping-dialog.cpp
index e57cead2..6dc6d15f 100644
--- a/gui/mapping-dialog.cpp
+++ b/gui/mapping-dialog.cpp
@@ -94,20 +94,18 @@ void mapping_dialog::load()
{ nullptr, Yaw, nullptr, false }
};
- ui.max_pitch_output->setItemData(0, int(axis_opts::o_r180));
- ui.max_pitch_output->setItemData(1, int(axis_opts::o_r90));
-
using a = axis_opts::max_clamp;
+ ui.max_pitch_output->setItemData(0, int(a::o_r180));
+ ui.max_pitch_output->setItemData(1, int(a::o_r90));
+
for (QComboBox* x : { ui.max_yaw_rotation, ui.max_pitch_rotation, ui.max_roll_rotation })
for (a y : { a::r180, a::r90, a::r60, a::r45, a::r30, a::r25, a::r20, a::r15, a::r10 })
x->addItem(tr("%1°").arg(y), y);
for (QComboBox* x : { ui.max_x_translation, ui.max_y_translation, ui.max_z_translation })
for (a y : { a::t30, a::t20, a::t15, a::t10, a::t100 })
- x->addItem(QStringLiteral("%1 cm").arg(int(y)), y);
-
- // XXX TODO add tie_setting overload for spline_widget!!! -sh 20171020
+ x->addItem(tr("%1 cm").arg(int(y)), y);
for (int i = 0; qfcs[i].qfc; i++)
{
@@ -121,20 +119,16 @@ void mapping_dialog::load()
{
connect(&axis.opts.altp,
value_::value_changed<bool>(),
- this,
- [&](bool f) {qfc.setEnabled(f); qfc.force_redraw();});
+ this, [&](bool f) { qfc.setEnabled(f); });
qfc.setEnabled(axis.opts.altp);
- qfc.force_redraw();
}
- using c = axis_opts::max_clamp;
-
auto update_xstep = [&qfc](int clamp_x) {
int value;
- if (clamp_x <= c::r20)
+ if (clamp_x <= a::r30)
value = 1;
- else if (clamp_x <= c::r30)
+ else if (clamp_x <= a::r45)
value = 5;
else
value = 10;
@@ -147,11 +141,11 @@ void mapping_dialog::load()
switch (clamp_y)
{
default:
- case c::o_r180:
- value = 15; break;
- case c::o_r90:
+ case a::o_r180:
+ value = 20; break;
+ case a::o_r90:
value = 10; break;
- case c::o_t75:
+ case a::o_t75:
value = 5; break;
}
qfc.set_y_step(value);
@@ -163,7 +157,7 @@ void mapping_dialog::load()
connect(&axis.opts.clamp_y_, value_::value_changed<int>(), &qfc, update_ystep);
// force signal to avoid duplicating the slot's logic
- qfc.setConfig(&conf);
+ qfc.set_config(&conf);
update_xstep(axis.opts.clamp_x_);
update_ystep(axis.opts.clamp_y_);
diff --git a/gui/process_detector.cpp b/gui/process_detector.cpp
index 0ff05f93..b17d5dd0 100644
--- a/gui/process_detector.cpp
+++ b/gui/process_detector.cpp
@@ -20,8 +20,8 @@
#include <QSettings>
#include <QtEvents>
-static constexpr inline auto RECORD_SEPARATOR = QChar(char(0x1e)); // RS ^]
-static constexpr inline auto UNIT_SEPARATOR = QChar(char(0x1f)); // US ^_
+static constexpr auto RECORD_SEPARATOR = QChar(char(0x1e)); // RS ^]
+static constexpr auto UNIT_SEPARATOR = QChar(char(0x1f)); // US ^_
using namespace options;
using namespace options::globals;
@@ -106,7 +106,7 @@ int process_detector::add_row(QString const& exe_name, QString const& profile)
{
BrowseButton* b = new BrowseButton(twi);
b->setText("...");
- QObject::connect(b, SIGNAL(clicked()), b, SLOT(browse()));
+ QObject::connect(b, &BrowseButton::clicked, b, &BrowseButton::browse);
ui.tableWidget->setCellWidget(i, 2, b);
}
@@ -174,14 +174,14 @@ void process_detector::remove()
bool process_detector_worker::should_stop()
{
- if (last_exe_name == "")
+ if (last_exe_name == QString())
return false;
proc_detector_settings s;
if (!s.is_enabled())
{
- last_exe_name = "";
+ last_exe_name = QString{};
return false;
}
@@ -190,17 +190,17 @@ bool process_detector_worker::should_stop()
if (exe_list.contains(last_exe_name))
return false;
- last_exe_name = "";
+ last_exe_name = QString{};
return true;
}
-bool process_detector_worker::config_to_start(QString& str)
+bool process_detector_worker::profile_to_start(QString& str)
{
proc_detector_settings s;
if (!s.is_enabled())
{
- last_exe_name = "";
+ last_exe_name = QString{};
return false;
}
@@ -218,9 +218,9 @@ bool process_detector_worker::config_to_start(QString& str)
{
if (filenames.contains(name))
{
- last_exe_name = name;
str = filenames[name];
- return str != "";
+ last_exe_name = std::move(name);
+ return str != QString{};
}
}
diff --git a/gui/process_detector.h b/gui/process_detector.h
index 7439b19b..4e8842c6 100644
--- a/gui/process_detector.h
+++ b/gui/process_detector.h
@@ -63,7 +63,7 @@ class OTR_GUI_EXPORT process_detector_worker : QObject
proc_detector_settings s;
QString last_exe_name;
public:
- bool config_to_start(QString& s);
+ bool profile_to_start(QString& str);
bool should_stop();
};
diff --git a/gui/settings.cpp b/gui/settings.cpp
index 711fb0f0..79a8dbfb 100644
--- a/gui/settings.cpp
+++ b/gui/settings.cpp
@@ -45,7 +45,7 @@ void options_dialog::set_disable_translation_state(bool value)
});
}
-options_dialog::options_dialog(std::function<void(bool)>&& pause_keybindings) :
+options_dialog::options_dialog(std::function<void(bool)> pause_keybindings) :
pause_keybindings(std::move(pause_keybindings))
{
ui.setupUi(this);
diff --git a/gui/settings.hpp b/gui/settings.hpp
index 50245a59..8ef5aa2d 100644
--- a/gui/settings.hpp
+++ b/gui/settings.hpp
@@ -17,7 +17,7 @@ class OTR_GUI_EXPORT options_dialog : public QDialog
signals:
void closing();
public:
- explicit options_dialog(std::function<void(bool)>&& pause_keybindings);
+ explicit options_dialog(std::function<void(bool)> pause_keybindings);
private:
main_settings main;
std::function<void(bool)> pause_keybindings;