Add a --showkey option to winpty-agent.

The intent is to make it easier to determine how Windows creates KEY_EVENT
records.  The code lives in winpty-agent because (1) it's very small, and
(2) I can't test all the interesting keyboards/locales/etc, so if
someone hits a bug, placing it in winpty-agent.exe ensures that they'll
have access to the tools needed to debug it.
This commit is contained in:
Ryan Prichard 2015-12-03 01:06:15 -06:00
parent 850eb9ff3f
commit f1e3b092ba
2 changed files with 68 additions and 15 deletions

View File

@ -111,15 +111,15 @@ static const char *getVirtualKeyString(int virtualKey)
std::string InputMap::Key::toString() const {
std::string ret;
if (keyState & SHIFT_PRESSED) {
ret += "Shift-";
}
if (keyState & LEFT_CTRL_PRESSED) {
ret += "Ctrl-";
}
if (keyState & LEFT_ALT_PRESSED) {
ret += "Alt-";
}
if (keyState & CAPSLOCK_ON) { ret += "CapsLock-"; }
if (keyState & ENHANCED_KEY) { ret += "Enhanced-"; }
if (keyState & LEFT_ALT_PRESSED) { ret += "LAlt-"; }
if (keyState & LEFT_CTRL_PRESSED) { ret += "LCtrl-"; }
if (keyState & NUMLOCK_ON) { ret += "NumLock-"; }
if (keyState & RIGHT_ALT_PRESSED) { ret += "RAlt-"; }
if (keyState & RIGHT_CTRL_PRESSED) { ret += "RCtrl-"; }
if (keyState & SCROLLLOCK_ON) { ret += "ScrollLock-"; }
if (keyState & SHIFT_PRESSED) { ret += "Shift-"; }
char buf[256];
const char *vkString = getVirtualKeyString(virtualKey);
if (vkString != NULL) {

View File

@ -22,9 +22,23 @@
#include <stdlib.h>
#include "Agent.h"
#include "InputMap.h"
#include "../shared/WinptyAssert.h"
#include "../shared/WinptyVersion.h"
const char USAGE[] =
"Usage: %s controlPipeName dataPipeName cols rows\n"
"\n"
"Ordinarily, this program is launched by winpty.dll and is not directly\n"
"useful to winpty users. However, it also has options intended for\n"
"debugging winpty.\n"
"\n"
"Usage: %s [options]\n"
"\n"
"Options:\n"
" --showkey Dump KEY_EVENT records read from the console input buffer\n"
" --version Print the winpty version\n";
static wchar_t *heapMbsToWcs(const char *text)
{
size_t len = mbstowcs(NULL, text, 0);
@ -35,6 +49,45 @@ static wchar_t *heapMbsToWcs(const char *text)
return ret;
}
static void debugShowKey()
{
HANDLE conin = GetStdHandle(STD_INPUT_HANDLE);
DWORD consoleMode = 0;
if (!GetConsoleMode(conin, &consoleMode) ||
!SetConsoleMode(conin, consoleMode &
~(ENABLE_PROCESSED_INPUT |
ENABLE_LINE_INPUT |
ENABLE_ECHO_INPUT))) {
printf("Error: could not set console mode -- "
"is STDIN a console handle?\n");
exit(1);
}
printf("\nPress any keys -- Ctrl-D exits\n\n");
INPUT_RECORD record;
DWORD actual = 0;
while (ReadConsoleInputW(conin, &record, 1, &actual) && actual == 1) {
if (record.EventType != KEY_EVENT) {
continue;
}
KEY_EVENT_RECORD &ker = record.Event.KeyEvent;
InputMap::Key key = {
ker.wVirtualKeyCode,
ker.uChar.UnicodeChar,
static_cast<uint16_t>(ker.dwControlKeyState),
};
printf("%s rpt=%d scn=%d %s\n",
ker.bKeyDown ? "dn" : "up",
ker.wRepeatCount,
ker.wVirtualScanCode,
key.toString().c_str());
if ((ker.dwControlKeyState & LEFT_CTRL_PRESSED) &&
ker.wVirtualKeyCode == 'D') {
break;
}
}
SetConsoleMode(conin, consoleMode);
}
int main(int argc, char *argv[])
{
if (argc == 2 && !strcmp(argv[1], "--version")) {
@ -42,13 +95,13 @@ int main(int argc, char *argv[])
return 0;
}
if (argc == 2 && !strcmp(argv[1], "--showkey")) {
debugShowKey();
return 0;
}
if (argc != 5) {
fprintf(stderr,
"Usage: %s controlPipeName dataPipeName cols rows\n"
"Usage: %s --version\n"
"\n"
"(Note: This program is intended to be run by libwinpty.dll.)\n",
argv[0], argv[0]);
fprintf(stderr, USAGE, argv[0], argv[0]);
return 1;
}