diff --git a/src/Console/Getch.php b/src/Console/Getch.php index 5479c35..dbcc7d8 100644 --- a/src/Console/Getch.php +++ b/src/Console/Getch.php @@ -67,19 +67,32 @@ final class Getch if (null === self::$ffi) { $osFamily = PHP_OS_FAMILY; if ('Windows' === $osFamily) { - self::$ffi = FFI::cdef(self::DECLARATIONS, self::WINDOWS_LIBRARY); + $declarations = self::DECLARATIONS . ' int _kbhit();'; + self::$ffi = FFI::cdef($declarations, self::WINDOWS_LIBRARY); } elseif ('Linux' === $osFamily) { if (!file_exists($linuxLibrary)) { throw new RuntimeException(sprintf('Could not find library file %s.', $linuxLibrary)); } - - self::$ffi = FFI::cdef(self::DECLARATIONS, $linuxLibrary); + $declarations = self::DECLARATIONS . ' int cinPeek();'; + self::$ffi = FFI::cdef($declarations, $linuxLibrary); } else { throw new RuntimeException(sprintf('Sorry, %s is not supported yet.', $osFamily)); } } } + public function peek(): int + { + if(PHP_OS_FAMILY === 'Windows') { + if($ffi->_kbhit()) { + $result = $ffi->_getch(); + $ffi->_ungetch($result); + return $result; + } + return -1; + } + return $ffi->cinPeek(); + } /* public function keyCode(string $device): array { diff --git a/src/Console/Resources/getch.c b/src/Console/Resources/getch.c index ac71127..b39122a 100644 --- a/src/Console/Resources/getch.c +++ b/src/Console/Resources/getch.c @@ -20,6 +20,33 @@ static struct termios oldTermAttributes; +inline static void reverseString(char * str) +{ + if (str) + { + char * end = str + strlen(str) - 1; + + // swap the values in the two given variables + // XXX: fails when a and b refer to same memory location +# define XOR_SWAP(a,b) do\ + {\ + (a) ^= (b);\ + (b) ^= (a);\ + (a) ^= (b);\ + } while (0) + + // walk inwards from both ends of the string, + // swapping until we get to the middle + while (str < end) + { + XOR_SWAP(*str, *end); + str++; + end--; + } +# undef XOR_SWAP + } +} + static int discardRead(unsigned int length) { char buffer[length]; @@ -37,7 +64,7 @@ static int discardRead(unsigned int length) return (int)bytesRead; } -static int getEventDevice(const char * device) +static int getEventDevice(char ** device) { glob_t search; @@ -63,7 +90,8 @@ static int getEventDevice(const char * device) for(int i = 0; igetch()); self::assertEquals(71, $g->getch()); } + + public function setPeek() + { + $g = new Getch(); + $g->ungetch('q'); + $peek = $g->peek(); + $getch = $g->getch(); + self::assertEquals($peek, $getch); + self::assertEquals(113, $peek); + } }