ReactOS 0.4.16-dev-1067-ge98bba2
getch.cpp File Reference
#include <conio.h>
#include <corecrt_internal_lowio.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for getch.cpp:

Go to the source code of this file.

Classes

struct  anonymous_namespace{getch.cpp}::CharPair
 
struct  anonymous_namespace{getch.cpp}::EnhKeyVals
 
struct  anonymous_namespace{getch.cpp}::NormKeyVals
 

Namespaces

namespace  anonymous_namespace{getch.cpp}
 

Macros

#define NUM_EKA_ELTS   (sizeof(EnhancedKeys) / sizeof(EnhKeyVals))
 

Functions

static bool is_getch_pushback_buffer_full ()
 
static void add_to_getch_pushback_buffer (int const c)
 
static int peek_next_getch_pushback_buffer ()
 
static int get_next_getch_pushback_buffer ()
 
CharPair const *__cdecl _getextendedkeycode (KEY_EVENT_RECORD *)
 
int __cdecl _kbhit_nolock ()
 
int __cdecl _getch ()
 
int __cdecl _getche ()
 
int __cdecl _getch_nolock ()
 
int __cdecl _getche_nolock ()
 
int __cdecl _kbhit ()
 
int __cdecl _ungetch (int const c)
 
int __cdecl _ungetch_nolock (int const c)
 

Variables

static EnhKeyVals const EnhancedKeys []
 
static NormKeyVals const NormalKeys []
 
size_t const getch_pushback_buffer_capacity = 3
 
static int getch_pushback_buffer [getch_pushback_buffer_capacity]
 
static int getch_pushback_buffer_index = 0
 
static int getch_pushback_buffer_current_size = 0
 
intptr_t __dcrt_lowio_console_input_handle
 

Macro Definition Documentation

◆ NUM_EKA_ELTS

#define NUM_EKA_ELTS   (sizeof(EnhancedKeys) / sizeof(EnhKeyVals))

Definition at line 63 of file getch.cpp.

Function Documentation

◆ _getch()

int __cdecl _getch ( void  )

Definition at line 245 of file getch.cpp.

246{
248 int result = 0;
249 __try
250 {
252 }
254 {
256 }
258 return result;
259}
void __cdecl __acrt_unlock(_In_ __acrt_lock_id lock)
Definition: locks.cpp:57
@ __acrt_conio_lock
__acrt_lock(__acrt_heap_lock)
int __cdecl _getch_nolock()
Definition: getch.cpp:277
GLuint64EXT * result
Definition: glext.h:11304
#define __try
Definition: pseh2_64.h:188
#define __endtry
Definition: pseh2_64.h:191
#define __finally
Definition: pseh2_64.h:190

Referenced by _cgets(), _getche(), _tmain(), abort(), DumpFont(), GetPass(), gl_getc(), gl_getcx(), gl_getpass(), main(), MainUsage(), PrintHelp(), ShowAppList(), TestEventsGeneration(), Wait(), and wmain().

◆ _getch_nolock()

int __cdecl _getch_nolock ( void  )

Definition at line 277 of file getch.cpp.

