1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5
6 /*
7 * G15 Helper Daemon for Mac OS X.
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <time.h>
13 #include <CoreFoundation/CoreFoundation.h>
14
15 #include "g15helper.h"
16 #include "lglcd.h"
17
18 #define ERROR_SUCCESS 0
19 #define BOOL unsigned char
20 #define BYTE unsigned char
21 #define TRUE 1
22 #define FALSE 0
23
ods(const char * fmt,va_list args)24 static void ods(const char *fmt, va_list args) {
25 vfprintf(stderr, fmt, args);
26 }
27
warn(const char * fmt,...)28 static void warn(const char *fmt, ...) {
29 va_list args;
30 va_start(args, fmt);
31 ods(fmt, args);
32 va_end(args);
33 }
34
die(int err,const char * fmt,...)35 static void die(int err, const char *fmt, ...) {
36 va_list args;
37 va_start(args, fmt);
38 ods(fmt, args);
39 va_end(args);
40 exit(err);
41 }
42
main(int argc,char * argv[])43 int main(int argc, char *argv[]) {
44 int dwErr;
45 BOOL bDetect = FALSE;
46 int i;
47 lgLcdConnectContextEx conn;
48 lgLcdOpenByTypeContext ctx;
49 lgLcdBitmap160x43x1 bitmap;
50
51 if (argc > 1 && (strcmp(argv[1], "/detect") == 0)) {
52 warn("Detect mode!");
53 bDetect = TRUE;
54 } else if (!(argc > 1) || (strcmp(argv[1], "/mumble") != 0)) {
55 CFUserNotificationDisplayAlert(0, 0, NULL, NULL, NULL, CFSTR("Nothing to see here"), CFSTR("This program is run by Mumble, and should not be started separately."), CFSTR("OK"), NULL, NULL, NULL);
56 return 0;
57 }
58
59 /*
60 * Clear and set up initial structures.
61 */
62 memset(&conn, 0, sizeof(conn));
63 memset(&ctx, 0, sizeof(ctx));
64 memset(&bitmap, 0, sizeof(bitmap));
65
66 conn.appFriendlyName = G15_WIDGET_NAME;
67 conn.isAutostartable = FALSE;
68 conn.isPersistent = FALSE;
69 conn.dwAppletCapabilitiesSupported =LGLCD_APPLET_CAP_BASIC | LGLCD_APPLET_CAP_BW;
70 conn.connection = LGLCD_INVALID_CONNECTION;
71
72 /*
73 * Initialize and connect.
74 */
75 dwErr = lgLcdInit();
76 if (dwErr != ERROR_SUCCESS)
77 die(G15_ERR_INIT, "Unable to initialize Logitech LCD library. (Error: %i)", dwErr);
78
79 dwErr = lgLcdConnectEx(&conn);
80 if (dwErr != ERROR_SUCCESS)
81 die(G15_ERR_CONNECT, "Unable to connect to Logitech LCD manager. (Error: %i)", dwErr);
82
83 ctx.connection = conn.connection;
84 ctx.device = LGLCD_INVALID_DEVICE;
85 ctx.deviceType =LGLCD_DEVICE_BW;
86
87 dwErr = lgLcdOpenByType(&ctx);
88
89 warn("That returned %d %d", dwErr, ERROR_SUCCESS);
90
91 if (bDetect)
92 return (dwErr != ERROR_SUCCESS);
93 else if (dwErr != ERROR_SUCCESS)
94 die(G15_ERR_OPEN, "Unable to open device. (Error: %i)", dwErr);
95
96 /*
97 * Diplay buffer format.
98 */
99 bitmap.hdr.Format = LGLCD_BMP_FORMAT_160x43x1;
100
101 /*
102 * Main drawing loop.
103 */
104 while (1) {
105 int ret;
106 int remain = 0;
107 BYTE bPriority;
108
109 ret = read(0, &bPriority, 1);
110 if (ret == -1 || ret != 1)
111 die(G15_ERR_READFILE, "Error while reading priority.");
112
113 do {
114 ret = read(0, bitmap.pixels + remain, G15_MAX_FBMEM - remain);
115 if (ret < 1)
116 die(G15_ERR_READFILE, "Error while reading framebuffer. %d (%s)", ret, strerror(errno));
117 remain += ret;
118 } while (remain < G15_MAX_FBMEM);
119
120 dwErr = lgLcdUpdateBitmap(ctx.device, (const lgLcdBitmapHeader *) &bitmap, bPriority ? LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_ALERT) : LGLCD_SYNC_UPDATE(LGLCD_PRIORITY_NORMAL));
121 if (dwErr != ERROR_SUCCESS)
122 warn("Unable to update bitmap for device #%i successfully. (Error: %i)", i, dwErr);
123 }
124
125 /*
126 * Close device connections.
127 */
128 dwErr = lgLcdClose(ctx.device);
129 if (dwErr != ERROR_SUCCESS)
130 die(G15_ERR_CLOSE, "Unable to close LCD device. (Error: %i)", dwErr);
131
132 /*
133 * Disconnect from LCD monitor.
134 */
135 dwErr = lgLcdDisconnect(conn.connection);
136 if (dwErr != ERROR_SUCCESS)
137 die(G15_ERR_DISCONNECT, "Unable to disconnect from LCD manager. (Error: %i)", dwErr);
138
139 /*
140 * Deinitialize G15 library.
141 */
142 dwErr = lgLcdDeInit();
143 if (dwErr != ERROR_SUCCESS)
144 die(G15_ERR_DEINIT, "Unable to deinitialize LCD library. (Error: %i)", dwErr);
145
146 warn("Terminated successfully.");
147
148 return 0;
149 }
150