diff --git a/mirror.c b/mirror.c index 0adb910..4da993b 100644 --- a/mirror.c +++ b/mirror.c @@ -15,6 +15,20 @@ struct nd_pair IMMDevice *device; }; +HANDLE termination = NULL; + +BOOL CtrlHandler(DWORD type) +{ + (void)type; + + if (termination != NULL) + { + SetEvent(termination); + } + + return TRUE; +} + int list_devices(struct nd_pair **pairs) { int result = -1; @@ -254,11 +268,22 @@ bool mirror(IMMDevice *monitor, IMMDevice *output) goto out; } + HANDLE events[] = {termination, event}; + for (;;) { - if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) + switch (WaitForMultipleObjects(ARRAYSIZE(events), events, FALSE, INFINITE)) { - break; + case WAIT_OBJECT_0: // termination + result = true; + goto out; + + case WAIT_OBJECT_0 + 1: // event + break; + + default: + fprintf(stderr, "Failed to wait for events!\n"); + goto out; } for (;;) @@ -340,8 +365,6 @@ bool mirror(IMMDevice *monitor, IMMDevice *output) } } - result = true; - out: if (render != NULL) { @@ -409,27 +432,27 @@ bool run() printf("Select device to monitor: "); - char *res = fgets(buf, 5, stdin); + char *res = fgets(buf, ARRAYSIZE(buf), stdin); int mon = strtol(buf, NULL, 10); while (res != buf || mon < 0 || mon >= count) { printf("Select device to monitor: "); - res = fgets(buf, 5, stdin); + res = fgets(buf, ARRAYSIZE(buf), stdin); mon = strtol(buf, NULL, 10); } printf("Select output device: "); - res = fgets(buf, 5, stdin); + res = fgets(buf, ARRAYSIZE(buf), stdin); int out = strtol(buf, NULL, 10); while (res != buf || out < 0 || out >= count || out == mon) { printf("Select output device: "); - res = fgets(buf, 5, stdin); + res = fgets(buf, ARRAYSIZE(buf), stdin); out = strtol(buf, NULL, 10); } @@ -446,17 +469,33 @@ out: int main(void) { + if ((termination = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) + { + fprintf(stderr, "Failed to create termination event!\n"); + return EXIT_FAILURE; + } + + if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE) != TRUE) + { + fprintf(stderr, "Failed to set console control handler!\n"); + CloseHandle(termination); + return EXIT_FAILURE; + } + if (CoInitialize(NULL) != S_OK) { + CloseHandle(termination); return EXIT_FAILURE; } if (! run()) { CoUninitialize(); + CloseHandle(termination); return EXIT_FAILURE; } CoUninitialize(); + CloseHandle(termination); return EXIT_SUCCESS; }