278{
279 // Check the pushback buffer for a character. If one is present, return it:
280 int const pushback = get_next_getch_pushback_buffer();
281 if (pushback != EOF)
282 {
283 return pushback;
284 }
285
287 return EOF;
288 }
289
290 // Switch console to raw mode:
291 DWORD old_console_mode;
292 __dcrt_get_input_console_mode(&old_console_mode);
294
295 int result = 0;
296
297 __try
298 {
299 for ( ; ; )
300 {
301 // Get a console input event:
302 INPUT_RECORD input_record;
303 DWORD num_read;
304
305 if (__dcrt_read_console_input(&input_record, 1, &num_read) == FALSE || num_read == 0)
306 {
307 result = EOF;
308 __leave;
309 }
310
311 // Look for, and decipher, key events.
312 if (input_record.EventType == KEY_EVENT && input_record.Event.KeyEvent.bKeyDown)
313 {
314 // Simple case: if UnicodeChar is non-zero, we can convert it to char and return it.
315 wchar_t const c = input_record.Event.KeyEvent.uChar.UnicodeChar;
316 if (c != 0)
317 {
318 wchar_t const c_buffer[2] = {c, L'\0'};
319 char mb_chars[4];
320
321 size_t const amount_written = __acrt_wcs_to_mbs_cp_array(
322 c_buffer,
323 mb_chars,
325 );
326
327 // Mask with 0xFF to just get lowest byte
328 if (amount_written >= 1) {
329 result = mb_chars[0] & 0xFF;
330 }
331
332 if (amount_written >= 2) {
333 for (size_t i = 1; i < amount_written; ++i) {
334 add_to_getch_pushback_buffer(mb_chars[i] & 0xFF);
335 }
336 }
337 __leave;
338 }
339
340 // Hard case: either it is an extended code or an event which
341 // should not be recognized. Let _getextendedkeycode do the work:
342 CharPair const* const cp = _getextendedkeycode(&input_record.Event.KeyEvent);
343 if (cp != nullptr)
344 {
345 // Mask with 0xFF to just get lowest byte
346 add_to_getch_pushback_buffer(cp->SecondChar & 0xFF);
347 result = cp->LeadChar & 0xFF;
348 __leave;
349 }
350 }
351 }
352 }
354 {
355 // Restore the previous console mode:
356 __dcrt_set_input_console_mode(old_console_mode);
357 }
359 return result;
360}
size_t __acrt_wcs_to_mbs_cp_array(wchar_t const *const null_terminated_input_string, char(&buffer)[N], unsigned int const code_page)
#define FALSE
Definition: types.h:117
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2391
unsigned long DWORD
Definition: ntddk_ex.h:95
static int get_next_getch_pushback_buffer()
Definition: getch.cpp:216
CharPair const *__cdecl _getextendedkeycode(KEY_EVENT_RECORD *)
Definition: getch.cpp:506
static void add_to_getch_pushback_buffer(int const c)
Definition: getch.cpp:201
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EOF
Definition: stdio.h:24
BOOL __cdecl __dcrt_read_console_input(_Out_ PINPUT_RECORD lpBuffer, _In_ DWORD nLength, _Out_ LPDWORD lpNumberOfEventsRead)
Definition: initconin.cpp:67
BOOL __cdecl __dcrt_get_input_console_mode(_Out_ LPDWORD lpMode)
Definition: initconin.cpp:136
BOOL __cdecl __dcrt_lowio_ensure_console_input_initialized()
Definition: initconin.cpp:31
BOOL __cdecl __dcrt_set_input_console_mode(_In_ DWORD dwMode)
Definition: initconin.cpp:150
#define c
Definition: ke_i.h:80
POINT cp
Definition: magnifier.c:59
#define L(x)
Definition: ntvdm.h:50
#define __leave
Definition: pseh2_64.h:192
union _INPUT_RECORD::@3388 Event
WORD EventType
Definition: wincon.h:273
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:275
union _KEY_EVENT_RECORD::@3387 uChar
WCHAR UnicodeChar
Definition: wincon.h:245
#define KEY_EVENT
Definition: wincon.h:128

Referenced by _getch(), and _getche_nolock().

◆ _getche()

int __cdecl _getche ( void  )

Definition at line 261 of file getch.cpp.

262{
264 int result = 0;
265 __try
266 {
268 }
270 {
272 }
274 return result;
275}
int __cdecl _getche_nolock()
Definition: getch.cpp:364

◆ _getche_nolock()

int __cdecl _getche_nolock ( void  )

Definition at line 364 of file getch.cpp.

365{
366 // Check the pushback buffer for a character. If one is present, return
367 // it without echoing:
368 int const pushback = get_next_getch_pushback_buffer();
369 if (pushback != EOF)
370 {
371 return pushback;
372 }
373
374 // Otherwise, read the next character from the console and echo it:
375 int const c = _getch_nolock();
376 if (c == EOF)
377 return EOF;
378
379 if (_putch_nolock(c) == EOF)
380 return EOF;
381
382 return c;
383}
_CRTIMP int __cdecl _putch_nolock(_In_ int _Ch)

Referenced by _getche().

◆ _getextendedkeycode()

CharPair const *__cdecl _getextendedkeycode ( KEY_EVENT_RECORD pKE)

Definition at line 506 of file getch.cpp.

