Author: fireball
Date: Thu Dec 11 10:44:07 2008
New Revision: 38019
URL:
http://svn.reactos.org/svn/reactos?rev=38019&view=rev
Log:
- An "almost working" kbhit implementation by Russel. The code is rather crappy,
feel free to improve it.
Some notes:
1) Forgive my sloppy coding skills (all those LeaveCriticalSections, use of malloc/free),
a lot of it was written in a rush to get something going. 2) For some reason, the first
char entered isn't detected (on windows and reactos)
3) The thread safety code is questionable, I haven't tested this, but windows does use
critical sections for it.
4) Compared to the windows way of doing it, it is probably wrong.
5) Maybe other things as well.
But it does work (at least when I tested it on windows and reactos) compared to the
previous implementation of it which did not at all.
See issue #3747 for more details.
Modified:
trunk/reactos/lib/sdk/crt/conio/kbhit.c
Modified: trunk/reactos/lib/sdk/crt/conio/kbhit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/conio/kbhit.c?…
==============================================================================
--- trunk/reactos/lib/sdk/crt/conio/kbhit.c [iso-8859-1] (original)
+++ trunk/reactos/lib/sdk/crt/conio/kbhit.c [iso-8859-1] Thu Dec 11 10:44:07 2008
@@ -3,28 +3,99 @@
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/kbhit.c
* PURPOSE: Checks for keyboard hits
- * PROGRAMER: Ariadne
+ * PROGRAMERS: Ariadne, Russell
* UPDATE HISTORY:
* 28/12/98: Created
+ * 27/9/08: An almost 100% working version of _kbhit()
*/
#include <precomp.h>
+static CRITICAL_SECTION CriticalSection;
+volatile BOOL CriticalSectionInitialized=FALSE;
+
/*
- * FIXME PeekConsoleInput returns more than keyboard hits
+ * FIXME Initial keyboard char not detected on first punch
*
- * @unimplemented
+ * @implemented
*/
+
int _kbhit(void)
{
- //INPUT_RECORD InputRecord;
- DWORD NumberRead=0;
- if (char_avail)
- return(1);
- else {
- //FIXME PeekConsoleInput might do DeviceIo
- //PeekConsoleInput((HANDLE)stdin->_file,&InputRecord,1,&NumberRead);
- return NumberRead;
+ PINPUT_RECORD InputRecord = NULL;
+ DWORD NumberRead = 0;
+ DWORD EventsRead = 0;
+ DWORD RecordIndex = 0;
+ DWORD BufferIndex = 0;
+ HANDLE StdInputHandle = 0;
+ DWORD ConsoleInputMode = 0;
+
+ /* Attempt some thread safety */
+ if (!CriticalSectionInitialized)
+ {
+ InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400);
+ CriticalSectionInitialized = TRUE;
}
- return 0;
+
+ EnterCriticalSection(&CriticalSection);
+
+ if (char_avail)
+ {
+ LeaveCriticalSection(&CriticalSection);
+ return 1;
+ }
+
+ StdInputHandle = GetStdHandle(STD_INPUT_HANDLE);
+
+ /* Turn off processed input so we get key modifiers as well */
+ GetConsoleMode(StdInputHandle, &ConsoleInputMode);
+
+ SetConsoleMode(StdInputHandle, ConsoleInputMode & ~ENABLE_PROCESSED_INPUT);
+
+ /* Start the process */
+ if (!GetNumberOfConsoleInputEvents(StdInputHandle, &EventsRead))
+ {
+ LeaveCriticalSection(&CriticalSection);
+ return 0;
+ }
+
+ if (!EventsRead)
+ {
+ LeaveCriticalSection(&CriticalSection);
+ return 0;
+ }
+
+ if (!(InputRecord = (PINPUT_RECORD)malloc(EventsRead * sizeof(INPUT_RECORD))))
+ {
+ LeaveCriticalSection(&CriticalSection);
+ return 0;
+ }
+
+ if (!ReadConsoleInput(StdInputHandle, InputRecord, EventsRead, &NumberRead))
+ {
+ free(InputRecord);
+ LeaveCriticalSection(&CriticalSection);
+ return 0;
+ }
+
+ for (RecordIndex = 0; RecordIndex < NumberRead; RecordIndex++)
+ {
+ if (InputRecord[RecordIndex].EventType == KEY_EVENT &&
+ InputRecord[RecordIndex].Event.KeyEvent.bKeyDown)
+ {
+ BufferIndex = 1;
+ break;
+ }
+ }
+
+ free(InputRecord);
+
+ /* Restore console input mode */
+ SetConsoleMode(StdInputHandle, ConsoleInputMode);
+
+ LeaveCriticalSection(&CriticalSection);
+
+ return BufferIndex;
}
+
+