// Copyright 2005-2020 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 Daemon for Win32. */ #include #include #include #include #include #include "g15helper.h" #include "lglcd.h" static void __cdecl ods(const char *fmt, va_list args) { char buffer[2048]; _vsnprintf_s(buffer, 2048, _TRUNCATE, fmt, args); OutputDebugStringA(buffer); } static void __cdecl warn(const char *fmt, ...) { va_list args; va_start(args, fmt); ods(fmt, args); va_end(args); } static void __cdecl die(int err, const char *fmt, ...) { va_list args; va_start(args, fmt); ods(fmt, args); va_end(args); exit(err); } int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DWORD dwErr; BOOL bErr; BOOL bDetect = FALSE; HANDLE hStdin, hStdout; lgLcdConnectContextEx conn; lgLcdOpenByTypeContext ctx; lgLcdBitmap160x43x1 bitmap; warn("Args: %s", lpCmdLine); if (lpCmdLine && (strcmp(lpCmdLine, "/detect") == 0)) { warn("Detect mode!"); bDetect = TRUE; } 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; } hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) die(G15_ERR_INIT, "Failed to get standard input"); hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdout == INVALID_HANDLE_VALUE) die(G15_ERR_INIT, "Failed to get standard output"); /* * Clear and set up initial structures. */ ZeroMemory(&conn, sizeof(conn)); ZeroMemory(&ctx, sizeof(ctx)); ZeroMemory(&bitmap, sizeof(bitmap)); conn.appFriendlyName = G15_WIDGET_NAME; conn.isAutostartable = FALSE; conn.isPersistent = FALSE; conn.dwAppletCapabilitiesSupported =LGLCD_APPLET_CAP_BASIC | LGLCD_APPLET_CAP_BW; conn.connection = LGLCD_INVALID_CONNECTION; /* * Initialize and connect. */ dwErr = lgLcdInit(); if (dwErr != ERROR_SUCCESS) die(G15_ERR_INIT, "Unable to initialize Logitech LCD library. (Error: %i)", dwErr); dwErr = lgLcdConnectEx(&conn); if (dwErr != ERROR_SUCCESS) die(G15_ERR_CONNECT, "Unable to connect to Logitech LCD manager. (Error: %i)", dwErr); ctx.connection = conn.connection; ctx.device = LGLCD_INVALID_DEVICE; ctx.deviceType =LGLCD_DEVICE_BW; dwErr = lgLcdOpenByType(&ctx); warn("That returned %d %d", dwErr, ERROR_SUCCESS); if (bDetect) return (dwErr != ERROR_SUCCESS); else if (dwErr != ERROR_SUCCESS) die(G15_ERR_OPEN, "Unable to open device. (Error: %i)", dwErr); /* * Diplay buffer format. */ bitmap.hdr.Format = LGLCD_BMP_FORMAT_160x43x1; /* * Main drawing loop. */ while (1) { DWORD dwRead; DWORD dwTotRead = 0; BYTE bPriority; dwErr = WaitForSingleObject(hStdin, 2000); if (dwErr != WAIT_OBJECT_0) { die(0, "Unable to wait for object."); } bErr = ReadFile(hStdin, &bPriority, 1, &dwRead, NULL); if ((bErr == FALSE) || (dwRead != 1)) die(G15_ERR_READFILE, "Error while reading priority."); do { dwErr = WaitForSingleObject(hStdin, 2000); if (dwErr != WAIT_OBJECT_0) { die(0, "Unable to wait for object."); } bErr = ReadFile(hStdin, bitmap.pixels + dwTotRead, G15_MAX_FBMEM - dwTotRead, &dwRead, NULL); if (bErr == FALSE || dwRead == 0) die(G15_ERR_READFILE, "Error while reading framebuffer. %d %x",dwRead,GetLastError()); dwTotRead += dwRead; } while (dwTotRead < G15_MAX_FBMEM); dwErr = lgLcdUpdateBitmap(ctx.device, (const lgLcdBitmapHeader *) &bitmap, bPriority ? LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_ALERT) : LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_NORMAL)); if (dwErr != ERROR_SUCCESS) warn("Unable to update bitmap for device. (Error: %i)", dwErr); } /* * Close device connections. */ dwErr = lgLcdClose(ctx.device); if (dwErr != ERROR_SUCCESS) die(G15_ERR_CLOSE, "Unable to close LCD device. (Error: %i)", dwErr); /* * Disconnect from LCD monitor. */ dwErr = lgLcdDisconnect(conn.connection); if (dwErr != ERROR_SUCCESS) die(G15_ERR_DISCONNECT, "Unable to disconnect from LCD manager. (Error: %i)", dwErr); /* * Deinitialize G15 library. */ dwErr = lgLcdDeInit(); if (dwErr != ERROR_SUCCESS) die(G15_ERR_DEINIT, "Unable to deinitialize LCD library. (Error: %i)", dwErr); warn("Terminated successfully."); return 0; }