void ProcessInput(Action <KeyEvent> keyHandler, Action <KeyEvent> keyDownHandler, Action <KeyEvent> keyUpHandler, Action <MouseEvent> mouseHandler) { int wch; var code = Curses.get_wch(out wch); if (code == Curses.ERR) { return; } keyModifiers = new KeyModifiers(); Key k = Key.Null; if (code == Curses.KEY_CODE_YES) { if (wch == Curses.KeyResize) { if (Curses.CheckWinChange()) { TerminalResized?.Invoke(); return; } } if (wch == Curses.KeyMouse) { Curses.getmouse(out Curses.MouseEvent ev); //System.Diagnostics.Debug.WriteLine ($"ButtonState: {ev.ButtonState}; ID: {ev.ID}; X: {ev.X}; Y: {ev.Y}; Z: {ev.Z}"); mouseHandler(ToDriverMouse(ev)); return; } k = MapCursesKey(wch); if (wch >= 277 && wch <= 288) // Shift+(F1 - F12) { wch -= 12; k = Key.ShiftMask | MapCursesKey(wch); } else if (wch >= 289 && wch <= 300) // Ctrl+(F1 - F12) { wch -= 24; k = Key.CtrlMask | MapCursesKey(wch); } else if (wch >= 301 && wch <= 312) // Ctrl+Shift+(F1 - F12) { wch -= 36; k = Key.CtrlMask | Key.ShiftMask | MapCursesKey(wch); } else if (wch >= 313 && wch <= 324) // Alt+(F1 - F12) { wch -= 48; k = Key.AltMask | MapCursesKey(wch); } else if (wch >= 325 && wch <= 327) // Shift+Alt+(F1 - F3) { wch -= 60; k = Key.ShiftMask | Key.AltMask | MapCursesKey(wch); } keyDownHandler(new KeyEvent(k, MapKeyModifiers(k))); keyHandler(new KeyEvent(k, MapKeyModifiers(k))); keyUpHandler(new KeyEvent(k, MapKeyModifiers(k))); return; } // Special handling for ESC, we want to try to catch ESC+letter to simulate alt-letter as well as Alt-Fkey if (wch == 27) { Curses.timeout(200); code = Curses.get_wch(out int wch2); if (code == Curses.KEY_CODE_YES) { k = Key.AltMask | MapCursesKey(wch); } if (code == 0) { KeyEvent key; // The ESC-number handling, debatable. // Simulates the AltMask itself by pressing Alt + Space. if (wch2 == (int)Key.Space) { k = Key.AltMask; } else if (wch2 - (int)Key.Space >= (uint)Key.A && wch2 - (int)Key.Space <= (uint)Key.Z) { k = (Key)((uint)Key.AltMask + (wch2 - (int)Key.Space)); } else if (wch2 >= (uint)Key.A - 64 && wch2 <= (uint)Key.Z - 64) { k = (Key)((uint)(Key.AltMask | Key.CtrlMask) + (wch2 + 64)); } else if (wch2 >= (uint)Key.D0 && wch2 <= (uint)Key.D9) { k = (Key)((uint)Key.AltMask + (uint)Key.D0 + (wch2 - (uint)Key.D0)); } else if (wch2 == 27) { k = (Key)wch2; } else if (wch2 == Curses.KEY_CODE_SEQ) { int [] c = null; while (code == 0) { code = Curses.get_wch(out wch2); if (wch2 > 0) { Array.Resize(ref c, c == null ? 1 : c.Length + 1); c [c.Length - 1] = wch2; } } if (c [0] == 49 && c [1] == 59 && c [2] == 55 && c [3] >= 80 && c [3] <= 83) // Ctrl+Alt+(F1 - F4) { wch2 = c [3] + 185; k = Key.CtrlMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 49 && c [2] == 59 && c [3] == 55 && c [4] == 126 && c [1] >= 53 && c [1] <= 57) // Ctrl+Alt+(F5 - F8) { wch2 = c [1] == 53 ? c [1] + 216 : c [1] + 215; k = Key.CtrlMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 50 && c [2] == 59 && c [3] == 55 && c [4] == 126 && c [1] >= 48 && c [1] <= 52) // Ctrl+Alt+(F9 - F12) { wch2 = c [1] < 51 ? c [1] + 225 : c [1] + 224; k = Key.CtrlMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 49 && c [1] == 59 && c [2] == 56 && c [3] >= 80 && c [3] <= 83) // Ctrl+Shift+Alt+(F1 - F4) { wch2 = c [3] + 185; k = Key.CtrlMask | Key.ShiftMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 49 && c [2] == 59 && c [3] == 56 && c [4] == 126 && c [1] >= 53 && c [1] <= 57) // Ctrl+Shift+Alt+(F5 - F8) { wch2 = c [1] == 53 ? c [1] + 216 : c [1] + 215; k = Key.CtrlMask | Key.ShiftMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 50 && c [2] == 59 && c [3] == 56 && c [4] == 126 && c [1] >= 48 && c [1] <= 52) // Ctrl+Shift+Alt+(F9 - F12) { wch2 = c [1] < 51 ? c [1] + 225 : c [1] + 224; k = Key.CtrlMask | Key.ShiftMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 49 && c [1] == 59 && c [2] == 52 && c [3] == 83) // Shift+Alt+(F4) { wch2 = 268; k = Key.ShiftMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 49 && c [2] == 59 && c [3] == 52 && c [4] == 126 && c [1] >= 53 && c [1] <= 57) // Shift+Alt+(F5 - F8) { wch2 = c [1] < 55 ? c [1] + 216 : c [1] + 215; k = Key.ShiftMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 50 && c [2] == 59 && c [3] == 52 && c [4] == 126 && c [1] >= 48 && c [1] <= 52) // Shift+Alt+(F9 - F12) { wch2 = c [1] < 51 ? c [1] + 225 : c [1] + 224; k = Key.ShiftMask | Key.AltMask | MapCursesKey(wch2); } else if (c [0] == 54 && c [1] == 59 && c [2] == 56 && c [3] == 126) // Shift+Ctrl+Alt+KeyNPage { k = Key.ShiftMask | Key.CtrlMask | Key.AltMask | Key.PageDown; } else if (c [0] == 53 && c [1] == 59 && c [2] == 56 && c [3] == 126) // Shift+Ctrl+Alt+KeyPPage { k = Key.ShiftMask | Key.CtrlMask | Key.AltMask | Key.PageUp; } else if (c [0] == 49 && c [1] == 59 && c [2] == 56 && c [3] == 72) // Shift+Ctrl+Alt+KeyHome { k = Key.ShiftMask | Key.CtrlMask | Key.AltMask | Key.Home; } else if (c [0] == 49 && c [1] == 59 && c [2] == 56 && c [3] == 70) // Shift+Ctrl+Alt+KeyEnd { k = Key.ShiftMask | Key.CtrlMask | Key.AltMask | Key.End; } else { k = MapCursesKey(wch2); } } else { // Unfortunately there are no way to differentiate Ctrl+Alt+alfa and Ctrl+Shift+Alt+alfa. if (((Key)wch2 & Key.CtrlMask) != 0) { keyModifiers.Ctrl = true; } if (wch2 == 0) { k = Key.CtrlMask | Key.AltMask | Key.Space; } else if (wch >= (uint)Key.A && wch <= (uint)Key.Z) { keyModifiers.Shift = true; keyModifiers.Alt = true; } else if (wch2 < 256) { k = (Key)wch2; keyModifiers.Alt = true; } else { k = (Key)((uint)(Key.AltMask | Key.CtrlMask) + wch2); } } key = new KeyEvent(k, MapKeyModifiers(k)); keyDownHandler(key); keyHandler(key); } else { k = Key.Esc; keyHandler(new KeyEvent(k, MapKeyModifiers(k))); } } else if (wch == Curses.KeyTab) { k = MapCursesKey(wch); keyDownHandler(new KeyEvent(k, MapKeyModifiers(k))); keyHandler(new KeyEvent(k, MapKeyModifiers(k))); } else { // Unfortunately there are no way to differentiate Ctrl+alfa and Ctrl+Shift+alfa. k = (Key)wch; if (wch == 0) { k = Key.CtrlMask | Key.Space; } else if (wch >= (uint)Key.A - 64 && wch <= (uint)Key.Z - 64) { if ((Key)(wch + 64) != Key.J) { k = Key.CtrlMask | (Key)(wch + 64); } } else if (wch >= (uint)Key.A && wch <= (uint)Key.Z) { keyModifiers.Shift = true; } keyDownHandler(new KeyEvent(k, MapKeyModifiers(k))); keyHandler(new KeyEvent(k, MapKeyModifiers(k))); keyUpHandler(new KeyEvent(k, MapKeyModifiers(k))); } // Cause OnKeyUp and OnKeyPressed. Note that the special handling for ESC above // will not impact KeyUp. // This is causing ESC firing even if another keystroke was handled. //if (wch == Curses.KeyTab) { // keyUpHandler (new KeyEvent (MapCursesKey (wch), keyModifiers)); //} else { // keyUpHandler (new KeyEvent ((Key)wch, keyModifiers)); //} }
/// <summary> /// Constructs a new <see cref="KeyEvent"/> /// </summary> public KeyEvent() { Key = Key.Unknown; keyModifiers = new KeyModifiers(); }
/// <summary> /// Constructs a new <see cref="KeyEvent"/> from the provided Key value - can be a rune cast into a Key value /// </summary> public KeyEvent(Key k, KeyModifiers km) { Key = k; keyModifiers = km; }
void ProcessInput(Action <KeyEvent> keyHandler, Action <KeyEvent> keyDownHandler, Action <KeyEvent> keyUpHandler, Action <MouseEvent> mouseHandler) { int wch; var code = Curses.get_wch(out wch); if (code == Curses.ERR) { return; } keyModifiers = new KeyModifiers(); Key k; if (code == Curses.KEY_CODE_YES) { if (wch == Curses.KeyResize) { if (Curses.CheckWinChange()) { TerminalResized?.Invoke(); return; } } if (wch == Curses.KeyMouse) { Curses.MouseEvent ev; Curses.getmouse(out ev); mouseHandler(ToDriverMouse(ev)); return; } keyHandler(new KeyEvent(MapCursesKey(wch), keyModifiers)); keyUpHandler(new KeyEvent(MapCursesKey(wch), keyModifiers)); return; } // Special handling for ESC, we want to try to catch ESC+letter to simulate alt-letter as well as Alt-Fkey if (wch == 27) { Curses.timeout(200); code = Curses.get_wch(out int wch2); if (code == Curses.KEY_CODE_YES) { k = Key.AltMask | MapCursesKey(wch); keyHandler(new KeyEvent(k, MapKeyModifiers(k))); } if (code == 0) { KeyEvent key; // The ESC-number handling, debatable. // Simulates the AltMask itself by pressing Alt + Space. if (wch2 == (int)Key.Space) { k = Key.AltMask; key = new KeyEvent(k, MapKeyModifiers(k)); } else if (wch2 - (int)Key.Space >= 'A' && wch2 - (int)Key.Space <= 'Z') { k = (Key)((uint)Key.AltMask + (wch2 - (int)Key.Space)); key = new KeyEvent(k, MapKeyModifiers(k)); } else if (wch2 >= '1' && wch <= '9') { k = (Key)((int)Key.F1 + (wch2 - '0' - 1)); key = new KeyEvent(k, MapKeyModifiers(k)); } else if (wch2 == '0') { k = Key.F10; key = new KeyEvent(k, MapKeyModifiers(k)); } else if (wch2 == 27) { k = (Key)wch2; key = new KeyEvent(k, MapKeyModifiers(k)); } else { k = Key.AltMask | (Key)wch2; key = new KeyEvent(k, MapKeyModifiers(k)); } keyHandler(key); } else { k = Key.Esc; keyHandler(new KeyEvent(k, MapKeyModifiers(k))); } } else if (wch == Curses.KeyTab) { k = MapCursesKey(wch); keyDownHandler(new KeyEvent(k, MapKeyModifiers(k))); keyHandler(new KeyEvent(k, MapKeyModifiers(k))); } else { k = (Key)wch; keyDownHandler(new KeyEvent(k, MapKeyModifiers(k))); keyHandler(new KeyEvent(k, MapKeyModifiers(k))); } // Cause OnKeyUp and OnKeyPressed. Note that the special handling for ESC above // will not impact KeyUp. // This is causing ESC firing even if another keystroke was handled. //if (wch == Curses.KeyTab) { // keyUpHandler (new KeyEvent (MapCursesKey (wch), keyModifiers)); //} else { // keyUpHandler (new KeyEvent ((Key)wch, keyModifiers)); //} }