Read one keypress at a time from STDIN [UPDATE]
Posted: Fri Dec 17, 2004 5:57 pm
Has anyone come up with a solution for this? I'm not sure why it should be so difficult.
Thanks,
Norm
Thanks,
Norm
A community of PHP developers offering assistance, advice, discussion, and friendship.
http://forums.devnetwork.net/
Because php uses stream oriented IO. You might want to experiment with ncurses extension, particularly with [php_man]ncurses_cbreak[/php_man] function.npeelman wrote:I'm not sure why it should be so difficult.
Currently working on a solution to this, actually having some success. Details to follow (maybe).Weirdan wrote:Because php uses stream oriented IO. You might want to experiment with ncurses extension, particularly with [php_man]ncurses_cbreak[/php_man] function.npeelman wrote:I'm not sure why it should be so difficult.
Ok,npeelman wrote:Currently working on a solution to this, actually having some success. Details to follow (maybe).Weirdan wrote:Because php uses stream oriented IO. You might want to experiment with ncurses extension, particularly with [php_man]ncurses_cbreak[/php_man] function.npeelman wrote:I'm not sure why it should be so difficult.
Norm
Actually yesnpeelman wrote: 1) ncurses/ or derivative (Windows compatible ???)
Post you code, we might be able to help you. To my understanding you should be able to use functions of win32 console subsystem (e.g. ReadConsoleInputA) without much problems.3) system calls (win32.api via FFI - http://pecl.php.net/package/ffi )
<...skipped...>
Currently, I can receive keystrokes from the keyboard one keypress at a time, BUT I am receiving ALL keypresses system wide (for any/all applications).
I was hoping to come up with a simple solution that would be PHP only, or in otherwords PHP and something that people already have on their computer (namely the OS). My real problem at this point is my knowlege of C/C++ style programming conventions and how they relate to the FFI package. I'm not sure if the FFI package supports ALL C/C++ variable types and I would have to create alot of structs to work with the 'window'ing message que's, etc. I was hoping that I could simply pay attention to whether my 'shell' window had focus or not and only process the keystrokes if it does, but that's not quite working either.Weirdan wrote:Actually yesnpeelman wrote: 1) ncurses/ or derivative (Windows compatible ???)Cygwin compatible.
Post you code, we might be able to help you. To my understanding you should be able to use functions of win32 console subsystem (e.g. ReadConsoleInputA) without much problems.3) system calls (win32.api via FFI - http://pecl.php.net/package/ffi )
<...skipped...>
Currently, I can receive keystrokes from the keyboard one keypress at a time, BUT I am receiving ALL keypresses system wide (for any/all applications).
npeelman wrote:I was hoping to come up with a simple solution that would be PHP only, or in otherwords PHP and something that people already have on their computer (namely the OS). My real problem at this point is my knowlege of C/C++ style programming conventions and how they relate to the FFI package. I'm not sure if the FFI package supports ALL C/C++ variable types and I would have to create alot of structs to work with the 'window'ing message que's, etc. I was hoping that I could simply pay attention to whether my 'shell' window had focus or not and only process the keystrokes if it does, but that's not quite working either.Weirdan wrote:Actually yesnpeelman wrote: 1) ncurses/ or derivative (Windows compatible ???)Cygwin compatible.
Post you code, we might be able to help you. To my understanding you should be able to use functions of win32 console subsystem (e.g. ReadConsoleInputA) without much problems.3) system calls (win32.api via FFI - http://pecl.php.net/package/ffi )
<...skipped...>
Currently, I can receive keystrokes from the keyboard one keypress at a time, BUT I am receiving ALL keypresses system wide (for any/all applications).
I'll post some code this evening when i've had a chance to clran it up a bit. It's a mess right now.
Norm
Code: Select all
<?php
//CONSTANTS
$win32 = <<<EOD
[lib='user32.dll'] int BlockInput(int fBlockIt);
[lib='user32.dll'] int BringWindowToTop(int hWnd);
[lib='user32.dll'] int EnableWindow(int hWnd, int bEnable);
[lib='user32.dll'] int GetShellWindow();
[lib='user32.dll'] int GetFocus();
[lib='user32.dll'] int GetForegroundWindow();
[lib='user32.dll'] int GetActiveWindow(int hWnd);
[lib='user32.dll'] int GetAsyncKeyState(int v_key);
[lib='user32.dll'] int GetKeyState(int v_key);
[lib='user32.dll'] int GetKeyNameText(int lparam, int *lpstring, int nsize);
[lib='user32.dll'] int GetKeyboardState(char* lpkeystate);
[lib='user32.dll'] int GetTopWindow(int hWnd);
[lib='user32.dll'] int LockSetForegroundWindow(int uLockCode);
[lib='user32.dll'] int SetForegroundWindow(int hWnd);
[lib='user32.dll'] int SetFocus(int hWnd);
[lib='kernel32.dll'] int GetLastError();
EOD;
/*
GetKeyState -> For A-Z,a-z, and 0-9 set v_key == ascii-code for desired key.
else use virtual key code
*/
$key_in = 0;
$key = '';
$kb_array = str_repeat('0',256);
$kb_array2 = $kb_array;
//$accept = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ".chr(13).chr(27);
// $accept = all key codes
for($loop = 0; $loop <= 256; $loop++)
{
@$accept .= chr($loop);
}
$kb_focus = 0;
$win_handle = 0;
$foreground_handle = 0;
$console32 = new ffi($win32);
$win_handle = $console32->GetShellWindow();
if ($win_handle == NULL)
{
echo "Could not get handle to shell!\n\r";
exit;
}
else
{
echo "Got handle to shell window!\n\r";
$old_focus = $console32->GetActiveWindow($win_handle);
if ($old_focus == NULL)
{
echo "win_handle focus not set!\n\r";
//exit;
}
if ($console32->BringWindowToTop($win_handle) != 0)
{
echo "Window brought to top (should be active)\n\r";
$top_handle = $console32->GetTopWindow(NULL);
}
else
{
echo "Window not brought to top!\n\r";
exit;
}
if ($console32->SetForegroundWindow($win_handle) != 0)
{
echo "Window is now foregound window!\n\r";
$foreground_handle = $console32->GetForegroundWindow();
if ($foreground_handle == NULL)
{
echo "Could not get handle to foreground window!\n\r";
exit;
}
else
{
echo "Got handle to foreground window!\n\r";
}
}
}
if ($win_handle != $foreground_handle)
{
echo "Not the same handle!\n\r";
//exit;
}
else
{
echo "The same handle!\n\r";
$go = 1;
}
echo "Window handles checked OK! \n\r";
//while ($win_handle == $console32->GetForegroundWindow())
//{
// echo "Focused!\n\r";
// sleep(1);
//}
//echo "Not focused!";
//exit;
//$go = 1;
$char = 0;
$tmp = '';
$extended = 0;
if ($go = 1)
{
echo "Will accept everything, even mouse - ESC to quit\n\r";
while(true)
{
/* this really doesn't work right
if ($win_handle == $console32->GetForegroundWindow())
{
echo "Has focus!\n\r";
}
else
{
echo "Lost focus!\n\r";
}
*/
$key_in = $console32->GetAsyncKeyState(ord($accept[$char]));
if ($key_in != 0)
{
// we have a key press
if ($char >= 112 && $char <= 124)
{
echo "\n\rFUNCTION KEY\n\r";
continue;
}
$key = $accept[$char];
/* alternate Fkey code
if ($key >= 'p' && $key <= '{')
{
$extended = 1;
}
if ($extended == 1)
{
echo "\n\rFunction key ";
switch (ord($key))
{
case 112:
{
echo 'F1';
break;
}
case 113:
{
echo 'F2';
break;
}
default:
{
echo 'F?';
break;
}
}
echo " pressed!\n\r";
$extended = 0;
}
*/
if ($key == chr(27))
{
echo "\n\r 'ESC' was pressed!\n\r";
echo "\n\r\n\rYou typed -> \n\r $tmp";
exit;
}
else
{
echo $key;
//echo $key.ord($key);
$tmp .= $key;
}
}
if ($char == (strlen($accept) - 1))
{
$char = -1;
}
usleep(500);
$char++;
}
}
/* this sortof works - keystate rotates through all values
$key_test = $console32->GetKeyState(65);
echo "The 'A' key is ";
switch ($key_test)
{
case -127:
{
echo "pressed";
break;
}
case -128:
{
echo "pressed w/shift";
break;
}
default:
{
echo "up";
}
}
*/
/* this just doesn't work at all as $kb_array never gets updated.
for($loop = 0; $loop <= 10000; $loop++)
{
$result = $console32->GetKeyboardState($kb_array);
echo "$kb_array \n\r";
echo "\n\rResult = $result\n\r";
echo $console32->GetLastError()."\n\r";
for($loop2 = 0; $loop2 <= 255; $loop2++)
{
if ($kb_array[$loop2] != 0)
{
echo "Key pressed!";
exit;
}
else
{
echo ord($kb_array[$loop2])."\n\r";
}
}
usleep(10000);
}
*/
?>