// SPDX-License-Identifier: LGPL-2.1-or-later #include #include "../menu_bridge.h" static HWND editor; static BOOL typed; static BOOL marker_exists(const WCHAR *variable) { WCHAR path[4096]; return GetEnvironmentVariableW(variable, path, 4096) && GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES; } static void marker(const WCHAR *variable) { WCHAR path[4096]; if (!GetEnvironmentVariableW(variable, path, 4096)) return; HANDLE file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) CloseHandle(file); } static LRESULT CALLBACK window_proc(HWND window, UINT message, WPARAM wp, LPARAM lp) { if (message == WM_TIMER && !typed && marker_exists(L"WINE_ACCESS_READER_WAITING")) { typed = TRUE; const WCHAR *text = L"abbacdef"; for (const WCHAR *cursor = text; *cursor; ++cursor) SendMessageW(editor, WM_CHAR, *cursor, 1); WCHAR actual[32]; DWORD start = 0, end = 0; GetWindowTextW(editor, actual, 32); SendMessageW(editor, EM_GETSEL, (WPARAM)&start, (LPARAM)&end); if (lstrcmpW(actual, text) || start != 8 || end != 8) ExitProcess(2); marker(L"WINE_ACCESS_READER_TYPED"); return 0; } if (message == WM_TIMER && typed && marker_exists(L"WINE_ACCESS_READER_RESUME")) { KillTimer(window, 1); SendMessageW(editor, WM_CHAR, 'z', 1); return 0; } if (message == WM_DESTROY) { PostQuitMessage(0); return 0; } return DefWindowProcW(window, message, wp, lp); } int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR args, int show) { (void)previous; (void)show; if (lstrcmpA(args, "quit-helper") == 0) { DWORD thread = GetWindowThreadProcessId(FindWindowW(WINE_ACCESS_MENU_CLASS, NULL), NULL); return thread && PostThreadMessageW(thread, WM_QUIT, 0, 0) ? 0 : 3; } WNDCLASSW cls = {0}; cls.hInstance = instance; cls.lpfnWndProc = window_proc; cls.lpszClassName = L"WineReaderStallFixture"; RegisterClassW(&cls); HWND window = CreateWindowW(cls.lpszClassName, L"Reader stall fixture", WS_OVERLAPPEDWINDOW, 100, 100, 500, 300, NULL, NULL, instance, NULL); editor = CreateWindowW(L"Edit", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 10, 10, 300, 30, window, NULL, instance, NULL); ShowWindow(window, SW_SHOW); SetForegroundWindow(window); SetFocus(editor); SetTimer(window, 1, 10, NULL); MSG message; while (GetMessageW(&message, NULL, 0, 0) > 0) { TranslateMessage(&message); DispatchMessageW(&message); } return 0; }