From 8d8506d4890b77394d6fb18a0440b3a7d6aaa2e0 Mon Sep 17 00:00:00 2001 From: Ryan Prichard Date: Tue, 1 Dec 2015 23:37:17 -0600 Subject: [PATCH] Handle many more keypress escape sequences, particularly for putty/rxvt * Factor out the tables from ConsoleInput.cc to DefaultInputMap.cc. Fixes https://github.com/rprichard/winpty/issues/40 --- src/agent/ConsoleInput.cc | 123 +------------ src/agent/DefaultInputMap.cc | 322 +++++++++++++++++++++++++++++++++++ src/agent/DefaultInputMap.h | 28 +++ src/agent/subdir.mk | 1 + src/winpty.gyp | 2 + 5 files changed, 356 insertions(+), 120 deletions(-) create mode 100755 src/agent/DefaultInputMap.cc create mode 100755 src/agent/DefaultInputMap.h diff --git a/src/agent/ConsoleInput.cc b/src/agent/ConsoleInput.cc index 1d094865..4d7a065e 100644 --- a/src/agent/ConsoleInput.cc +++ b/src/agent/ConsoleInput.cc @@ -25,8 +25,9 @@ #include -#include "Win32Console.h" +#include "DefaultInputMap.h" #include "DsrSender.h" +#include "Win32Console.h" #include "../shared/DebugClient.h" #include "../shared/UnixCtrlChars.h" @@ -36,131 +37,13 @@ const int kIncompleteEscapeTimeoutMs = 1000; -#define ESC "\x1B" -#define CSI ESC"[" -#define DIM(x) (sizeof(x) / sizeof((x)[0])) - ConsoleInput::ConsoleInput(DsrSender *dsrSender) : m_console(new Win32Console), m_dsrSender(dsrSender), m_dsrSent(false), lastWriteTick(0) { - struct KeyDescriptor { - const char *encoding; - InputMap::Key key; - }; - const int vkLB = VkKeyScan('[') & 0xFF; - static const KeyDescriptor keyDescriptorTable[] = { - // Ctrl- seems to be handled OK by the default code path. - // TODO: Alt-ESC is encoded as ESC ESC. Can it be handled? - - { ESC, { VK_ESCAPE, '\x1B', 0, } }, - - // Alt- - { ESC"O", { 'O', 'O', LEFT_ALT_PRESSED | SHIFT_PRESSED } }, - { ESC"[", { vkLB, '[', LEFT_ALT_PRESSED } }, - - // F1-F4 function keys. F5-F12 seem to be handled more consistently among - // various TERM=xterm terminals (gnome-terminal, konsole, xterm, mintty), - // using a CSI-prefix with an optional extra modifier digit. (putty is - // also TERM=xterm, though, and has completely different modified F5-F12 - // encodings.) - { ESC"OP", { VK_F1, '\0', 0, } }, // xt gt kon - { ESC"OQ", { VK_F2, '\0', 0, } }, // xt gt kon - { ESC"OR", { VK_F3, '\0', 0, } }, // xt gt kon - { ESC"OS", { VK_F4, '\0', 0, } }, // xt gt kon - - { "\x7F", { VK_BACK, '\x08', 0, } }, - { ESC"\x7F", { VK_BACK, '\x08', LEFT_ALT_PRESSED, } }, - { ESC"OH", { VK_HOME, '\0', 0, } }, // gt - { ESC"OF", { VK_END, '\0', 0, } }, // gt - { ESC"[Z", { VK_TAB, '\t', SHIFT_PRESSED } }, - }; - - struct CsiEncoding { - int id; - char letter; - int virtualKey; - }; - static const CsiEncoding csiEncodings[] = { - { 0, 'A', VK_UP }, - { 0, 'B', VK_DOWN }, - { 0, 'C', VK_RIGHT }, - { 0, 'D', VK_LEFT }, - { 0, 'E', VK_NUMPAD5 }, - { 0, 'F', VK_END }, - { 0, 'H', VK_HOME }, - { 0, 'P', VK_F1 }, // mod+F1 for xterm and mintty - { 0, 'Q', VK_F2 }, // mod+F2 for xterm and mintty - { 0, 'R', VK_F3 }, // mod+F3 for xterm and mintty - { 0, 'S', VK_F4 }, // mod+F4 for xterm and mintty - { 1, '~', VK_HOME }, - { 2, '~', VK_INSERT }, - { 3, '~', VK_DELETE }, - { 4, '~', VK_END }, // gnome-terminal keypad home/end - { 5, '~', VK_PRIOR }, - { 6, '~', VK_NEXT }, - { 7, '~', VK_HOME }, - { 8, '~', VK_END }, - { 15, '~', VK_F5 }, - { 17, '~', VK_F6 }, - { 18, '~', VK_F7 }, - { 19, '~', VK_F8 }, - { 20, '~', VK_F9 }, - { 21, '~', VK_F10 }, - { 23, '~', VK_F11 }, - { 24, '~', VK_F12 }, - }; - - const int kCsiShiftModifier = 1; - const int kCsiAltModifier = 2; - const int kCsiCtrlModifier = 4; - char encoding[32]; - for (size_t i = 0; i < DIM(csiEncodings); ++i) { - const CsiEncoding *e = &csiEncodings[i]; - if (e->id == 0) - sprintf(encoding, CSI"%c", e->letter); - else - sprintf(encoding, CSI"%d%c", e->id, e->letter); - InputMap::Key k = { csiEncodings[i].virtualKey, 0, 0 }; - m_inputMap.set(encoding, k); - int id = !e->id ? 1 : e->id; - for (int mod = 2; mod <= 8; ++mod) { - sprintf(encoding, CSI"%d;%d%c", id, mod, e->letter); - k.keyState = 0; - if ((mod - 1) & kCsiShiftModifier) k.keyState |= SHIFT_PRESSED; - if ((mod - 1) & kCsiAltModifier) k.keyState |= LEFT_ALT_PRESSED; - if ((mod - 1) & kCsiCtrlModifier) k.keyState |= LEFT_CTRL_PRESSED; - m_inputMap.set(encoding, k); - } - } - - // Modified F1-F4 on gnome-terminal and konsole. - for (int mod = 2; mod <= 8; ++mod) { - for (int fn = 0; fn < 4; ++fn) { - for (int fmt = 0; fmt < 1; ++fmt) { - if (fmt == 0) { - // gnome-terminal - sprintf(encoding, ESC"O1;%d%c", mod, 'P' + fn); - } else { - // konsole - sprintf(encoding, ESC"O%d%c", mod, 'P' + fn); - } - InputMap::Key k = { VK_F1 + fn, 0, 0 }; - if ((mod - 1) & kCsiShiftModifier) k.keyState |= SHIFT_PRESSED; - if ((mod - 1) & kCsiAltModifier) k.keyState |= LEFT_ALT_PRESSED; - if ((mod - 1) & kCsiCtrlModifier) k.keyState |= LEFT_CTRL_PRESSED; - m_inputMap.set(encoding, k); - } - } - } - - // Static key encodings. - for (size_t i = 0; i < DIM(keyDescriptorTable); ++i) { - m_inputMap.set(keyDescriptorTable[i].encoding, - keyDescriptorTable[i].key); - } + addDefaultEntriesToInputMap(m_inputMap); } ConsoleInput::~ConsoleInput() diff --git a/src/agent/DefaultInputMap.cc b/src/agent/DefaultInputMap.cc new file mode 100755 index 00000000..f47ad784 --- /dev/null +++ b/src/agent/DefaultInputMap.cc @@ -0,0 +1,322 @@ +// Copyright (c) 2015 Ryan Prichard +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "DefaultInputMap.h" + +#include +#include + +#include "InputMap.h" + +#define ESC "\x1B" +#define DIM(x) (sizeof(x) / sizeof((x)[0])) + +namespace { + +struct EscapeEncoding { + bool alt_prefix_allowed; + char prefix; + char id; + int modifiers; + InputMap::Key key; +}; + +// Modifiers. A "modifier" is an integer from 2 to 8 that conveys the status +// of Shift(1), Alt(2), and Ctrl(4). The value is constructed by OR'ing the +// appropriate value for each active modifier, then adding 1. +// +// Details: +// - kBare: expands to: ESC +// - kSemiMod: expands to: ESC ; +// - kBareMod: expands to: ESC +// (kBareMod is used only for Konsole's modified F1-F4) +const int kBare = 0x01; +const int kSemiMod = 0x02; +const int kBareMod = 0x04; + +// Numeric escape sequences suffixes: +// - with no flag: accept: ~ +// - kSuffixCtrl: accept: ~ ^ +// - kSuffixShift: accept: ~ $ +// - kSuffixBoth: accept: ~ ^ $ @ +const int kSuffixCtrl = 0x08; +const int kSuffixShift = 0x10; +const int kSuffixBoth = kSuffixCtrl | kSuffixShift; + +static const EscapeEncoding escapeLetterEncodings[] = { + // Conventional arrow keys + { true, '[', 'A', kBare | kSemiMod, { VK_UP, '\0', 0 } }, + { true, '[', 'B', kBare | kSemiMod, { VK_DOWN, '\0', 0 } }, + { true, '[', 'C', kBare | kSemiMod, { VK_RIGHT, '\0', 0 } }, + { true, '[', 'D', kBare | kSemiMod, { VK_LEFT, '\0', 0 } }, + + // putty. putty uses this sequence for Ctrl-Arrow, Shift-Arrow, and + // Ctrl-Shift-Arrow, but I can only decode to one choice, so I'm just + // leaving the modifier off altogether. + { true, 'O', 'A', kBare, { VK_UP, '\0', 0 } }, + { true, 'O', 'B', kBare, { VK_DOWN, '\0', 0 } }, + { true, 'O', 'C', kBare, { VK_RIGHT, '\0', 0 } }, + { true, 'O', 'D', kBare, { VK_LEFT, '\0', 0 } }, + + // rxvt, rxvt-unicode + // Shift-Ctrl-Arrow can't be identified. It's the same as Shift-Arrow. + { true, '[', 'a', kBare, { VK_UP, '\0', SHIFT_PRESSED } }, + { true, '[', 'b', kBare, { VK_DOWN, '\0', SHIFT_PRESSED } }, + { true, '[', 'c', kBare, { VK_RIGHT, '\0', SHIFT_PRESSED } }, + { true, '[', 'd', kBare, { VK_LEFT, '\0', SHIFT_PRESSED } }, + { true, 'O', 'a', kBare, { VK_UP, '\0', LEFT_CTRL_PRESSED } }, + { true, 'O', 'b', kBare, { VK_DOWN, '\0', LEFT_CTRL_PRESSED } }, + { true, 'O', 'c', kBare, { VK_RIGHT, '\0', LEFT_CTRL_PRESSED } }, + { true, 'O', 'd', kBare, { VK_LEFT, '\0', LEFT_CTRL_PRESSED } }, + + // Numpad 5 with NumLock off + // * xterm, mintty, and gnome-terminal use `ESC [ E`. + // * putty, TERM=cygwin, TERM=linux all use `ESC [ G` for 5 + // * putty uses `ESC O G` for Ctrl-5 and Shift-5. Omit the modifier + // as with putty's arrow keys. + // * I never saw modifiers inserted into these escapes, but I think + // it should be completely OK with the CSI escapes. + { true, '[', 'E', kBare | kSemiMod, { VK_NUMPAD5, '\0', 0 } }, + { true, '[', 'G', kBare | kSemiMod, { VK_NUMPAD5, '\0', 0 } }, + { true, 'O', 'G', kBare, { VK_NUMPAD5, '\0', 0 } }, + + // Home/End, letter version + // * gnome-terminal uses `ESC O [HF]`. I never saw it modified. + { true, '[', 'H', kBare | kSemiMod, { VK_HOME, '\0', 0 } }, + { true, '[', 'F', kBare | kSemiMod, { VK_END, '\0', 0 } }, + { true, 'O', 'H', kBare, { VK_HOME, '\0', 0 } }, + { true, 'O', 'F', kBare, { VK_END, '\0', 0 } }, + + // F1-F4, letter version (xterm, VTE, konsole) + { true, '[', 'P', kSemiMod, { VK_F1, '\0', 0 } }, + { true, '[', 'Q', kSemiMod, { VK_F2, '\0', 0 } }, + { true, '[', 'R', kSemiMod, { VK_F3, '\0', 0 } }, + { true, '[', 'S', kSemiMod, { VK_F4, '\0', 0 } }, + + // GNOME VTE and Konsole have special encodings for modified F1-F4: + // * [VTE] ESC O 1 ; n [PQRS] + // * [Konsole] ESC O n [PQRS] + { false, 'O', 'P', kBare | kBareMod | kSemiMod, { VK_F1, '\0', 0 } }, + { false, 'O', 'Q', kBare | kBareMod | kSemiMod, { VK_F2, '\0', 0 } }, + { false, 'O', 'R', kBare | kBareMod | kSemiMod, { VK_F3, '\0', 0 } }, + { false, 'O', 'S', kBare | kBareMod | kSemiMod, { VK_F4, '\0', 0 } }, + + { false, '[', 'Z', kBare, { VK_TAB, '\t', SHIFT_PRESSED } }, +}; + +static const EscapeEncoding escapeNumericEncodings[] = { + { true, '[', 1, kBare | kSemiMod | kSuffixBoth, { VK_HOME, '\0', 0 } }, + { true, '[', 2, kBare | kSemiMod | kSuffixBoth, { VK_INSERT, '\0', 0 } }, + { true, '[', 3, kBare | kSemiMod | kSuffixBoth, { VK_DELETE, '\0', 0 } }, + { true, '[', 4, kBare | kSemiMod | kSuffixBoth, { VK_END, '\0', 0 } }, + { true, '[', 5, kBare | kSemiMod | kSuffixBoth, { VK_PRIOR, '\0', 0 } }, + { true, '[', 6, kBare | kSemiMod | kSuffixBoth, { VK_NEXT, '\0', 0 } }, + { true, '[', 7, kBare | kSemiMod | kSuffixBoth, { VK_HOME, '\0', 0 } }, + { true, '[', 8, kBare | kSemiMod | kSuffixBoth, { VK_END, '\0', 0 } }, + { true, '[', 11, kBare | kSemiMod | kSuffixBoth, { VK_F1, '\0', 0 } }, + { true, '[', 12, kBare | kSemiMod | kSuffixBoth, { VK_F2, '\0', 0 } }, + { true, '[', 13, kBare | kSemiMod | kSuffixBoth, { VK_F3, '\0', 0 } }, + { true, '[', 14, kBare | kSemiMod | kSuffixBoth, { VK_F4, '\0', 0 } }, + { true, '[', 15, kBare | kSemiMod | kSuffixBoth, { VK_F5, '\0', 0 } }, + { true, '[', 17, kBare | kSemiMod | kSuffixBoth, { VK_F6, '\0', 0 } }, + { true, '[', 18, kBare | kSemiMod | kSuffixBoth, { VK_F7, '\0', 0 } }, + { true, '[', 19, kBare | kSemiMod | kSuffixBoth, { VK_F8, '\0', 0 } }, + { true, '[', 20, kBare | kSemiMod | kSuffixBoth, { VK_F9, '\0', 0 } }, + { true, '[', 21, kBare | kSemiMod | kSuffixBoth, { VK_F10, '\0', 0 } }, + { true, '[', 23, kBare | kSemiMod | kSuffixBoth, { VK_F11, '\0', 0 } }, + { true, '[', 24, kBare | kSemiMod | kSuffixBoth, { VK_F12, '\0', 0 } }, + { true, '[', 25, kBare | kSemiMod | kSuffixBoth, { VK_F3, '\0', SHIFT_PRESSED } }, + { true, '[', 26, kBare | kSemiMod | kSuffixBoth, { VK_F4, '\0', SHIFT_PRESSED } }, + { true, '[', 28, kBare | kSemiMod | kSuffixBoth, { VK_F5, '\0', SHIFT_PRESSED } }, + { true, '[', 29, kBare | kSemiMod | kSuffixBoth, { VK_F6, '\0', SHIFT_PRESSED } }, + { true, '[', 31, kBare | kSemiMod | kSuffixBoth, { VK_F7, '\0', SHIFT_PRESSED } }, + { true, '[', 32, kBare | kSemiMod | kSuffixBoth, { VK_F8, '\0', SHIFT_PRESSED } }, + { true, '[', 33, kBare | kSemiMod | kSuffixBoth, { VK_F9, '\0', SHIFT_PRESSED } }, + { true, '[', 34, kBare | kSemiMod | kSuffixBoth, { VK_F10, '\0', SHIFT_PRESSED } }, +}; + +const int kCsiShiftModifier = 1; +const int kCsiAltModifier = 2; +const int kCsiCtrlModifier = 4; + +static void addSimpleEntries(InputMap &inputMap) { + struct SimpleEncoding { + const char *encoding; + InputMap::Key key; + }; + + const int vkLB = VkKeyScan('[') & 0xFF; + + static const SimpleEncoding simpleEncodings[] = { + // Ctrl- seems to be handled OK by the default code path. + // TODO: Alt-ESC is encoded as ESC ESC. Can it be handled? + + { ESC, { VK_ESCAPE, '\x1B', 0, } }, + + // Alt- + { ESC"O", { 'O', 'O', LEFT_ALT_PRESSED | SHIFT_PRESSED } }, + { ESC"[", { vkLB, '[', LEFT_ALT_PRESSED } }, + + { "\x7F", { VK_BACK, '\x08', 0, } }, + { ESC"\x7F", { VK_BACK, '\x08', LEFT_ALT_PRESSED, } }, + + // Handle special F1-F5 for TERM=linux and TERM=cygwin. + { ESC"[[A", { VK_F1, '\0', 0 } }, + { ESC"[[B", { VK_F2, '\0', 0 } }, + { ESC"[[C", { VK_F3, '\0', 0 } }, + { ESC"[[D", { VK_F4, '\0', 0 } }, + { ESC"[[E", { VK_F5, '\0', 0 } }, + }; + + for (size_t i = 0; i < DIM(simpleEncodings); ++i) { + inputMap.set(simpleEncodings[i].encoding, + simpleEncodings[i].key); + } +} + +struct ExpandContext { + InputMap &inputMap; + const EscapeEncoding &e; + char *buffer; +}; + +static inline void setEncoding(const ExpandContext &ctx, int extraKeyState) { + InputMap::Key k = ctx.e.key; + k.keyState |= extraKeyState; + ctx.inputMap.set(ctx.buffer, k); +} + +static inline int keyStateForMod(int mod) { + int ret = 0; + if ((mod - 1) & kCsiShiftModifier) ret |= SHIFT_PRESSED; + if ((mod - 1) & kCsiAltModifier) ret |= LEFT_ALT_PRESSED; + if ((mod - 1) & kCsiCtrlModifier) ret |= LEFT_CTRL_PRESSED; + return ret; +} + +static void expandNumericEncodingSuffix(const ExpandContext &ctx, char *p, + int extraKeyState) { + { + char *q = p; + *q++ = '~'; + *q++ = '\0'; + setEncoding(ctx, extraKeyState); + } + if (ctx.e.modifiers & kSuffixShift) { + char *q = p; + *q++ = '$'; + *q++ = '\0'; + setEncoding(ctx, extraKeyState | SHIFT_PRESSED); + } + if (ctx.e.modifiers & kSuffixCtrl) { + char *q = p; + *q++ = '^'; + *q++ = '\0'; + setEncoding(ctx, extraKeyState | LEFT_CTRL_PRESSED); + } + if (ctx.e.modifiers & (kSuffixCtrl | kSuffixShift)) { + char *q = p; + *q++ = '@'; + *q++ = '\0'; + setEncoding(ctx, extraKeyState | SHIFT_PRESSED | LEFT_CTRL_PRESSED); + } +} + +template +static inline void expandEncodingAfterAltPrefix( + const ExpandContext &ctx, char *p, int extraKeyState) { + *p++ = '\x1b'; + *p++ = ctx.e.prefix; + if (ctx.e.modifiers & kBare) { + char *q = p; + if (is_numeric) { + q += sprintf(q, "%d", ctx.e.id); + expandNumericEncodingSuffix(ctx, q, extraKeyState); + } else { + *q++ = ctx.e.id; + *q++ = '\0'; + setEncoding(ctx, extraKeyState); + } + } + if (ctx.e.modifiers & kBareMod) { + ASSERT(!is_numeric && "kBareMod is invalid with numeric sequences"); + for (int mod = 2; mod <= 8; ++mod) { + char *q = p; + *q++ = '0' + mod; + *q++ = ctx.e.id; + *q++ = '\0'; + setEncoding(ctx, extraKeyState | keyStateForMod(mod)); + } + } + if (ctx.e.modifiers & kSemiMod) { + for (int mod = 2; mod <= 8; ++mod) { + char *q = p; + if (is_numeric) { + q += sprintf(q, "%d", ctx.e.id); + *q++ = ';'; + *q++ = '0' + mod; + expandNumericEncodingSuffix( + ctx, q, extraKeyState | keyStateForMod(mod)); + } else { + *q++ = '1'; + *q++ = ';'; + *q++ = '0' + mod; + *q++ = ctx.e.id; + *q++ = '\0'; + setEncoding(ctx, extraKeyState | keyStateForMod(mod)); + } + } + } +} + +template +static inline void expandEncoding(const ExpandContext &ctx) { + if (ctx.e.alt_prefix_allowed) { + // For better or for worse, this code expands all of: + // * ESC [ -- + // * ESC ESC [ -- Alt- + // * ESC [ 1 ; 3 -- Alt- + // * ESC ESC [ 1 ; 3 -- Alt- specified twice + // I suspect no terminal actually emits the last one (i.e. specifying + // the Alt modifier using both methods), but I have seen a terminal + // that emitted a prefix ESC for Alt and a non-Alt modifier. + char *p = ctx.buffer; + *p++ = '\x1b'; + expandEncodingAfterAltPrefix(ctx, p, LEFT_ALT_PRESSED); + } + expandEncodingAfterAltPrefix(ctx, ctx.buffer, 0); +} + +template +static void addEscapes(InputMap &inputMap, const EscapeEncoding (&encodings)[N]) { + char buffer[32]; + for (size_t i = 0; i < DIM(encodings); ++i) { + ExpandContext ctx = { inputMap, encodings[i], buffer }; + expandEncoding(ctx); + } +} + +} // anonymous namespace + +void addDefaultEntriesToInputMap(InputMap &inputMap) { + addEscapes(inputMap, escapeLetterEncodings); + addEscapes(inputMap, escapeNumericEncodings); + addSimpleEntries(inputMap); +} diff --git a/src/agent/DefaultInputMap.h b/src/agent/DefaultInputMap.h new file mode 100755 index 00000000..c4b90836 --- /dev/null +++ b/src/agent/DefaultInputMap.h @@ -0,0 +1,28 @@ +// Copyright (c) 2015 Ryan Prichard +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef DEFAULT_INPUT_MAP_H +#define DEFAULT_INPUT_MAP_H + +class InputMap; + +void addDefaultEntriesToInputMap(InputMap &inputMap); + +#endif // DEFAULT_INPUT_MAP_H diff --git a/src/agent/subdir.mk b/src/agent/subdir.mk index abb6ea63..eb52aa43 100644 --- a/src/agent/subdir.mk +++ b/src/agent/subdir.mk @@ -26,6 +26,7 @@ AGENT_OBJECTS = \ build/mingw/agent/ConsoleInput.o \ build/mingw/agent/ConsoleLine.o \ build/mingw/agent/Coord.o \ + build/mingw/agent/DefaultInputMap.o \ build/mingw/agent/EventLoop.o \ build/mingw/agent/InputMap.o \ build/mingw/agent/LargeConsoleRead.o \ diff --git a/src/winpty.gyp b/src/winpty.gyp index f200f6bc..801e970a 100644 --- a/src/winpty.gyp +++ b/src/winpty.gyp @@ -38,6 +38,8 @@ 'agent/ConsoleLine.h', 'agent/Coord.h', 'agent/Coord.cc', + 'agent/DefaultInputMap.h', + 'agent/DefaultInputMap.cc', 'agent/DsrSender.h', 'agent/EventLoop.h', 'agent/EventLoop.cc',