diff options
Diffstat (limited to 'gui/init.cpp')
-rw-r--r-- | gui/init.cpp | 159 |
1 files changed, 102 insertions, 57 deletions
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 |