507{
508 DWORD const CKS = pKE->dwControlKeyState;
509
510 if (CKS & ENHANCED_KEY)
511 {
512 // Find the appropriate entry in EnhancedKeys[]:
513 for (int i = 0 ; i < NUM_EKA_ELTS; ++i)
514 {
516 {
517 continue;
518 }
519
520 // We found a match! Determine which pair to return:
522 {
523 return &EnhancedKeys[i].AltChars;
524 }
525 else if (CKS & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
526 {
527 return &EnhancedKeys[i].CtrlChars;
528 }
529 else if (CKS & SHIFT_PRESSED)
530 {
531 return &EnhancedKeys[i].ShiftChars;
532 }
533 else
534 {
535 return &EnhancedKeys[i].RegChars;
536 }
537 }
538
539 return nullptr;
540 }
541 else
542 {
543 // Regular key or keyboard event which shouldn't be recognized.
544 // Determine which by getting the proper field of the proper entry in
545 // NormalKeys[] and examining the extended code.
546 CharPair const* pCP;
547
549 {
550 pCP = &NormalKeys[pKE->wVirtualScanCode].AltChars;
551 }
552 else if (CKS & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
553 {
554 pCP = &NormalKeys[pKE->wVirtualScanCode].CtrlChars;
555 }
556 else if (CKS & SHIFT_PRESSED)
557 {
558 pCP = &NormalKeys[pKE->wVirtualScanCode].ShiftChars;
559 }
560 else
561 {
562 pCP = &NormalKeys[pKE->wVirtualScanCode].RegChars;
563 }
564
565 // Make sure it wasn't a keyboard event which should not be recognized
566 // (e.g. the shift key was pressed):
567 if ((pCP->LeadChar != 0 && pCP->LeadChar != 224) || pCP->SecondChar == 0)
568 {
569 return nullptr;
570 }
571
572 return pCP;
573 }
574}
UINT ScanCode
Definition: VirtualKey.c:24
static EnhKeyVals const EnhancedKeys[]
Definition: getch.cpp:46
static NormKeyVals const NormalKeys[]
Definition: getch.cpp:69
#define NUM_EKA_ELTS
Definition: getch.cpp:63
WORD wVirtualScanCode
Definition: wincon.h:243
DWORD dwControlKeyState
Definition: wincon.h:248
#define LEFT_CTRL_PRESSED
Definition: wincon.h:140
#define SHIFT_PRESSED
Definition: wincon.h:141
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:139
#define RIGHT_ALT_PRESSED
Definition: wincon.h:137
#define ENHANCED_KEY
Definition: wincon.h:145
#define LEFT_ALT_PRESSED
Definition: wincon.h:138

Referenced by _getch_nolock(), _getwch_nolock(), and _kbhit_nolock().

◆ _kbhit()

int __cdecl _kbhit ( void  )

Definition at line 388 of file getch.cpp.

389{
391 int result = 0;
392 __try
393 {
395 }
397 {
399 }
401 return result;
402}
int __cdecl _kbhit_nolock()
Definition: getch.cpp:406

Referenced by gl_getcx(), and main().

◆ _kbhit_nolock()

int __cdecl _kbhit_nolock ( )

Definition at line 406 of file getch.cpp.

407{
408 // If a character has been pushed back, return TRUE:
410 return TRUE;
411 }
412
414 return FALSE;
415 }
416
417 // Peek at all pending console events:
418 DWORD num_pending;
420 return FALSE;
421 }
422
423 if (num_pending == 0) {
424 return FALSE;
425 }
426
427 __crt_scoped_stack_ptr<INPUT_RECORD> const input_buffer(_malloca_crt_t(INPUT_RECORD, num_pending));
428 if (input_buffer.get() == nullptr) {
429 return FALSE;
430 }
431
432 DWORD num_peeked;
433 // AsciiChar is not read, so using the narrow Win32 API is permitted.
434 if (__dcrt_peek_console_input_a(input_buffer.get(), num_pending, &num_peeked) == FALSE) {
435 return FALSE;
436 }
437
438 if (num_peeked == 0 || num_peeked > num_pending) {
439 return FALSE;
440 }
441
442 // Scan all of the peeked events to determine if any is a key event
443 // that should be recognized:
444 for (INPUT_RECORD* p = input_buffer.get(); num_peeked > 0; --num_peeked, ++p)
445 {
446 if (p->EventType != KEY_EVENT)
447 continue;
448
449 if (!p->Event.KeyEvent.bKeyDown)
450 continue;
451
452 if (p->Event.KeyEvent.uChar.AsciiChar == 0 &&
453 _getextendedkeycode(&p->Event.KeyEvent) == nullptr)
454 continue;
455
456 return TRUE;
457 }
458
459 return FALSE;
460}
#define TRUE
Definition: types.h:120
static int peek_next_getch_pushback_buffer()
Definition: getch.cpp:207
GLfloat GLfloat p
Definition: glext.h:8902
BOOL __cdecl __dcrt_peek_console_input_a(_Out_ PINPUT_RECORD lpBuffer, _In_ DWORD nLength, _Out_ LPDWORD lpNumberOfEventsRead)
Definition: initconin.cpp:118
BOOL __cdecl __dcrt_get_number_of_console_input_events(_Out_ LPDWORD lpcNumberOfEvents)
Definition: initconin.cpp:104

Referenced by _kbhit().

