89e3f025bd8bb1a04d91a012df9de24a6206c6f8
[reactos.git] / reactos / lib / sdk / crt / conio / kbhit.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/msvcrt/conio/kbhit.c
5 * PURPOSE: Checks for keyboard hits
6 * PROGRAMERS: Ariadne, Russell
7 * UPDATE HISTORY:
8 * 28/12/98: Created
9 * 27/9/08: An almost 100% working version of _kbhit()
10 */
11
12 #include <precomp.h>
13
14 static CRITICAL_SECTION CriticalSection;
15 volatile BOOL CriticalSectionInitialized=FALSE;
16
17 /*
18 * @implemented
19 */
20
21 int _kbhit(void)
22 {
23 PINPUT_RECORD InputRecord = NULL;
24 DWORD NumberRead = 0;
25 DWORD EventsRead = 0;
26 DWORD RecordIndex = 0;
27 DWORD BufferIndex = 0;
28 HANDLE StdInputHandle = 0;
29 DWORD ConsoleInputMode = 0;
30
31 /* Attempt some thread safety */
32 if (!CriticalSectionInitialized)
33 {
34 InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400);
35 CriticalSectionInitialized = TRUE;
36 }
37
38 EnterCriticalSection(&CriticalSection);
39
40 if (char_avail)
41 {
42 LeaveCriticalSection(&CriticalSection);
43 return 1;
44 }
45
46 StdInputHandle = GetStdHandle(STD_INPUT_HANDLE);
47
48 /* Turn off processed input so we get key modifiers as well */
49 GetConsoleMode(StdInputHandle, &ConsoleInputMode);
50
51 SetConsoleMode(StdInputHandle, ConsoleInputMode & ~ENABLE_PROCESSED_INPUT);
52
53 /* Start the process */
54 if (!GetNumberOfConsoleInputEvents(StdInputHandle, &EventsRead))
55 {
56 LeaveCriticalSection(&CriticalSection);
57 return 0;
58 }
59
60 if (!EventsRead)
61 {
62 LeaveCriticalSection(&CriticalSection);
63 return 0;
64 }
65
66 if (!(InputRecord = (PINPUT_RECORD)malloc(EventsRead * sizeof(INPUT_RECORD))))
67 {
68 LeaveCriticalSection(&CriticalSection);
69 return 0;
70 }
71
72 if (!PeekConsoleInput(StdInputHandle, InputRecord, EventsRead, &NumberRead))
73 {
74 free(InputRecord);
75 LeaveCriticalSection(&CriticalSection);
76 return 0;
77 }
78
79 for (RecordIndex = 0; RecordIndex < NumberRead; RecordIndex++)
80 {
81 if (InputRecord[RecordIndex].EventType == KEY_EVENT &&
82 InputRecord[RecordIndex].Event.KeyEvent.bKeyDown)
83 {
84 BufferIndex = 1;
85 break;
86 }
87 }
88
89 free(InputRecord);
90
91 /* Restore console input mode */
92 SetConsoleMode(StdInputHandle, ConsoleInputMode);
93
94 LeaveCriticalSection(&CriticalSection);
95
96 return BufferIndex;
97 }
98
99