From 9923ec93d0e1472a100967f4d9383532499e4290 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Sat, 16 Jul 2016 00:40:38 +0200 Subject: g15helper: add Qt-based G15 emulator, for debugging. --- .gitignore | 1 + INSTALL | 6 ++ g15helper/g15helper.pro | 108 +++++++++++++++++++++++------------- g15helper/g15helper_emu.cpp | 132 ++++++++++++++++++++++++++++++++++++++++++++ g15helper/g15helper_emu.h | 35 ++++++++++++ 5 files changed, 243 insertions(+), 39 deletions(-) create mode 100644 g15helper/g15helper_emu.cpp create mode 100644 g15helper/g15helper_emu.h diff --git a/.gitignore b/.gitignore index 4092fd646..efc5b5645 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ src/mumble/mumble_plugin_import.cpp src/mumble/mumble_app_plugin_import.cpp src/murmur/murmurd_plugin_import.cpp src/murmur/murmur_plugin_import.cpp +g15helper/mumble-g15-helper_plugin_import.cpp doxygen/ .qmake.cache .qmake.stash diff --git a/INSTALL b/INSTALL index 4b17764df..1d59a4c30 100644 --- a/INSTALL +++ b/INSTALL @@ -179,3 +179,9 @@ CONFIG+=no-qssldiffiehellmanparameters CONFIG+=no-xboxinput (Mumble, Win32) Don't build in support for global shortcuts from Xbox controllers via the XInput DLL. + +CONFIG+=g15-emulator (Mumble, Win32) + Build the g15helper executable in emulator + mode. This will cause an emulated G15 window + to appear on screen. Allows the use of Mumble's + G15 support without owning the physical hardware. diff --git a/g15helper/g15helper.pro b/g15helper/g15helper.pro index 68a3b9253..322e4b630 100644 --- a/g15helper/g15helper.pro +++ b/g15helper/g15helper.pro @@ -5,58 +5,88 @@ # Build rules for G15 helper daemon -CONFIG += force-x86-toolchain +win32:!CONFIG(g15-emulator) { + CONFIG += force-x86-toolchain +} include (../compiler.pri) TEMPLATE = app -CONFIG -= qt CONFIG *= debug_and_release warn_on TARGET = mumble-g15-helper HEADERS = g15helper.h -win32 { - SOURCES = g15helper.c - RC_FILE = g15helper.rc - LIBS *= -llgLcd -ladvapi32 -lshell32 -luser32 - 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) - - CONFIG(release, debug|release) { - QMAKE_CFLAGS_RELEASE -= -MD - QMAKE_CFLAGS_RELEASE *= -MT - QMAKE_CXXFLAGS_RELEASE -= -MD - QMAKE_CXXFLAGS_RELEASE *= -MT +# The g15helper utility can be built in two modes: +# +# - Native. This is what will be built if you're +# on Windows or macOS by default. +# +# - Emulator. This can be enabled by using the +# CONFIG(g15-emulator) when invoking qmake. +# Instead of building a g15helper that talks +# to the G15 LCD using the Logitech provided +# library, we build a small program that +# emulates the LCD display in an on-screen +# window. This is useful for debugging +# Mumble's LCD/G15 support. +CONFIG(g15-emulator) { + QT *= core gui + isEqual(QT_MAJOR_VERSION, 5) { + QT *= widgets } - CONFIG(debug, debug|release) { - QMAKE_CFLAGS_DEBUG -= -MDd - QMAKE_CFLAGS_DEBUG *= -MTd - QMAKE_CXXFLAGS_DEBUG -= -MDd - QMAKE_CXXFLAGS_DEBUG *= -MTd + + SOURCES *= g15helper_emu.cpp + HEADERS *= g15helper_emu.h + + 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) } +} else { + CONFIG -= qt -} + win32 { + SOURCES = g15helper.c + RC_FILE = g15helper.rc + LIBS *= -llgLcd -ladvapi32 -lshell32 -luser32 + 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) -macx { - CONFIG -= app_bundle - isEqual(QT_MAJOR_VERSION, 5) { - QMAKE_CFLAGS += -arch i386 - QMAKE_OBJECTIVE_CFLAGS += -arch i386 - QMAKE_CXXFLAGS += -arch i386 - QMAKE_LFLAGS += -arch i386 - } else { - CONFIG -= x86_64 - CONFIG += x86 + CONFIG(release, debug|release) { + QMAKE_CFLAGS_RELEASE -= -MD + QMAKE_CFLAGS_RELEASE *= -MT + QMAKE_CXXFLAGS_RELEASE -= -MD + QMAKE_CXXFLAGS_RELEASE *= -MT + } + CONFIG(debug, debug|release) { + QMAKE_CFLAGS_DEBUG -= -MDd + QMAKE_CFLAGS_DEBUG *= -MTd + QMAKE_CXXFLAGS_DEBUG -= -MDd + QMAKE_CXXFLAGS_DEBUG *= -MTd + } + } + + macx { + CONFIG -= app_bundle + isEqual(QT_MAJOR_VERSION, 5) { + QMAKE_CFLAGS += -arch i386 + QMAKE_OBJECTIVE_CFLAGS += -arch i386 + QMAKE_CXXFLAGS += -arch i386 + QMAKE_LFLAGS += -arch i386 + } else { + CONFIG -= x86_64 + CONFIG += x86 + } + SOURCES = g15helper_macx.c + LIBS *= -llgLcd + QMAKE_LIBDIR *= $$(MUMBLE_PREFIX)/../LCDSDK/lib/ + INCLUDEPATH *= $$(MUMBLE_PREFIX)/../LCDSDK/Src/ + QMAKE_LFLAGS += -framework CoreFoundation -sectcreate __TEXT __info_plist g15helper.plist + DEFINES *= APPLE + DIST = g15helper.plist } - SOURCES = g15helper_macx.c - LIBS *= -llgLcd - QMAKE_LIBDIR *= $$(MUMBLE_PREFIX)/../LCDSDK/lib/ - INCLUDEPATH *= $$(MUMBLE_PREFIX)/../LCDSDK/Src/ - QMAKE_LFLAGS += -framework CoreFoundation -sectcreate __TEXT __info_plist g15helper.plist - DEFINES *= APPLE - DIST = g15helper.plist } CONFIG(release, debug|release) { diff --git a/g15helper/g15helper_emu.cpp b/g15helper/g15helper_emu.cpp new file mode 100644 index 000000000..381fe65f3 --- /dev/null +++ b/g15helper/g15helper_emu.cpp @@ -0,0 +1,132 @@ +// Copyright 2005-2016 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 . + +/* + * G15 Helper Emulator + */ + +#include +#include + +#include + +#include "g15helper.h" +#include "g15helper_emu.h" + +#if defined(Q_OS_WIN) +# include +# include +#endif + +G15Reader::G15Reader() + : QThread() { + + moveToThread(this); + + m_isRunning = true; +} + +G15Reader::~G15Reader() { + m_isRunning = false; +} + +void G15Reader::run() { +#if defined(Q_OS_WIN) + _setmode(_fileno(stdin), O_BINARY); +#endif + + quint8 buf[G15_MAX_FBMEM]; + + QImage img(QSize(G15_MAX_WIDTH, G15_MAX_HEIGHT), QImage::Format_RGB32); + + while (m_isRunning) { + quint8 priority = 0; + size_t nread = 0; + size_t ntotal = 0; + + memset(&buf, 0, G15_MAX_FBMEM); + + nread = fread(&priority, 1, sizeof(priority), stdin); + if (nread <= 0) { + qFatal("g15helper_emu: unable to read stdin, retval %lli", + static_cast(nread)); + } + + // The priority flag is not used by the emulator. + Q_UNUSED(priority); + + do { + nread = fread(&buf[0] + ntotal, 1, G15_MAX_FBMEM - ntotal, stdin); + if (nread <= 0) { + qFatal("g15helper_emu: unable to read stdin, retval %lli", + static_cast(nread)); + } + ntotal += nread; + } while (ntotal < G15_MAX_FBMEM); + + for (int w = 0; w < G15_MAX_WIDTH; w++) { + for (int h = 0; h < G15_MAX_HEIGHT; h++) { + quint8 color = buf[G15_MAX_WIDTH * h + w]; + uint val = 0xff000000; + if (color == 0xff) { + val = 0xffffffff; + } + img.setPixel(w, h, val); + } + } + + QPixmap p = QPixmap::fromImage(img); + + emit readFrame(p); + } +} + +G15Emulator::G15Emulator() + : QMainWindow() { + + setWindowTitle(QLatin1String("Mumble G15 Emulator")); + setStyleSheet("QMainWindow {background: #cacaca;}"); + + m_displayLabel = new QLabel(this); + m_displayLabel->setMinimumSize(QSize(G15_MAX_WIDTH, G15_MAX_HEIGHT)); + setCentralWidget(m_displayLabel); +} + +void G15Emulator::drawFrame(QPixmap p) { + m_displayLabel->setPixmap(p); +} + +int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + Q_UNUSED(hInstance); + Q_UNUSED(hPrevInstance); + Q_UNUSED(nCmdShow); + + if (lpCmdLine && (strcmp(lpCmdLine, "/detect") == 0)) { + return 0; + } else if (! lpCmdLine || (strcmp(lpCmdLine, "/mumble") != 0)) { + MessageBox(NULL, L"This program is run by Mumble, and should not be started separately.", L"Nothing to see here, move along", MB_OK | MB_ICONERROR); + return 0; + } + + char *argvec[1]; + argvec[0] = NULL; + + int argc = 0; + char **argv = &argvec[0]; + + QApplication app(argc, argv); + + G15Reader reader; + G15Emulator emu; + + QObject::connect(&reader, SIGNAL(readFrame(QPixmap)), &emu, SLOT(drawFrame(QPixmap))); + + reader.start(); + emu.show(); + + app.exec(); + + return 0; +} diff --git a/g15helper/g15helper_emu.h b/g15helper/g15helper_emu.h new file mode 100644 index 000000000..cd87f9a1e --- /dev/null +++ b/g15helper/g15helper_emu.h @@ -0,0 +1,35 @@ +// Copyright 2005-2016 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_G15_HELPER_EMU_H_ +#define MUMBLE_G15_HELPER_EMU_H_ + +#include +#include +#include +#include + +class G15Reader : public QThread { + Q_OBJECT +public: + G15Reader(); + ~G15Reader(); + void run() Q_DECL_OVERRIDE; + + bool m_isRunning; +signals: + void readFrame(QPixmap p); +}; + +class G15Emulator : public QMainWindow { + Q_OBJECT +public: + QLabel *m_displayLabel; + G15Emulator(); +public slots: + void drawFrame(QPixmap p); +}; + +#endif -- cgit v1.2.3