diff --git a/.travis.yml b/.travis.yml index 912d36d265a..fdb29a2658b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,13 @@ compiler: gcc env: matrix: - - MUMBLE_QT=qt4 - - MUMBLE_QT=qt5 + - MUMBLE_QT=qt4 MUMBLE_HOST=x86_64-linux-gnu + - MUMBLE_QT=qt5 MUMBLE_HOST=x86_64-linux-gnu + - MUMBLE_QT=qt5 MUMBLE_HOST=i686-w64-mingw32 + - MUMBLE_QT=qt5 MUMBLE_HOST=x86_64-w64-mingw32 + allow_failures: + - env: MUMBLE_QT=qt5 MUMBLE_HOST=i686-w64-mingw32 + - env: MUMBLE_QT=qt5 MUMBLE_HOST=x86_64-w64-mingw32 before_install: - ./scripts/travis-ci/before_install.bash diff --git a/3rdparty/celt-0.11.0-build/celt-0.11.0-build.pro b/3rdparty/celt-0.11.0-build/celt-0.11.0-build.pro index 0be7db2bad0..8f8d92d2566 100644 --- a/3rdparty/celt-0.11.0-build/celt-0.11.0-build.pro +++ b/3rdparty/celt-0.11.0-build/celt-0.11.0-build.pro @@ -36,13 +36,21 @@ QMAKE_CFLAGS -= -fPIE -pie win32 { DEFINES += WIN32 _WIN32 - INCLUDEPATH += ../$$BUILDDIR/win32 - CONFIG(sse2) { - TARGET_VERSION_EXT = .$${VERSION}.sse2 - } else { - QMAKE_CFLAGS_RELEASE -= -arch:SSE - QMAKE_CFLAGS_DEBUG -= -arch:SSE + win32-g++ { + # MinGW uses the config.h for Unix-like systems. + INCLUDEPATH += ../$$BUILDDIR + } + + win32-msvc* { + INCLUDEPATH += ../$$BUILDDIR/win32 + + CONFIG(sse2) { + TARGET_VERSION_EXT = .$${VERSION}.sse2 + } else { + QMAKE_CFLAGS_RELEASE -= -arch:SSE + QMAKE_CFLAGS_DEBUG -= -arch:SSE + } } } diff --git a/3rdparty/celt-0.7.0-build/celt-0.7.0-build.pro b/3rdparty/celt-0.7.0-build/celt-0.7.0-build.pro index fc52f57d13a..0ebf4889adb 100644 --- a/3rdparty/celt-0.7.0-build/celt-0.7.0-build.pro +++ b/3rdparty/celt-0.7.0-build/celt-0.7.0-build.pro @@ -43,13 +43,21 @@ QMAKE_CFLAGS -= -fPIE -pie win32 { DEFINES += WIN32 _WIN32 - INCLUDEPATH += ../$$BUILDDIR/win32 - CONFIG(sse2) { - TARGET_VERSION_EXT = .$${VERSION}.sse2 - } else { - QMAKE_CFLAGS_RELEASE -= -arch:SSE - QMAKE_CFLAGS_DEBUG -= -arch:SSE + win32-g++ { + # MinGW uses the config.h for Unix-like systems. + INCLUDEPATH += ../$$BUILDDIR + } + + win32-msvc* { + INCLUDEPATH += ../$$BUILDDIR/win32 + + CONFIG(sse2) { + TARGET_VERSION_EXT = .$${VERSION}.sse2 + } else { + QMAKE_CFLAGS_RELEASE -= -arch:SSE + QMAKE_CFLAGS_DEBUG -= -arch:SSE + } } } diff --git a/3rdparty/minhook-build/minhook-build.pro b/3rdparty/minhook-build/minhook-build.pro index 82795641bf2..5d1e1586299 100644 --- a/3rdparty/minhook-build/minhook-build.pro +++ b/3rdparty/minhook-build/minhook-build.pro @@ -34,11 +34,13 @@ DEFINES += WIN32 _WINDOWS _USRDLL MINHOOK_EXPORTS CONFIG += warn_off } -QMAKE_CFLAGS_RELEASE -= -MD -QMAKE_CFLAGS_DEBUG -= -MDd +win32-msvc* { + QMAKE_CFLAGS_RELEASE -= -MD + QMAKE_CFLAGS_DEBUG -= -MDd -QMAKE_CXXFLAGS_RELEASE *= -MT -QMAKE_CXXFLAGS_DEBUG *= -MTd + QMAKE_CXXFLAGS_RELEASE *= -MT + QMAKE_CXXFLAGS_DEBUG *= -MTd +} SOURCES *= \ src/hde/hde64.c \ diff --git a/3rdparty/opus-build/opus-build.pro b/3rdparty/opus-build/opus-build.pro index a7de5ed3e82..09e00922b75 100644 --- a/3rdparty/opus-build/opus-build.pro +++ b/3rdparty/opus-build/opus-build.pro @@ -76,7 +76,7 @@ INCLUDEPATH *= \ ../$$SOURCEDIR/silk/x86 \ ../$$SOURCEDIR/silk/float -win32 { +win32-msvc* { CONFIG *= opus-sse-sources CONFIG *= opus-sse2-sources CONFIG *= opus-sse41-sources diff --git a/3rdparty/opus-build/Win32/config.h b/3rdparty/opus-build/win32/config.h similarity index 100% rename from 3rdparty/opus-build/Win32/config.h rename to 3rdparty/opus-build/win32/config.h diff --git a/3rdparty/opus-build/Win32/version.h b/3rdparty/opus-build/win32/version.h similarity index 100% rename from 3rdparty/opus-build/Win32/version.h rename to 3rdparty/opus-build/win32/version.h diff --git a/3rdparty/speex-build/speex-build.pro b/3rdparty/speex-build/speex-build.pro index 755665a1539..0955c938900 100644 --- a/3rdparty/speex-build/speex-build.pro +++ b/3rdparty/speex-build/speex-build.pro @@ -43,19 +43,29 @@ INCLUDEPATH = ../speex-src/include ../speex-src/libspeex ../speexdsp-src/include win32 { INCLUDEPATH += ../speex-build/win32 DEFINES+=WIN32 _WINDOWS _USE_SSE _USE_MATH_DEFINES + + win32-g++ { + # MinGW uses the config.h for Unix-like systems. + INCLUDEPATH += ../speex-build + } + + win32-msvc* { + INCLUDEPATH += ../speex-build/win32 + + CONFIG(sse2) { + TARGET = speex.sse2 + DEFINES += _USE_SSE2 + } else { + QMAKE_CFLAGS_RELEASE -= -arch:SSE + QMAKE_CFLAGS_DEBUG -= -arch:SSE + } + } + SOURCES *= mumble_speex_init.c CONFIG -= static CONFIG += shared - CONFIG(sse2) { - TARGET = speex.sse2 - DEFINES += _USE_SSE2 - } else { - QMAKE_CFLAGS_RELEASE -= -arch:SSE - QMAKE_CFLAGS_DEBUG -= -arch:SSE - } - DEFINES+=USE_SMALLFT } else { diff --git a/g15helper/g15helper.pro b/g15helper/g15helper.pro index e8e61db40fd..9a504dcd725 100644 --- a/g15helper/g15helper.pro +++ b/g15helper/g15helper.pro @@ -40,7 +40,10 @@ CONFIG(g15-emulator) { win32 { RC_FILE = g15helper.rc - QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../src/mumble/mumble.appcompat.manifest) + + win32-msvc* { + QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../src/mumble/mumble.appcompat.manifest) + } } } else { CONFIG -= qt @@ -52,7 +55,10 @@ CONFIG(g15-emulator) { QMAKE_LIBDIR *= "$$G15SDK_PATH/Lib/x86" INCLUDEPATH *= "$$G15SDK_PATH/Src" DEFINES *= WIN32 - QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../src/mumble/mumble.appcompat.manifest) + + win32-msvc* { + QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../src/mumble/mumble.appcompat.manifest) + } CONFIG(release, debug|release) { QMAKE_CFLAGS_RELEASE -= -MD diff --git a/qmake/compiler.pri b/qmake/compiler.pri index 26e556904d2..f23beebea3e 100644 --- a/qmake/compiler.pri +++ b/qmake/compiler.pri @@ -24,8 +24,27 @@ QMAKE_RESOURCE_FLAGS += -compress 9 # QMAKE_TARGET.arch doesn't suffice any longer, and # we define MUMBLE_ARCH to be used in its place. MUMBLE_ARCH = $$QMAKE_TARGET.arch +# When using Qt 5, use QT_ARCH instead of QMAKE_TARGET. +# It also works for cross-builds. +isEqual(QT_MAJOR_VERSION, 5) { + MUMBLE_ARCH = $$QT_ARCH +} + +win32-g++ { + DEFINES *= MINGW_HAS_SECURE_API + + # Enable SSE + QMAKE_CFLAGS *= -msse -msse2 + QMAKE_CXXFLAGS *= -msse -msse2 + + CONFIG(symbols) { + # Configure build to be able to properly debug release builds + QMAKE_CFLAGS *= -g + QMAKE_CXXFLAGS *= -g + } +} -win32 { +win32-msvc* { # Define the CONFIG options 'force-x86-toolchain' and # 'force-x86_64-toolchain'. These can be used to force # the target of a .pro file to be built for a specific @@ -189,7 +208,7 @@ win32 { } } -unix { +unix|win32-g++ { DEFINES *= RESTRICT=__restrict__ QMAKE_CFLAGS *= -fvisibility=hidden QMAKE_CXXFLAGS *= -fvisibility=hidden diff --git a/qmake/openssl.pri b/qmake/openssl.pri index 5ca7c5c5538..71a5040406a 100644 --- a/qmake/openssl.pri +++ b/qmake/openssl.pri @@ -13,12 +13,16 @@ include(pkgconfig.pri) # This file can't include compiler.pri: it can # only be included once per .pro file. -win32 { +win32-msvc* { INCLUDEPATH *= "$$OPENSSL_PATH/include" QMAKE_LIBDIR *= "$$OPENSSL_PATH/lib" LIBS *= -lgdi32 -llibeay32 } +win32-g++ { + LIBS *= -lssl -lcrypto -lgdi32 +} + unix { contains(UNAME, FreeBSD) { LIBS *= -lcrypto -lssl diff --git a/scripts/travis-ci/before_install.bash b/scripts/travis-ci/before_install.bash index f3076677ff0..5df2bfe437d 100755 --- a/scripts/travis-ci/before_install.bash +++ b/scripts/travis-ci/before_install.bash @@ -5,14 +5,54 @@ # that can be found in the LICENSE file at the root of the # Mumble source tree or at . +MUMBLE_HOST_DEB=${MUMBLE_HOST/_/-} + if [ "${TRAVIS_OS_NAME}" == "linux" ]; then - if [ "${MUMBLE_QT}" == "qt4" ]; then + if [ "${MUMBLE_QT}" == "qt4" ] && [ "${MUMBLE_HOST}" == "x86_64-linux-gnu" ]; then sudo apt-get -qq update sudo apt-get build-dep -qq mumble - elif [ "${MUMBLE_QT}" == "qt5" ]; then + elif [ "${MUMBLE_QT}" == "qt5" ] && [ "${MUMBLE_HOST}" == "x86_64-linux-gnu" ]; then sudo apt-get -qq update sudo apt-get build-dep -qq mumble sudo apt-get install qt5-default qttools5-dev qttools5-dev-tools qtbase5-dev qtbase5-dev-tools qttranslations5-l10n libqt5svg5-dev + elif [ "${MUMBLE_QT}" == "qt5" ] && [ "${MUMBLE_HOST}" == "i686-w64-mingw32" ]; then + sudo dpkg --add-architecture i386 + sudo apt-get -qq update + echo "deb http://pkg.mxe.cc/repos/apt/debian jessie main" | sudo tee /etc/apt/sources.list.d/mxeapt.list + sudo apt-key adv --keyserver x-hkp://keys.gnupg.net --recv-keys D43A795B73B16ABE9643FE1AFD8FFF16DB45C6AB + sudo apt-get -qq update + sudo apt-get install \ + wine \ + mxe-${MUMBLE_HOST_DEB}.static-qtbase \ + mxe-${MUMBLE_HOST_DEB}.static-qtsvg \ + mxe-${MUMBLE_HOST_DEB}.static-qttools \ + mxe-${MUMBLE_HOST_DEB}.static-qttranslations \ + mxe-${MUMBLE_HOST_DEB}.static-boost \ + mxe-${MUMBLE_HOST_DEB}.static-protobuf \ + mxe-${MUMBLE_HOST_DEB}.static-sqlite \ + mxe-${MUMBLE_HOST_DEB}.static-flac \ + mxe-${MUMBLE_HOST_DEB}.static-ogg \ + mxe-${MUMBLE_HOST_DEB}.static-vorbis \ + mxe-${MUMBLE_HOST_DEB}.static-libsndfile + elif [ "${MUMBLE_QT}" == "qt5" ] && [ "${MUMBLE_HOST}" == "x86_64-w64-mingw32" ]; then + sudo dpkg --add-architecture i386 + sudo apt-get -qq update + echo "deb http://pkg.mxe.cc/repos/apt/debian jessie main" | sudo tee /etc/apt/sources.list.d/mxeapt.list + sudo apt-key adv --keyserver x-hkp://keys.gnupg.net --recv-keys D43A795B73B16ABE9643FE1AFD8FFF16DB45C6AB + sudo apt-get -qq update + sudo apt-get install \ + wine \ + mxe-${MUMBLE_HOST_DEB}.static-qtbase \ + mxe-${MUMBLE_HOST_DEB}.static-qtsvg \ + mxe-${MUMBLE_HOST_DEB}.static-qttools \ + mxe-${MUMBLE_HOST_DEB}.static-qttranslations \ + mxe-${MUMBLE_HOST_DEB}.static-boost \ + mxe-${MUMBLE_HOST_DEB}.static-protobuf \ + mxe-${MUMBLE_HOST_DEB}.static-sqlite \ + mxe-${MUMBLE_HOST_DEB}.static-flac \ + mxe-${MUMBLE_HOST_DEB}.static-ogg \ + mxe-${MUMBLE_HOST_DEB}.static-vorbis \ + mxe-${MUMBLE_HOST_DEB}.static-libsndfile else exit 1 fi diff --git a/scripts/travis-ci/script.bash b/scripts/travis-ci/script.bash index fcd3ce54de0..34fe4b6fb29 100755 --- a/scripts/travis-ci/script.bash +++ b/scripts/travis-ci/script.bash @@ -6,10 +6,28 @@ # Mumble source tree or at . if [ "${TRAVIS_OS_NAME}" == "linux" ]; then - if [ "${MUMBLE_QT}" == "qt4" ]; then + if [ "${MUMBLE_QT}" == "qt4" ] && [ "${MUMBLE_HOST}" == "x86_64-linux-gnu" ]; then qmake-qt4 CONFIG+="release tests g15-emulator qt4-legacy-compat" -recursive && make -j2 && make check - elif [ "${MUMBLE_QT}" == "qt5" ]; then + elif [ "${MUMBLE_QT}" == "qt5" ] && [ "${MUMBLE_HOST}" == "x86_64-linux-gnu" ]; then qmake CONFIG+="release tests g15-emulator" -recursive && make -j2 && make check + elif [ "${MUMBLE_QT}" == "qt5" ] && [ "${MUMBLE_HOST}" == "i686-w64-mingw32" ]; then + wget http://www.steinberg.net/sdk_downloads/asiosdk2.3.zip -P ../ + unzip ../asiosdk2.3.zip -d ../ + mv ../ASIOSDK2.3 3rdparty/asio + PATH=$PATH:/usr/lib/mxe/usr/bin + export MUMBLE_PROTOC=/usr/lib/mxe/usr/x86_64-unknown-linux-gnu/bin/protoc + ${MUMBLE_HOST}.static-qmake-qt5 -recursive -Wall CONFIG+="release tests warnings-as-errors winpaths_custom g15-emulator no-overlay no-bonjour no-elevation no-ice" + make -j2 + make check TESTRUNNER="wine" + elif [ "${MUMBLE_QT}" == "qt5" ] && [ "${MUMBLE_HOST}" == "x86_64-w64-mingw32" ]; then + wget http://www.steinberg.net/sdk_downloads/asiosdk2.3.zip -P ../ + unzip ../asiosdk2.3.zip -d ../ + mv ../ASIOSDK2.3 3rdparty/asio + PATH=$PATH:/usr/lib/mxe/usr/bin + export MUMBLE_PROTOC=/usr/lib/mxe/usr/x86_64-unknown-linux-gnu/bin/protoc + ${MUMBLE_HOST}.static-qmake-qt5 -recursive -Wall CONFIG+="release tests warnings-as-errors winpaths_custom g15-emulator no-overlay no-bonjour no-elevation no-ice" + make -j2 + make check TESTRUNNER="wine" else exit 1 fi diff --git a/src/Connection.cpp b/src/Connection.cpp index 2b864774e2d..3b67c2c2a1e 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -62,7 +62,7 @@ void Connection::setToS() { return; dwFlow = 0; - if (! QOSAddSocketToFlow(hQoS, qtsSocket->socketDescriptor(), NULL, QOSTrafficTypeAudioVideo, QOS_NON_ADAPTIVE_FLOW, &dwFlow)) + if (! QOSAddSocketToFlow(hQoS, qtsSocket->socketDescriptor(), NULL, QOSTrafficTypeAudioVideo, QOS_NON_ADAPTIVE_FLOW, reinterpret_cast(&dwFlow))) qWarning("Connection: Failed to add flow to QOS"); #elif defined(Q_OS_UNIX) int val = 0xa0; diff --git a/src/Timer.cpp b/src/Timer.cpp index b80c1e9f418..33d75ae2297 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -18,7 +18,7 @@ // https://github.com/boostorg/system/blob/boost-1.56.0/include/boost/system/error_code.hpp#L514-L516 // vs. // https://github.com/boostorg/system/blob/boost-1.55.0/include/boost/system/error_code.hpp#L515-L517 -#if BOOST_VERSION >= 105600 +#if BOOST_VERSION >= 105600 && !defined(__MINGW32__) # define USE_BOOST_CHRONO #endif diff --git a/src/mumble.pri b/src/mumble.pri index e9e1206bcf4..e12f263ec32 100644 --- a/src/mumble.pri +++ b/src/mumble.pri @@ -36,7 +36,7 @@ CONFIG(packaged) { # Add OpenSSL dependency include(../qmake/openssl.pri) -win32 { +win32-msvc* { INCLUDEPATH *= "$$PROTOBUF_PATH/vsprojects/include" "$$PROTOBUF_PATH/src" protobuf CONFIG(debug, debug|release) { QMAKE_LIBDIR *= "$$PROTOBUF_PATH/vsprojects/Debug" @@ -48,6 +48,11 @@ win32 { LIBS *= -ldelayimp -lQwave -delayload:Qwave.DLL } +win32-g++ { + LIBS *= -lprotobuf -lcrypt32 -lws2_32 + LIBS *= -ldelayimp -lqwave -delayload:qwave.dll +} + unix { CONFIG(static) { PKG_CONFIG = pkg-config --static diff --git a/src/mumble/CrashReporter.cpp b/src/mumble/CrashReporter.cpp index 92825a7ce83..83782ca5e2b 100644 --- a/src/mumble/CrashReporter.cpp +++ b/src/mumble/CrashReporter.cpp @@ -10,6 +10,7 @@ #include "Global.h" #include "NetworkConfig.h" #include "OSInfo.h" +#include "EnvUtils.h" CrashReporter::CrashReporter(QWidget *p) : QDialog(p) { setWindowTitle(tr("Mumble Crash Report")); @@ -146,11 +147,10 @@ void CrashReporter::run() { qsl << qtf.fileName(); QString app = QLatin1String("dxdiag.exe"); - wchar_t *sr = NULL; - size_t srsize = 0; - if (_wdupenv_s(&sr, &srsize, L"SystemRoot") == 0) { - app = QDir::fromNativeSeparators(QString::fromWCharArray(sr)) + QLatin1String("/System32/dxdiag.exe"); - free(sr); + QString systemRoot = EnvUtils::getenv(QLatin1String("SystemRoot")); + + if (systemRoot.count() > 0) { + app = QDir::fromNativeSeparators(systemRoot + QLatin1String("/System32/dxdiag.exe")); } qp.start(app, qsl); diff --git a/src/mumble/DirectSound.cpp b/src/mumble/DirectSound.cpp index 4e53b0ab8cd..f30df816255 100644 --- a/src/mumble/DirectSound.cpp +++ b/src/mumble/DirectSound.cpp @@ -201,7 +201,7 @@ void DXAudioOutput::run() { LPDIRECTSOUND8 pDS = NULL; LPDIRECTSOUNDBUFFER pDSBPrimary = NULL; LPDIRECTSOUNDBUFFER pDSBOutput = NULL; - LPDIRECTSOUNDNOTIFY8 pDSNotify = NULL; + LPDIRECTSOUNDNOTIFY pDSNotify = NULL; int iLastwriteblock; LPVOID aptr1, aptr2; @@ -457,7 +457,7 @@ DXAudioInput::~DXAudioInput() { void DXAudioInput::run() { LPDIRECTSOUNDCAPTURE8 pDSCapture; LPDIRECTSOUNDCAPTUREBUFFER pDSCaptureBuffer; - LPDIRECTSOUNDNOTIFY8 pDSNotify; + LPDIRECTSOUNDNOTIFY pDSNotify; DWORD dwBufferSize; bool bOk; diff --git a/src/mumble/DirectSound.h b/src/mumble/DirectSound.h index e952158318d..abf058d19dd 100644 --- a/src/mumble/DirectSound.h +++ b/src/mumble/DirectSound.h @@ -10,6 +10,7 @@ #include "AudioOutput.h" #define DIRECTSOUND_VERSION 0x1000 +#include #include #include #include diff --git a/src/mumble/EnvUtils.cpp b/src/mumble/EnvUtils.cpp new file mode 100644 index 00000000000..a3194a64a7f --- /dev/null +++ b/src/mumble/EnvUtils.cpp @@ -0,0 +1,40 @@ +// Copyright 2005-2017 The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at . + +#include "EnvUtils.h" + +#include + +QString EnvUtils::getenv(QString name) { +#ifdef Q_OS_WIN + QByteArray buf; + size_t requiredSize = 0; + + static_assert(sizeof(wchar_t) == sizeof(ushort), "expected 2-byte wchar_t"); + + const wchar_t *wname = reinterpret_cast(name.utf16()); + + // Query the required buffer size (in elements). + _wgetenv_s(&requiredSize, 0, 0, wname); + if (requiredSize == 0) { + return QString(); + } + + // Resize buf to fit the value and put it there. + buf.resize(static_cast(requiredSize * sizeof(wchar_t))); + _wgetenv_s(&requiredSize, reinterpret_cast(buf.data()), requiredSize, wname); + + // Convert the value to QString and return it. + const wchar_t *wbuf = reinterpret_cast(buf.constData()); + return QString::fromWCharArray(wbuf); +#else + QByteArray nameU8 = name.toUtf8(); + char *val = ::getenv(nameU8.constData()); + if (val == NULL) { + return QString(); + } + return QString::fromUtf8(val); +#endif +} diff --git a/src/mumble/EnvUtils.h b/src/mumble/EnvUtils.h new file mode 100644 index 00000000000..2ee45e2beaf --- /dev/null +++ b/src/mumble/EnvUtils.h @@ -0,0 +1,23 @@ +// Copyright 2005-2017 The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at . + +#ifndef MUMBLE_MUMBLE_ENVUTILS_H_ +#define MUMBLE_MUMBLE_ENVUTILS_H_ + +#include + +class EnvUtils { +public: + // getEnvVariable is a wrapper around _wgetenv_s (on Windows) + // and getenv (on everything else). + // + // On Windows, it expects a Unicode environment -- so variables + // are expected to be UTF16. + // On everything else, it expects the environment variables to be + // UTF-8 encoded. + static QString getenv(QString name); +}; + +#endif diff --git a/src/mumble/MumbleApplication.cpp b/src/mumble/MumbleApplication.cpp index 6247aace037..f4366d49c59 100644 --- a/src/mumble/MumbleApplication.cpp +++ b/src/mumble/MumbleApplication.cpp @@ -10,45 +10,7 @@ #include "MainWindow.h" #include "GlobalShortcut.h" #include "Global.h" - -// getenvQString is a wrapper around _wgetenv_s (on Windows) -// and getenv (on everything else). -// -// On Windows, it expects a Unicode environment -- so variables -// are expected to be UTF16. -// On everthing else, it expects the environment variables to be -// UTF-8 encoded. -static QString getenvQString(QString name) { -#ifdef Q_OS_WIN - QByteArray buf; - size_t requiredSize = 0; - - static_assert(sizeof(wchar_t) == sizeof(ushort), "expected 2-byte wchar_t"); - - const wchar_t *wname = reinterpret_cast(name.utf16()); - - // Query the required buffer size (in elements). - _wgetenv_s(&requiredSize, 0, 0, wname); - if (requiredSize == 0) { - return QString(); - } - - // Resize buf to fit the value and put it there. - buf.resize(static_cast(requiredSize * sizeof(wchar_t))); - _wgetenv_s(&requiredSize, reinterpret_cast(buf.data()), requiredSize, wname); - - // Convert the value to QString and return it. - const wchar_t *wbuf = reinterpret_cast(buf.constData()); - return QString::fromWCharArray(wbuf); -#else - QByteArray nameU8 = name.toUtf8(); - char *val = ::getenv(nameU8.constData()); - if (val == NULL) { - return QString(); - } - return QString::fromUtf8(val); -#endif -} +#include "EnvUtils.h" MumbleApplication *MumbleApplication::instance() { return static_cast(QCoreApplication::instance()); @@ -64,7 +26,7 @@ MumbleApplication::MumbleApplication(int &pargc, char **pargv) } QString MumbleApplication::applicationVersionRootPath() { - QString versionRoot = getenvQString(QLatin1String("MUMBLE_VERSION_ROOT")); + QString versionRoot = EnvUtils::getenv(QLatin1String("MUMBLE_VERSION_ROOT")); if (versionRoot.count() > 0) { return versionRoot; } diff --git a/src/mumble/ServerHandler.cpp b/src/mumble/ServerHandler.cpp index a012948c354..4c0e0f8ace2 100644 --- a/src/mumble/ServerHandler.cpp +++ b/src/mumble/ServerHandler.cpp @@ -35,6 +35,8 @@ static HANDLE loadQoS() { HRESULT hr = E_FAIL; +// We don't support delay-loading QoS on MinGW. Only enable it for MSVC. +#ifdef _MSC_VER __try { hr = __HrLoadAllImportsForDll("qwave.dll"); } @@ -42,6 +44,7 @@ static HANDLE loadQoS() { __except(EXCEPTION_EXECUTE_HANDLER) { hr = E_FAIL; } +#endif if (! SUCCEEDED(hr)) { qWarning("ServerHandler: Failed to load qWave.dll, no QoS available"); @@ -645,7 +648,7 @@ void ServerHandler::serverConnectionConnected() { addr.sin_addr.s_addr = htonl(qhaRemote.toIPv4Address()); dwFlowUDP = 0; - if (! QOSAddSocketToFlow(hQoS, qusUdp->socketDescriptor(), reinterpret_cast(&addr), QOSTrafficTypeVoice, QOS_NON_ADAPTIVE_FLOW, &dwFlowUDP)) + if (! QOSAddSocketToFlow(hQoS, qusUdp->socketDescriptor(), reinterpret_cast(&addr), QOSTrafficTypeVoice, QOS_NON_ADAPTIVE_FLOW, reinterpret_cast(&dwFlowUDP))) qWarning("ServerHandler: Failed to add UDP to QOS"); } #endif diff --git a/src/mumble/WASAPI.cpp b/src/mumble/WASAPI.cpp index cbaa0ed083b..57d02fe092d 100644 --- a/src/mumble/WASAPI.cpp +++ b/src/mumble/WASAPI.cpp @@ -13,11 +13,13 @@ // Now that Win7 is published, which includes public versions of these // interfaces, we simply inherit from those but use the "old" IIDs. +DEFINE_GUID(IID_IVistaAudioSessionControl2, 0x33969B1DL, 0xD06F, 0x4281, 0xB8, 0x37, 0x7E, 0xAA, 0xFD, 0x21, 0xA9, 0xC0); MIDL_INTERFACE("33969B1D-D06F-4281-B837-7EAAFD21A9C0") IVistaAudioSessionControl2 : public IAudioSessionControl2 { }; +DEFINE_GUID(IID_IAudioSessionQuery, 0x94BE9D30L, 0x53AC, 0x4802, 0x82, 0x9C, 0xF1, 0x3E, 0x5A, 0xD3, 0x47, 0x75); MIDL_INTERFACE("94BE9D30-53AC-4802-829C-F13E5AD34775") IAudioSessionQuery : public IUnknown { @@ -677,7 +679,7 @@ void WASAPIOutput::setVolumes(IMMDevice *pDevice, bool talking) { IAudioSessionEnumerator *pEnumerator = NULL; IAudioSessionQuery *pMysticQuery = NULL; if (! bIsWin7) { - if (SUCCEEDED(hr = pAudioSessionManager->QueryInterface(__uuidof(IAudioSessionQuery), (void **) &pMysticQuery))) { + if (SUCCEEDED(hr = pAudioSessionManager->QueryInterface(IID_IAudioSessionQuery, (void **) &pMysticQuery))) { hr = pMysticQuery->GetQueryInterface(&pEnumerator); } } else { @@ -757,7 +759,7 @@ bool WASAPIOutput::setVolumeForSessionControl(IAudioSessionControl *control, con HRESULT hr; IAudioSessionControl2 *pControl2 = NULL; - if (!SUCCEEDED(hr = control->QueryInterface(bIsWin7 ? __uuidof(IAudioSessionControl2) : __uuidof(IVistaAudioSessionControl2), (void **) &pControl2))) + if (!SUCCEEDED(hr = control->QueryInterface(bIsWin7 ? __uuidof(IAudioSessionControl2) : IID_IVistaAudioSessionControl2, (void **) &pControl2))) return false; bool result = setVolumeForSessionControl2(pControl2, mumblePID, seen); @@ -831,6 +833,7 @@ void WASAPIOutput::run() { bool lastspoke = false; REFERENCE_TIME bufferDuration = (g.s.iOutputDelay > 1) ? (g.s.iOutputDelay + 1) * 100000 : 0; bool exclusive = false; + bool mixed = false; CoInitialize(NULL); @@ -997,7 +1000,6 @@ void WASAPIOutput::run() { iChannels = pwfx->nChannels; initializeMixer(chanmasks); - bool mixed = false; numFramesAvailable = 0; while (bRunning && ! FAILED(hr)) { diff --git a/src/mumble/WASAPI.h b/src/mumble/WASAPI.h index 6466752983b..8218efa8342 100644 --- a/src/mumble/WASAPI.h +++ b/src/mumble/WASAPI.h @@ -17,9 +17,11 @@ #include #include #include +#ifdef _INC_FUNCTIONDISCOVERYKEYS +# undef _INC_FUNCTIONDISCOVERYKEYS +#endif #include #include -#include #include #include "AudioInput.h" diff --git a/src/mumble/WASAPINotificationClient.cpp b/src/mumble/WASAPINotificationClient.cpp index da3adf0aa50..a65d015c4a4 100644 --- a/src/mumble/WASAPINotificationClient.cpp +++ b/src/mumble/WASAPINotificationClient.cpp @@ -8,7 +8,6 @@ #include "Global.h" #include "MainWindow.h" -#include #include "WASAPINotificationClient.h" #include diff --git a/src/mumble/WinGUIDs.cpp b/src/mumble/WinGUIDs.cpp new file mode 100644 index 00000000000..47eb2f9a278 --- /dev/null +++ b/src/mumble/WinGUIDs.cpp @@ -0,0 +1,24 @@ +// Copyright 2005-2017 The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _INC_FUNCTIONDISCOVERYKEYS +# undef _INC_FUNCTIONDISCOVERYKEYS +#endif +#include +#include +#include + +DEFINE_GUID(IID_IVistaAudioSessionControl2, 0x33969B1DL, 0xD06F, 0x4281, 0xB8, 0x37, 0x7E, 0xAA, 0xFD, 0x21, 0xA9, 0xC0); +DEFINE_GUID(IID_IAudioSessionQuery, 0x94BE9D30L, 0x53AC, 0x4802, 0x82, 0x9C, 0xF1, 0x3E, 0x5A, 0xD3, 0x47, 0x75); diff --git a/src/mumble/mumble.pro b/src/mumble/mumble.pro index 74b10f37ca4..af806f7c481 100644 --- a/src/mumble/mumble.pro +++ b/src/mumble/mumble.pro @@ -138,7 +138,8 @@ HEADERS *= BanEditor.h \ Themes.h \ OverlayPositionableItem.h \ widgets/MUComboBox.h \ - DeveloperConsole.h + DeveloperConsole.h \ + EnvUtils.h SOURCES *= BanEditor.cpp \ ACLEditor.cpp \ @@ -204,7 +205,8 @@ SOURCES *= BanEditor.cpp \ Themes.cpp \ OverlayPositionableItem.cpp \ widgets/MUComboBox.cpp \ - DeveloperConsole.cpp + DeveloperConsole.cpp \ + EnvUtils.cpp CONFIG(qtspeech) { SOURCES *= TextToSpeech.cpp @@ -370,14 +372,19 @@ win32 { RC_FILE = mumble.rc } HEADERS *= GlobalShortcut_win.h Overlay_win.h TaskList.h UserLockFile.h - SOURCES *= GlobalShortcut_win.cpp Overlay_win.cpp SharedMemory_win.cpp Log_win.cpp os_win.cpp TaskList.cpp ../../overlay/ods.cpp UserLockFile_win.cpp + SOURCES *= GlobalShortcut_win.cpp Overlay_win.cpp SharedMemory_win.cpp Log_win.cpp os_win.cpp TaskList.cpp WinGUIDs.cpp ../../overlay/ods.cpp UserLockFile_win.cpp !CONFIG(qtspeech) { SOURCES *= TextToSpeech_win.cpp } LIBS *= -ldxguid -ldinput8 -lsapi -lole32 -lws2_32 -ladvapi32 -lwintrust -ldbghelp -lshell32 -lshlwapi -luser32 -lgdi32 -lpsapi - LIBS *= -logg -lvorbis -lvorbisfile -lFLAC -lsndfile + win32-g++ { + LIBS *= -lsndfile -lvorbis -lvorbisfile -lvorbisenc -logg -lFLAC + } + win32-msvc* { + LIBS *= -lsndfile -lvorbis -lvorbisfile -logg -lFLAC + } LIBS *= -ldelayimp -delayload:shell32.dll DEFINES *= WIN32 @@ -419,7 +426,9 @@ win32 { QMAKE_LFLAGS *= /MANIFESTUAC:\"level=\'asInvoker\' uiAccess=\'true\'\" } } - QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest mumble.appcompat.manifest) + win32-msvc* { + QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest mumble.appcompat.manifest) + } } } @@ -609,13 +618,19 @@ directsound { HEADERS *= DirectSound.h SOURCES *= DirectSound.cpp LIBS *= -ldsound + win32-g++ { + LIBS *= -lksuser + } } wasapi { DEFINES *= USE_WASAPI HEADERS *= WASAPI.h WASAPINotificationClient.h SOURCES *= WASAPI.cpp WASAPINotificationClient.cpp - LIBS *= -lAVRT -delayload:AVRT.DLL + LIBS *= -lavrt -delayload:avrt.DLL + win32-g++ { + LIBS *= -lboost_system-mt + } } g15 { diff --git a/src/mumble/mumble_pch.hpp b/src/mumble/mumble_pch.hpp index 80202db907f..ba87eab3b0d 100644 --- a/src/mumble/mumble_pch.hpp +++ b/src/mumble/mumble_pch.hpp @@ -26,6 +26,16 @@ #undef TYPE_BOOL #endif +#ifdef __MINGW32__ +// Our MinGW build targets Windows 7 for now. +// Set up the appropriate Windows macros such that +// MinGW's Windows headers expose all the functionality +// we need. +#define _WIN32_WINNT 0x0601 +#define NTDDI_VERSION NTDDI_WIN7 +#include +#endif + #include #include #if QT_VERSION >= 0x050000 @@ -74,6 +84,8 @@ #include #ifdef Q_OS_WIN +#include "../qos2_mingw.h" + #include #include #include diff --git a/src/mumble/os_win.cpp b/src/mumble/os_win.cpp index efea65d1641..62aab502c93 100644 --- a/src/mumble/os_win.cpp +++ b/src/mumble/os_win.cpp @@ -10,6 +10,10 @@ #include #include #include +#include +#include +#include +#include // For share flags for _wfsopen #include "Global.h" #include "Version.h" @@ -152,6 +156,8 @@ BOOL SetHeapOptions() { return fRet; } +// We only support delay-loading on MSVC, not on MinGW. +#ifdef _MSC_VER FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) { if (dliNotify != dliNotePreLoadLibrary) return 0; @@ -203,6 +209,7 @@ FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) { } decltype(__pfnDliNotifyHook2) __pfnDliNotifyHook2 = delayHook; +#endif void os_init() { __cpuid(cpuinfo, 1); diff --git a/src/mumble_exe/mumble_exe.pro b/src/mumble_exe/mumble_exe.pro index 2135f6adeb0..5e121e7f8a8 100644 --- a/src/mumble_exe/mumble_exe.pro +++ b/src/mumble_exe/mumble_exe.pro @@ -15,13 +15,20 @@ win32 { RC_FILE = ../mumble/mumble.rc LIBS *= -luser32 -lshlwapi - CONFIG(release, debug|release) { - QMAKE_CXXFLAGS_RELEASE -= -MD - QMAKE_CXXFLAGS += -MT + win32-g++ { + QMAKE_LFLAGS *= -municode + DEFINES *= _UNICODE } - CONFIG(debug, debug|release) { - QMAKE_CXXFLAGS_DEBUG -= -MDd - QMAKE_CXXFLAGS += -MTd + + win32-msvc* { + CONFIG(release, debug|release) { + QMAKE_CXXFLAGS_RELEASE -= -MD + QMAKE_CXXFLAGS += -MT + } + CONFIG(debug, debug|release) { + QMAKE_CXXFLAGS_DEBUG -= -MDd + QMAKE_CXXFLAGS += -MTd + } } } @@ -33,7 +40,9 @@ SOURCES *= mumble_exe.cpp Overlay.cpp } } -QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../mumble/mumble.appcompat.manifest) +win32-msvc* { + QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../mumble/mumble.appcompat.manifest) +} CONFIG(debug, debug|release) { CONFIG += console diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp index 2e2cca708c6..7e15286cb95 100644 --- a/src/murmur/Server.cpp +++ b/src/murmur/Server.cpp @@ -909,7 +909,7 @@ void Server::sendMessage(ServerUser *u, const char *data, int len, QByteArray &c #ifdef Q_OS_WIN DWORD dwFlow = 0; if (Meta::hQoS) - QOSAddSocketToFlow(Meta::hQoS, u->sUdpSocket, reinterpret_cast(& u->saiUdpAddress), QOSTrafficTypeVoice, QOS_NON_ADAPTIVE_FLOW, &dwFlow); + QOSAddSocketToFlow(Meta::hQoS, u->sUdpSocket, reinterpret_cast(& u->saiUdpAddress), QOSTrafficTypeVoice, QOS_NON_ADAPTIVE_FLOW, reinterpret_cast(&dwFlow)); #endif #ifdef Q_OS_LINUX struct msghdr msg; diff --git a/src/murmur/murmur.pro b/src/murmur/murmur.pro index 96c37f1d66f..234f675c477 100644 --- a/src/murmur/murmur.pro +++ b/src/murmur/murmur.pro @@ -45,7 +45,9 @@ win32 { SOURCES *= Tray.cpp About.cpp HEADERS *= Tray.h About.h LIBS *= -luser32 - QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../mumble/mumble.appcompat.manifest) + win32-msvc* { + QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote(mt.exe -nologo -updateresource:$(DESTDIR_TARGET);1 -manifest ../mumble/mumble.appcompat.manifest) + } } unix { diff --git a/src/murmur/murmur_pch.h b/src/murmur/murmur_pch.h index 7df14cf5598..3b3e576a8c2 100644 --- a/src/murmur/murmur_pch.h +++ b/src/murmur/murmur_pch.h @@ -18,6 +18,12 @@ #undef TYPE_BOOL #endif +#ifdef __MINGW32__ +#define _WIN32_WINNT 0x0600 +#include +#include +#endif + #include #include #include @@ -34,6 +40,9 @@ # include "Qt4Compat.h" # include #endif + +#include "../qos2_mingw.h" + #include #include #include diff --git a/src/qos2_mingw.h b/src/qos2_mingw.h new file mode 100644 index 00000000000..94764feb626 --- /dev/null +++ b/src/qos2_mingw.h @@ -0,0 +1,19 @@ +// Copyright 2005-2017 The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at . + +// This is a collection of fixes for MinGW's header. +// MinGW's header does not provide everything we need, +// so define QOS_FLOWID (and PQOS_FLOWID) as well as QOS_NON_ADAPTIVE_FLOW ourselves +// to allow us to build with QoS support on MinGW. + +#ifndef MUMBLE_QOS2_MINGW_H_ +#define MUMBLE_QOS2_MINGW_H_ + +#ifdef __MINGW32__ + typedef UINT32 QOS_FLOWID, *PQOS_FLOWID; + #define QOS_NON_ADAPTIVE_FLOW 0x00000002 // MinGW's qos2.h header doesn't define QOS_NON_ADAPTIVE_FLOW, so we define it ourselves for MinGW to use. +#endif + +#endif