From c36da9e799fbd33de03c945b29d3036489791a83 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 15 Jul 2018 19:52:59 +0200 Subject: [PATCH] Keyboard functions are now in a separate class --- ChangeLog | 3 + include/final/fapplication.h | 24 +- include/final/fkey_map.h | 828 +-------------------------------- include/final/fkeyboard.h | 253 ++++++++++ include/final/fterm.h | 72 +-- include/final/ftermdetection.h | 1 + include/final/ftypes.h | 30 +- include/final/fvterm.h | 1 + src/Makefile.am | 3 + src/Makefile.clang | 3 + src/Makefile.gcc | 3 + src/Makefile.in | 22 +- src/fapplication.cpp | 203 +++----- src/fkey_map.cpp | 819 ++++++++++++++++++++++++++++++++ src/fkeyboard.cpp | 504 ++++++++++++++++++++ src/fterm.cpp | 322 ++----------- src/fvterm.cpp | 22 +- 17 files changed, 1779 insertions(+), 1334 deletions(-) create mode 100644 include/final/fkeyboard.h create mode 100644 src/fkey_map.cpp create mode 100644 src/fkeyboard.cpp diff --git a/ChangeLog b/ChangeLog index 7258dc13..f60c0c78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2017-07-15 Markus Gans + * Keyboarb functions are now in a separate class + 2017-07-08 Markus Gans * Extension of the unit test of FOptiMove diff --git a/include/final/fapplication.h b/include/final/fapplication.h index f27fbacf..fcb4df4b 100644 --- a/include/final/fapplication.h +++ b/include/final/fapplication.h @@ -138,14 +138,13 @@ class FApplication : public FWidget // Methods void init (long, long); static void cmd_options (const int&, char*[]); - bool KeyPressed(); - ssize_t readKey(); - FWidget* findKeyboardWidget(); - bool getKeyPressedState(); - void emptyKeyBufferOnTimeout(); - void parseKeyBuffer (FWidget*); - void performKeyboardAction (FWidget*); - void sendEscapeKeyPressEvent (FWidget*); + void findKeyboardWidget(); + bool isKeyPressed(); + void keyPressed(); + void keyReleased(); + void escapeKeyPressed(); + void performKeyboardAction(); + void sendEscapeKeyPressEvent(); bool sendKeyDownEvent (FWidget*); bool sendKeyPressEvent (FWidget*); bool sendKeyUpEvent (FWidget*); @@ -181,21 +180,16 @@ class FApplication : public FWidget // Data Members int app_argc; char** app_argv; - int key; - char k_buf[1024]; - char fifo_buf[512]; - int fifo_offset; - bool fifo_in_use; - int fifo_buf_size; long key_timeout; long dblclick_interval; - struct timeval time_keypressed; static FMouseControl* mouse; static eventQueue* event_queue; static int quit_code; static bool quit_now; static int loop_level; static bool process_timer_event; + static FKeyboard* keyboard; + static FWidget* keyboard_widget; static FWidget* move_size_widget; static FWidget* main_widget; static FWidget* active_window; diff --git a/include/final/fkey_map.h b/include/final/fkey_map.h index 8fb3a0bd..0d357f5f 100644 --- a/include/final/fkey_map.h +++ b/include/final/fkey_map.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2015-2017 Markus Gans * +* Copyright 2015-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -28,832 +28,14 @@ #endif #include +#include "final/ftypes.h" namespace fc { -#pragma pack(push) -#pragma pack(1) - -typedef struct -{ - int num; - char* string; - char tname[4]; -} -fkeymap; - -#pragma pack(pop) - -static fkeymap Fkey[] = -{ - { fc::Fkey_backspace, 0, "kb" }, // backspace key - { fc::Fkey_catab , 0, "ka" }, // clear-all-tabs key - { fc::Fkey_clear , 0, "kC" }, // clear-screen or erase key - { fc::Fkey_ctab , 0, "kt" }, // clear-tab key - { fc::Fkey_dc , 0, "kD" }, // delete-character key - { fc::Fkey_dl , 0, "kL" }, // delete-line key - { fc::Fkey_down , 0, "kd" }, // down-arrow key - { fc::Fkey_down , 0, "kdx"}, // down-arrow key - { fc::Fkey_eic , 0, "kM" }, // sent by rmir or smir in insert mode - { fc::Fkey_eol , 0, "kE" }, // clear-to-end-of-line key - { fc::Fkey_eos , 0, "kS" }, // clear-to-end-of-screen key - { fc::Fkey_f0 , 0, "k0" }, // F0 function key - { fc::Fkey_f1 , 0, "k1" }, // F1 function key - { fc::Fkey_f1 , 0, "k1x"}, // F1 function key - { fc::Fkey_f1 , 0, "k1X"}, // F1 function key - { fc::Fkey_f2 , 0, "k2" }, // F2 function key - { fc::Fkey_f2 , 0, "k2x"}, // F2 function key - { fc::Fkey_f2 , 0, "k2X"}, // F2 function key - { fc::Fkey_f3 , 0, "k3" }, // F3 function key - { fc::Fkey_f3 , 0, "k3x"}, // F3 function key - { fc::Fkey_f3 , 0, "k3X"}, // F3 function key - { fc::Fkey_f4 , 0, "k4" }, // F4 function key - { fc::Fkey_f4 , 0, "k4x"}, // F4 function key - { fc::Fkey_f4 , 0, "k4X"}, // F4 function key - { fc::Fkey_f5 , 0, "k5" }, // F5 function key - { fc::Fkey_f6 , 0, "k6" }, // F6 function key - { fc::Fkey_f7 , 0, "k7" }, // F7 function key - { fc::Fkey_f8 , 0, "k8" }, // F8 fucntion key - { fc::Fkey_f9 , 0, "k9" }, // F9 function key - { fc::Fkey_f10 , 0, "k;" }, // F10 function key - { fc::Fkey_home , 0, "kh" }, // home key - { fc::Fkey_home , 0, "khx"}, // home key - { fc::Fkey_ic , 0, "kI" }, // insert-character key - { fc::Fkey_il , 0, "kA" }, // insert-line key - { fc::Fkey_left , 0, "kl" }, // left-arrow key - { fc::Fkey_left , 0, "klx"}, // left-arrow key - { fc::Fkey_ll , 0, "kH" }, // last-line key - { fc::Fkey_npage , 0, "kN" }, // next-page key - { fc::Fkey_ppage , 0, "kP" }, // prev-page key - { fc::Fkey_right , 0, "kr" }, // right-arrow key - { fc::Fkey_right , 0, "krx"}, // right-arrow key - { fc::Fkey_sf , 0, "kF" }, // scroll-forward key - { fc::Fkey_sr , 0, "kR" }, // scroll-backward key - { fc::Fkey_stab , 0, "kT" }, // set-tab key - { fc::Fkey_up , 0, "ku" }, // up-arrow key - { fc::Fkey_up , 0, "kux"}, // up-arrow key - { fc::Fkey_a1 , 0, "K1" }, // upper left of keypad - { fc::Fkey_a3 , 0, "K3" }, // upper right of keypad - { fc::Fkey_b2 , 0, "K2" }, // center of keypad - { fc::Fkey_c1 , 0, "K4" }, // lower left of keypad - { fc::Fkey_c3 , 0, "K5" }, // lower right of keypad - { fc::Fkey_btab , 0, "kB" }, // back-tab key - { fc::Fkey_beg , 0, "@1" }, // begin key - { fc::Fkey_cancel , 0, "@2" }, // cancel key - { fc::Fkey_close , 0, "@3" }, // close key - { fc::Fkey_command , 0, "@4" }, // command key - { fc::Fkey_copy , 0, "@5" }, // copy key - { fc::Fkey_create , 0, "@6" }, // create key - { fc::Fkey_end , 0, "@7" }, // end key - { fc::Fkey_end , 0, "@7x"}, // end key - { fc::Fkey_end , 0, "@7X"}, // end key - { fc::Fkey_enter , 0, "@8" }, // enter/send key - { fc::Fkey_exit , 0, "@9" }, // exit key - { fc::Fkey_find , 0, "@0" }, // find key - { fc::Fkey_help , 0, "%1" }, // help key - { fc::Fkey_mark , 0, "%2" }, // mark key - { fc::Fkey_message , 0, "%3" }, // message key - { fc::Fkey_move , 0, "%4" }, // move key - { fc::Fkey_next , 0, "%5" }, // next key - { fc::Fkey_open , 0, "%6" }, // open key - { fc::Fkey_options , 0, "%7" }, // options key - { fc::Fkey_previous , 0, "%8" }, // previous key - { fc::Fkey_print , 0, "%9" }, // print key - { fc::Fkey_redo , 0, "%0" }, // redo key - { fc::Fkey_reference, 0, "&1" }, // reference key - { fc::Fkey_refresh , 0, "&2" }, // refresh key - { fc::Fkey_replace , 0, "&3" }, // replace key - { fc::Fkey_restart , 0, "&4" }, // restart key - { fc::Fkey_resume , 0, "&5" }, // resume key - { fc::Fkey_save , 0, "&6" }, // save key - { fc::Fkey_suspend , 0, "&7" }, // suspend key - { fc::Fkey_undo , 0, "&8" }, // undo key - { fc::Fkey_sbeg , 0, "&9" }, // shifted key - { fc::Fkey_scancel , 0, "&0" }, // shifted key - { fc::Fkey_scommand , 0, "*1" }, // shifted key - { fc::Fkey_scopy , 0, "*2" }, // shifted key - { fc::Fkey_screate , 0, "*3" }, // shifted key - { fc::Fkey_sdc , 0, "*4" }, // shifted key - { fc::Fkey_sdl , 0, "*5" }, // shifted key - { fc::Fkey_select , 0, "*6" }, // select key - { fc::Fkey_send , 0, "*7" }, // shifted key - { fc::Fkey_seol , 0, "*8" }, // shifted key - { fc::Fkey_sexit , 0, "*9" }, // shifted key - { fc::Fkey_sfind , 0, "*0" }, // shifted key - { fc::Fkey_shelp , 0, "#1" }, // shifted key - { fc::Fkey_shome , 0, "#2" }, // shifted key - { fc::Fkey_sic , 0, "#3" }, // shifted key - { fc::Fkey_sleft , 0, "#4" }, // shifted key - { fc::Fkey_smessage , 0, "%a" }, // shifted key - { fc::Fkey_smove , 0, "%b" }, // shifted key - { fc::Fkey_snext , 0, "%c" }, // shifted key - { fc::Fkey_soptions , 0, "%d" }, // shifted key - { fc::Fkey_sprevious, 0, "%e" }, // shifted key - { fc::Fkey_sprint , 0, "%f" }, // shifted key - { fc::Fkey_sredo , 0, "%g" }, // shifted key - { fc::Fkey_sreplace , 0, "%h" }, // shifted key - { fc::Fkey_sright , 0, "%i" }, // shifted key - { fc::Fkey_srsume , 0, "%j" }, // shifted key - { fc::Fkey_ssave , 0, "!1" }, // shifted key - { fc::Fkey_ssuspend , 0, "!2" }, // shifted key - { fc::Fkey_sundo , 0, "!3" }, // shifted key - { fc::Fkey_f11 , 0, "F1" }, // F11 function key - { fc::Fkey_f12 , 0, "F2" }, // F12 function key - { fc::Fkey_f13 , 0, "F3" }, // F13 function key - { fc::Fkey_f14 , 0, "F4" }, // F14 function key - { fc::Fkey_f15 , 0, "F5" }, // F15 function key - { fc::Fkey_f16 , 0, "F6" }, // F16 function key - { fc::Fkey_f17 , 0, "F7" }, // F17 function key - { fc::Fkey_f18 , 0, "F8" }, // F18 function key - { fc::Fkey_f19 , 0, "F9" }, // F19 function key - { fc::Fkey_f20 , 0, "FA" }, // F20 function key - { fc::Fkey_f21 , 0, "FB" }, // F21 function key - { fc::Fkey_f22 , 0, "FC" }, // F22 function key - { fc::Fkey_f23 , 0, "FD" }, // F23 function key - { fc::Fkey_f24 , 0, "FE" }, // F24 function key - { fc::Fkey_f25 , 0, "FF" }, // F25 function key - { fc::Fkey_f26 , 0, "FG" }, // F26 function key - { fc::Fkey_f27 , 0, "FH" }, // F27 function key - { fc::Fkey_f28 , 0, "FI" }, // F28 function key - { fc::Fkey_f29 , 0, "FJ" }, // F29 function key - { fc::Fkey_f30 , 0, "FK" }, // F30 function key - { fc::Fkey_f31 , 0, "FL" }, // F31 function key - { fc::Fkey_f32 , 0, "FM" }, // F32 function key - { fc::Fkey_f33 , 0, "FN" }, // F33 function key - { fc::Fkey_f34 , 0, "FO" }, // F34 function key - { fc::Fkey_f35 , 0, "FP" }, // F35 function key - { fc::Fkey_f36 , 0, "FQ" }, // F36 function key - { fc::Fkey_f37 , 0, "FR" }, // F37 function key - { fc::Fkey_f38 , 0, "FS" }, // F38 function key - { fc::Fkey_f39 , 0, "FT" }, // F39 function key - { fc::Fkey_f40 , 0, "FU" }, // F40 function key - { fc::Fkey_f41 , 0, "FV" }, // F41 function key - { fc::Fkey_f42 , 0, "FW" }, // F42 function key - { fc::Fkey_f43 , 0, "FX" }, // F43 function key - { fc::Fkey_f44 , 0, "FY" }, // F44 function key - { fc::Fkey_f45 , 0, "FZ" }, // F45 function key - { fc::Fkey_f46 , 0, "Fa" }, // F46 function key - { fc::Fkey_f47 , 0, "Fb" }, // F47 function key - { fc::Fkey_f48 , 0, "Fc" }, // F48 function key - { fc::Fkey_f49 , 0, "Fd" }, // F49 function key - { fc::Fkey_f50 , 0, "Fe" }, // F50 function key - { fc::Fkey_f51 , 0, "Ff" }, // F51 function key - { fc::Fkey_f52 , 0, "Fg" }, // F52 function key - { fc::Fkey_f53 , 0, "Fh" }, // F53 function key - { fc::Fkey_f54 , 0, "Fi" }, // F54 function key - { fc::Fkey_f55 , 0, "Fj" }, // F55 function key - { fc::Fkey_f56 , 0, "Fk" }, // F56 function key - { fc::Fkey_f57 , 0, "Fl" }, // F57 function key - { fc::Fkey_f58 , 0, "Fm" }, // F58 function key - { fc::Fkey_f59 , 0, "Fn" }, // F59 function key - { fc::Fkey_f60 , 0, "Fo" }, // F60 function key - { fc::Fkey_f61 , 0, "Fp" }, // F61 function key - { fc::Fkey_f62 , 0, "Fq" }, // F62 function key - { fc::Fkey_f63 , 0, "Fr" }, // F63 function key - { 0 , 0, "\0" } -}; - -typedef struct -{ - int num; - char string[8]; -} -fmetakeymap; - -static fmetakeymap Fmetakey[] = -{ - { fc::Fmkey_ic , "\033[2;3~" }, // M-insert - { fc::Fmkey_ic , "\033\033[2~" }, // M-insert - { fc::Fmkey_dc , "\033[3;3~" }, // M-delete - { fc::Fmkey_dc , "\033\033[3~" }, // M-delete - { fc::Fmkey_home , "\033[1;3H" }, // M-home - { fc::Fmkey_home , "\033\033[1~" }, // M-home - { fc::Fmkey_end , "\033[1;3F" }, // M-end - { fc::Fmkey_end , "\033\033[4~" }, // M-end - { fc::Fmkey_ppage , "\033[5;3~" }, // M-prev-page - { fc::Fmkey_ppage , "\033\033[5~" }, // M-prev-page - { fc::Fmkey_npage , "\033[6;3~" }, // M-next-page - { fc::Fmkey_npage , "\033\033[6~" }, // M-next-page - { fc::Fmkey_f1 , "\033[1;3P" }, // M-f1 - { fc::Fmkey_f1 , "\033\033[11~"}, // M-f1 - { fc::Fmkey_f2 , "\033[1;3Q" }, // M-f2 - { fc::Fmkey_f2 , "\033\033[12~"}, // M-f2 - { fc::Fmkey_f3 , "\033[1;3R" }, // M-f3 - { fc::Fmkey_f3 , "\033\033[13~"}, // M-f3 - { fc::Fmkey_f4 , "\033[1;3S" }, // M-f4 - { fc::Fmkey_f4 , "\033\033[14~"}, // M-f4 - { fc::Fmkey_f5 , "\033[15;3~" }, // M-f5 - { fc::Fmkey_f5 , "\033\033[15~"}, // M-f5 - { fc::Fmkey_f6 , "\033[17;3~" }, // M-f6 - { fc::Fmkey_f6 , "\033\033[17~"}, // M-f6 - { fc::Fmkey_f7 , "\033[18;3~" }, // M-f7 - { fc::Fmkey_f7 , "\033\033[18~"}, // M-f7 - { fc::Fmkey_f8 , "\033[19;3~" }, // M-f8 - { fc::Fmkey_f8 , "\033\033[19~"}, // M-f8 - { fc::Fmkey_f9 , "\033[20;3~" }, // M-f9 - { fc::Fmkey_f9 , "\033\033[20~"}, // M-f9 - { fc::Fmkey_f10 , "\033[21;3~" }, // M-f10 - { fc::Fmkey_f10 , "\033\033[21~"}, // M-f10 - { fc::Fmkey_f11 , "\033[23;3~" }, // M-f11 - { fc::Fmkey_f11 , "\033\033[23~"}, // M-f11 - { fc::Fmkey_f12 , "\033[24;3~" }, // M-f12 - { fc::Fmkey_f12 , "\033\033[24~"}, // M-f12 - { fc::Fmkey_up , "\033[1;3A" }, // M-up - { fc::Fmkey_up , "\033\033[A" }, // M-up - { fc::Fmkey_down , "\033[1;3B" }, // M-down - { fc::Fmkey_down , "\033\033[B" }, // M-down - { fc::Fmkey_right , "\033[1;3C" }, // M-right - { fc::Fmkey_right , "\033\033[C" }, // M-right - { fc::Fmkey_left , "\033[1;3D" }, // M-left - { fc::Fmkey_left , "\033\033[D" }, // M-left - { fc::Fmkey_sic , "\033[2;4~" }, // shift-M-insert - { fc::Fmkey_sdc , "\033[3;4~" }, // shift-M-delete - { fc::Fmkey_shome , "\033[1;4H" }, // shift-M-home - { fc::Fmkey_send , "\033[1;4F" }, // shift-M-end - { fc::Fmkey_sppage , "\033[5;4~" }, // shift-M-prev-page - { fc::Fmkey_snpage , "\033[6;4~" }, // shift-M-next-page - { fc::Fmkey_sf1 , "\033[1;4P" }, // shift-M-f1 - { fc::Fmkey_sf2 , "\033[1;4Q" }, // shift-M-f2 - { fc::Fmkey_sf3 , "\033[1;4R" }, // shift-M-f3 - { fc::Fmkey_sf4 , "\033[1;4S" }, // shift-M-f4 - { fc::Fmkey_sf5 , "\033[15;4~" }, // shift-M-f5 - { fc::Fmkey_sf6 , "\033[17;4~" }, // shift-M-f6 - { fc::Fmkey_sf7 , "\033[18;4~" }, // shift-M-f7 - { fc::Fmkey_sf8 , "\033[19;4~" }, // shift-M-f8 - { fc::Fmkey_sf9 , "\033[20;4~" }, // shift-M-f9 - { fc::Fmkey_sf10 , "\033[21;4~" }, // shift-M-f10 - { fc::Fmkey_sf11 , "\033[23;4~" }, // shift-M-f11 - { fc::Fmkey_sf12 , "\033[24;4~" }, // shift-M-f12 - { fc::Fmkey_sup , "\033[1;4A" }, // shift-M-up - { fc::Fmkey_sdown , "\033[1;4B" }, // shift-M-down - { fc::Fmkey_sright , "\033[1;4C" }, // shift-M-right - { fc::Fmkey_sleft , "\033[1;4D" }, // shift-M-left - { fc::Fckey_ic , "\033[2;5~" }, // ctrl-insert - { fc::Fckey_dc , "\033[3;5~" }, // ctrl-delete - { fc::Fckey_home , "\033[1;5H" }, // ctrl-home - { fc::Fckey_end , "\033[1;5F" }, // ctrl-end - { fc::Fckey_ppage , "\033[5;5~" }, // ctrl-prev-page - { fc::Fckey_npage , "\033[6;5~" }, // ctrl-next-page - { fc::Fckey_up , "\033[1;5A" }, // ctrl-up - { fc::Fckey_down , "\033[1;5B" }, // ctrl-down - { fc::Fckey_right , "\033[1;5C" }, // ctrl-right - { fc::Fckey_left , "\033[1;5D" }, // ctrl-left - { fc::Fckey_sic , "\033[2;6~" }, // shift-ctrl-M-insert - { fc::Fckey_sdc , "\033[3;6~" }, // shift-ctrl-M-delete - { fc::Fckey_shome , "\033[1;6H" }, // shift-ctrl-M-home - { fc::Fckey_send , "\033[1;6F" }, // shift-ctrl-M-end - { fc::Fckey_sppage , "\033[5;6~" }, // shift-ctrl-M-prev-page - { fc::Fckey_snpage , "\033[6;6~" }, // shift-ctrl-M-next-page - { fc::Fckey_sup , "\033[1;6A" }, // shift-ctrl-M-up - { fc::Fckey_sdown , "\033[1;6B" }, // shift-ctrl-M-down - { fc::Fckey_sright , "\033[1;6C" }, // shift-ctrl-M-right - { fc::Fckey_sleft , "\033[1;6D" }, // shift-ctrl-M-left - { fc::Fcmkey_ic , "\033[2;7~" }, // ctrl-M-insert - { fc::Fcmkey_dc , "\033[3;7~" }, // ctrl-M-delete - { fc::Fcmkey_home , "\033[1;7H" }, // ctrl-M-home - { fc::Fcmkey_end , "\033[1;7F" }, // ctrl-M-end - { fc::Fcmkey_ppage , "\033[5;7~" }, // ctrl-M-prev-page - { fc::Fcmkey_npage , "\033[6;7~" }, // ctrl-M-next-page - { fc::Fcmkey_up , "\033[1;7A" }, // ctrl-M-up - { fc::Fcmkey_down , "\033[1;7B" }, // ctrl-M-down - { fc::Fcmkey_right , "\033[1;7C" }, // ctrl-M-right - { fc::Fcmkey_left , "\033[1;7D" }, // ctrl-M-left - { fc::Fcmkey_sic , "\033[2;8~" }, // shift-ctrl-M-insert - { fc::Fcmkey_sdc , "\033[3;8~" }, // shift-ctrl-M-delete - { fc::Fcmkey_shome , "\033[1;8H" }, // shift-ctrl-M-home - { fc::Fcmkey_send , "\033[1;8F" }, // shift-ctrl-M-end - { fc::Fcmkey_sppage , "\033[5;8~" }, // shift-ctrl-M-prev-page - { fc::Fcmkey_snpage , "\033[6;8~" }, // shift-ctrl-M-next-page - { fc::Fcmkey_sf1 , "\033[1;8P" }, // shift-ctrl-M-f1 - { fc::Fcmkey_sf2 , "\033[1;8Q" }, // shift-ctrl-M-f2 - { fc::Fcmkey_sf3 , "\033[1;8R" }, // shift-ctrl-M-f3 - { fc::Fcmkey_sf4 , "\033[1;8S" }, // shift-ctrl-M-f4 - { fc::Fcmkey_sf5 , "\033[15;8~" }, // shift-ctrl-M-f5 - { fc::Fcmkey_sf6 , "\033[17;8~" }, // shift-ctrl-M-f6 - { fc::Fcmkey_sf7 , "\033[18;8~" }, // shift-ctrl-M-f7 - { fc::Fcmkey_sf8 , "\033[19;8~" }, // shift-ctrl-M-f8 - { fc::Fcmkey_sf9 , "\033[20;8~" }, // shift-ctrl-M-f9 - { fc::Fcmkey_sf10 , "\033[21;8~" }, // shift-ctrl-M-f10 - { fc::Fcmkey_sf11 , "\033[23;8~" }, // shift-ctrl-M-f11 - { fc::Fcmkey_sf12 , "\033[24;8~" }, // shift-ctrl-M-f12 - { fc::Fcmkey_sup , "\033[1;8A" }, // shift-ctrl-M-up - { fc::Fcmkey_sdown , "\033[1;8B" }, // shift-ctrl-M-down - { fc::Fcmkey_sright , "\033[1;8C" }, // shift-ctrl-M-right - { fc::Fcmkey_sleft , "\033[1;8D" }, // shift-ctrl-M-left - { fc::Fkey_menu , "\033[29~" }, // menu - { fc::Fkey_smenu , "\033[29$" }, // shift-menu - { fc::Fkey_smenu , "\033[29;2~" }, // shift-menu - { fc::Fckey_menu , "\033[29^" }, // ctrl-menu - { fc::Fckey_menu , "\033[29;5~" }, // ctrl-menu - { fc::Fckey_smenu , "\033[29@" }, // shift-ctrl-menu - { fc::Fckey_smenu , "\033[29;6~" }, // shift-ctrl-menu - { fc::Fmkey_menu , "\033[29;3~" }, // M-menu - { fc::Fmkey_smenu , "\033[29;4~" }, // shift-M-menu - { fc::Fcmkey_menu , "\033[29;7~" }, // ctrl-M-menu - { fc::Fcmkey_smenu , "\033[29;8~" }, // shift-ctrl-M-menu - { fc::Fkey_escape_mintty , "\033O["}, // mintty Esc - { fc::Fmkey_tab , "\033\t"}, // M-tab - { fc::Fmkey_enter , "\033\n"}, // M-enter - { fc::Fmkey_enter , "\033\r"}, // M-enter - { fc::Fmkey_space , "\033 " }, // M-' ' - { fc::Fmkey_bang , "\033!" }, // M-! - { fc::Fmkey_quotes , "\033\""}, // M-" - { fc::Fmkey_hash , "\033#" }, // M-# - { fc::Fmkey_dollar , "\033$" }, // M-$ - { fc::Fmkey_percent , "\033%" }, // M-% - { fc::Fmkey_ampersand , "\033&" }, // M-& - { fc::Fmkey_apostrophe , "\033'" }, // M-' - { fc::Fmkey_left_parenthesis , "\033(" }, // M-( - { fc::Fmkey_right_parenthesis , "\033)" }, // M-) - { fc::Fmkey_asterisk , "\033*" }, // M-* - { fc::Fmkey_plus , "\033+" }, // M-+ - { fc::Fmkey_comma , "\033," }, // M-, - { fc::Fmkey_minus , "\033-" }, // M-'-' - { fc::Fmkey_full_stop , "\033." }, // M-. - { fc::Fmkey_slash , "\033/" }, // M-/ - { fc::Fmkey_0 , "\0330" }, // M-0 - { fc::Fmkey_1 , "\0331" }, // M-1 - { fc::Fmkey_2 , "\0332" }, // M-2 - { fc::Fmkey_3 , "\0333" }, // M-3 - { fc::Fmkey_4 , "\0334" }, // M-4 - { fc::Fmkey_5 , "\0335" }, // M-5 - { fc::Fmkey_6 , "\0336" }, // M-6 - { fc::Fmkey_7 , "\0337" }, // M-7 - { fc::Fmkey_8 , "\0338" }, // M-8 - { fc::Fmkey_9 , "\0339" }, // M-9 - { fc::Fmkey_colon , "\033:" }, // M-: - { fc::Fmkey_semicolon , "\033;" }, // M-; - { fc::Fmkey_less_than , "\033<" }, // M-< - { fc::Fmkey_equals , "\033=" }, // M-= - { fc::Fmkey_greater_than , "\033>" }, // M-> - { fc::Fmkey_question_mark , "\033?" }, // M-? - { fc::Fmkey_at , "\033@" }, // M-@ - { fc::Fmkey_A , "\033A" }, // M-A - { fc::Fmkey_B , "\033B" }, // M-B - { fc::Fmkey_C , "\033C" }, // M-C - { fc::Fmkey_D , "\033D" }, // M-D - { fc::Fmkey_E , "\033E" }, // M-E - { fc::Fmkey_F , "\033F" }, // M-F - { fc::Fmkey_G , "\033G" }, // M-G - { fc::Fmkey_H , "\033H" }, // M-H - { fc::Fmkey_I , "\033I" }, // M-I - { fc::Fmkey_J , "\033J" }, // M-J - { fc::Fmkey_K , "\033K" }, // M-K - { fc::Fmkey_L , "\033L" }, // M-L - { fc::Fmkey_M , "\033M" }, // M-M - { fc::Fmkey_N , "\033N" }, // M-N - { fc::Fmkey_O , "\033O" }, // M-O - { fc::Fmkey_P , "\033P" }, // M-P - { fc::Fmkey_Q , "\033Q" }, // M-Q - { fc::Fmkey_R , "\033R" }, // M-R - { fc::Fmkey_S , "\033S" }, // M-S - { fc::Fmkey_T , "\033T" }, // M-T - { fc::Fmkey_U , "\033U" }, // M-U - { fc::Fmkey_V , "\033V" }, // M-V - { fc::Fmkey_W , "\033W" }, // M-W - { fc::Fmkey_X , "\033X" }, // M-X - { fc::Fmkey_Y , "\033Y" }, // M-Y - { fc::Fmkey_Z , "\033Z" }, // M-Z - { fc::Fmkey_left_square_bracket , "\033[" }, // M-[ - { fc::Fmkey_backslash , "\033\\"}, // M-'\' - { fc::Fmkey_right_square_bracket , "\033]" }, // M-] - { fc::Fmkey_caret , "\033^" }, // M-^ - { fc::Fmkey_underscore , "\033_" }, // M-_ - { fc::Fmkey_grave_accent , "\033`" }, // M-` - { fc::Fmkey_a , "\033a" }, // M-a - { fc::Fmkey_b , "\033b" }, // M-b - { fc::Fmkey_c , "\033c" }, // M-c - { fc::Fmkey_d , "\033d" }, // M-d - { fc::Fmkey_e , "\033e" }, // M-e - { fc::Fmkey_f , "\033f" }, // M-f - { fc::Fmkey_g , "\033g" }, // M-g - { fc::Fmkey_h , "\033h" }, // M-h - { fc::Fmkey_i , "\033i" }, // M-i - { fc::Fmkey_j , "\033j" }, // M-j - { fc::Fmkey_k , "\033k" }, // M-k - { fc::Fmkey_l , "\033l" }, // M-l - { fc::Fmkey_m , "\033m" }, // M-m - { fc::Fmkey_n , "\033n" }, // M-n - { fc::Fmkey_o , "\033o" }, // M-o - { fc::Fmkey_p , "\033p" }, // M-p - { fc::Fmkey_q , "\033q" }, // M-q - { fc::Fmkey_r , "\033r" }, // M-r - { fc::Fmkey_s , "\033s" }, // M-s - { fc::Fmkey_t , "\033t" }, // M-t - { fc::Fmkey_u , "\033u" }, // M-u - { fc::Fmkey_v , "\033v" }, // M-v - { fc::Fmkey_w , "\033w" }, // M-w - { fc::Fmkey_x , "\033x" }, // M-x - { fc::Fmkey_y , "\033y" }, // M-y - { fc::Fmkey_z , "\033z" }, // M-z - { fc::Fmkey_left_curly_bracket , "\033{" }, // M-{ - { fc::Fmkey_vertical_bar , "\033|" }, // M-| - { fc::Fmkey_right_curly_bracket , "\033}" }, // M-} - { fc::Fmkey_tilde , "\033~" }, // M-~ - { 0 , "\0" } -}; - - -#pragma pack(push) -#pragma pack(1) - -typedef struct -{ - int num; - char string[25]; -} -keyname; - -#pragma pack(pop) - -static keyname FkeyName[] = -{ - { fc::Fckey_a , "Ctrl+A" }, - { fc::Fckey_b , "Ctrl+B" }, - { fc::Fckey_c , "Ctrl+C" }, - { fc::Fckey_d , "Ctrl+D" }, - { fc::Fckey_e , "Ctrl+E" }, - { fc::Fckey_f , "Ctrl+F" }, - { fc::Fckey_g , "Ctrl+G" }, - { fc::Fkey_erase , "Backspace" }, // Ctrl+H - { fc::Fkey_tab , "Tab" }, // Ctrl+I - { fc::Fckey_j , "Ctrl+J" }, - { fc::Fckey_h , "Ctrl+K" }, - { fc::Fckey_l , "Ctrl+L" }, - { fc::Fkey_return , "Return" }, // Ctrl+M - { fc::Fckey_n , "Ctrl+N" }, - { fc::Fckey_o , "Ctrl+O" }, - { fc::Fckey_p , "Ctrl+P" }, - { fc::Fckey_q , "Ctrl+Q" }, - { fc::Fckey_r , "Ctrl+R" }, - { fc::Fckey_s , "Ctrl+S" }, - { fc::Fckey_t , "Ctrl+T" }, - { fc::Fckey_u , "Ctrl+U" }, - { fc::Fckey_v , "Ctrl+V" }, - { fc::Fckey_w , "Ctrl+W" }, - { fc::Fckey_x , "Ctrl+X" }, - { fc::Fckey_y , "Ctrl+Y" }, - { fc::Fckey_z , "Ctrl+Z" }, - { fc::Fkey_escape , "Esc" }, // Ctrl+[ - { fc::Fckey_backslash , "Ctrl+\\" }, - { fc::Fckey_right_square_bracket, "Ctrl+]" }, - { fc::Fckey_caret , "Ctrl+^" }, - { fc::Fckey_underscore , "Ctrl+_" }, - { fc::Fkey_space , "Space" }, - { fc::Fckey_space , "Ctrl+Space" }, // Ctrl+(Space or @) - { fc::Fkey_backspace , "Backspace" }, - { fc::Fkey_catab , "Clear-All-Tabs" }, - { fc::Fkey_clear , "Clear-Screen" }, - { fc::Fkey_ctab , "Clear-Tab" }, - { fc::Fkey_dc , "Del" }, - { fc::Fkey_dl , "Del-line" }, - { fc::Fkey_down , "Down" }, - { fc::Fkey_eic , "Exit-Ins" }, - { fc::Fkey_eol , "Clear-End-of-Line" }, - { fc::Fkey_eos , "Clear-End-of-Screen" }, - { fc::Fkey_f0 , "F0" }, - { fc::Fkey_f1 , "F1" }, - { fc::Fkey_f2 , "F2" }, - { fc::Fkey_f3 , "F3" }, - { fc::Fkey_f4 , "F4" }, - { fc::Fkey_f5 , "F5" }, - { fc::Fkey_f6 , "F6" }, - { fc::Fkey_f7 , "F7" }, - { fc::Fkey_f8 , "F8" }, - { fc::Fkey_f9 , "F9" }, - { fc::Fkey_f10 , "F10" }, - { fc::Fkey_home , "Home" }, - { fc::Fkey_ic , "Ins" }, - { fc::Fkey_il , "Ins-Line" }, - { fc::Fkey_left , "Left" }, - { fc::Fkey_ll , "Lower-Left" }, - { fc::Fkey_npage , "PgDn" }, - { fc::Fkey_ppage , "PgUp" }, - { fc::Fkey_right , "Right" }, - { fc::Fkey_sf , "Scroll-Forward" }, - { fc::Fkey_sr , "Scroll-Backward" }, - { fc::Fkey_stab , "Set-Tab" }, - { fc::Fkey_up , "Up" }, - { fc::Fkey_a1 , "Upper-Left" }, - { fc::Fkey_a3 , "Upper-Right" }, - { fc::Fkey_b2 , "Center" }, - { fc::Fkey_c1 , "Lower-Left" }, - { fc::Fkey_c3 , "Lower-Right" }, - { fc::Fkey_btab , "Shift+Tab" }, - { fc::Fkey_beg , "Begin" }, - { fc::Fkey_cancel , "Cancel" }, - { fc::Fkey_close , "Close" }, - { fc::Fkey_command , "Command" }, - { fc::Fkey_copy , "Copy" }, - { fc::Fkey_create , "Create" }, - { fc::Fkey_end , "End" }, - { fc::Fkey_enter , "Enter" }, - { fc::Fkey_exit , "Exit" }, - { fc::Fkey_find , "Find" }, - { fc::Fkey_help , "Help" }, - { fc::Fkey_mark , "Mark" }, - { fc::Fkey_message , "Message" }, - { fc::Fkey_move , "Move" }, - { fc::Fkey_next , "Next" }, - { fc::Fkey_open , "Open" }, - { fc::Fkey_options , "Options" }, - { fc::Fkey_previous , "Previous" }, - { fc::Fkey_print , "Print" }, - { fc::Fkey_redo , "Redo" }, - { fc::Fkey_reference , "Reference" }, - { fc::Fkey_refresh , "Refresh" }, - { fc::Fkey_replace , "Replace" }, - { fc::Fkey_restart , "Restart" }, - { fc::Fkey_resume , "Resume" }, - { fc::Fkey_save , "Save" }, - { fc::Fkey_suspend , "Suspend" }, - { fc::Fkey_undo , "Undo" }, - { fc::Fkey_sbeg , "Shift+Begin" }, - { fc::Fkey_scancel , "Shift+Cancel" }, - { fc::Fkey_scommand , "Shift+Command" }, - { fc::Fkey_scopy , "Shift+Copy" }, - { fc::Fkey_screate , "Shift+Create" }, - { fc::Fkey_sdc , "Shift+Del" }, - { fc::Fkey_sdl , "Shift+Del-line" }, - { fc::Fkey_select , "Select" }, - { fc::Fkey_send , "Shift+End" }, - { fc::Fkey_seol , "Shift+Clear-End-of-Line" }, - { fc::Fkey_sexit , "Shift+Exit" }, - { fc::Fkey_sfind , "Shift+Find" }, - { fc::Fkey_shelp , "Shift+Help" }, - { fc::Fkey_shome , "Shift+Home" }, - { fc::Fkey_sic , "Shift+Ins" }, - { fc::Fkey_sleft , "Shift+Left" }, - { fc::Fkey_smessage , "Shift+Message" }, - { fc::Fkey_smove , "Shift+Move" }, - { fc::Fkey_snext , "Shift+Next" }, - { fc::Fkey_soptions , "Shift+Options" }, - { fc::Fkey_sprevious , "Shift+Previous" }, - { fc::Fkey_sprint , "Shift+Print" }, - { fc::Fkey_sredo , "Shift+Redo" }, - { fc::Fkey_sreplace , "Shift+Replace" }, - { fc::Fkey_sright , "Shift+Right" }, - { fc::Fkey_srsume , "Shift+Resume" }, - { fc::Fkey_ssave , "Shift+Save" }, - { fc::Fkey_ssuspend , "Shift+Suspend" }, - { fc::Fkey_sundo , "Shift+Undo" }, - { fc::Fkey_f11 , "F11" }, - { fc::Fkey_f12 , "F12" }, - { fc::Fkey_f13 , "Shift+F1" }, - { fc::Fkey_f14 , "Shift+F2" }, - { fc::Fkey_f15 , "Shift+F3" }, - { fc::Fkey_f16 , "Shift+F4" }, - { fc::Fkey_f17 , "Shift+F5" }, - { fc::Fkey_f18 , "Shift+F6" }, - { fc::Fkey_f19 , "Shift+F7" }, - { fc::Fkey_f20 , "Shift+F8" }, - { fc::Fkey_f21 , "Shift+F9" }, - { fc::Fkey_f22 , "Shift+F10" }, - { fc::Fkey_f23 , "Shift+F11" }, - { fc::Fkey_f24 , "Shift+F12" }, - { fc::Fkey_f25 , "Ctrl+F1" }, - { fc::Fkey_f26 , "Ctrl+F2" }, - { fc::Fkey_f27 , "Ctrl+F3" }, - { fc::Fkey_f28 , "Ctrl+F4" }, - { fc::Fkey_f29 , "Ctrl+F5" }, - { fc::Fkey_f30 , "Ctrl+F6" }, - { fc::Fkey_f31 , "Ctrl+F7" }, - { fc::Fkey_f32 , "Ctrl+F8" }, - { fc::Fkey_f33 , "Ctrl+F9" }, - { fc::Fkey_f34 , "Ctrl+F10" }, - { fc::Fkey_f35 , "Ctrl+F11" }, - { fc::Fkey_f36 , "Ctrl+F12" }, - { fc::Fkey_f37 , "Shift+Ctrl+F1" }, - { fc::Fkey_f38 , "Shift+Ctrl+F2" }, - { fc::Fkey_f39 , "Shift+Ctrl+F3" }, - { fc::Fkey_f40 , "Shift+Ctrl+F4" }, - { fc::Fkey_f41 , "Shift+Ctrl+F5" }, - { fc::Fkey_f42 , "Shift+Ctrl+F6" }, - { fc::Fkey_f43 , "Shift+Ctrl+F7" }, - { fc::Fkey_f44 , "Shift+Ctrl+F8" }, - { fc::Fkey_f45 , "Shift+Ctrl+F9" }, - { fc::Fkey_f46 , "Shift+Ctrl+F10" }, - { fc::Fkey_f47 , "Shift+Ctrl+F11" }, - { fc::Fkey_f48 , "Shift+Ctrl+F12" }, - { fc::Fkey_f49 , "Meta+F1" }, - { fc::Fkey_f50 , "Meta+F2" }, - { fc::Fkey_f51 , "Meta+F3" }, - { fc::Fkey_f52 , "Meta+F4" }, - { fc::Fkey_f53 , "Meta+F5" }, - { fc::Fkey_f54 , "Meta+F6" }, - { fc::Fkey_f55 , "Meta+F7" }, - { fc::Fkey_f56 , "Meta+F8" }, - { fc::Fkey_f57 , "Meta+F9" }, - { fc::Fkey_f58 , "Meta+F10" }, - { fc::Fkey_f59 , "Meta+F11" }, - { fc::Fkey_f60 , "Meta+F12" }, - { fc::Fkey_f61 , "Shift+Meta+F1" }, - { fc::Fkey_f62 , "Shift+Meta+F2" }, - { fc::Fkey_f63 , "Shift+Meta+F3" }, - { fc::Fmkey_ic , "Meta+Ins" }, - { fc::Fmkey_dc , "Meta+Del" }, - { fc::Fmkey_home , "Meta+Home" }, - { fc::Fmkey_end , "Meta+End" }, - { fc::Fmkey_ppage , "Meta+PgUp" }, - { fc::Fmkey_npage , "Meta+PgDn" }, - { fc::Fmkey_f1 , "Meta+F1" }, - { fc::Fmkey_f2 , "Meta+F2" }, - { fc::Fmkey_f3 , "Meta+F3" }, - { fc::Fmkey_f4 , "Meta+F4" }, - { fc::Fmkey_f5 , "Meta+F5" }, - { fc::Fmkey_f6 , "Meta+F6" }, - { fc::Fmkey_f7 , "Meta+F7" }, - { fc::Fmkey_f8 , "Meta+F8" }, - { fc::Fmkey_f9 , "Meta+F9" }, - { fc::Fmkey_f10 , "Meta+F10" }, - { fc::Fmkey_f11 , "Meta+F11" }, - { fc::Fmkey_f12 , "Meta+F12" }, - { fc::Fmkey_up , "Meta+Up" }, - { fc::Fmkey_down , "Meta+Down" }, - { fc::Fmkey_right , "Meta+Right" }, - { fc::Fmkey_left , "Meta+Left" }, - { fc::Fmkey_sic , "Shift+Meta+Ins" }, - { fc::Fmkey_sdc , "Shift+Meta+Del" }, - { fc::Fmkey_shome , "Shift+Meta+Home" }, - { fc::Fmkey_send , "Shift+Meta+End" }, - { fc::Fmkey_sppage , "Shift+Meta+PgUp" }, - { fc::Fmkey_snpage , "Shift+Meta+PgDn" }, - { fc::Fmkey_sf1 , "Shift+Meta+F1" }, - { fc::Fmkey_sf2 , "Shift+Meta+F2" }, - { fc::Fmkey_sf3 , "Shift+Meta+F3" }, - { fc::Fmkey_sf4 , "Shift+Meta+F4" }, - { fc::Fmkey_sf5 , "Shift+Meta+F5" }, - { fc::Fmkey_sf6 , "Shift+Meta+F6" }, - { fc::Fmkey_sf7 , "Shift+Meta+F7" }, - { fc::Fmkey_sf8 , "Shift+Meta+F8" }, - { fc::Fmkey_sf9 , "Shift+Meta+F9" }, - { fc::Fmkey_sf10 , "Shift+Meta+F10" }, - { fc::Fmkey_sf11 , "Shift+Meta+F11" }, - { fc::Fmkey_sf12 , "Shift+Meta+F12" }, - { fc::Fmkey_sup , "Shift+Meta+Up" }, - { fc::Fmkey_sdown , "Shift+Meta+Down" }, - { fc::Fmkey_sright , "Shift+Meta+Right" }, - { fc::Fmkey_sleft , "Shift+Meta+Left" }, - { fc::Fckey_ic , "Ctrl+Ins" }, - { fc::Fckey_dc , "Ctrl+Del" }, - { fc::Fckey_home , "Ctrl+Home" }, - { fc::Fckey_end , "Ctrl+End" }, - { fc::Fckey_ppage , "Ctrl+PgUp" }, - { fc::Fckey_npage , "Ctrl+PgDn" }, - { fc::Fckey_up , "Ctrl+Up" }, - { fc::Fckey_down , "Ctrl+Down" }, - { fc::Fckey_right , "Ctrl+Right" }, - { fc::Fckey_left , "Ctrl+Left" }, - { fc::Fckey_sic , "Shift+Ctrl+Ins" }, - { fc::Fckey_sdc , "Shift+Ctrl+Del" }, - { fc::Fckey_shome , "Shift+Ctrl+Home" }, - { fc::Fckey_send , "Shift+Ctrl+End" }, - { fc::Fckey_sppage , "Shift+Ctrl+PgUp" }, - { fc::Fckey_snpage , "Shift+Ctrl+PgDn" }, - { fc::Fckey_sup , "Shift+Ctrl+Up" }, - { fc::Fckey_sdown , "Shift+Ctrl+Down" }, - { fc::Fckey_sright , "Shift+Ctrl+Right" }, - { fc::Fckey_sleft , "Shift+Ctrl+Left" }, - { fc::Fcmkey_ic , "Ctrl+Meta+Ins" }, - { fc::Fcmkey_dc , "Ctrl+Meta+Del" }, - { fc::Fcmkey_home , "Ctrl+Meta+Home" }, - { fc::Fcmkey_end , "Ctrl+Meta+End" }, - { fc::Fcmkey_ppage , "Ctrl+Meta+PgUp" }, - { fc::Fcmkey_npage , "Ctrl+Meta+PgDn" }, - { fc::Fcmkey_up , "Ctrl+Meta+Up" }, - { fc::Fcmkey_down , "Ctrl+Meta+Down" }, - { fc::Fcmkey_right , "Ctrl+Meta+Right" }, - { fc::Fcmkey_left , "Ctrl+Meta+Left" }, - { fc::Fcmkey_sic , "Shift+Ctrl+Meta+Ins" }, - { fc::Fcmkey_sdc , "Shift+Ctrl+Meta+Del" }, - { fc::Fcmkey_shome , "Shift+Ctrl+Meta+Home" }, - { fc::Fcmkey_send , "Shift+Ctrl+Meta+End" }, - { fc::Fcmkey_sppage , "Shift+Ctrl+Meta+PgUp" }, - { fc::Fcmkey_snpage , "Shift+Ctrl+Meta+PgDn" }, - { fc::Fcmkey_sf1 , "Shift+Ctrl+Meta+F1" }, - { fc::Fcmkey_sf2 , "Shift+Ctrl+Meta+F2" }, - { fc::Fcmkey_sf3 , "Shift+Ctrl+Meta+F3" }, - { fc::Fcmkey_sf4 , "Shift+Ctrl+Meta+F4" }, - { fc::Fcmkey_sf5 , "Shift+Ctrl+Meta+F5" }, - { fc::Fcmkey_sf6 , "Shift+Ctrl+Meta+F6" }, - { fc::Fcmkey_sf7 , "Shift+Ctrl+Meta+F7" }, - { fc::Fcmkey_sf8 , "Shift+Ctrl+Meta+F8" }, - { fc::Fcmkey_sf9 , "Shift+Ctrl+Meta+F9" }, - { fc::Fcmkey_sf10 , "Shift+Ctrl+Meta+F10" }, - { fc::Fcmkey_sf11 , "Shift+Ctrl+Meta+F11" }, - { fc::Fcmkey_sf12 , "Shift+Ctrl+Meta+F12" }, - { fc::Fcmkey_sup , "Shift+Ctrl+Meta+Up" }, - { fc::Fcmkey_sdown , "Shift+Ctrl+Meta+Down" }, - { fc::Fcmkey_sright , "Shift+Ctrl+Meta+Right" }, - { fc::Fcmkey_sleft , "Shift+Ctrl+Meta+Left" }, - { fc::Fkey_menu , "Menu" }, - { fc::Fkey_smenu , "Shift+Menu" }, - { fc::Fckey_menu , "Ctrl+Menu" }, - { fc::Fckey_smenu , "Shift+Ctrl+Menu" }, - { fc::Fmkey_menu , "Meta+Menu" }, - { fc::Fmkey_smenu , "Shift+Meta+Menu" }, - { fc::Fcmkey_menu , "Ctrl+Meta+Menu" }, - { fc::Fcmkey_smenu , "Shift+Ctrl+Meta+Menu" }, - { fc::Fmkey_tab , "Meta+Tab" }, - { fc::Fmkey_enter , "Meta+Enter" }, - { fc::Fmkey_space , "Meta+Space" }, - { fc::Fmkey_bang , "Meta+!" }, - { fc::Fmkey_quotes , "Meta+\"" }, - { fc::Fmkey_hash , "Meta+#" }, - { fc::Fmkey_dollar , "Meta+$" }, - { fc::Fmkey_percent , "Meta+%" }, - { fc::Fmkey_ampersand , "Meta+&" }, - { fc::Fmkey_apostrophe , "Meta+'" }, - { fc::Fmkey_left_parenthesis , "Meta+(" }, - { fc::Fmkey_right_parenthesis , "Meta+)" }, - { fc::Fmkey_asterisk , "Meta+*" }, - { fc::Fmkey_plus , "Meta++" }, - { fc::Fmkey_comma , "Meta+," }, - { fc::Fmkey_minus , "Meta+-" }, - { fc::Fmkey_full_stop , "Meta+." }, - { fc::Fmkey_slash , "Meta+/" }, - { fc::Fmkey_0 , "Meta+0" }, - { fc::Fmkey_1 , "Meta+1" }, - { fc::Fmkey_2 , "Meta+2" }, - { fc::Fmkey_3 , "Meta+3" }, - { fc::Fmkey_4 , "Meta+4" }, - { fc::Fmkey_5 , "Meta+5" }, - { fc::Fmkey_6 , "Meta+6" }, - { fc::Fmkey_7 , "Meta+7" }, - { fc::Fmkey_8 , "Meta+8" }, - { fc::Fmkey_9 , "Meta+9" }, - { fc::Fmkey_colon , "Meta+:" }, - { fc::Fmkey_semicolon , "Meta+;" }, - { fc::Fmkey_less_than , "Meta+<" }, - { fc::Fmkey_equals , "Meta+=" }, - { fc::Fmkey_greater_than , "Meta+>" }, - { fc::Fmkey_question_mark , "Meta+?" }, - { fc::Fmkey_at , "Meta+@" }, - { fc::Fmkey_A , "Shift+Meta+A" }, - { fc::Fmkey_B , "Shift+Meta+B" }, - { fc::Fmkey_C , "Shift+Meta+C" }, - { fc::Fmkey_D , "Shift+Meta+D" }, - { fc::Fmkey_E , "Shift+Meta+E" }, - { fc::Fmkey_F , "Shift+Meta+F" }, - { fc::Fmkey_G , "Shift+Meta+G" }, - { fc::Fmkey_H , "Shift+Meta+H" }, - { fc::Fmkey_I , "Shift+Meta+I" }, - { fc::Fmkey_J , "Shift+Meta+J" }, - { fc::Fmkey_K , "Shift+Meta+K" }, - { fc::Fmkey_L , "Shift+Meta+L" }, - { fc::Fmkey_M , "Shift+Meta+M" }, - { fc::Fmkey_N , "Shift+Meta+N" }, - { fc::Fmkey_O , "Shift+Meta+O" }, - { fc::Fmkey_P , "Shift+Meta+P" }, - { fc::Fmkey_Q , "Shift+Meta+Q" }, - { fc::Fmkey_R , "Shift+Meta+R" }, - { fc::Fmkey_S , "Shift+Meta+S" }, - { fc::Fmkey_T , "Shift+Meta+T" }, - { fc::Fmkey_U , "Shift+Meta+U" }, - { fc::Fmkey_V , "Shift+Meta+V" }, - { fc::Fmkey_W , "Shift+Meta+W" }, - { fc::Fmkey_X , "Shift+Meta+X" }, - { fc::Fmkey_Y , "Shift+Meta+Y" }, - { fc::Fmkey_Z , "Shift+Meta+Z" }, - { fc::Fmkey_left_square_bracket , "Meta+[" }, - { fc::Fmkey_backslash , "Meta+\\" }, - { fc::Fmkey_right_square_bracket, "Meta+]" }, - { fc::Fmkey_caret , "Meta+^" }, - { fc::Fmkey_underscore , "Meta+_" }, - { fc::Fmkey_grave_accent , "Meta+`" }, - { fc::Fmkey_a , "Meta+A" }, - { fc::Fmkey_b , "Meta+B" }, - { fc::Fmkey_c , "Meta+C" }, - { fc::Fmkey_d , "Meta+D" }, - { fc::Fmkey_e , "Meta+E" }, - { fc::Fmkey_f , "Meta+F" }, - { fc::Fmkey_g , "Meta+G" }, - { fc::Fmkey_h , "Meta+H" }, - { fc::Fmkey_i , "Meta+I" }, - { fc::Fmkey_j , "Meta+J" }, - { fc::Fmkey_k , "Meta+K" }, - { fc::Fmkey_l , "Meta+L" }, - { fc::Fmkey_m , "Meta+M" }, - { fc::Fmkey_n , "Meta+N" }, - { fc::Fmkey_o , "Meta+O" }, - { fc::Fmkey_p , "Meta+P" }, - { fc::Fmkey_q , "Meta+Q" }, - { fc::Fmkey_r , "Meta+R" }, - { fc::Fmkey_s , "Meta+S" }, - { fc::Fmkey_t , "Meta+T" }, - { fc::Fmkey_u , "Meta+U" }, - { fc::Fmkey_v , "Meta+V" }, - { fc::Fmkey_w , "Meta+W" }, - { fc::Fmkey_x , "Meta+X" }, - { fc::Fmkey_y , "Meta+Y" }, - { fc::Fmkey_z , "Meta+Z" }, - { fc::Fmkey_left_curly_bracket , "Meta+{" }, - { fc::Fmkey_vertical_bar , "Meta+|" }, - { fc::Fmkey_right_curly_bracket , "Meta+}" }, - { fc::Fmkey_tilde , "Meta+~" }, - { 0 , "\0" } -}; +extern fkeymap Fkey[]; +extern fmetakeymap Fmetakey[]; +extern keyname FkeyName[]; } // namespace fc diff --git a/include/final/fkeyboard.h b/include/final/fkeyboard.h new file mode 100644 index 00000000..cb92bad8 --- /dev/null +++ b/include/final/fkeyboard.h @@ -0,0 +1,253 @@ +/*********************************************************************** +* fkeyboard.h - Read keyboard events * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2018 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +/* Standalone class + * ════════════════ + * + * ▕▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ FKeyboard ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▏ + */ + +#ifndef FKEYBOARD_H +#define FKEYBOARD_H + +#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) + #error "Only can be included directly." +#endif + +#include "final/fobject.h" +#include "final/ftypes.h" + +#if defined(__linux__) + #include "final/ftermlinux.h" +#endif + +// class forward declaration +class FApplication; + + +//---------------------------------------------------------------------- +// class FKeyboardCommand +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FKeyboardCommand +{ + public: + // Constructor + FKeyboardCommand (FApplication* = 0, void(FApplication::*)() = 0); + + // Method + void execute(); + + private: + // Data Members + FApplication* instance; + void (FApplication::*handler)(); +}; +#pragma pack(pop) + + +//---------------------------------------------------------------------- +// class FKeyboard +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FKeyboard +{ + public: + // Constructor + FKeyboard(); + + // Destructor + ~FKeyboard(); + + // Accessors + int getKey(); + const FString getKeyName (int); + char* getKeyBuffer(); + int getKeyBufferSize(); + timeval* getKeyPressedTime(); + + // Mutators + void setTermcapMap (fc::fkeymap*); + void setKeypressTimeout (const long); + void enableUTF8(); + void disableUTF8(); + void enableMouseSequences(); + void disableMouseSequences(); + +#if defined(__linux__) + void setFTermLinux (FTermLinux*); +#endif + + void setPressCommand (FKeyboardCommand); + void setReleaseCommand (FKeyboardCommand); + void setEscPressedCommand (FKeyboardCommand); + + // Inquiry + bool isInputDataPending(); + + // Methods + bool& unprocessedInput(); + bool isKeyPressed(); + void emptyKeyBufferOnTimeout(); + void fetchKeyCode(); + void escapeKeyHandling(); + + private: + // Constants + static const int NEED_MORE_DATA = -1; + + // Disable copy constructor + FKeyboard (const FKeyboard&); + + // Disable assignment operator (=) + FKeyboard& operator = (const FKeyboard&); + + // Accessors + int getMouseProtocolKey(); + int getTermcapKey(); + int getMetaKey(); + int getSingleKey(); + + // Mutators + bool setNonBlockingInput (bool); + bool setNonBlockingInput(); + bool unsetNonBlockingInput(); + + // Inquiry + static bool isKeypressTimeout (timeval*); + + // Methods + int UTF8decode (const char[]); + ssize_t readKey(); + void parseKeyBuffer(); + int parseKeyString(); + int keyCorrection (const int&); + void keyPressed(); + void keyReleased(); + void escapeKeyPressed(); + + // Data Members + int key; + char k_buf[1024]; + char fifo_buf[512]; + int fifo_offset; + bool fifo_in_use; + int fifo_buf_size; + int stdin_status_flags; + static long key_timeout; + bool input_data_pending; + bool utf8_input; + bool mouse_support; + bool non_blocking_stdin; + FKeyboardCommand keypressed_cmd; + FKeyboardCommand keyreleased_cmd; + FKeyboardCommand escape_key_cmd; + + struct timeval time_keypressed; + fc::fkeymap* termcap_map; + //void* termcap_map; + +#if defined(__linux__) + #undef linux + static FTermLinux* linux; +#endif +}; +#pragma pack(pop) + +// FKeyboard inline functions +//---------------------------------------------------------------------- +inline int FKeyboard::getKey() +{ return key; } + +inline char* FKeyboard::getKeyBuffer() +{ return fifo_buf; } + +//---------------------------------------------------------------------- +inline int FKeyboard::getKeyBufferSize() +{ return fifo_buf_size; } + +//---------------------------------------------------------------------- +inline struct timeval* FKeyboard::getKeyPressedTime() +{ return &time_keypressed; } + +//---------------------------------------------------------------------- +inline void FKeyboard::setKeypressTimeout (const long timeout) +{ key_timeout = timeout; } + +//---------------------------------------------------------------------- +inline void FKeyboard::enableUTF8() +{ utf8_input = true; } + +//---------------------------------------------------------------------- +inline void FKeyboard::disableUTF8() +{ utf8_input = false; } + +//---------------------------------------------------------------------- +inline void FKeyboard::enableMouseSequences() +{ mouse_support = true; } + +//---------------------------------------------------------------------- +inline void FKeyboard::disableMouseSequences() +{ mouse_support = false; } + +#if defined(__linux__) +//---------------------------------------------------------------------- +inline void FKeyboard::setFTermLinux (FTermLinux* linux_obj) +{ linux = linux_obj; } +#endif + +//---------------------------------------------------------------------- +inline void FKeyboard::setPressCommand (FKeyboardCommand cmd) +{ keypressed_cmd = cmd; } + +//---------------------------------------------------------------------- +inline void FKeyboard::setReleaseCommand (FKeyboardCommand cmd) +{ keyreleased_cmd = cmd; } + +//---------------------------------------------------------------------- +inline void FKeyboard::setEscPressedCommand (FKeyboardCommand cmd) +{ escape_key_cmd = cmd; } + +//---------------------------------------------------------------------- +inline bool FKeyboard::isKeypressTimeout (timeval* time) +{ return FObject::isTimeout (time, key_timeout); } + +//---------------------------------------------------------------------- +inline bool FKeyboard::isInputDataPending() +{ return input_data_pending; } +//---------------------------------------------------------------------- +inline bool FKeyboard::setNonBlockingInput() +{ return setNonBlockingInput(true); } + +//---------------------------------------------------------------------- +inline bool FKeyboard::unsetNonBlockingInput() +{ return setNonBlockingInput(false); } + +#endif // FKEYBOARD_H diff --git a/include/final/fterm.h b/include/final/fterm.h index 823b9b70..1a39838e 100644 --- a/include/final/fterm.h +++ b/include/final/fterm.h @@ -67,6 +67,10 @@ * :- - - -▕ FOptiMove ▏ * : ▕▁▁▁▁▁▁▁▁▁▁▁▏ * : + * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏ + * :- - - -▕ FKeyboard ▏ + * : ▕▁▁▁▁▁▁▁▁▁▁▁▏ + * : * : *▕▔▔▔▔▔▔▔▔▔▏ * :- - - -▕ FString ▏ * : ▕▁▁▁▁▁▁▁▁▁▏ @@ -128,6 +132,7 @@ #include "final/fc.h" #include "final/fcolorpalette.h" +#include "final/fkeyboard.h" #include "final/fmouse.h" #include "final/fobject.h" #include "final/foptiattr.h" @@ -176,13 +181,13 @@ class FTerm // Accessors virtual const char* getClassName() const; - static termios getTTY(); - static int getTTYFileDescriptor(); + static FKeyboard* getKeyboard(); + static FMouseControl* getMouseControl(); static int getLineNumber(); static int getColumnNumber(); static const FString getKeyName (int); - static FMouseControl* getMouseControl(); + static int getTTYFileDescriptor(); static char* getTermType(); static char* getTermFileName(); static int getTabstop(); @@ -199,7 +204,6 @@ class FTerm // Inquiries static bool isCursorHidden(); - static bool isKeypressTimeout (timeval*); static bool isNormal (charData*&); static bool isRaw(); static bool hasPCcharset(); @@ -226,7 +230,6 @@ class FTerm static bool isOpenBSDTerm(); static bool isScreenTerm(); static bool isTmuxTerm(); - static bool isInputDataPending(); static bool isNewFont(); static bool isUTF8(); @@ -237,20 +240,13 @@ class FTerm static void unsetInsertCursor(); static bool setCursorOptimisation (bool); static void redefineDefaultColors (bool); - static void setKeypressTimeout (const long); static void setDblclickInterval (const long); static void disableAltScreen(); static bool setUTF8 (bool); static bool setUTF8(); static bool unsetUTF8(); - static bool setNonBlockingInput (bool); - static bool setNonBlockingInput(); - static bool unsetNonBlockingInput(); // Methods - static int parseKeyString (char[], int, timeval*); - static int keyCorrection (const int&); - static bool& unprocessedInput(); static bool setVGAFont(); static bool setNewFont(); static bool setOldFont(); @@ -300,7 +296,6 @@ class FTerm static int putchar_ASCII (register int); static int putchar_UTF8 (register int); - static int UTF8decode (const char[]); #if DEBUG static int framebuffer_bpp; @@ -380,9 +375,6 @@ class FTerm // Typedefs typedef FTermcap::tcap_map termcap_map; - // Constants - static const int NEED_MORE_DATA = -1; // parseKeyString return value - // Disable copy constructor FTerm (const FTerm&); // Disable assignment operator (=) @@ -397,6 +389,7 @@ class FTerm static void init_cygwin_charmap(); static void init_teraterm_charmap(); static void init_fixed_max_color(); + static void init_keyboard(); static void init_termcap(); static void init_termcap_error (int); static void init_termcap_variables(char*&); @@ -432,10 +425,6 @@ class FTerm void finishOSspecifics1(); void finish_encoding(); static uInt cp437_to_unicode (uChar); - static int getMouseProtocolKey (char[]); - static int getTermcapKey (char[], int); - static int getMetaKey (char[], int, timeval*); - static int getSingleKey (char[], int); static void setSignalHandler(); static void resetSignalHandler(); static void signal_handler (int); @@ -451,10 +440,7 @@ class FTerm static bool cursor_optimisation; static bool hidden_cursor; static bool use_alternate_screen; - static bool input_data_pending; - static bool non_blocking_stdin; static bool pc_charset_console; - static bool utf8_input; static bool utf8_state; static bool utf8_console; static bool utf8_linux_terminal; @@ -471,20 +457,22 @@ class FTerm static char* locale_xterm; static FRect* term; // current terminal geometry - static int stdin_status_flags; static int fd_tty; static uInt baudrate; - static long key_timeout; static bool resize_term; - static fc::linuxConsoleCursorStyle linux_console_cursor_style; - static struct console_font_op screen_font; - static struct unimapdesc screen_unicode_map; + static fc::linuxConsoleCursorStyle \ + linux_console_cursor_style; + static struct console_font_op \ + screen_font; + static struct unimapdesc \ + screen_unicode_map; static FOptiMove* opti_move; static FOptiAttr* opti_attr; static FTermDetection* term_detection; static FTermXTerminal* xterm; + static FKeyboard* keyboard; #if defined(__linux__) #undef linux @@ -511,6 +499,14 @@ class FTerm inline const char* FTerm::getClassName() const { return "FTerm"; } +//---------------------------------------------------------------------- +inline FKeyboard* FTerm::getKeyboard() +{ return ( keyboard ) ? keyboard : 0; } + +//---------------------------------------------------------------------- +inline FMouseControl* FTerm::getMouseControl() +{ return ( mouse ) ? mouse : 0; } + //---------------------------------------------------------------------- inline int FTerm::getTTYFileDescriptor() { return fd_tty; } @@ -561,10 +557,6 @@ inline int FTerm::getFramebufferBpp() inline bool FTerm::isCursorHidden() { return hidden_cursor; } -//---------------------------------------------------------------------- -inline bool FTerm::isKeypressTimeout (timeval* time) -{ return FObject::isTimeout (time, key_timeout); } - //---------------------------------------------------------------------- inline bool FTerm::hasPCcharset() { return pc_charset_console; } @@ -661,10 +653,6 @@ inline bool FTerm::isScreenTerm() inline bool FTerm::isTmuxTerm() { return term_detection->isTmuxTerm(); } -//---------------------------------------------------------------------- -inline bool FTerm::isInputDataPending() -{ return input_data_pending; } - //---------------------------------------------------------------------- inline bool FTerm::isNewFont() { return NewFont; } @@ -685,10 +673,6 @@ inline void FTerm::unsetInsertCursor() inline bool FTerm::setCursorOptimisation (bool on) { return cursor_optimisation = ( on ) ? true : false; } -//---------------------------------------------------------------------- -inline void FTerm::setKeypressTimeout (const long timeout) -{ key_timeout = timeout; } - //---------------------------------------------------------------------- inline void FTerm::disableAltScreen() { use_alternate_screen = false; } @@ -701,14 +685,6 @@ inline bool FTerm::setUTF8() inline bool FTerm::unsetUTF8() { return setUTF8(false); } -//---------------------------------------------------------------------- -inline bool FTerm::setNonBlockingInput() -{ return setNonBlockingInput(true); } - -//---------------------------------------------------------------------- -inline bool FTerm::unsetNonBlockingInput() -{ return setNonBlockingInput(false); } - //---------------------------------------------------------------------- inline bool FTerm::hasChangedTermSize() { return resize_term; } diff --git a/include/final/ftermdetection.h b/include/final/ftermdetection.h index 96c08193..48f21745 100644 --- a/include/final/ftermdetection.h +++ b/include/final/ftermdetection.h @@ -42,6 +42,7 @@ #include #include "final/fc.h" +#include "final/fconfig.h" #include "final/ftermios.h" #include "final/ftypes.h" diff --git a/include/final/ftypes.h b/include/final/ftypes.h index ffab7656..a9a8ba93 100644 --- a/include/final/ftypes.h +++ b/include/final/ftypes.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2017 Markus Gans * +* Copyright 2017-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -49,5 +49,33 @@ typedef int64_t sInt64; typedef long double lDouble; +namespace fc +{ +#pragma pack(push) +#pragma pack(1) +typedef struct +{ + int num; + char* string; + char tname[4]; +} +fkeymap; + +typedef struct +{ + int num; + char string[8]; +} +fmetakeymap; + +typedef struct +{ + int num; + char string[25]; +} +keyname; +#pragma pack(pop) +} // namespace fc + #endif // FTYPES_H diff --git a/include/final/fvterm.h b/include/final/fvterm.h index dd5b3a09..7d293105 100644 --- a/include/final/fvterm.h +++ b/include/final/fvterm.h @@ -438,6 +438,7 @@ class FVTerm : public FTerm static charData i_ch; // inherit background character static FPoint* term_pos; // terminal cursor position static termcap_map* tcap; + static FKeyboard* keyboard; static bool terminal_update_complete; static bool terminal_update_pending; static bool force_terminal_update; diff --git a/src/Makefile.am b/src/Makefile.am index 7a5c3960..e22fb167 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,6 +26,7 @@ libfinal_la_SOURCES = \ flistview.cpp \ fmenu.cpp \ fmouse.cpp \ + fkeyboard.cpp \ fdialoglistmenu.cpp \ fmenubar.cpp \ fmenuitem.cpp \ @@ -38,6 +39,7 @@ libfinal_la_SOURCES = \ fmessagebox.cpp \ ftooltip.cpp \ ffiledialog.cpp \ + fkey_map.cpp \ ftextview.cpp \ fstatusbar.cpp \ ftermcapquirks.cpp \ @@ -85,6 +87,7 @@ finalcutinclude_HEADERS = \ ../include/final/flistview.h \ ../include/final/fmenu.h \ ../include/final/fmouse.h \ + ../include/final/fkeyboard.h \ ../include/final/fdialoglistmenu.h \ ../include/final/fmenubar.h \ ../include/final/fmenuitem.h \ diff --git a/src/Makefile.clang b/src/Makefile.clang index bb1548f2..a8b43447 100644 --- a/src/Makefile.clang +++ b/src/Makefile.clang @@ -24,6 +24,7 @@ INCLUDE_HEADERS = \ flistview.h \ fmenu.h \ fmouse.h \ + fkeyboard.h \ fdialoglistmenu.h \ fmenubar.h \ fradiomenuitem.h \ @@ -87,6 +88,7 @@ OBJS = \ flistview.o \ fmenu.o \ fmouse.o \ + fkeyboard.o \ fdialoglistmenu.o \ fmenubar.o \ fmenuitem.o \ @@ -99,6 +101,7 @@ OBJS = \ fmessagebox.o \ ftooltip.o \ ffiledialog.o \ + fkey_map.o \ ftextview.o \ fstatusbar.o \ fterm.o \ diff --git a/src/Makefile.gcc b/src/Makefile.gcc index a425ae32..be51bd6f 100644 --- a/src/Makefile.gcc +++ b/src/Makefile.gcc @@ -24,6 +24,7 @@ INCLUDE_HEADERS = \ flistview.h \ fmenu.h \ fmouse.h \ + fkeyboard.h \ fdialoglistmenu.h \ fmenubar.h \ fradiomenuitem.h \ @@ -87,6 +88,7 @@ OBJS = \ flistview.o \ fmenu.o \ fmouse.o \ + fkeyboard.o \ fdialoglistmenu.o \ fmenubar.o \ fmenuitem.o \ @@ -99,6 +101,7 @@ OBJS = \ fmessagebox.o \ ftooltip.o \ ffiledialog.o \ + fkey_map.o \ ftextview.o \ fstatusbar.o \ fterm.o \ diff --git a/src/Makefile.in b/src/Makefile.in index 8512b101..2fde7a48 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -133,14 +133,15 @@ am_libfinal_la_OBJECTS = fstring.lo fpoint.lo frect.lo fscrollbar.lo \ fprogressbar.lo flineedit.lo fbutton.lo fbuttongroup.lo \ ftogglebutton.lo fradiobutton.lo fcheckbox.lo fswitch.lo \ flabel.lo flistbox.lo flistview.lo fmenu.lo fmouse.lo \ - fdialoglistmenu.lo fmenubar.lo fmenuitem.lo fradiomenuitem.lo \ - fcheckmenuitem.lo fmenulist.lo fdialog.lo fscrollview.lo \ - fwindow.lo fmessagebox.lo ftooltip.lo ffiledialog.lo \ - ftextview.lo fstatusbar.lo ftermcapquirks.lo ftermxterminal.lo \ - ftermfreebsd.lo ftermopenbsd.lo ftermlinux.lo \ - ftermdetection.lo ftermios.lo fterm.lo fvterm.lo fevent.lo \ - foptiattr.lo foptimove.lo ftermbuffer.lo fapplication.lo \ - fcolorpalette.lo fwidgetcolors.lo fwidget.lo fobject.lo + fkeyboard.lo fdialoglistmenu.lo fmenubar.lo fmenuitem.lo \ + fradiomenuitem.lo fcheckmenuitem.lo fmenulist.lo fdialog.lo \ + fscrollview.lo fwindow.lo fmessagebox.lo ftooltip.lo \ + ffiledialog.lo fkey_map.lo ftextview.lo fstatusbar.lo \ + ftermcapquirks.lo ftermxterminal.lo ftermfreebsd.lo \ + ftermopenbsd.lo ftermlinux.lo ftermdetection.lo ftermios.lo \ + fterm.lo fvterm.lo fevent.lo foptiattr.lo foptimove.lo \ + ftermbuffer.lo fapplication.lo fcolorpalette.lo \ + fwidgetcolors.lo fwidget.lo fobject.lo libfinal_la_OBJECTS = $(am_libfinal_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -400,6 +401,7 @@ libfinal_la_SOURCES = \ flistview.cpp \ fmenu.cpp \ fmouse.cpp \ + fkeyboard.cpp \ fdialoglistmenu.cpp \ fmenubar.cpp \ fmenuitem.cpp \ @@ -412,6 +414,7 @@ libfinal_la_SOURCES = \ fmessagebox.cpp \ ftooltip.cpp \ ffiledialog.cpp \ + fkey_map.cpp \ ftextview.cpp \ fstatusbar.cpp \ ftermcapquirks.cpp \ @@ -457,6 +460,7 @@ finalcutinclude_HEADERS = \ ../include/final/flistview.h \ ../include/final/fmenu.h \ ../include/final/fmouse.h \ + ../include/final/fkeyboard.h \ ../include/final/fdialoglistmenu.h \ ../include/final/fmenubar.h \ ../include/final/fmenuitem.h \ @@ -584,6 +588,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdialoglistmenu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fevent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffiledialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fkey_map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fkeyboard.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flabel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flineedit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flistbox.Plo@am__quote@ diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 7433187e..04343e32 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -42,6 +42,8 @@ FWidget* FApplication::focus_widget = 0; // has keyboard input focus FWidget* FApplication::clicked_widget = 0; // is focused by click FWidget* FApplication::open_menu = 0; // currently open menu FWidget* FApplication::move_size_widget = 0; // move/size by keyboard +FWidget* FApplication::keyboard_widget = 0; // has the keyboard focus +FKeyboard* FApplication::keyboard = 0; // keyboard access FMouseControl* FApplication::mouse = 0; // mouse control int FApplication::quit_code = 0; bool FApplication::quit_now = false; @@ -61,13 +63,8 @@ FApplication::FApplication ( const int& _argc : FWidget(processParameters(_argc,_argv), disable_alt_screen) , app_argc(_argc) , app_argv(_argv) - , key(0) - , fifo_offset(0) - , fifo_in_use(false) - , fifo_buf_size(sizeof(fifo_buf)) , key_timeout(100000) // 100 ms , dblclick_interval(500000) // 500 ms - , time_keypressed() { assert ( ! rootObj && "FApplication: There should be only one application object" ); @@ -377,12 +374,20 @@ void FApplication::closeConfirmationDialog (FWidget* w, FCloseEvent* ev) //---------------------------------------------------------------------- void FApplication::init (long key_time, long dblclick_time) { - // Initialize keyboard values - time_keypressed.tv_sec = 0; - time_keypressed.tv_usec = 0; + // Initialize keyboard + keyboard = getKeyboard(); // Set the keyboard keypress timeout - setKeypressTimeout (key_time); + if ( keyboard ) + { + FKeyboardCommand key_cmd1 (this, &FApplication::keyPressed); + FKeyboardCommand key_cmd2 (this, &FApplication::keyReleased); + FKeyboardCommand key_cmd3 (this, &FApplication::escapeKeyPressed); + keyboard->setPressCommand (key_cmd1); + keyboard->setReleaseCommand (key_cmd2); + keyboard->setEscPressedCommand (key_cmd3); + keyboard->setKeypressTimeout (key_time); + } // Initialize mouse control mouse = getMouseControl(); @@ -404,10 +409,6 @@ void FApplication::init (long key_time, long dblclick_time) std::cerr << "not enough memory to alloc " << ex.what() << std::endl; std::abort(); } - - // Initialize arrays with '\0' - std::fill_n (k_buf, sizeof(k_buf), '\0'); - std::fill_n (fifo_buf, fifo_buf_size, '\0'); } //---------------------------------------------------------------------- @@ -504,38 +505,10 @@ void FApplication::cmd_options (const int& argc, char* argv[]) } //---------------------------------------------------------------------- -inline bool FApplication::KeyPressed() +inline void FApplication::findKeyboardWidget() { - register int result; - fd_set ifds; - struct timeval tv; - int stdin_no = FTermios::getStdIn(); + // Find the widget that has the keyboard focus - FD_ZERO(&ifds); - FD_SET(stdin_no, &ifds); - tv.tv_sec = 0; - tv.tv_usec = 100000; // 100 ms - result = select (stdin_no + 1, &ifds, 0, 0, &tv); - - if ( result > 0 && FD_ISSET(stdin_no, &ifds) ) - FD_CLR (stdin_no, &ifds); - - return ( result > 0 ); -} - -//---------------------------------------------------------------------- -inline ssize_t FApplication::readKey() -{ - register ssize_t bytes; - setNonBlockingInput(); - bytes = read(FTermios::getStdIn(), &k_buf, sizeof(k_buf) - 1); - unsetNonBlockingInput(); - return bytes; -} - -//---------------------------------------------------------------------- -inline FWidget* FApplication::findKeyboardWidget() -{ FWidget* widget = 0; if ( focus_widget ) @@ -553,79 +526,40 @@ inline FWidget* FApplication::findKeyboardWidget() widget->focusFirstChild(); } - return widget; + keyboard_widget = widget; } //---------------------------------------------------------------------- -inline bool FApplication::getKeyPressedState() +inline bool FApplication::isKeyPressed() { if ( mouse && mouse->isGpmMouseEnabled() ) - return mouse->getGpmKeyPressed(unprocessedInput()); + return mouse->getGpmKeyPressed(keyboard->unprocessedInput()); - return KeyPressed(); + return keyboard->isKeyPressed(); } //---------------------------------------------------------------------- -inline void FApplication::emptyKeyBufferOnTimeout() +void FApplication::keyPressed() { - // Empty the buffer on timeout - if ( fifo_in_use && isKeypressTimeout(&time_keypressed) ) - { - fifo_offset = 0; - key = 0; - std::fill_n (fifo_buf, fifo_buf_size, '\0'); - fifo_in_use = false; - } + performKeyboardAction(); } //---------------------------------------------------------------------- -inline void FApplication::parseKeyBuffer (FWidget* widget) +void FApplication::keyReleased() { - register ssize_t bytesread; - getCurrentTime (&time_keypressed); - - if ( quit_now || app_exit_loop ) - return; - - while ( (bytesread = readKey()) > 0 ) - { - if ( bytesread + fifo_offset <= fifo_buf_size ) - { - for (int i = 0; i < bytesread; i++) - { - fifo_buf[fifo_offset] = k_buf[i]; - fifo_offset++; - } - - fifo_in_use = true; - } - - // Read the rest from the fifo buffer - while ( ! widget->isKeypressTimeout(&time_keypressed) - && fifo_offset > 0 - && key != NEED_MORE_DATA ) - { - key = FTerm::parseKeyString(fifo_buf, fifo_buf_size, &time_keypressed); - key = keyCorrection(key); - - if ( key != NEED_MORE_DATA ) - performKeyboardAction (widget); - - fifo_offset = int(std::strlen(fifo_buf)); - } - - // Send key up event - sendKeyUpEvent (widget); - key = 0; - } - - std::fill_n (k_buf, sizeof(k_buf), '\0'); + sendKeyUpEvent (keyboard_widget); } //---------------------------------------------------------------------- -inline void FApplication::performKeyboardAction (FWidget* widget) +void FApplication::escapeKeyPressed() { - switch ( key ) + sendEscapeKeyPressEvent(); +} + +//---------------------------------------------------------------------- +inline void FApplication::performKeyboardAction() +{ + switch ( keyboard->getKey() ) { case fc::Fckey_l: // Ctrl-L (redraw the screen) redraw(); @@ -634,8 +568,10 @@ inline void FApplication::performKeyboardAction (FWidget* widget) case fc::Fkey_mouse: if ( mouse ) { - mouse->setRawData (FMouse::x11, fifo_buf, sizeof(fifo_buf)); - unprocessedInput() = mouse->isInputDataPending(); + char* buffer = keyboard->getKeyBuffer(); + int buffer_size = keyboard->getKeyBufferSize(); + mouse->setRawData (FMouse::x11, buffer, buffer_size); + keyboard->unprocessedInput() = mouse->isInputDataPending(); processMouseEvent(); } break; @@ -643,8 +579,10 @@ inline void FApplication::performKeyboardAction (FWidget* widget) case fc::Fkey_extended_mouse: if ( mouse ) { - mouse->setRawData (FMouse::sgr, fifo_buf, sizeof(fifo_buf)); - unprocessedInput() = mouse->isInputDataPending(); + char* buffer = keyboard->getKeyBuffer(); + int buffer_size = keyboard->getKeyBufferSize(); + mouse->setRawData (FMouse::sgr, buffer, buffer_size); + keyboard->unprocessedInput() = mouse->isInputDataPending(); processMouseEvent(); } break; @@ -652,15 +590,17 @@ inline void FApplication::performKeyboardAction (FWidget* widget) case fc::Fkey_urxvt_mouse: if ( mouse ) { - mouse->setRawData (FMouse::urxvt, fifo_buf, sizeof(fifo_buf)); - unprocessedInput() = mouse->isInputDataPending(); + char* buffer = keyboard->getKeyBuffer(); + int buffer_size = keyboard->getKeyBufferSize(); + mouse->setRawData (FMouse::urxvt, buffer, buffer_size); + keyboard->unprocessedInput() = mouse->isInputDataPending(); processMouseEvent(); } break; default: - bool acceptKeyDown = sendKeyDownEvent (widget); - bool acceptKeyPress = sendKeyPressEvent (widget); + bool acceptKeyDown = sendKeyDownEvent (keyboard_widget); + bool acceptKeyPress = sendKeyPressEvent (keyboard_widget); if ( ! (acceptKeyDown || acceptKeyPress) ) sendKeyboardAccelerator(); @@ -670,28 +610,18 @@ inline void FApplication::performKeyboardAction (FWidget* widget) } //---------------------------------------------------------------------- -inline void FApplication::sendEscapeKeyPressEvent (FWidget* widget) +inline void FApplication::sendEscapeKeyPressEvent() { - // Send an escape key press event if there is only one 0x1b - // in the buffer and the timeout is reached - - if ( fifo_in_use - && fifo_offset == 1 - && fifo_buf[0] == 0x1b - && fifo_buf[1] == 0x00 - && isKeypressTimeout(&time_keypressed) ) - { - FKeyEvent k_press_ev (fc::KeyPress_Event, fc::Fkey_escape); - sendEvent (widget, &k_press_ev); - unprocessedInput() = false; - } + // Send an escape key press event + FKeyEvent k_press_ev (fc::KeyPress_Event, fc::Fkey_escape); + sendEvent (keyboard_widget, &k_press_ev); } //---------------------------------------------------------------------- inline bool FApplication::sendKeyDownEvent (FWidget* widget) { // Send key down event - FKeyEvent k_down_ev (fc::KeyDown_Event, key); + FKeyEvent k_down_ev (fc::KeyDown_Event, keyboard->getKey()); sendEvent (widget, &k_down_ev); return k_down_ev.isAccepted(); } @@ -700,7 +630,7 @@ inline bool FApplication::sendKeyDownEvent (FWidget* widget) inline bool FApplication::sendKeyPressEvent (FWidget* widget) { // Send key press event - FKeyEvent k_press_ev (fc::KeyPress_Event, key); + FKeyEvent k_press_ev (fc::KeyPress_Event, keyboard->getKey()); sendEvent (widget, &k_press_ev); return k_press_ev.isAccepted(); } @@ -709,7 +639,7 @@ inline bool FApplication::sendKeyPressEvent (FWidget* widget) inline bool FApplication::sendKeyUpEvent (FWidget* widget) { // Send key up event - FKeyEvent k_up_ev (fc::KeyUp_Event, key); + FKeyEvent k_up_ev (fc::KeyUp_Event, keyboard->getKey()); sendEvent (widget, &k_up_ev); return k_up_ev.isAccepted(); } @@ -745,23 +675,27 @@ inline void FApplication::sendKeyboardAccelerator() //---------------------------------------------------------------------- void FApplication::processKeyboardEvent() { - FWidget* widget = findKeyboardWidget(); - emptyKeyBufferOnTimeout(); - flush_out(); - bool isKeyPressed = getKeyPressedState(); + if ( quit_now || app_exit_loop ) + return; - if ( isKeyPressed ) - parseKeyBuffer (widget); + findKeyboardWidget(); + flush_out(); + keyboard->emptyKeyBufferOnTimeout(); + + if ( isKeyPressed() ) + keyboard->fetchKeyCode(); // special case: Esc key - sendEscapeKeyPressEvent (widget); + keyboard->escapeKeyHandling(); } //---------------------------------------------------------------------- bool FApplication::processDialogSwitchAccelerator() { - if ( key >= fc::Fmkey_1 && key <= fc::Fmkey_9 ) + if ( keyboard->getKey() >= fc::Fmkey_1 + && keyboard->getKey() <= fc::Fmkey_9 ) { + int key = keyboard->getKey(); uLong n = uLong(key - fc::Fmkey_0); uLong s = dialog_list->size(); @@ -802,7 +736,7 @@ bool FApplication::processAccelerator (const FWidget*& widget) if ( quit_now || app_exit_loop ) break; - if ( iter->key == key ) + if ( iter->key == keyboard->getKey() ) { // unset the move/size mode if ( move_size_widget ) @@ -832,8 +766,9 @@ bool FApplication::getMouseEvent() if ( mouse && mouse->hasData() ) { - mouse->processEvent (&time_keypressed); - unprocessedInput() = mouse->isInputDataPending(); + struct timeval* time_keypressed = keyboard->getKeyPressedTime(); + mouse->processEvent (time_keypressed); + keyboard->unprocessedInput() = mouse->isInputDataPending(); mouse_event_occurred = mouse->hasEvent(); } diff --git a/src/fkey_map.cpp b/src/fkey_map.cpp new file mode 100644 index 00000000..a3ac8d58 --- /dev/null +++ b/src/fkey_map.cpp @@ -0,0 +1,819 @@ +/*********************************************************************** +* fkey_map.cpp - Key name mapping * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2018 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +#include +#include + +namespace fc +{ + +fkeymap Fkey[] = +{ + { fc::Fkey_backspace, 0, "kb" }, // backspace key + { fc::Fkey_catab , 0, "ka" }, // clear-all-tabs key + { fc::Fkey_clear , 0, "kC" }, // clear-screen or erase key + { fc::Fkey_ctab , 0, "kt" }, // clear-tab key + { fc::Fkey_dc , 0, "kD" }, // delete-character key + { fc::Fkey_dl , 0, "kL" }, // delete-line key + { fc::Fkey_down , 0, "kd" }, // down-arrow key + { fc::Fkey_down , 0, "kdx"}, // down-arrow key + { fc::Fkey_eic , 0, "kM" }, // sent by rmir or smir in insert mode + { fc::Fkey_eol , 0, "kE" }, // clear-to-end-of-line key + { fc::Fkey_eos , 0, "kS" }, // clear-to-end-of-screen key + { fc::Fkey_f0 , 0, "k0" }, // F0 function key + { fc::Fkey_f1 , 0, "k1" }, // F1 function key + { fc::Fkey_f1 , 0, "k1x"}, // F1 function key + { fc::Fkey_f1 , 0, "k1X"}, // F1 function key + { fc::Fkey_f2 , 0, "k2" }, // F2 function key + { fc::Fkey_f2 , 0, "k2x"}, // F2 function key + { fc::Fkey_f2 , 0, "k2X"}, // F2 function key + { fc::Fkey_f3 , 0, "k3" }, // F3 function key + { fc::Fkey_f3 , 0, "k3x"}, // F3 function key + { fc::Fkey_f3 , 0, "k3X"}, // F3 function key + { fc::Fkey_f4 , 0, "k4" }, // F4 function key + { fc::Fkey_f4 , 0, "k4x"}, // F4 function key + { fc::Fkey_f4 , 0, "k4X"}, // F4 function key + { fc::Fkey_f5 , 0, "k5" }, // F5 function key + { fc::Fkey_f6 , 0, "k6" }, // F6 function key + { fc::Fkey_f7 , 0, "k7" }, // F7 function key + { fc::Fkey_f8 , 0, "k8" }, // F8 fucntion key + { fc::Fkey_f9 , 0, "k9" }, // F9 function key + { fc::Fkey_f10 , 0, "k;" }, // F10 function key + { fc::Fkey_home , 0, "kh" }, // home key + { fc::Fkey_home , 0, "khx"}, // home key + { fc::Fkey_ic , 0, "kI" }, // insert-character key + { fc::Fkey_il , 0, "kA" }, // insert-line key + { fc::Fkey_left , 0, "kl" }, // left-arrow key + { fc::Fkey_left , 0, "klx"}, // left-arrow key + { fc::Fkey_ll , 0, "kH" }, // last-line key + { fc::Fkey_npage , 0, "kN" }, // next-page key + { fc::Fkey_ppage , 0, "kP" }, // prev-page key + { fc::Fkey_right , 0, "kr" }, // right-arrow key + { fc::Fkey_right , 0, "krx"}, // right-arrow key + { fc::Fkey_sf , 0, "kF" }, // scroll-forward key + { fc::Fkey_sr , 0, "kR" }, // scroll-backward key + { fc::Fkey_stab , 0, "kT" }, // set-tab key + { fc::Fkey_up , 0, "ku" }, // up-arrow key + { fc::Fkey_up , 0, "kux"}, // up-arrow key + { fc::Fkey_a1 , 0, "K1" }, // upper left of keypad + { fc::Fkey_a3 , 0, "K3" }, // upper right of keypad + { fc::Fkey_b2 , 0, "K2" }, // center of keypad + { fc::Fkey_c1 , 0, "K4" }, // lower left of keypad + { fc::Fkey_c3 , 0, "K5" }, // lower right of keypad + { fc::Fkey_btab , 0, "kB" }, // back-tab key + { fc::Fkey_beg , 0, "@1" }, // begin key + { fc::Fkey_cancel , 0, "@2" }, // cancel key + { fc::Fkey_close , 0, "@3" }, // close key + { fc::Fkey_command , 0, "@4" }, // command key + { fc::Fkey_copy , 0, "@5" }, // copy key + { fc::Fkey_create , 0, "@6" }, // create key + { fc::Fkey_end , 0, "@7" }, // end key + { fc::Fkey_end , 0, "@7x"}, // end key + { fc::Fkey_end , 0, "@7X"}, // end key + { fc::Fkey_enter , 0, "@8" }, // enter/send key + { fc::Fkey_exit , 0, "@9" }, // exit key + { fc::Fkey_find , 0, "@0" }, // find key + { fc::Fkey_help , 0, "%1" }, // help key + { fc::Fkey_mark , 0, "%2" }, // mark key + { fc::Fkey_message , 0, "%3" }, // message key + { fc::Fkey_move , 0, "%4" }, // move key + { fc::Fkey_next , 0, "%5" }, // next key + { fc::Fkey_open , 0, "%6" }, // open key + { fc::Fkey_options , 0, "%7" }, // options key + { fc::Fkey_previous , 0, "%8" }, // previous key + { fc::Fkey_print , 0, "%9" }, // print key + { fc::Fkey_redo , 0, "%0" }, // redo key + { fc::Fkey_reference, 0, "&1" }, // reference key + { fc::Fkey_refresh , 0, "&2" }, // refresh key + { fc::Fkey_replace , 0, "&3" }, // replace key + { fc::Fkey_restart , 0, "&4" }, // restart key + { fc::Fkey_resume , 0, "&5" }, // resume key + { fc::Fkey_save , 0, "&6" }, // save key + { fc::Fkey_suspend , 0, "&7" }, // suspend key + { fc::Fkey_undo , 0, "&8" }, // undo key + { fc::Fkey_sbeg , 0, "&9" }, // shifted key + { fc::Fkey_scancel , 0, "&0" }, // shifted key + { fc::Fkey_scommand , 0, "*1" }, // shifted key + { fc::Fkey_scopy , 0, "*2" }, // shifted key + { fc::Fkey_screate , 0, "*3" }, // shifted key + { fc::Fkey_sdc , 0, "*4" }, // shifted key + { fc::Fkey_sdl , 0, "*5" }, // shifted key + { fc::Fkey_select , 0, "*6" }, // select key + { fc::Fkey_send , 0, "*7" }, // shifted key + { fc::Fkey_seol , 0, "*8" }, // shifted key + { fc::Fkey_sexit , 0, "*9" }, // shifted key + { fc::Fkey_sfind , 0, "*0" }, // shifted key + { fc::Fkey_shelp , 0, "#1" }, // shifted key + { fc::Fkey_shome , 0, "#2" }, // shifted key + { fc::Fkey_sic , 0, "#3" }, // shifted key + { fc::Fkey_sleft , 0, "#4" }, // shifted key + { fc::Fkey_smessage , 0, "%a" }, // shifted key + { fc::Fkey_smove , 0, "%b" }, // shifted key + { fc::Fkey_snext , 0, "%c" }, // shifted key + { fc::Fkey_soptions , 0, "%d" }, // shifted key + { fc::Fkey_sprevious, 0, "%e" }, // shifted key + { fc::Fkey_sprint , 0, "%f" }, // shifted key + { fc::Fkey_sredo , 0, "%g" }, // shifted key + { fc::Fkey_sreplace , 0, "%h" }, // shifted key + { fc::Fkey_sright , 0, "%i" }, // shifted key + { fc::Fkey_srsume , 0, "%j" }, // shifted key + { fc::Fkey_ssave , 0, "!1" }, // shifted key + { fc::Fkey_ssuspend , 0, "!2" }, // shifted key + { fc::Fkey_sundo , 0, "!3" }, // shifted key + { fc::Fkey_f11 , 0, "F1" }, // F11 function key + { fc::Fkey_f12 , 0, "F2" }, // F12 function key + { fc::Fkey_f13 , 0, "F3" }, // F13 function key + { fc::Fkey_f14 , 0, "F4" }, // F14 function key + { fc::Fkey_f15 , 0, "F5" }, // F15 function key + { fc::Fkey_f16 , 0, "F6" }, // F16 function key + { fc::Fkey_f17 , 0, "F7" }, // F17 function key + { fc::Fkey_f18 , 0, "F8" }, // F18 function key + { fc::Fkey_f19 , 0, "F9" }, // F19 function key + { fc::Fkey_f20 , 0, "FA" }, // F20 function key + { fc::Fkey_f21 , 0, "FB" }, // F21 function key + { fc::Fkey_f22 , 0, "FC" }, // F22 function key + { fc::Fkey_f23 , 0, "FD" }, // F23 function key + { fc::Fkey_f24 , 0, "FE" }, // F24 function key + { fc::Fkey_f25 , 0, "FF" }, // F25 function key + { fc::Fkey_f26 , 0, "FG" }, // F26 function key + { fc::Fkey_f27 , 0, "FH" }, // F27 function key + { fc::Fkey_f28 , 0, "FI" }, // F28 function key + { fc::Fkey_f29 , 0, "FJ" }, // F29 function key + { fc::Fkey_f30 , 0, "FK" }, // F30 function key + { fc::Fkey_f31 , 0, "FL" }, // F31 function key + { fc::Fkey_f32 , 0, "FM" }, // F32 function key + { fc::Fkey_f33 , 0, "FN" }, // F33 function key + { fc::Fkey_f34 , 0, "FO" }, // F34 function key + { fc::Fkey_f35 , 0, "FP" }, // F35 function key + { fc::Fkey_f36 , 0, "FQ" }, // F36 function key + { fc::Fkey_f37 , 0, "FR" }, // F37 function key + { fc::Fkey_f38 , 0, "FS" }, // F38 function key + { fc::Fkey_f39 , 0, "FT" }, // F39 function key + { fc::Fkey_f40 , 0, "FU" }, // F40 function key + { fc::Fkey_f41 , 0, "FV" }, // F41 function key + { fc::Fkey_f42 , 0, "FW" }, // F42 function key + { fc::Fkey_f43 , 0, "FX" }, // F43 function key + { fc::Fkey_f44 , 0, "FY" }, // F44 function key + { fc::Fkey_f45 , 0, "FZ" }, // F45 function key + { fc::Fkey_f46 , 0, "Fa" }, // F46 function key + { fc::Fkey_f47 , 0, "Fb" }, // F47 function key + { fc::Fkey_f48 , 0, "Fc" }, // F48 function key + { fc::Fkey_f49 , 0, "Fd" }, // F49 function key + { fc::Fkey_f50 , 0, "Fe" }, // F50 function key + { fc::Fkey_f51 , 0, "Ff" }, // F51 function key + { fc::Fkey_f52 , 0, "Fg" }, // F52 function key + { fc::Fkey_f53 , 0, "Fh" }, // F53 function key + { fc::Fkey_f54 , 0, "Fi" }, // F54 function key + { fc::Fkey_f55 , 0, "Fj" }, // F55 function key + { fc::Fkey_f56 , 0, "Fk" }, // F56 function key + { fc::Fkey_f57 , 0, "Fl" }, // F57 function key + { fc::Fkey_f58 , 0, "Fm" }, // F58 function key + { fc::Fkey_f59 , 0, "Fn" }, // F59 function key + { fc::Fkey_f60 , 0, "Fo" }, // F60 function key + { fc::Fkey_f61 , 0, "Fp" }, // F61 function key + { fc::Fkey_f62 , 0, "Fq" }, // F62 function key + { fc::Fkey_f63 , 0, "Fr" }, // F63 function key + { 0 , 0, "\0" } +}; + +fmetakeymap Fmetakey[] = +{ + { fc::Fmkey_ic , "\033[2;3~" }, // M-insert + { fc::Fmkey_ic , "\033\033[2~" }, // M-insert + { fc::Fmkey_dc , "\033[3;3~" }, // M-delete + { fc::Fmkey_dc , "\033\033[3~" }, // M-delete + { fc::Fmkey_home , "\033[1;3H" }, // M-home + { fc::Fmkey_home , "\033\033[1~" }, // M-home + { fc::Fmkey_end , "\033[1;3F" }, // M-end + { fc::Fmkey_end , "\033\033[4~" }, // M-end + { fc::Fmkey_ppage , "\033[5;3~" }, // M-prev-page + { fc::Fmkey_ppage , "\033\033[5~" }, // M-prev-page + { fc::Fmkey_npage , "\033[6;3~" }, // M-next-page + { fc::Fmkey_npage , "\033\033[6~" }, // M-next-page + { fc::Fmkey_f1 , "\033[1;3P" }, // M-f1 + { fc::Fmkey_f1 , "\033\033[11~"}, // M-f1 + { fc::Fmkey_f2 , "\033[1;3Q" }, // M-f2 + { fc::Fmkey_f2 , "\033\033[12~"}, // M-f2 + { fc::Fmkey_f3 , "\033[1;3R" }, // M-f3 + { fc::Fmkey_f3 , "\033\033[13~"}, // M-f3 + { fc::Fmkey_f4 , "\033[1;3S" }, // M-f4 + { fc::Fmkey_f4 , "\033\033[14~"}, // M-f4 + { fc::Fmkey_f5 , "\033[15;3~" }, // M-f5 + { fc::Fmkey_f5 , "\033\033[15~"}, // M-f5 + { fc::Fmkey_f6 , "\033[17;3~" }, // M-f6 + { fc::Fmkey_f6 , "\033\033[17~"}, // M-f6 + { fc::Fmkey_f7 , "\033[18;3~" }, // M-f7 + { fc::Fmkey_f7 , "\033\033[18~"}, // M-f7 + { fc::Fmkey_f8 , "\033[19;3~" }, // M-f8 + { fc::Fmkey_f8 , "\033\033[19~"}, // M-f8 + { fc::Fmkey_f9 , "\033[20;3~" }, // M-f9 + { fc::Fmkey_f9 , "\033\033[20~"}, // M-f9 + { fc::Fmkey_f10 , "\033[21;3~" }, // M-f10 + { fc::Fmkey_f10 , "\033\033[21~"}, // M-f10 + { fc::Fmkey_f11 , "\033[23;3~" }, // M-f11 + { fc::Fmkey_f11 , "\033\033[23~"}, // M-f11 + { fc::Fmkey_f12 , "\033[24;3~" }, // M-f12 + { fc::Fmkey_f12 , "\033\033[24~"}, // M-f12 + { fc::Fmkey_up , "\033[1;3A" }, // M-up + { fc::Fmkey_up , "\033\033[A" }, // M-up + { fc::Fmkey_down , "\033[1;3B" }, // M-down + { fc::Fmkey_down , "\033\033[B" }, // M-down + { fc::Fmkey_right , "\033[1;3C" }, // M-right + { fc::Fmkey_right , "\033\033[C" }, // M-right + { fc::Fmkey_left , "\033[1;3D" }, // M-left + { fc::Fmkey_left , "\033\033[D" }, // M-left + { fc::Fmkey_sic , "\033[2;4~" }, // shift-M-insert + { fc::Fmkey_sdc , "\033[3;4~" }, // shift-M-delete + { fc::Fmkey_shome , "\033[1;4H" }, // shift-M-home + { fc::Fmkey_send , "\033[1;4F" }, // shift-M-end + { fc::Fmkey_sppage , "\033[5;4~" }, // shift-M-prev-page + { fc::Fmkey_snpage , "\033[6;4~" }, // shift-M-next-page + { fc::Fmkey_sf1 , "\033[1;4P" }, // shift-M-f1 + { fc::Fmkey_sf2 , "\033[1;4Q" }, // shift-M-f2 + { fc::Fmkey_sf3 , "\033[1;4R" }, // shift-M-f3 + { fc::Fmkey_sf4 , "\033[1;4S" }, // shift-M-f4 + { fc::Fmkey_sf5 , "\033[15;4~" }, // shift-M-f5 + { fc::Fmkey_sf6 , "\033[17;4~" }, // shift-M-f6 + { fc::Fmkey_sf7 , "\033[18;4~" }, // shift-M-f7 + { fc::Fmkey_sf8 , "\033[19;4~" }, // shift-M-f8 + { fc::Fmkey_sf9 , "\033[20;4~" }, // shift-M-f9 + { fc::Fmkey_sf10 , "\033[21;4~" }, // shift-M-f10 + { fc::Fmkey_sf11 , "\033[23;4~" }, // shift-M-f11 + { fc::Fmkey_sf12 , "\033[24;4~" }, // shift-M-f12 + { fc::Fmkey_sup , "\033[1;4A" }, // shift-M-up + { fc::Fmkey_sdown , "\033[1;4B" }, // shift-M-down + { fc::Fmkey_sright , "\033[1;4C" }, // shift-M-right + { fc::Fmkey_sleft , "\033[1;4D" }, // shift-M-left + { fc::Fckey_ic , "\033[2;5~" }, // ctrl-insert + { fc::Fckey_dc , "\033[3;5~" }, // ctrl-delete + { fc::Fckey_home , "\033[1;5H" }, // ctrl-home + { fc::Fckey_end , "\033[1;5F" }, // ctrl-end + { fc::Fckey_ppage , "\033[5;5~" }, // ctrl-prev-page + { fc::Fckey_npage , "\033[6;5~" }, // ctrl-next-page + { fc::Fckey_up , "\033[1;5A" }, // ctrl-up + { fc::Fckey_down , "\033[1;5B" }, // ctrl-down + { fc::Fckey_right , "\033[1;5C" }, // ctrl-right + { fc::Fckey_left , "\033[1;5D" }, // ctrl-left + { fc::Fckey_sic , "\033[2;6~" }, // shift-ctrl-M-insert + { fc::Fckey_sdc , "\033[3;6~" }, // shift-ctrl-M-delete + { fc::Fckey_shome , "\033[1;6H" }, // shift-ctrl-M-home + { fc::Fckey_send , "\033[1;6F" }, // shift-ctrl-M-end + { fc::Fckey_sppage , "\033[5;6~" }, // shift-ctrl-M-prev-page + { fc::Fckey_snpage , "\033[6;6~" }, // shift-ctrl-M-next-page + { fc::Fckey_sup , "\033[1;6A" }, // shift-ctrl-M-up + { fc::Fckey_sdown , "\033[1;6B" }, // shift-ctrl-M-down + { fc::Fckey_sright , "\033[1;6C" }, // shift-ctrl-M-right + { fc::Fckey_sleft , "\033[1;6D" }, // shift-ctrl-M-left + { fc::Fcmkey_ic , "\033[2;7~" }, // ctrl-M-insert + { fc::Fcmkey_dc , "\033[3;7~" }, // ctrl-M-delete + { fc::Fcmkey_home , "\033[1;7H" }, // ctrl-M-home + { fc::Fcmkey_end , "\033[1;7F" }, // ctrl-M-end + { fc::Fcmkey_ppage , "\033[5;7~" }, // ctrl-M-prev-page + { fc::Fcmkey_npage , "\033[6;7~" }, // ctrl-M-next-page + { fc::Fcmkey_up , "\033[1;7A" }, // ctrl-M-up + { fc::Fcmkey_down , "\033[1;7B" }, // ctrl-M-down + { fc::Fcmkey_right , "\033[1;7C" }, // ctrl-M-right + { fc::Fcmkey_left , "\033[1;7D" }, // ctrl-M-left + { fc::Fcmkey_sic , "\033[2;8~" }, // shift-ctrl-M-insert + { fc::Fcmkey_sdc , "\033[3;8~" }, // shift-ctrl-M-delete + { fc::Fcmkey_shome , "\033[1;8H" }, // shift-ctrl-M-home + { fc::Fcmkey_send , "\033[1;8F" }, // shift-ctrl-M-end + { fc::Fcmkey_sppage , "\033[5;8~" }, // shift-ctrl-M-prev-page + { fc::Fcmkey_snpage , "\033[6;8~" }, // shift-ctrl-M-next-page + { fc::Fcmkey_sf1 , "\033[1;8P" }, // shift-ctrl-M-f1 + { fc::Fcmkey_sf2 , "\033[1;8Q" }, // shift-ctrl-M-f2 + { fc::Fcmkey_sf3 , "\033[1;8R" }, // shift-ctrl-M-f3 + { fc::Fcmkey_sf4 , "\033[1;8S" }, // shift-ctrl-M-f4 + { fc::Fcmkey_sf5 , "\033[15;8~" }, // shift-ctrl-M-f5 + { fc::Fcmkey_sf6 , "\033[17;8~" }, // shift-ctrl-M-f6 + { fc::Fcmkey_sf7 , "\033[18;8~" }, // shift-ctrl-M-f7 + { fc::Fcmkey_sf8 , "\033[19;8~" }, // shift-ctrl-M-f8 + { fc::Fcmkey_sf9 , "\033[20;8~" }, // shift-ctrl-M-f9 + { fc::Fcmkey_sf10 , "\033[21;8~" }, // shift-ctrl-M-f10 + { fc::Fcmkey_sf11 , "\033[23;8~" }, // shift-ctrl-M-f11 + { fc::Fcmkey_sf12 , "\033[24;8~" }, // shift-ctrl-M-f12 + { fc::Fcmkey_sup , "\033[1;8A" }, // shift-ctrl-M-up + { fc::Fcmkey_sdown , "\033[1;8B" }, // shift-ctrl-M-down + { fc::Fcmkey_sright , "\033[1;8C" }, // shift-ctrl-M-right + { fc::Fcmkey_sleft , "\033[1;8D" }, // shift-ctrl-M-left + { fc::Fkey_menu , "\033[29~" }, // menu + { fc::Fkey_smenu , "\033[29$" }, // shift-menu + { fc::Fkey_smenu , "\033[29;2~" }, // shift-menu + { fc::Fckey_menu , "\033[29^" }, // ctrl-menu + { fc::Fckey_menu , "\033[29;5~" }, // ctrl-menu + { fc::Fckey_smenu , "\033[29@" }, // shift-ctrl-menu + { fc::Fckey_smenu , "\033[29;6~" }, // shift-ctrl-menu + { fc::Fmkey_menu , "\033[29;3~" }, // M-menu + { fc::Fmkey_smenu , "\033[29;4~" }, // shift-M-menu + { fc::Fcmkey_menu , "\033[29;7~" }, // ctrl-M-menu + { fc::Fcmkey_smenu , "\033[29;8~" }, // shift-ctrl-M-menu + { fc::Fkey_escape_mintty , "\033O["}, // mintty Esc + { fc::Fmkey_tab , "\033\t"}, // M-tab + { fc::Fmkey_enter , "\033\n"}, // M-enter + { fc::Fmkey_enter , "\033\r"}, // M-enter + { fc::Fmkey_space , "\033 " }, // M-' ' + { fc::Fmkey_bang , "\033!" }, // M-! + { fc::Fmkey_quotes , "\033\""}, // M-" + { fc::Fmkey_hash , "\033#" }, // M-# + { fc::Fmkey_dollar , "\033$" }, // M-$ + { fc::Fmkey_percent , "\033%" }, // M-% + { fc::Fmkey_ampersand , "\033&" }, // M-& + { fc::Fmkey_apostrophe , "\033'" }, // M-' + { fc::Fmkey_left_parenthesis , "\033(" }, // M-( + { fc::Fmkey_right_parenthesis , "\033)" }, // M-) + { fc::Fmkey_asterisk , "\033*" }, // M-* + { fc::Fmkey_plus , "\033+" }, // M-+ + { fc::Fmkey_comma , "\033," }, // M-, + { fc::Fmkey_minus , "\033-" }, // M-'-' + { fc::Fmkey_full_stop , "\033." }, // M-. + { fc::Fmkey_slash , "\033/" }, // M-/ + { fc::Fmkey_0 , "\0330" }, // M-0 + { fc::Fmkey_1 , "\0331" }, // M-1 + { fc::Fmkey_2 , "\0332" }, // M-2 + { fc::Fmkey_3 , "\0333" }, // M-3 + { fc::Fmkey_4 , "\0334" }, // M-4 + { fc::Fmkey_5 , "\0335" }, // M-5 + { fc::Fmkey_6 , "\0336" }, // M-6 + { fc::Fmkey_7 , "\0337" }, // M-7 + { fc::Fmkey_8 , "\0338" }, // M-8 + { fc::Fmkey_9 , "\0339" }, // M-9 + { fc::Fmkey_colon , "\033:" }, // M-: + { fc::Fmkey_semicolon , "\033;" }, // M-; + { fc::Fmkey_less_than , "\033<" }, // M-< + { fc::Fmkey_equals , "\033=" }, // M-= + { fc::Fmkey_greater_than , "\033>" }, // M-> + { fc::Fmkey_question_mark , "\033?" }, // M-? + { fc::Fmkey_at , "\033@" }, // M-@ + { fc::Fmkey_A , "\033A" }, // M-A + { fc::Fmkey_B , "\033B" }, // M-B + { fc::Fmkey_C , "\033C" }, // M-C + { fc::Fmkey_D , "\033D" }, // M-D + { fc::Fmkey_E , "\033E" }, // M-E + { fc::Fmkey_F , "\033F" }, // M-F + { fc::Fmkey_G , "\033G" }, // M-G + { fc::Fmkey_H , "\033H" }, // M-H + { fc::Fmkey_I , "\033I" }, // M-I + { fc::Fmkey_J , "\033J" }, // M-J + { fc::Fmkey_K , "\033K" }, // M-K + { fc::Fmkey_L , "\033L" }, // M-L + { fc::Fmkey_M , "\033M" }, // M-M + { fc::Fmkey_N , "\033N" }, // M-N + { fc::Fmkey_O , "\033O" }, // M-O + { fc::Fmkey_P , "\033P" }, // M-P + { fc::Fmkey_Q , "\033Q" }, // M-Q + { fc::Fmkey_R , "\033R" }, // M-R + { fc::Fmkey_S , "\033S" }, // M-S + { fc::Fmkey_T , "\033T" }, // M-T + { fc::Fmkey_U , "\033U" }, // M-U + { fc::Fmkey_V , "\033V" }, // M-V + { fc::Fmkey_W , "\033W" }, // M-W + { fc::Fmkey_X , "\033X" }, // M-X + { fc::Fmkey_Y , "\033Y" }, // M-Y + { fc::Fmkey_Z , "\033Z" }, // M-Z + { fc::Fmkey_left_square_bracket , "\033[" }, // M-[ + { fc::Fmkey_backslash , "\033\\"}, // M-'\' + { fc::Fmkey_right_square_bracket , "\033]" }, // M-] + { fc::Fmkey_caret , "\033^" }, // M-^ + { fc::Fmkey_underscore , "\033_" }, // M-_ + { fc::Fmkey_grave_accent , "\033`" }, // M-` + { fc::Fmkey_a , "\033a" }, // M-a + { fc::Fmkey_b , "\033b" }, // M-b + { fc::Fmkey_c , "\033c" }, // M-c + { fc::Fmkey_d , "\033d" }, // M-d + { fc::Fmkey_e , "\033e" }, // M-e + { fc::Fmkey_f , "\033f" }, // M-f + { fc::Fmkey_g , "\033g" }, // M-g + { fc::Fmkey_h , "\033h" }, // M-h + { fc::Fmkey_i , "\033i" }, // M-i + { fc::Fmkey_j , "\033j" }, // M-j + { fc::Fmkey_k , "\033k" }, // M-k + { fc::Fmkey_l , "\033l" }, // M-l + { fc::Fmkey_m , "\033m" }, // M-m + { fc::Fmkey_n , "\033n" }, // M-n + { fc::Fmkey_o , "\033o" }, // M-o + { fc::Fmkey_p , "\033p" }, // M-p + { fc::Fmkey_q , "\033q" }, // M-q + { fc::Fmkey_r , "\033r" }, // M-r + { fc::Fmkey_s , "\033s" }, // M-s + { fc::Fmkey_t , "\033t" }, // M-t + { fc::Fmkey_u , "\033u" }, // M-u + { fc::Fmkey_v , "\033v" }, // M-v + { fc::Fmkey_w , "\033w" }, // M-w + { fc::Fmkey_x , "\033x" }, // M-x + { fc::Fmkey_y , "\033y" }, // M-y + { fc::Fmkey_z , "\033z" }, // M-z + { fc::Fmkey_left_curly_bracket , "\033{" }, // M-{ + { fc::Fmkey_vertical_bar , "\033|" }, // M-| + { fc::Fmkey_right_curly_bracket , "\033}" }, // M-} + { fc::Fmkey_tilde , "\033~" }, // M-~ + { 0 , "\0" } +}; + +keyname FkeyName[] = +{ + { fc::Fckey_a , "Ctrl+A" }, + { fc::Fckey_b , "Ctrl+B" }, + { fc::Fckey_c , "Ctrl+C" }, + { fc::Fckey_d , "Ctrl+D" }, + { fc::Fckey_e , "Ctrl+E" }, + { fc::Fckey_f , "Ctrl+F" }, + { fc::Fckey_g , "Ctrl+G" }, + { fc::Fkey_erase , "Backspace" }, // Ctrl+H + { fc::Fkey_tab , "Tab" }, // Ctrl+I + { fc::Fckey_j , "Ctrl+J" }, + { fc::Fckey_h , "Ctrl+K" }, + { fc::Fckey_l , "Ctrl+L" }, + { fc::Fkey_return , "Return" }, // Ctrl+M + { fc::Fckey_n , "Ctrl+N" }, + { fc::Fckey_o , "Ctrl+O" }, + { fc::Fckey_p , "Ctrl+P" }, + { fc::Fckey_q , "Ctrl+Q" }, + { fc::Fckey_r , "Ctrl+R" }, + { fc::Fckey_s , "Ctrl+S" }, + { fc::Fckey_t , "Ctrl+T" }, + { fc::Fckey_u , "Ctrl+U" }, + { fc::Fckey_v , "Ctrl+V" }, + { fc::Fckey_w , "Ctrl+W" }, + { fc::Fckey_x , "Ctrl+X" }, + { fc::Fckey_y , "Ctrl+Y" }, + { fc::Fckey_z , "Ctrl+Z" }, + { fc::Fkey_escape , "Esc" }, // Ctrl+[ + { fc::Fckey_backslash , "Ctrl+\\" }, + { fc::Fckey_right_square_bracket, "Ctrl+]" }, + { fc::Fckey_caret , "Ctrl+^" }, + { fc::Fckey_underscore , "Ctrl+_" }, + { fc::Fkey_space , "Space" }, + { fc::Fckey_space , "Ctrl+Space" }, // Ctrl+(Space or @) + { fc::Fkey_backspace , "Backspace" }, + { fc::Fkey_catab , "Clear-All-Tabs" }, + { fc::Fkey_clear , "Clear-Screen" }, + { fc::Fkey_ctab , "Clear-Tab" }, + { fc::Fkey_dc , "Del" }, + { fc::Fkey_dl , "Del-line" }, + { fc::Fkey_down , "Down" }, + { fc::Fkey_eic , "Exit-Ins" }, + { fc::Fkey_eol , "Clear-End-of-Line" }, + { fc::Fkey_eos , "Clear-End-of-Screen" }, + { fc::Fkey_f0 , "F0" }, + { fc::Fkey_f1 , "F1" }, + { fc::Fkey_f2 , "F2" }, + { fc::Fkey_f3 , "F3" }, + { fc::Fkey_f4 , "F4" }, + { fc::Fkey_f5 , "F5" }, + { fc::Fkey_f6 , "F6" }, + { fc::Fkey_f7 , "F7" }, + { fc::Fkey_f8 , "F8" }, + { fc::Fkey_f9 , "F9" }, + { fc::Fkey_f10 , "F10" }, + { fc::Fkey_home , "Home" }, + { fc::Fkey_ic , "Ins" }, + { fc::Fkey_il , "Ins-Line" }, + { fc::Fkey_left , "Left" }, + { fc::Fkey_ll , "Lower-Left" }, + { fc::Fkey_npage , "PgDn" }, + { fc::Fkey_ppage , "PgUp" }, + { fc::Fkey_right , "Right" }, + { fc::Fkey_sf , "Scroll-Forward" }, + { fc::Fkey_sr , "Scroll-Backward" }, + { fc::Fkey_stab , "Set-Tab" }, + { fc::Fkey_up , "Up" }, + { fc::Fkey_a1 , "Upper-Left" }, + { fc::Fkey_a3 , "Upper-Right" }, + { fc::Fkey_b2 , "Center" }, + { fc::Fkey_c1 , "Lower-Left" }, + { fc::Fkey_c3 , "Lower-Right" }, + { fc::Fkey_btab , "Shift+Tab" }, + { fc::Fkey_beg , "Begin" }, + { fc::Fkey_cancel , "Cancel" }, + { fc::Fkey_close , "Close" }, + { fc::Fkey_command , "Command" }, + { fc::Fkey_copy , "Copy" }, + { fc::Fkey_create , "Create" }, + { fc::Fkey_end , "End" }, + { fc::Fkey_enter , "Enter" }, + { fc::Fkey_exit , "Exit" }, + { fc::Fkey_find , "Find" }, + { fc::Fkey_help , "Help" }, + { fc::Fkey_mark , "Mark" }, + { fc::Fkey_message , "Message" }, + { fc::Fkey_move , "Move" }, + { fc::Fkey_next , "Next" }, + { fc::Fkey_open , "Open" }, + { fc::Fkey_options , "Options" }, + { fc::Fkey_previous , "Previous" }, + { fc::Fkey_print , "Print" }, + { fc::Fkey_redo , "Redo" }, + { fc::Fkey_reference , "Reference" }, + { fc::Fkey_refresh , "Refresh" }, + { fc::Fkey_replace , "Replace" }, + { fc::Fkey_restart , "Restart" }, + { fc::Fkey_resume , "Resume" }, + { fc::Fkey_save , "Save" }, + { fc::Fkey_suspend , "Suspend" }, + { fc::Fkey_undo , "Undo" }, + { fc::Fkey_sbeg , "Shift+Begin" }, + { fc::Fkey_scancel , "Shift+Cancel" }, + { fc::Fkey_scommand , "Shift+Command" }, + { fc::Fkey_scopy , "Shift+Copy" }, + { fc::Fkey_screate , "Shift+Create" }, + { fc::Fkey_sdc , "Shift+Del" }, + { fc::Fkey_sdl , "Shift+Del-line" }, + { fc::Fkey_select , "Select" }, + { fc::Fkey_send , "Shift+End" }, + { fc::Fkey_seol , "Shift+Clear-End-of-Line" }, + { fc::Fkey_sexit , "Shift+Exit" }, + { fc::Fkey_sfind , "Shift+Find" }, + { fc::Fkey_shelp , "Shift+Help" }, + { fc::Fkey_shome , "Shift+Home" }, + { fc::Fkey_sic , "Shift+Ins" }, + { fc::Fkey_sleft , "Shift+Left" }, + { fc::Fkey_smessage , "Shift+Message" }, + { fc::Fkey_smove , "Shift+Move" }, + { fc::Fkey_snext , "Shift+Next" }, + { fc::Fkey_soptions , "Shift+Options" }, + { fc::Fkey_sprevious , "Shift+Previous" }, + { fc::Fkey_sprint , "Shift+Print" }, + { fc::Fkey_sredo , "Shift+Redo" }, + { fc::Fkey_sreplace , "Shift+Replace" }, + { fc::Fkey_sright , "Shift+Right" }, + { fc::Fkey_srsume , "Shift+Resume" }, + { fc::Fkey_ssave , "Shift+Save" }, + { fc::Fkey_ssuspend , "Shift+Suspend" }, + { fc::Fkey_sundo , "Shift+Undo" }, + { fc::Fkey_f11 , "F11" }, + { fc::Fkey_f12 , "F12" }, + { fc::Fkey_f13 , "Shift+F1" }, + { fc::Fkey_f14 , "Shift+F2" }, + { fc::Fkey_f15 , "Shift+F3" }, + { fc::Fkey_f16 , "Shift+F4" }, + { fc::Fkey_f17 , "Shift+F5" }, + { fc::Fkey_f18 , "Shift+F6" }, + { fc::Fkey_f19 , "Shift+F7" }, + { fc::Fkey_f20 , "Shift+F8" }, + { fc::Fkey_f21 , "Shift+F9" }, + { fc::Fkey_f22 , "Shift+F10" }, + { fc::Fkey_f23 , "Shift+F11" }, + { fc::Fkey_f24 , "Shift+F12" }, + { fc::Fkey_f25 , "Ctrl+F1" }, + { fc::Fkey_f26 , "Ctrl+F2" }, + { fc::Fkey_f27 , "Ctrl+F3" }, + { fc::Fkey_f28 , "Ctrl+F4" }, + { fc::Fkey_f29 , "Ctrl+F5" }, + { fc::Fkey_f30 , "Ctrl+F6" }, + { fc::Fkey_f31 , "Ctrl+F7" }, + { fc::Fkey_f32 , "Ctrl+F8" }, + { fc::Fkey_f33 , "Ctrl+F9" }, + { fc::Fkey_f34 , "Ctrl+F10" }, + { fc::Fkey_f35 , "Ctrl+F11" }, + { fc::Fkey_f36 , "Ctrl+F12" }, + { fc::Fkey_f37 , "Shift+Ctrl+F1" }, + { fc::Fkey_f38 , "Shift+Ctrl+F2" }, + { fc::Fkey_f39 , "Shift+Ctrl+F3" }, + { fc::Fkey_f40 , "Shift+Ctrl+F4" }, + { fc::Fkey_f41 , "Shift+Ctrl+F5" }, + { fc::Fkey_f42 , "Shift+Ctrl+F6" }, + { fc::Fkey_f43 , "Shift+Ctrl+F7" }, + { fc::Fkey_f44 , "Shift+Ctrl+F8" }, + { fc::Fkey_f45 , "Shift+Ctrl+F9" }, + { fc::Fkey_f46 , "Shift+Ctrl+F10" }, + { fc::Fkey_f47 , "Shift+Ctrl+F11" }, + { fc::Fkey_f48 , "Shift+Ctrl+F12" }, + { fc::Fkey_f49 , "Meta+F1" }, + { fc::Fkey_f50 , "Meta+F2" }, + { fc::Fkey_f51 , "Meta+F3" }, + { fc::Fkey_f52 , "Meta+F4" }, + { fc::Fkey_f53 , "Meta+F5" }, + { fc::Fkey_f54 , "Meta+F6" }, + { fc::Fkey_f55 , "Meta+F7" }, + { fc::Fkey_f56 , "Meta+F8" }, + { fc::Fkey_f57 , "Meta+F9" }, + { fc::Fkey_f58 , "Meta+F10" }, + { fc::Fkey_f59 , "Meta+F11" }, + { fc::Fkey_f60 , "Meta+F12" }, + { fc::Fkey_f61 , "Shift+Meta+F1" }, + { fc::Fkey_f62 , "Shift+Meta+F2" }, + { fc::Fkey_f63 , "Shift+Meta+F3" }, + { fc::Fmkey_ic , "Meta+Ins" }, + { fc::Fmkey_dc , "Meta+Del" }, + { fc::Fmkey_home , "Meta+Home" }, + { fc::Fmkey_end , "Meta+End" }, + { fc::Fmkey_ppage , "Meta+PgUp" }, + { fc::Fmkey_npage , "Meta+PgDn" }, + { fc::Fmkey_f1 , "Meta+F1" }, + { fc::Fmkey_f2 , "Meta+F2" }, + { fc::Fmkey_f3 , "Meta+F3" }, + { fc::Fmkey_f4 , "Meta+F4" }, + { fc::Fmkey_f5 , "Meta+F5" }, + { fc::Fmkey_f6 , "Meta+F6" }, + { fc::Fmkey_f7 , "Meta+F7" }, + { fc::Fmkey_f8 , "Meta+F8" }, + { fc::Fmkey_f9 , "Meta+F9" }, + { fc::Fmkey_f10 , "Meta+F10" }, + { fc::Fmkey_f11 , "Meta+F11" }, + { fc::Fmkey_f12 , "Meta+F12" }, + { fc::Fmkey_up , "Meta+Up" }, + { fc::Fmkey_down , "Meta+Down" }, + { fc::Fmkey_right , "Meta+Right" }, + { fc::Fmkey_left , "Meta+Left" }, + { fc::Fmkey_sic , "Shift+Meta+Ins" }, + { fc::Fmkey_sdc , "Shift+Meta+Del" }, + { fc::Fmkey_shome , "Shift+Meta+Home" }, + { fc::Fmkey_send , "Shift+Meta+End" }, + { fc::Fmkey_sppage , "Shift+Meta+PgUp" }, + { fc::Fmkey_snpage , "Shift+Meta+PgDn" }, + { fc::Fmkey_sf1 , "Shift+Meta+F1" }, + { fc::Fmkey_sf2 , "Shift+Meta+F2" }, + { fc::Fmkey_sf3 , "Shift+Meta+F3" }, + { fc::Fmkey_sf4 , "Shift+Meta+F4" }, + { fc::Fmkey_sf5 , "Shift+Meta+F5" }, + { fc::Fmkey_sf6 , "Shift+Meta+F6" }, + { fc::Fmkey_sf7 , "Shift+Meta+F7" }, + { fc::Fmkey_sf8 , "Shift+Meta+F8" }, + { fc::Fmkey_sf9 , "Shift+Meta+F9" }, + { fc::Fmkey_sf10 , "Shift+Meta+F10" }, + { fc::Fmkey_sf11 , "Shift+Meta+F11" }, + { fc::Fmkey_sf12 , "Shift+Meta+F12" }, + { fc::Fmkey_sup , "Shift+Meta+Up" }, + { fc::Fmkey_sdown , "Shift+Meta+Down" }, + { fc::Fmkey_sright , "Shift+Meta+Right" }, + { fc::Fmkey_sleft , "Shift+Meta+Left" }, + { fc::Fckey_ic , "Ctrl+Ins" }, + { fc::Fckey_dc , "Ctrl+Del" }, + { fc::Fckey_home , "Ctrl+Home" }, + { fc::Fckey_end , "Ctrl+End" }, + { fc::Fckey_ppage , "Ctrl+PgUp" }, + { fc::Fckey_npage , "Ctrl+PgDn" }, + { fc::Fckey_up , "Ctrl+Up" }, + { fc::Fckey_down , "Ctrl+Down" }, + { fc::Fckey_right , "Ctrl+Right" }, + { fc::Fckey_left , "Ctrl+Left" }, + { fc::Fckey_sic , "Shift+Ctrl+Ins" }, + { fc::Fckey_sdc , "Shift+Ctrl+Del" }, + { fc::Fckey_shome , "Shift+Ctrl+Home" }, + { fc::Fckey_send , "Shift+Ctrl+End" }, + { fc::Fckey_sppage , "Shift+Ctrl+PgUp" }, + { fc::Fckey_snpage , "Shift+Ctrl+PgDn" }, + { fc::Fckey_sup , "Shift+Ctrl+Up" }, + { fc::Fckey_sdown , "Shift+Ctrl+Down" }, + { fc::Fckey_sright , "Shift+Ctrl+Right" }, + { fc::Fckey_sleft , "Shift+Ctrl+Left" }, + { fc::Fcmkey_ic , "Ctrl+Meta+Ins" }, + { fc::Fcmkey_dc , "Ctrl+Meta+Del" }, + { fc::Fcmkey_home , "Ctrl+Meta+Home" }, + { fc::Fcmkey_end , "Ctrl+Meta+End" }, + { fc::Fcmkey_ppage , "Ctrl+Meta+PgUp" }, + { fc::Fcmkey_npage , "Ctrl+Meta+PgDn" }, + { fc::Fcmkey_up , "Ctrl+Meta+Up" }, + { fc::Fcmkey_down , "Ctrl+Meta+Down" }, + { fc::Fcmkey_right , "Ctrl+Meta+Right" }, + { fc::Fcmkey_left , "Ctrl+Meta+Left" }, + { fc::Fcmkey_sic , "Shift+Ctrl+Meta+Ins" }, + { fc::Fcmkey_sdc , "Shift+Ctrl+Meta+Del" }, + { fc::Fcmkey_shome , "Shift+Ctrl+Meta+Home" }, + { fc::Fcmkey_send , "Shift+Ctrl+Meta+End" }, + { fc::Fcmkey_sppage , "Shift+Ctrl+Meta+PgUp" }, + { fc::Fcmkey_snpage , "Shift+Ctrl+Meta+PgDn" }, + { fc::Fcmkey_sf1 , "Shift+Ctrl+Meta+F1" }, + { fc::Fcmkey_sf2 , "Shift+Ctrl+Meta+F2" }, + { fc::Fcmkey_sf3 , "Shift+Ctrl+Meta+F3" }, + { fc::Fcmkey_sf4 , "Shift+Ctrl+Meta+F4" }, + { fc::Fcmkey_sf5 , "Shift+Ctrl+Meta+F5" }, + { fc::Fcmkey_sf6 , "Shift+Ctrl+Meta+F6" }, + { fc::Fcmkey_sf7 , "Shift+Ctrl+Meta+F7" }, + { fc::Fcmkey_sf8 , "Shift+Ctrl+Meta+F8" }, + { fc::Fcmkey_sf9 , "Shift+Ctrl+Meta+F9" }, + { fc::Fcmkey_sf10 , "Shift+Ctrl+Meta+F10" }, + { fc::Fcmkey_sf11 , "Shift+Ctrl+Meta+F11" }, + { fc::Fcmkey_sf12 , "Shift+Ctrl+Meta+F12" }, + { fc::Fcmkey_sup , "Shift+Ctrl+Meta+Up" }, + { fc::Fcmkey_sdown , "Shift+Ctrl+Meta+Down" }, + { fc::Fcmkey_sright , "Shift+Ctrl+Meta+Right" }, + { fc::Fcmkey_sleft , "Shift+Ctrl+Meta+Left" }, + { fc::Fkey_menu , "Menu" }, + { fc::Fkey_smenu , "Shift+Menu" }, + { fc::Fckey_menu , "Ctrl+Menu" }, + { fc::Fckey_smenu , "Shift+Ctrl+Menu" }, + { fc::Fmkey_menu , "Meta+Menu" }, + { fc::Fmkey_smenu , "Shift+Meta+Menu" }, + { fc::Fcmkey_menu , "Ctrl+Meta+Menu" }, + { fc::Fcmkey_smenu , "Shift+Ctrl+Meta+Menu" }, + { fc::Fmkey_tab , "Meta+Tab" }, + { fc::Fmkey_enter , "Meta+Enter" }, + { fc::Fmkey_space , "Meta+Space" }, + { fc::Fmkey_bang , "Meta+!" }, + { fc::Fmkey_quotes , "Meta+\"" }, + { fc::Fmkey_hash , "Meta+#" }, + { fc::Fmkey_dollar , "Meta+$" }, + { fc::Fmkey_percent , "Meta+%" }, + { fc::Fmkey_ampersand , "Meta+&" }, + { fc::Fmkey_apostrophe , "Meta+'" }, + { fc::Fmkey_left_parenthesis , "Meta+(" }, + { fc::Fmkey_right_parenthesis , "Meta+)" }, + { fc::Fmkey_asterisk , "Meta+*" }, + { fc::Fmkey_plus , "Meta++" }, + { fc::Fmkey_comma , "Meta+," }, + { fc::Fmkey_minus , "Meta+-" }, + { fc::Fmkey_full_stop , "Meta+." }, + { fc::Fmkey_slash , "Meta+/" }, + { fc::Fmkey_0 , "Meta+0" }, + { fc::Fmkey_1 , "Meta+1" }, + { fc::Fmkey_2 , "Meta+2" }, + { fc::Fmkey_3 , "Meta+3" }, + { fc::Fmkey_4 , "Meta+4" }, + { fc::Fmkey_5 , "Meta+5" }, + { fc::Fmkey_6 , "Meta+6" }, + { fc::Fmkey_7 , "Meta+7" }, + { fc::Fmkey_8 , "Meta+8" }, + { fc::Fmkey_9 , "Meta+9" }, + { fc::Fmkey_colon , "Meta+:" }, + { fc::Fmkey_semicolon , "Meta+;" }, + { fc::Fmkey_less_than , "Meta+<" }, + { fc::Fmkey_equals , "Meta+=" }, + { fc::Fmkey_greater_than , "Meta+>" }, + { fc::Fmkey_question_mark , "Meta+?" }, + { fc::Fmkey_at , "Meta+@" }, + { fc::Fmkey_A , "Shift+Meta+A" }, + { fc::Fmkey_B , "Shift+Meta+B" }, + { fc::Fmkey_C , "Shift+Meta+C" }, + { fc::Fmkey_D , "Shift+Meta+D" }, + { fc::Fmkey_E , "Shift+Meta+E" }, + { fc::Fmkey_F , "Shift+Meta+F" }, + { fc::Fmkey_G , "Shift+Meta+G" }, + { fc::Fmkey_H , "Shift+Meta+H" }, + { fc::Fmkey_I , "Shift+Meta+I" }, + { fc::Fmkey_J , "Shift+Meta+J" }, + { fc::Fmkey_K , "Shift+Meta+K" }, + { fc::Fmkey_L , "Shift+Meta+L" }, + { fc::Fmkey_M , "Shift+Meta+M" }, + { fc::Fmkey_N , "Shift+Meta+N" }, + { fc::Fmkey_O , "Shift+Meta+O" }, + { fc::Fmkey_P , "Shift+Meta+P" }, + { fc::Fmkey_Q , "Shift+Meta+Q" }, + { fc::Fmkey_R , "Shift+Meta+R" }, + { fc::Fmkey_S , "Shift+Meta+S" }, + { fc::Fmkey_T , "Shift+Meta+T" }, + { fc::Fmkey_U , "Shift+Meta+U" }, + { fc::Fmkey_V , "Shift+Meta+V" }, + { fc::Fmkey_W , "Shift+Meta+W" }, + { fc::Fmkey_X , "Shift+Meta+X" }, + { fc::Fmkey_Y , "Shift+Meta+Y" }, + { fc::Fmkey_Z , "Shift+Meta+Z" }, + { fc::Fmkey_left_square_bracket , "Meta+[" }, + { fc::Fmkey_backslash , "Meta+\\" }, + { fc::Fmkey_right_square_bracket, "Meta+]" }, + { fc::Fmkey_caret , "Meta+^" }, + { fc::Fmkey_underscore , "Meta+_" }, + { fc::Fmkey_grave_accent , "Meta+`" }, + { fc::Fmkey_a , "Meta+A" }, + { fc::Fmkey_b , "Meta+B" }, + { fc::Fmkey_c , "Meta+C" }, + { fc::Fmkey_d , "Meta+D" }, + { fc::Fmkey_e , "Meta+E" }, + { fc::Fmkey_f , "Meta+F" }, + { fc::Fmkey_g , "Meta+G" }, + { fc::Fmkey_h , "Meta+H" }, + { fc::Fmkey_i , "Meta+I" }, + { fc::Fmkey_j , "Meta+J" }, + { fc::Fmkey_k , "Meta+K" }, + { fc::Fmkey_l , "Meta+L" }, + { fc::Fmkey_m , "Meta+M" }, + { fc::Fmkey_n , "Meta+N" }, + { fc::Fmkey_o , "Meta+O" }, + { fc::Fmkey_p , "Meta+P" }, + { fc::Fmkey_q , "Meta+Q" }, + { fc::Fmkey_r , "Meta+R" }, + { fc::Fmkey_s , "Meta+S" }, + { fc::Fmkey_t , "Meta+T" }, + { fc::Fmkey_u , "Meta+U" }, + { fc::Fmkey_v , "Meta+V" }, + { fc::Fmkey_w , "Meta+W" }, + { fc::Fmkey_x , "Meta+X" }, + { fc::Fmkey_y , "Meta+Y" }, + { fc::Fmkey_z , "Meta+Z" }, + { fc::Fmkey_left_curly_bracket , "Meta+{" }, + { fc::Fmkey_vertical_bar , "Meta+|" }, + { fc::Fmkey_right_curly_bracket , "Meta+}" }, + { fc::Fmkey_tilde , "Meta+~" }, + { 0 , "\0" } +}; + +} // namespace fc diff --git a/src/fkeyboard.cpp b/src/fkeyboard.cpp new file mode 100644 index 00000000..66e70831 --- /dev/null +++ b/src/fkeyboard.cpp @@ -0,0 +1,504 @@ +/*********************************************************************** +* fkeyboard.cpp - Read keyboard events * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2018 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +#include "final/fkeyboard.h" +#include "final/fkey_map.h" + +#include + +// static class attributes +long FKeyboard::key_timeout = 100000; // 100 ms (default timeout for keypress) + +#if defined(__linux__) + FTermLinux* FKeyboard::linux = 0; +#endif + +//---------------------------------------------------------------------- +// class FKeyboardCommand +//---------------------------------------------------------------------- + +// constructors and destructor +//---------------------------------------------------------------------- +FKeyboardCommand::FKeyboardCommand ( FApplication* object + , void(FApplication::*method)() ) + : instance(0) + , handler(0) +{ + instance = object; + handler = method; +} + +// public methods of FKeyboardCommand +//---------------------------------------------------------------------- +void FKeyboardCommand::execute() +{ + (instance->*handler)(); +} + + +//---------------------------------------------------------------------- +// class FKeyboard +//---------------------------------------------------------------------- + +// constructors and destructor +//---------------------------------------------------------------------- +FKeyboard::FKeyboard() + : key(0) + , fifo_offset(0) + , fifo_in_use(false) + , fifo_buf_size(sizeof(fifo_buf)) + , stdin_status_flags(0) + , input_data_pending(false) + , utf8_input(false) + , mouse_support(true) + , non_blocking_stdin(false) + , keypressed_cmd() + , keyreleased_cmd() + , escape_key_cmd() + , time_keypressed() + , termcap_map(0) +{ + // Initialize keyboard values + time_keypressed.tv_sec = 0; + time_keypressed.tv_usec = 0; + + // Get the stdin file status flags + stdin_status_flags = fcntl(FTermios::getStdIn(), F_GETFL); + + if ( stdin_status_flags == -1 ) + std::abort(); + + // Initialize arrays with '\0' + std::fill_n (k_buf, sizeof(k_buf), '\0'); + std::fill_n (fifo_buf, fifo_buf_size, '\0'); +} + +//---------------------------------------------------------------------- +FKeyboard::~FKeyboard() // destructor +{ } + +// public methods of FKeyboard +//---------------------------------------------------------------------- +void FKeyboard::fetchKeyCode() +{ + parseKeyBuffer(); +} + +//---------------------------------------------------------------------- +const FString FKeyboard::getKeyName (int keynum) +{ + for (int i = 0; fc::FkeyName[i].string[0] != 0; i++) + if ( fc::FkeyName[i].num && fc::FkeyName[i].num == keynum ) + return FString(fc::FkeyName[i].string); + + if ( keynum > 32 && keynum < 127 ) + return FString(char(keynum)); + + return FString(""); +} + +//---------------------------------------------------------------------- +void FKeyboard::setTermcapMap (fc::fkeymap* keymap) +{ + termcap_map = keymap; +} + +//---------------------------------------------------------------------- +bool& FKeyboard::unprocessedInput() +{ + return input_data_pending; +} + +//---------------------------------------------------------------------- +bool FKeyboard::isKeyPressed() +{ + register int result; + fd_set ifds; + struct timeval tv; + int stdin_no = FTermios::getStdIn(); + + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 100000; // 100 ms + result = select (stdin_no + 1, &ifds, 0, 0, &tv); + + if ( result > 0 && FD_ISSET(stdin_no, &ifds) ) + FD_CLR (stdin_no, &ifds); + + return ( result > 0 ); +} + +//---------------------------------------------------------------------- +void FKeyboard::emptyKeyBufferOnTimeout() +{ + // Empty the buffer on timeout + if ( fifo_in_use && isKeypressTimeout(&time_keypressed) ) + { + fifo_offset = 0; + key = 0; + std::fill_n (fifo_buf, fifo_buf_size, '\0'); + fifo_in_use = false; + } +} + +//---------------------------------------------------------------------- +void FKeyboard::escapeKeyHandling() +{ + // Send an escape key press event if there is only one 0x1b + // in the buffer and the timeout is reached + + if ( fifo_in_use + && fifo_offset == 1 + && fifo_buf[0] == 0x1b + && fifo_buf[1] == 0x00 + && isKeypressTimeout(&time_keypressed) ) + { + fifo_offset = 0; + fifo_buf[0] = 0x00; + fifo_in_use = false; + input_data_pending = false; + escapeKeyPressed(); + } +} + + +// private methods of FKeyboard +//---------------------------------------------------------------------- +inline int FKeyboard::getMouseProtocolKey() +{ + // Looking for mouse string in the key buffer + + if ( ! mouse_support ) + return -1; + + register std::size_t buf_len = std::strlen(fifo_buf); + + // x11 mouse tracking + if ( buf_len >= 6 && fifo_buf[1] == '[' && fifo_buf[2] == 'M' ) + return fc::Fkey_mouse; + + // SGR mouse tracking + if ( fifo_buf[1] == '[' && fifo_buf[2] == '<' && buf_len >= 9 + && (fifo_buf[buf_len - 1] == 'M' || fifo_buf[buf_len - 1] == 'm') ) + return fc::Fkey_extended_mouse; + + // urxvt mouse tracking + if ( fifo_buf[1] == '[' && fifo_buf[2] >= '1' && fifo_buf[2] <= '9' + && fifo_buf[3] >= '0' && fifo_buf[3] <= '9' && buf_len >= 9 + && fifo_buf[buf_len - 1] == 'M' ) + return fc::Fkey_urxvt_mouse; + + return -1; +} + +//---------------------------------------------------------------------- +inline int FKeyboard::getTermcapKey() +{ + // Looking for termcap key strings in the buffer + assert ( fifo_buf_size > 0 ); + + //for (int i = 0; fc::Fkey[i].tname[0] != 0; i++) + fc::fkeymap* keymap = reinterpret_cast(termcap_map); + for (int i = 0; keymap[i].tname[0] != 0; i++) + { + //char* k = fc::Fkey[i].string; + char* k = keymap[i].string; + register int len = ( k ) ? int(std::strlen(k)) : 0; + + if ( k && std::strncmp(k, fifo_buf, uInt(len)) == 0 ) // found + { + register int n; + + for (n = len; n < fifo_buf_size; n++) // Remove founded entry + fifo_buf[n - len] = fifo_buf[n]; + + for (; n - len < len; n++) // Fill rest with '\0' + fifo_buf[n - len] = '\0'; + + input_data_pending = bool(fifo_buf[0] != '\0'); + return fc::Fkey[i].num; + } + } + + return -1; +} + +//---------------------------------------------------------------------- +inline int FKeyboard::getMetaKey() +{ + // Looking for meta key strings in the buffer + assert ( fifo_buf_size > 0 ); + + for (int i = 0; fc::Fmetakey[i].string[0] != 0; i++) + { + char* kmeta = fc::Fmetakey[i].string; // The string is never null + register int len = int(std::strlen(kmeta)); + + if ( std::strncmp(kmeta, fifo_buf, uInt(len)) == 0 ) // found + { + register int n; + + if ( len == 2 && ( fifo_buf[1] == 'O' + || fifo_buf[1] == '[' + || fifo_buf[1] == ']' ) ) + { + if ( ! isKeypressTimeout(&time_keypressed) ) + return NEED_MORE_DATA; + } + + for (n = len; n < fifo_buf_size; n++) // Remove founded entry + fifo_buf[n - len] = fifo_buf[n]; + + for (; n - len < len; n++) // Fill rest with '\0' + fifo_buf[n - len] = '\0'; + + input_data_pending = bool(fifo_buf[0] != '\0'); + return fc::Fmetakey[i].num; + } + } + + return -1; +} + +//---------------------------------------------------------------------- +inline int FKeyboard::getSingleKey() +{ + register uChar firstchar = uChar(fifo_buf[0]); + int keycode, n, len; + len = 1; + + // Look for a utf-8 character + if ( utf8_input && (firstchar & 0xc0) == 0xc0 ) + { + char utf8char[4] = { }; // Init array with '\0' + + if ( (firstchar & 0xe0) == 0xc0 ) + len = 2; + else if ( (firstchar & 0xf0) == 0xe0 ) + len = 3; + else if ( (firstchar & 0xf8) == 0xf0 ) + len = 4; + + for (int i = 0; i < len ; i++) + utf8char[i] = char(fifo_buf[i] & 0xff); + + keycode = UTF8decode(utf8char); + } + else + keycode = uChar(fifo_buf[0] & 0xff); + + for (n = len; n < fifo_buf_size; n++) // Remove the key from the buffer front + fifo_buf[n - len] = fifo_buf[n]; + + for (n = n - len; n < fifo_buf_size; n++) // Fill the rest with '\0' bytes + fifo_buf[n] = '\0'; + + input_data_pending = bool(fifo_buf[0] != '\0'); + + if ( keycode == 0 ) // Ctrl+Space or Ctrl+@ + keycode = fc::Fckey_space; + + return int(keycode == 127 ? fc::Fkey_backspace : keycode); +} + +//---------------------------------------------------------------------- +bool FKeyboard::setNonBlockingInput (bool on) +{ + if ( on == non_blocking_stdin ) + return non_blocking_stdin; + + if ( on ) // make stdin non-blocking + { + stdin_status_flags |= O_NONBLOCK; + + if ( fcntl (FTermios::getStdIn(), F_SETFL, stdin_status_flags) != -1 ) + non_blocking_stdin = true; + } + else + { + stdin_status_flags &= ~O_NONBLOCK; + + if ( fcntl (FTermios::getStdIn(), F_SETFL, stdin_status_flags) != -1 ) + non_blocking_stdin = false; + } + + return non_blocking_stdin; +} + +//---------------------------------------------------------------------- +int FKeyboard::UTF8decode (const char utf8[]) +{ + register int ucs = 0; + + for (register int i = 0; i < int(std::strlen(utf8)); ++i) + { + register uChar ch = uChar(utf8[i]); + + if ( (ch & 0xc0) == 0x80 ) + { + // byte 2..4 = 10xxxxxx + ucs = (ucs << 6) | (ch & 0x3f); + } + else if ( ch < 128 ) + { + // byte 1 = 0xxxxxxx (1 byte mapping) + ucs = ch & 0xff; + } + else if ( (ch & 0xe0) == 0xc0 ) + { + // byte 1 = 110xxxxx (2 byte mapping) + ucs = ch & 0x1f; + } + else if ( (ch & 0xf0) == 0xe0 ) + { + // byte 1 = 1110xxxx (3 byte mapping) + ucs = ch & 0x0f; + } + else if ( (ch & 0xf8) == 0xf0 ) + { + // byte 1 = 11110xxx (4 byte mapping) + ucs = ch & 0x07; + } + else + { + // error + ucs = EOF; + } + } + + return ucs; +} + +//---------------------------------------------------------------------- +inline ssize_t FKeyboard::readKey() +{ + register ssize_t bytes; + setNonBlockingInput(); + bytes = read(FTermios::getStdIn(), &k_buf, sizeof(k_buf) - 1); + unsetNonBlockingInput(); + return bytes; +} + +//---------------------------------------------------------------------- +inline void FKeyboard::parseKeyBuffer() +{ + register ssize_t bytesread; + FObject::getCurrentTime (&time_keypressed); + + while ( (bytesread = readKey()) > 0 ) + { + if ( bytesread + fifo_offset <= fifo_buf_size ) + { + for (int i = 0; i < bytesread; i++) + { + fifo_buf[fifo_offset] = k_buf[i]; + fifo_offset++; + } + + fifo_in_use = true; + } + + // Read the rest from the fifo buffer + while ( ! isKeypressTimeout(&time_keypressed) + && fifo_offset > 0 + && key != NEED_MORE_DATA ) + { + key = parseKeyString(); + key = keyCorrection(key); + + if ( key != NEED_MORE_DATA ) + keyPressed(); + + fifo_offset = int(std::strlen(fifo_buf)); + } + + // Send key up event + if ( key > 0 ) + keyReleased(); + + key = 0; + } + + std::fill_n (k_buf, sizeof(k_buf), '\0'); +} + +//---------------------------------------------------------------------- +int FKeyboard::parseKeyString() +{ + uChar firstchar = uChar(fifo_buf[0]); + + if ( firstchar == ESC[0] ) + { + int keycode = getMouseProtocolKey(); + + if ( keycode > 0 ) + return keycode; + + keycode = getTermcapKey(); + + if ( keycode > 0 ) + return keycode; + + keycode = getMetaKey(); + + if ( keycode > 0 ) + return keycode; + + if ( ! isKeypressTimeout(&time_keypressed) ) + return NEED_MORE_DATA; + } + + return getSingleKey(); +} + +//---------------------------------------------------------------------- +int FKeyboard::keyCorrection (const int& keycode) +{ + int key_correction; + +#if defined(__linux__) + key_correction = linux->modifierKeyCorrection(keycode); +#else + key_correction = key; +#endif + + return key_correction; +} + +//---------------------------------------------------------------------- +void FKeyboard::keyPressed() +{ + keypressed_cmd.execute(); +} + +//---------------------------------------------------------------------- +void FKeyboard::keyReleased() +{ + keyreleased_cmd.execute(); +} + +//---------------------------------------------------------------------- +void FKeyboard::escapeKeyPressed() +{ + escape_key_cmd.execute(); +} diff --git a/src/fterm.cpp b/src/fterm.cpp index 343e1036..4051c6e3 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -41,15 +41,10 @@ int (*FTerm::Fputchar)(int); // static class attributes int FTerm::fd_tty; -int FTerm::stdin_status_flags; uInt FTerm::baudrate; -long FTerm::key_timeout; bool FTerm::resize_term; -bool FTerm::input_data_pending; -bool FTerm::non_blocking_stdin; bool FTerm::monochron; bool FTerm::pc_charset_console; -bool FTerm::utf8_input; bool FTerm::utf8_state; bool FTerm::utf8_console; bool FTerm::utf8_linux_terminal; @@ -80,6 +75,7 @@ FOptiMove* FTerm::opti_move = 0; FOptiAttr* FTerm::opti_attr = 0; FTermDetection* FTerm::term_detection = 0; FTermXTerminal* FTerm::xterm = 0; +FKeyboard* FTerm::keyboard = 0; FMouseControl* FTerm::mouse = 0; std::map* FTerm::vt100_alt_char = 0; std::map* \ @@ -158,23 +154,7 @@ int FTerm::getColumnNumber() //---------------------------------------------------------------------- const FString FTerm::getKeyName (int keynum) { - for (int i = 0; fc::FkeyName[i].string[0] != 0; i++) - if ( fc::FkeyName[i].num && fc::FkeyName[i].num == keynum ) - return FString(fc::FkeyName[i].string); - - if ( keynum > 32 && keynum < 127 ) - return FString(char(keynum)); - - return FString(""); -} - -//---------------------------------------------------------------------- -FMouseControl* FTerm::getMouseControl() -{ - if ( mouse ) - return mouse; - else - return 0; + return keyboard->getKeyName (keynum); } //---------------------------------------------------------------------- @@ -233,81 +213,6 @@ bool FTerm::setUTF8 (bool on) // UTF-8 (Unicode) return utf8_state; } -//---------------------------------------------------------------------- -bool FTerm::setNonBlockingInput (bool on) -{ - if ( on == non_blocking_stdin ) - return non_blocking_stdin; - - if ( on ) // make stdin non-blocking - { - stdin_status_flags |= O_NONBLOCK; - - if ( fcntl (FTermios::getStdIn(), F_SETFL, stdin_status_flags) != -1 ) - non_blocking_stdin = true; - } - else - { - stdin_status_flags &= ~O_NONBLOCK; - - if ( fcntl (FTermios::getStdIn(), F_SETFL, stdin_status_flags) != -1 ) - non_blocking_stdin = false; - } - - return non_blocking_stdin; -} - -//---------------------------------------------------------------------- -int FTerm::parseKeyString ( char buffer[] - , int buf_size - , timeval* time_keypressed ) -{ - uChar firstchar = uChar(buffer[0]); - - if ( firstchar == ESC[0] ) - { - int key = getMouseProtocolKey(buffer); - - if ( key > 0 ) - return key; - - key = getTermcapKey(buffer, buf_size); - - if ( key > 0 ) - return key; - - key = getMetaKey(buffer, buf_size, time_keypressed); - - if ( key > 0 ) - return key; - - if ( ! isKeypressTimeout(time_keypressed) ) - return NEED_MORE_DATA; - } - - return getSingleKey(buffer, buf_size); -} - -//---------------------------------------------------------------------- -int FTerm::keyCorrection (const int& key) -{ - int key_correction; - -#if defined(__linux__) - key_correction = linux->modifierKeyCorrection(key); -#else - key_correction = key; -#endif - - return key_correction; -} - -//---------------------------------------------------------------------- -bool& FTerm::unprocessedInput() -{ - return input_data_pending; -} - //---------------------------------------------------------------------- bool FTerm::setVGAFont() { @@ -952,50 +857,6 @@ int FTerm::putchar_UTF8 (register int c) return EOF; } -//---------------------------------------------------------------------- -int FTerm::UTF8decode (const char utf8[]) -{ - register int ucs = 0; - - for (register int i = 0; i < int(std::strlen(utf8)); ++i) - { - register uChar ch = uChar(utf8[i]); - - if ( (ch & 0xc0) == 0x80 ) - { - // byte 2..4 = 10xxxxxx - ucs = (ucs << 6) | (ch & 0x3f); - } - else if ( ch < 128 ) - { - // byte 1 = 0xxxxxxx (1 byte mapping) - ucs = ch & 0xff; - } - else if ( (ch & 0xe0) == 0xc0 ) - { - // byte 1 = 110xxxxx (2 byte mapping) - ucs = ch & 0x1f; - } - else if ( (ch & 0xf0) == 0xe0 ) - { - // byte 1 = 1110xxxx (3 byte mapping) - ucs = ch & 0x0f; - } - else if ( (ch & 0xf8) == 0xf0 ) - { - // byte 1 = 11110xxx (4 byte mapping) - ucs = ch & 0x07; - } - else - { - // error - ucs = EOF; - } - } - - return ucs; -} - // protected methods of FTerm //---------------------------------------------------------------------- @@ -1059,9 +920,6 @@ void FTerm::init_global_values() // Teletype (tty) file descriptor is still undefined fd_tty = -1; - // Set default timeout for keypress - key_timeout = 100000; // 100 ms - // Preset to true shadow_character = \ half_block_character = \ @@ -1070,7 +928,6 @@ void FTerm::init_global_values() // Preset to false hidden_cursor = \ utf8_console = \ - utf8_input = \ utf8_state = \ utf8_linux_terminal = \ pc_charset_console = \ @@ -1080,10 +937,6 @@ void FTerm::init_global_values() ascii_console = \ force_vt100 = false; - // Assertion: programm start in cooked mode - input_data_pending = \ - non_blocking_stdin = false; - // Init arrays with '\0' std::fill_n (exit_message, sizeof(exit_message), '\0'); @@ -1267,6 +1120,14 @@ void FTerm::init_teraterm_charmap() fc::character[i][fc::PC] = fc::character[i][fc::ASCII]; } +//---------------------------------------------------------------------- +void FTerm::init_keyboard() +{ +#if defined(__linux__) + keyboard->setFTermLinux (linux); +#endif +} + //---------------------------------------------------------------------- /* Terminal capability data base * ----------------------------- @@ -1288,10 +1149,10 @@ void FTerm::init_termcap() int status = uninitialized; bool color256 = term_detection->canDisplay256Colors(); - // share the terminal capabilities + // Share the terminal capabilities FTermcap().setTermcapMap(tcap); - // open termcap file + // Open termcap file terminals.push_back(termtype); // available terminal type if ( color256 ) // 1st fallback if not found @@ -1359,7 +1220,7 @@ void FTerm::init_termcap_variables (char*& buffer) // Terminal quirks FTermcapQuirks termcap_quirks; - termcap_quirks.setTermcapMap (tcap); // Parameter + termcap_quirks.setTermcapMap (tcap); termcap_quirks.setFTermDetection (term_detection); termcap_quirks.setTerminalType (termtype); termcap_quirks.terminalFixup(); // Fix terminal quirks @@ -1709,8 +1570,8 @@ void FTerm::init_term_encoding() term_encoding = fc::UTF8; Fputchar = &FTerm::putchar_UTF8; // function pointer utf8_state = true; - utf8_input = true; setUTF8(true); + keyboard->enableUTF8(); } else if ( isatty(stdout_no) && (std::strlen(termtype) > 0) @@ -1915,6 +1776,7 @@ void FTerm::enableMouse() if ( TCAP(fc::t_key_mouse) && ! isLinuxTerm() ) xterm_mouse = true; + keyboard->enableMouseSequences(); mouse->setMaxWidth (short(getColumnNumber())); mouse->setMaxHeight (short(getLineNumber())); // Enable the linux general purpose mouse (gpm) server @@ -1927,6 +1789,7 @@ void FTerm::enableMouse() //---------------------------------------------------------------------- void FTerm::disableMouse() { + keyboard->disableMouseSequences(); mouse->disable(); } @@ -1994,6 +1857,7 @@ inline void FTerm::allocationValues() openbsd = new FTermOpenBSD(); #endif + keyboard = new FKeyboard(); mouse = new FMouseControl(); term = new FRect(0, 0, 0, 0); vt100_alt_char = new std::map; @@ -2027,6 +1891,9 @@ inline void FTerm::deallocationValues() if ( mouse ) delete mouse; + if ( keyboard ) + delete keyboard; + #if defined(__NetBSD__) || defined(__OpenBSD__) if ( openbsd ) delete openbsd; @@ -2068,12 +1935,6 @@ void FTerm::init() // Initialize termios FTermios::init(); - // Get the stdin file status flags - stdin_status_flags = fcntl(FTermios::getStdIn(), F_GETFL); - - if ( stdin_status_flags == -1 ) - std::abort(); - // Get pathname of the terminal device if ( ttyname_r(stdout_no, termfilename, sizeof(termfilename)) ) termfilename[0] = '\0'; @@ -2102,12 +1963,18 @@ void FTerm::init() init_termcap(); init_alt_charset(); + // Pass the terminal capabilities to the keyboard object + keyboard->setTermcapMap (fc::Fkey); + // Initializes locale information init_locale(); // Detect environment and set encoding init_encoding(); + // Initializes keyboard settings + init_keyboard(); + // Enable the terminal mouse support if ( init_values.mouse_support ) enableMouse(); @@ -2325,143 +2192,6 @@ uInt FTerm::cp437_to_unicode (uChar c) return ucs; } -//---------------------------------------------------------------------- -inline int FTerm::getMouseProtocolKey (char buffer[]) -{ - // Looking for mouse string in the key buffer - - if ( ! init_values.mouse_support ) - return -1; - - register std::size_t buf_len = std::strlen(buffer); - - // x11 mouse tracking - if ( buf_len >= 6 && buffer[1] == '[' && buffer[2] == 'M' ) - return fc::Fkey_mouse; - - // SGR mouse tracking - if ( buffer[1] == '[' && buffer[2] == '<' && buf_len >= 9 - && (buffer[buf_len - 1] == 'M' || buffer[buf_len - 1] == 'm') ) - return fc::Fkey_extended_mouse; - - // urxvt mouse tracking - if ( buffer[1] == '[' && buffer[2] >= '1' && buffer[2] <= '9' - && buffer[3] >= '0' && buffer[3] <= '9' && buf_len >= 9 - && buffer[buf_len - 1] == 'M' ) - return fc::Fkey_urxvt_mouse; - - return -1; -} - -//---------------------------------------------------------------------- -inline int FTerm::getTermcapKey (char buffer[], int buf_size) -{ - // Looking for termcap key strings in the buffer - assert ( buf_size > 0 ); - - for (int i = 0; fc::Fkey[i].tname[0] != 0; i++) - { - char* k = fc::Fkey[i].string; - register int len = ( k ) ? int(std::strlen(k)) : 0; - - if ( k && std::strncmp(k, buffer, uInt(len)) == 0 ) // found - { - register int n; - - for (n = len; n < buf_size; n++) // Remove founded entry - buffer[n - len] = buffer[n]; - - for (; n - len < len; n++) // Fill rest with '\0' - buffer[n - len] = '\0'; - - input_data_pending = bool(buffer[0] != '\0'); - return fc::Fkey[i].num; - } - } - - return -1; -} - -//---------------------------------------------------------------------- -inline int FTerm::getMetaKey ( char buffer[] - , int buf_size - , timeval* time_keypressed ) -{ - // Looking for meta key strings in the buffer - assert ( buf_size > 0 ); - - for (int i = 0; fc::Fmetakey[i].string[0] != 0; i++) - { - char* kmeta = fc::Fmetakey[i].string; // The string is never null - register int len = int(std::strlen(kmeta)); - - if ( std::strncmp(kmeta, buffer, uInt(len)) == 0 ) // found - { - register int n; - - if ( len == 2 && ( buffer[1] == 'O' - || buffer[1] == '[' - || buffer[1] == ']' ) ) - { - if ( ! isKeypressTimeout(time_keypressed) ) - return NEED_MORE_DATA; - } - - for (n = len; n < buf_size; n++) // Remove founded entry - buffer[n - len] = buffer[n]; - - for (; n - len < len; n++) // Fill rest with '\0' - buffer[n - len] = '\0'; - - input_data_pending = bool(buffer[0] != '\0'); - return fc::Fmetakey[i].num; - } - } - - return -1; -} - -//---------------------------------------------------------------------- -inline int FTerm::getSingleKey (char buffer[], int buf_size) -{ - register uChar firstchar = uChar(buffer[0]); - int key, n, len; - len = 1; - - // Look for a utf-8 character - if ( utf8_input && (firstchar & 0xc0) == 0xc0 ) - { - char utf8char[4] = { }; // Init array with '\0' - - if ( (firstchar & 0xe0) == 0xc0 ) - len = 2; - else if ( (firstchar & 0xf0) == 0xe0 ) - len = 3; - else if ( (firstchar & 0xf8) == 0xf0 ) - len = 4; - - for (int i = 0; i < len ; i++) - utf8char[i] = char(buffer[i] & 0xff); - - key = UTF8decode(utf8char); - } - else - key = uChar(buffer[0] & 0xff); - - for (n = len; n < buf_size; n++) // Remove the key from the buffer front - buffer[n - len] = buffer[n]; - - for (n = n - len; n < buf_size; n++) // Fill the rest with '\0' bytes - buffer[n] = '\0'; - - input_data_pending = bool(buffer[0] != '\0'); - - if ( key == 0 ) // Ctrl+Space or Ctrl+@ - key = fc::Fckey_space; - - return int(key == 127 ? fc::Fkey_backspace : key); -} - //---------------------------------------------------------------------- void FTerm::setSignalHandler() { diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 8d671be9..665114ef 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -43,13 +43,14 @@ uInt FVTerm::repeat_char_length; uInt FVTerm::clr_bol_length; uInt FVTerm::clr_eol_length; uInt FVTerm::cursor_address_length; -std::queue* FVTerm::output_buffer = 0; -FPoint* FVTerm::term_pos = 0; -FVTerm::term_area* FVTerm::vterm = 0; -FVTerm::term_area* FVTerm::vdesktop = 0; -FVTerm::term_area* FVTerm::active_area = 0; -FVTerm::termcap_map* FVTerm::tcap = 0; -FTermcap::tcap_map* FTermcap::tcap = 0; +std::queue* FVTerm::output_buffer = 0; +FPoint* FVTerm::term_pos = 0; +FVTerm::term_area* FVTerm::vterm = 0; +FVTerm::term_area* FVTerm::vdesktop = 0; +FVTerm::term_area* FVTerm::active_area = 0; +FVTerm::termcap_map* FVTerm::tcap = 0; +FTermcap::tcap_map* FTermcap::tcap = 0; +FKeyboard* FVTerm::keyboard = 0; FVTerm::charData FVTerm::term_attribute; FVTerm::charData FVTerm::next_attribute; FVTerm::charData FVTerm::s_ch; @@ -237,7 +238,7 @@ void FVTerm::updateTerminal() if ( ! terminal_update_complete ) return; - if ( isInputDataPending() ) + if ( keyboard->isInputDataPending() ) { terminal_update_pending = true; return; @@ -2009,7 +2010,7 @@ void FVTerm::processTerminalUpdate() if ( ! terminal_update_pending ) return; - if ( ! unprocessedInput() ) + if ( ! keyboard->isInputDataPending() ) { updateTerminal(); terminal_update_pending = false; @@ -2102,6 +2103,9 @@ void FVTerm::init() vdesktop->visible = true; active_area = vdesktop; + // Initialize keyboard + keyboard = getKeyboard(); + // Hide the input cursor hideCursor();