Fix 4 bytes UTF-8 keyboard input

This commit is contained in:
Markus Gans 2018-07-27 12:16:43 +02:00
parent 5a77460e63
commit 0e86de5c81
3 changed files with 161 additions and 5 deletions

View File

@ -1,3 +1,8 @@
2017-07-27 Markus Gans <guru.mail@muenster.de>
* The array for keyboard input of UTF-8 characters was
not long enough for 4 bytes of UTF-8 codes.
* More tests in FKeyboard unit test
2017-07-22 Markus Gans <guru.mail@muenster.de> 2017-07-22 Markus Gans <guru.mail@muenster.de>
* Added unit test for FKeyboard * Added unit test for FKeyboard

View File

@ -303,7 +303,7 @@ inline int FKeyboard::getSingleKey()
// Look for a utf-8 character // Look for a utf-8 character
if ( utf8_input && (firstchar & 0xc0) == 0xc0 ) if ( utf8_input && (firstchar & 0xc0) == 0xc0 )
{ {
char utf8char[4] = { }; // Init array with '\0' char utf8char[5] = { }; // Init array with '\0'
if ( (firstchar & 0xe0) == 0xc0 ) if ( (firstchar & 0xe0) == 0xc0 )
len = 2; len = 2;
@ -368,8 +368,9 @@ bool FKeyboard::isKeypressTimeout()
int FKeyboard::UTF8decode (const char utf8[]) int FKeyboard::UTF8decode (const char utf8[])
{ {
register int ucs = 0; register int ucs = 0;
const int max = 4;
for (register int i = 0; i < int(std::strlen(utf8)); ++i) for (register int i = 0; i < int(std::strlen(utf8)) && i < max; ++i)
{ {
register uChar ch = uChar(utf8[i]); register uChar ch = uChar(utf8[i]);

View File

@ -63,7 +63,7 @@ fkeymap Fkey[] =
{ fc::Fkey_f1 , C_STR(ESC "OP") , "k1X"}, // F1 function key { fc::Fkey_f1 , C_STR(ESC "OP") , "k1X"}, // F1 function key
{ fc::Fkey_f2 , C_STR(ESC "OQ") , "k2" }, // F2 function key { fc::Fkey_f2 , C_STR(ESC "OQ") , "k2" }, // F2 function key
{ fc::Fkey_f2 , C_STR(CSI "12~") , "k2x"}, // F2 function key { fc::Fkey_f2 , C_STR(CSI "12~") , "k2x"}, // F2 function key
{ fc::Fkey_f2 , C_STR(ESC "OQ") , "k2X"}, // F2 function key { fc::Fkey_f2 , C_STR(CSI "OQ") , "k2X"}, // F2 function key
{ fc::Fkey_f3 , C_STR(ESC "OR") , "k3" }, // F3 function key { fc::Fkey_f3 , C_STR(ESC "OR") , "k3" }, // F3 function key
{ fc::Fkey_f3 , C_STR(CSI "13~") , "k3x"}, // F3 function key { fc::Fkey_f3 , C_STR(CSI "13~") , "k3x"}, // F3 function key
{ fc::Fkey_f3 , C_STR(ESC "OR") , "k3X"}, // F3 function key { fc::Fkey_f3 , C_STR(ESC "OR") , "k3X"}, // F3 function key
@ -257,7 +257,6 @@ class FKeyboardTest : public CPPUNIT_NS::TestFixture
int key_pressed; int key_pressed;
int key_released; int key_released;
FKeyboard* keyboard; FKeyboard* keyboard;
//FTerm t;
}; };
#pragma pack(pop) #pragma pack(pop)
@ -322,6 +321,7 @@ void FKeyboardTest::noArgumentTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FKeyboardTest::inputTest() void FKeyboardTest::inputTest()
{ {
// X11 mouse
std::cout << std::endl; std::cout << std::endl;
input("\033[M Z2"); input("\033[M Z2");
processInput(); processInput();
@ -329,56 +329,204 @@ void FKeyboardTest::inputTest()
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_mouse ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_mouse );
clear(); clear();
// SGR mouse
input("\033[<0;11;7M"); input("\033[<0;11;7M");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_extended_mouse ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_extended_mouse );
clear(); clear();
// URXVT mouse
input("\033[32;11;7M"); input("\033[32;11;7M");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_urxvt_mouse ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_urxvt_mouse );
clear(); clear();
// Without mouse support
keyboard->disableMouseSequences();
input("\033[M Z2");
processInput();
CPPUNIT_ASSERT ( key_pressed != fc::Fkey_mouse );
clear();
input("\033[<0;11;7M");
processInput();
CPPUNIT_ASSERT ( key_pressed != fc::Fkey_extended_mouse );
clear();
input("\033[32;11;7M");
processInput();
CPPUNIT_ASSERT ( key_pressed != fc::Fkey_urxvt_mouse );
clear();
std::cout << std::endl;
// Mintty application escape key
input("\033O["); input("\033O[");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_escape_mintty ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_escape_mintty );
clear(); clear();
// Normal escape (needs a timeout)
input("\033"); input("\033");
processInput(); processInput();
usleep(100000); usleep(100000);
keyboard->escapeKeyHandling(); keyboard->escapeKeyHandling();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_escape ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_escape );
clear(); keyboard->clearKeyBufferOnTimeout();
// Clear-tab
input("\033[3~"); input("\033[3~");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_ctab ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_ctab );
clear(); clear();
// Cursor down keys in positioning mode
input("\033OB"); input("\033OB");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_down ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_down );
clear(); clear();
// Cursor down keys in applications mode
input("\033[B"); input("\033[B");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_down ); CPPUNIT_ASSERT ( key_pressed == fc::Fkey_down );
clear(); clear();
// Cursor down in character by character input (e.g. rxvt-cygwin-native)
input("\033");
processInput();
input("[");
processInput();
input("B");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_down );
clear();
// Two one byte characters
input("aA"); input("aA");
processInput(); processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == 'A' ); CPPUNIT_ASSERT ( key_pressed == 'A' );
CPPUNIT_ASSERT ( key_released == 'A' ); CPPUNIT_ASSERT ( key_released == 'A' );
clear(); clear();
// UTF-8 encoded character
input("\360\220\200\200"); // Linear B syllable (4 bytes)
processInput();
std::cout << " - code: " << key_pressed << std::endl;
CPPUNIT_ASSERT ( key_released == 0x10000 );
input("\342\202\254"); // Euro sign (3 bytes)
processInput();
std::cout << " - code: " << key_pressed << std::endl;
CPPUNIT_ASSERT ( key_released == 0x20ac );
input("\303\274"); // u with two Dots (2 bytes)
processInput();
std::cout << " - code: " << key_pressed << std::endl;
CPPUNIT_ASSERT ( key_released == 0x00fc );
clear();
// Function key F1 (numeric keypad PF1)
input("\033OP");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f1 );
clear();
// Function key F1
input("\033[11~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f1 );
clear();
// Function key F2 (numeric keypad PF2)
input("\033OQ");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f2 );
clear();
// Function key F2
input("\033[12~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f2 );
clear();
// Function key F3 (numeric keypad PF1)
input("\033OR");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f3 );
clear();
// Function key F3
input("\033[13~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f3 );
clear();
// Function key F4 (numeric keypad PF1)
input("\033OS");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f4 );
clear();
// Function key F4
input("\033[14~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f4 );
clear();
// Function key F5
input("\033[15~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f5 );
clear();
// Function key F6
input("\033[17~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f6 );
clear();
// Function key F7
input("\033[18~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f7 );
clear();
// Function key F8
input("\033[19~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f8 );
clear();
// Function key F9
input("\033[20~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f9 );
clear();
// Function key F10
input("\033[21~");
processInput();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == fc::Fkey_f10 );
clear();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -399,6 +547,8 @@ void FKeyboardTest::init()
keyboard->setReleaseCommand (key_cmd2); keyboard->setReleaseCommand (key_cmd2);
keyboard->setEscPressedCommand (key_cmd3); keyboard->setEscPressedCommand (key_cmd3);
keyboard->setKeypressTimeout (100000); // 100 ms keyboard->setKeypressTimeout (100000); // 100 ms
processInput();
CPPUNIT_ASSERT ( key_pressed == 0 );
keyboard->enableUTF8(); keyboard->enableUTF8();
keyboard->enableMouseSequences(); keyboard->enableMouseSequences();
keyboard->setTermcapMap (reinterpret_cast<fc::fkeymap*>(test::Fkey)); keyboard->setTermcapMap (reinterpret_cast<fc::fkeymap*>(test::Fkey));