int ConsoleGetch() { int fd = fileno(stdin); HANDLE h; DWORD waitResult; if (!isatty(fd)) h = CreateThread(NULL, 0, stdin_pipe_reader, NULL, 0, NULL); else h = (HANDLE)_get_osfhandle(fd); do { waitResult = MsgWaitForMultipleObjects(1, &h, FALSE, INFINITE, QS_ALLINPUT); if (waitResult == WAIT_OBJECT_0) { DWORD c; if (isatty(fd)) { c = ConsoleReadCh(); if (c != NUL) return c; } else { GetExitCodeThread(h, &c); CloseHandle(h); return c; } } else if (waitResult == WAIT_OBJECT_0+1) { WinMessageLoop(); if (ctrlc_flag) return '\r'; } else break; } while (1); return '\r'; }
/* Non-blocking Sleep function, called by pause_command. This allows redrawing and (some) user interaction. */ void win_sleep(DWORD dwMilliSeconds) { DWORD t0, t1, tstop, rc; t0 = GetTickCount(); tstop = t0 + dwMilliSeconds; t1 = dwMilliSeconds; /* remaining time to wait */ do { HANDLE h; if (term->waitforinput != NULL) term->waitforinput(TERM_ONLY_CHECK_MOUSING); #ifndef HAVE_LIBCACA rc = MsgWaitForMultipleObjects(0, NULL, FALSE, t1, QS_ALLINPUT); if (rc != WAIT_TIMEOUT) { #else h = GetStdHandle(STD_INPUT_HANDLE); if (h != NULL) rc = MsgWaitForMultipleObjects(1, &h, FALSE, t1, QS_ALLINPUT); else rc = MsgWaitForMultipleObjects(0, NULL, FALSE, t1, QS_ALLINPUT); if (rc != WAIT_TIMEOUT) { if (strcmp(term->name, "caca") == 0) CACA_process_events(); #endif WinMessageLoop(); /* calculate remaining time, detect overflow */ t1 = GetTickCount(); if (tstop > t0) { if ((t1 >= tstop) || (t1 < t0)) rc = WAIT_TIMEOUT; } else { if ((t1 >= tstop) && (t1 < t0)) rc = WAIT_TIMEOUT; } t1 = tstop - t1; /* remaining time to wait */ } } while (rc != WAIT_TIMEOUT); } /* Create Pause Class */ /* called from PauseBox the first time a pause window is created */ static void CreatePauseClass(LPPW lppw) { WNDCLASS wndclass; wndclass.style = 0; wndclass.lpfnWndProc = (WNDPROC)WndPauseProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(void *); wndclass.hInstance = lppw->hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szPauseClass; RegisterClass(&wndclass); }
/* PauseBox */ int WDPROC PauseBox(LPPW lppw) { HDC hdc; int width, height; TEXTMETRIC tm; RECT rect; char *current_pause_title = lppw->Title; static char TITLE_PAUSE_MOUSE[] = "waiting for mouse click"; #ifdef USE_MOUSE if (paused_for_mouse) current_pause_title = TITLE_PAUSE_MOUSE; #endif if (!lppw->hPrevInstance) CreatePauseClass(lppw); GetWindowRect(GetDesktopWindow(), &rect); if ( (lppw->Origin.x == CW_USEDEFAULT) || (lppw->Origin.x == 0) ) lppw->Origin.x = (rect.right + rect.left) / 2; if ( (lppw->Origin.y == CW_USEDEFAULT) || (lppw->Origin.y == 0) ) lppw->Origin.y = (rect.bottom + rect.top) / 2; hdc = GetDC(NULL); SelectObject(hdc, GetStockObject(SYSTEM_FONT)); GetTextMetrics(hdc, &tm); width = max(24, 4 + strlen(lppw->Message)) * tm.tmAveCharWidth; width = min(width, rect.right-rect.left); height = 28 * (tm.tmHeight + tm.tmExternalLeading) / 4; ReleaseDC(NULL,hdc); lppw->hWndPause = CreateWindowEx( WS_EX_DLGMODALFRAME | WS_EX_APPWINDOW, szPauseClass, current_pause_title, /* HBB 981202: WS_POPUPWINDOW would have WS_SYSMENU in it, but we don't * want, nor need, a System menu in our Pause windows. */ WS_POPUP | WS_BORDER | WS_CAPTION, lppw->Origin.x - width/2, lppw->Origin.y - height/2, width, height, lppw->hWndParent, NULL, lppw->hInstance, lppw); /* Don't show the pause "OK CANCEL" dialog for "pause mouse ..." -- well, show it only for "pause -1". Note: maybe to show in the window titlebar or somewhere else a message like graphwin.Title = "gnuplot pausing (waiting for mouse click)"; */ #ifdef USE_MOUSE if (!paused_for_mouse) #endif { ShowWindow(lppw->hWndPause, SW_SHOWNORMAL); BringWindowToTop(lppw->hWndPause); UpdateWindow(lppw->hWndPause); } lppw->bPause = TRUE; lppw->bPauseCancel = IDCANCEL; while (lppw->bPause) { if (term->waitforinput == NULL) { /* Only handle message queue events */ WinMessageLoop(); WaitMessage(); } else { /* Call the non-blocking sleep function, which also handles console input (caca terminal) and mousing of the current terminal (e.g. qt) */ win_sleep(50); } } DestroyWindow(lppw->hWndPause); return lppw->bPauseCancel; }