diff --git a/src/keys.cc b/src/keys.cc index ba7ca47..11d797d 100644 --- a/src/keys.cc +++ b/src/keys.cc @@ -21,17 +21,39 @@ #include "utf8.hh" #include "msg.h" +#include +#include +#include + /* * Local data types */ -typedef struct { - const char *name; +struct KeyBinding_t { + std::string name; KeysCommand_t cmd; int modifier, key; -} KeyBinding_t; + + auto + value_lens() const + { + return std::tie( key, modifier ); + } + + friend auto + value_lens( const KeyBinding_t &key ) + { + return key.value_lens(); + } + + friend bool + operator < ( const KeyBinding_t &lhs, const KeyBinding_t &rhs ); + + friend bool + operator == ( const KeyBinding_t &lhs, const KeyBinding_t &rhs ); +}; typedef struct { - const char *name; + std::string_view name; const int value; } Mapping_t; @@ -143,7 +165,7 @@ static const KeyBinding_t default_keys[] = { { "zoom-reset" , KEYS_ZOOM_RESET , FL_CTRL , '0' }, }; -static Dlist *bindings; +static std::vector< std::unique_ptr< KeyBinding_t > > bindings; @@ -152,20 +174,21 @@ static Dlist *bindings; */ void Keys::init() { - KeyBinding_t *node; + std::unique_ptr< KeyBinding_t > node; // Fill our key bindings list - bindings = dList_new(32); for (uint_t i = 0; i < sizeof(default_keys) / sizeof(default_keys[0]); i++) { if (default_keys[i].key) { - node = dNew(KeyBinding_t, 1); - node->name = dStrdup(default_keys[i].name); + node = std::make_unique< KeyBinding_t >(); + node->name = default_keys[i].name; node->cmd = default_keys[i].cmd; node->modifier = default_keys[i].modifier; node->key = default_keys[i].key; - dList_insert_sorted(bindings, node, nodeByKeyCmp); + bindings.push_back( std::move( node ) ); } } + + std::sort( begin( bindings ), end( bindings ) ); } /** @@ -173,24 +196,23 @@ void Keys::init() */ void Keys::free() { - KeyBinding_t *node; - - while ((node = (KeyBinding_t*)dList_nth_data(bindings, 0))) { - dFree((char*)node->name); - dList_remove_fast(bindings, node); - dFree(node); - } - dList_free(bindings); + bindings.clear(); } /** * Compare function by {key,modifier} pairs. */ -int Keys::nodeByKeyCmp(const void *node, const void *key) +bool +operator < (const KeyBinding_t &n, const KeyBinding_t &k) { - KeyBinding_t *n = (KeyBinding_t*)node, *k = (KeyBinding_t*)key; _MSG("Keys::nodeByKeyCmp modifier=%d\n", k->modifier); - return (n->key != k->key) ? (n->key - k->key) : (n->modifier - k->modifier); + return value_lens( n ) < value_lens( k ); +} + +bool +operator == ( const KeyBinding_t &lhs, const KeyBinding_t &rhs ) +{ + return value_lens( lhs ) == value_lens( rhs ); } /** @@ -220,9 +242,10 @@ KeysCommand_t Keys::getKeyCmd() } _MSG("getKeyCmd: evkey=0x%x evtext=\'%s\' key=0x%x, mod=0x%x\n", Fl::event_key(), Fl::event_text(), keyNode.key, keyNode.modifier); - void *data = dList_find_sorted(bindings, &keyNode, nodeByKeyCmp); - if (data) - ret = ((KeyBinding_t*)data)->cmd; + auto data= std::find_if( begin( bindings ), end( bindings ), + [&]( const auto &node ){ return *node == keyNode; } ); + if ( data != end( bindings ) ) + ret = data->get()->cmd; return ret; } @@ -231,15 +254,14 @@ KeysCommand_t Keys::getKeyCmd() */ void Keys::delKeyCmd(int key, int mod) { - KeyBinding_t keyNode, *node; + KeyBinding_t keyNode; keyNode.key = key; keyNode.modifier = mod; - node = (KeyBinding_t*) dList_find_sorted(bindings, &keyNode, nodeByKeyCmp); - if (node) { - dList_remove(bindings, node); - dFree((char*)node->name); - dFree(node); + auto data= std::find_if( begin( bindings ), end( bindings ), + [&]( const auto &node ){ return *node == keyNode; } ); + if (data != end( bindings )) { + bindings.erase( data ); } } @@ -252,7 +274,7 @@ int Keys::getKeyCode(char *keyName) { uint_t i; for (i = 0; i < sizeof(keyNames) / sizeof(keyNames[0]); i++) { - if (!dStrAsciiCasecmp(keyNames[i].name, keyName)) { + if (!dStrAsciiCasecmp(keyNames[i].name.data(), keyName)) { return keyNames[i].value; } } @@ -269,7 +291,7 @@ KeysCommand_t Keys::getCmdCode(const char *commandName) uint_t i; for (i = 0; i < sizeof(default_keys) / sizeof(KeyBinding_t); i++) { - if (!dStrAsciiCasecmp(default_keys[i].name, commandName)) + if (!dStrAsciiCasecmp(default_keys[i].name.c_str(), commandName)) return default_keys[i].cmd; } return KEYS_INVALID; @@ -283,7 +305,7 @@ int Keys::getModifier(char *modifierName) { uint_t i; for (i = 0; i < sizeof(modifierNames) / sizeof(modifierNames[0]); i++) { - if (!dStrAsciiCasecmp(modifierNames[i].name, modifierName)) { + if (!dStrAsciiCasecmp(modifierNames[i].name.data(), modifierName)) { return modifierNames[i].value; } } @@ -297,10 +319,10 @@ int Keys::getModifier(char *modifierName) */ int Keys::getShortcut(KeysCommand_t cmd) { - int len = dList_length(bindings); + int len = bindings.size(); for (int i = 0; i < len; i++) { - KeyBinding_t *node = (KeyBinding_t*)dList_nth_data(bindings, i); + const KeyBinding_t *const node = bindings.at( i ).get(); if (cmd == node->cmd) return node->modifier + node->key; } @@ -362,12 +384,13 @@ void Keys::parseKey(char *key, char *commandName) if (keycode) { delKeyCmd(keycode, keymod); if (symcode != KEYS_NOP) { - KeyBinding_t *node = dNew(KeyBinding_t, 1); - node->name = dStrdup(commandName); + auto node = std::make_unique< KeyBinding_t >(); + node->name = commandName; node->cmd = symcode; node->modifier = keymod; node->key = keycode; - dList_insert_sorted(bindings, node, nodeByKeyCmp); + bindings.push_back( std::move( node ) ); + std::sort( begin( bindings ), end( bindings ) ); _MSG("parseKey: Adding key=%d, mod=%d\n", node->key, node->modifier); } }