static int windows_wminput_poll(ManyMouseEvent *ev) { MSG Msg; /* run the queue for WM_INPUT messages, etc ... */ int found = 0; /* ...favor existing events in the queue... */ pEnterCriticalSection(&mutex); if (input_events_read != input_events_write) /* no events if equal. */ { CopyMemory(ev, &input_events[input_events_read], sizeof (*ev)); input_events_read = ((input_events_read + 1) % MAX_EVENTS); found = 1; } /* if */ pLeaveCriticalSection(&mutex); if (!found) { /* pump Windows for new hardware events... */ while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE)) { pTranslateMessage(&Msg); pDispatchMessageA(&Msg); } /* while */ /* In case something new came in, give it to the app... */ pEnterCriticalSection(&mutex); if (input_events_read != input_events_write) /* no events if equal. */ { CopyMemory(ev, &input_events[input_events_read], sizeof (*ev)); input_events_read = ((input_events_read + 1) % MAX_EVENTS); found = 1; } /* if */ pLeaveCriticalSection(&mutex); } /* if */ /* * Check for disconnects if queue is totally empty and Windows didn't * report anything new at this time. This ensures that we don't send a * disconnect event through ManyMouse and then later give a valid * event to the app for a device that is now missing. */ if (!found) found = check_for_disconnects(ev); return found; } /* windows_wminput_poll */
static void cleanup_window(void) { if (raw_hwnd) { MSG Msg; pDestroyWindow(raw_hwnd); while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE)) { pTranslateMessage(&Msg); pDispatchMessageA(&Msg); } /* while */ raw_hwnd = 0; } /* if */ if (class_atom) { pUnregisterClassA(class_name, pGetModuleHandleA(NULL)); class_atom = 0; } /* if */ } /* cleanup_window */
/* * Monotonic and real time functions */ static unsigned __stdcall windows_clock_gettime_threaded(void *param) { struct timer_request *request; LARGE_INTEGER hires_counter; MSG msg; // The following call will create this thread's message queue // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); // Signal windows_init_clock() that we're ready to service requests if (!SetEvent((HANDLE)param)) usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0)); param = NULL; // Main loop - wait for requests while (1) { if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) { usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0)); return 1; } switch (msg.message) { case WM_TIMER_REQUEST: // Requests to this thread are for hires always // Microsoft says that this function always succeeds on XP and later // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx request = (struct timer_request *)msg.lParam; QueryPerformanceCounter(&hires_counter); request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency); request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps); if (!SetEvent(request->event)) usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0)); break; case WM_TIMER_EXIT: usbi_dbg("timer thread quitting"); return 0; } } }