◆ _ungetch()

int __cdecl _ungetch ( int const  c)

Definition at line 467 of file getch.cpp.

468{
470 int result = 0;
471 __try
472 {
474 }
476 {
478 }
480 return result;
481}
int __cdecl _ungetch_nolock(int const c)
Definition: getch.cpp:485

Referenced by _cgets().

◆ _ungetch_nolock()

int __cdecl _ungetch_nolock ( int const  c)

Definition at line 485 of file getch.cpp.

486{
487 // Fail if the character is EOF or the pusback buffer is nonempty:
488 if (c == EOF || is_getch_pushback_buffer_full()) {
489 return EOF;
490 }
491
493 return c;
494}
static bool is_getch_pushback_buffer_full()
Definition: getch.cpp:196

Referenced by _ungetch().

◆ add_to_getch_pushback_buffer()

static void add_to_getch_pushback_buffer ( int const  c)
static

Definition at line 201 of file getch.cpp.

202{
205}
#define _ASSERTE(expr)
Definition: crtdbg.h:114
static int getch_pushback_buffer[getch_pushback_buffer_capacity]
Definition: getch.cpp:192
static int getch_pushback_buffer_current_size
Definition: getch.cpp:194

Referenced by _getch_nolock(), and _ungetch_nolock().

◆ get_next_getch_pushback_buffer()

static int get_next_getch_pushback_buffer ( )
static

Definition at line 216 of file getch.cpp.

217{
219 return EOF;
220 }
221
223
227 }
228
229 return ret_val;
230}
static int getch_pushback_buffer_index
Definition: getch.cpp:193

Referenced by _getch_nolock(), and _getche_nolock().

◆ is_getch_pushback_buffer_full()

static bool is_getch_pushback_buffer_full ( )
static

Definition at line 196 of file getch.cpp.

197{
199}
size_t const getch_pushback_buffer_capacity
Definition: getch.cpp:190

Referenced by _ungetch_nolock(), and add_to_getch_pushback_buffer().

◆ peek_next_getch_pushback_buffer()

static int peek_next_getch_pushback_buffer ( )
static

Definition at line 207 of file getch.cpp.

208{
210 return EOF;
211 }
212
214}

Referenced by _kbhit_nolock().

Variable Documentation

◆ __dcrt_lowio_console_input_handle

intptr_t __dcrt_lowio_console_input_handle

Definition at line 232 of file getch.cpp.

◆ EnhancedKeys

EnhKeyVals const EnhancedKeys[]
static
Initial value:
=
{
{ 28, { 13, 0 }, { 13, 0 }, { 10, 0 }, { 0, 166 } },
{ 53, { 47, 0 }, { 63, 0 }, { 0, 149 }, { 0, 164 } },
{ 71, { 224, 71 }, { 224, 71 }, { 224, 119 }, { 0, 151 } },
{ 72, { 224, 72 }, { 224, 72 }, { 224, 141 }, { 0, 152 } },
{ 73, { 224, 73 }, { 224, 73 }, { 224, 134 }, { 0, 153 } },
{ 75, { 224, 75 }, { 224, 75 }, { 224, 115 }, { 0, 155 } },
{ 77, { 224, 77 }, { 224, 77 }, { 224, 116 }, { 0, 157 } },
{ 79, { 224, 79 }, { 224, 79 }, { 224, 117 }, { 0, 159 } },
{ 80, { 224, 80 }, { 224, 80 }, { 224, 145 }, { 0, 160 } },
{ 81, { 224, 81 }, { 224, 81 }, { 224, 118 }, { 0, 161 } },
{ 82, { 224, 82 }, { 224, 82 }, { 224, 146 }, { 0, 162 } },
{ 83, { 224, 83 }, { 224, 83 }, { 224, 147 }, { 0, 163 } }
}

Definition at line 46 of file getch.cpp.

Referenced by _getextendedkeycode().

◆ getch_pushback_buffer

◆ getch_pushback_buffer_capacity

size_t const getch_pushback_buffer_capacity = 3

Definition at line 190 of file getch.cpp.

Referenced by is_getch_pushback_buffer_full().

◆ getch_pushback_buffer_current_size

int getch_pushback_buffer_current_size = 0
static

◆ getch_pushback_buffer_index

int getch_pushback_buffer_index = 0
static

Definition at line 193 of file getch.cpp.

Referenced by get_next_getch_pushback_buffer(), and peek_next_getch_pushback_buffer().

◆ NormalKeys

NormKeyVals const NormalKeys[]
static

Definition at line 69 of file getch.cpp.

Referenced by _getextendedkeycode().