From 21a9a8a265cc9ecc6ee9d71026eb96058d99fe1b Mon Sep 17 00:00:00 2001 From: dokutan <54861821+dokutan@users.noreply.github.com> Date: Mon, 11 May 2020 19:02:26 +0200 Subject: [PATCH] Various internal improvements --- README.md | 2 +- TODO.md | 10 ++ include/data.cpp | 23 +++ include/getters.cpp | 137 ++++++++++++++++++ include/helpers.cpp | 325 +++++++++++++++++++++++++++++++++++++++++++ include/mouse_m908.h | 11 +- include/readers.cpp | 25 +--- include/setters.cpp | 1 + 8 files changed, 509 insertions(+), 25 deletions(-) create mode 100644 TODO.md diff --git a/README.md b/README.md index aec6485..35b2a39 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ mouse_m908 -c example.ini `` - Read the configuration from the mouse and store it in config.ini: `` -mouse_m908 -R > config.ini +mouse_m908 -R config.ini `` - Set active profile to number 3: `` diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..a087a75 --- /dev/null +++ b/TODO.md @@ -0,0 +1,10 @@ +- [ ] add support for reading macros from --read output + - [ ] update documentation +- [x] add file option to -D and -R +- [ ] read settings → memory +- [x] print settings ← memory +- [x] read scrollspeed? not supported by the official software/firmware +- [ ] unify makefile +- [x] check setters and getters + - [ ] add getter for macros +- [ ] release 2.0 diff --git a/include/data.cpp b/include/data.cpp index 64ad500..c591ce6 100644 --- a/include/data.cpp +++ b/include/data.cpp @@ -221,6 +221,29 @@ std::map< std::string, uint8_t > mouse_m908::_keyboard_key_values = { { "F23", 0x72 }, { "F24", 0x73 } }; +// Names of the physical buttons +std::map< int, std::string > mouse_m908::_button_names = { + { 0, "button_left" }, + { 1, "button_right" }, + { 2, "button_middle" }, + { 3, "button_fire" }, + { 4, "button_dpi_up" }, + { 5, "button_dpi_down" }, + { 6, "button_1" }, + { 7, "button_2" }, + { 8, "button_3" }, + { 9, "button_4" }, + { 10, "button_5" }, + { 11, "button_6" }, + { 12, "button_7" }, + { 13, "button_8" }, + { 14, "button_9" }, + { 15, "button_10" }, + { 16, "button_11" }, + { 17, "button_12" }, + { 18, "scroll_up" }, + { 19, "scroll_down" } }; + //usb data packets uint8_t mouse_m908::_data_profile[6][16] = { {0x02, 0xf3, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, diff --git a/include/getters.cpp b/include/getters.cpp index 05323d5..20f814a 100644 --- a/include/getters.cpp +++ b/include/getters.cpp @@ -63,3 +63,140 @@ uint8_t mouse_m908::get_macro_repeat( int macro_number ){ return _macro_repeat[macro_number]; } + +bool mouse_m908::get_detach_kernel_driver(){ + return _detach_kernel_driver; +} + +int mouse_m908::get_key_mapping_raw( mouse_m908::m908_profile profile, int key, std::array& mapping ){ + + if( key < 0 || key > 19 ) // valid key ? + return 1; + + mapping[0] = _keymap_data[profile][key][0]; + mapping[1] = _keymap_data[profile][key][1]; + mapping[2] = _keymap_data[profile][key][2]; + mapping[3] = _keymap_data[profile][key][3]; + + return 0; +} + +int mouse_m908::get_key_mapping( mouse_m908::m908_profile profile, int key, std::string& mapping ){ + + if( key < 0 || key > 19 ) // valid key ? + return 1; + + uint8_t b1 = _keymap_data[profile][key][0]; + uint8_t b2 = _keymap_data[profile][key][1]; + uint8_t b3 = _keymap_data[profile][key][2]; + uint8_t b4 = _keymap_data[profile][key][3]; + bool found_name = false; + + mapping = ""; + + // fire button + if( b1 == 0x99 ){ + + mapping += "fire:"; + + // button + if( b2 == 0x81 ) + mapping += "mouse_left:"; + else if( b2 == 0x82 ) + mapping += "mouse_right:"; + else if( b2 == 0x84 ) + mapping += "mouse_middle:"; + else{ + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == b2 ){ + + mapping += keycode.first; + break; + + } + + } + mapping += ":"; + } + + // repeats + mapping += std::to_string( (int)b3 ) + ":"; + + // delay + mapping += std::to_string( (int)b4 ); + + found_name = true; + + // keyboard key + } else if( b1 == 0x90 ){ + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == b3 ){ + + mapping += keycode.first; + found_name = true; + break; + + } + + } + + // modifiers + keyboard key + } else if( b1 == 0x8f ){ + + // iterate over _keyboard_modifier_values + for( auto modifier : _keyboard_modifier_values ){ + + if( modifier.second & b2 ){ + mapping += modifier.first; + } + + } + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == b3 ){ + + mapping += keycode.first; + found_name = true; + break; + + } + + } + + } else{ // mousebutton or special function ? + + // iterate over _keycodes + for( auto keycode : _keycodes ){ + + if( keycode.second[0] == b1 && + keycode.second[1] == b2 && + keycode.second[2] == b3 ){ + + mapping += keycode.first; + found_name = true; + break; + + } + + } + + } + + if( !found_name ){ + mapping += "unknown, please report as bug: "; + mapping += " " + std::to_string( (int)b1 ) + " "; + mapping += " " + std::to_string( (int)b2 ) + " "; + mapping += " " + std::to_string( (int)b3 ) + " "; + mapping += " " + std::to_string( (int)b4 ); + } + + return 0; +} diff --git a/include/helpers.cpp b/include/helpers.cpp index 87a366f..a8ad481 100644 --- a/include/helpers.cpp +++ b/include/helpers.cpp @@ -214,3 +214,328 @@ int mouse_m908::close_mouse(){ return 0; } + +// print current configuration +int mouse_m908::print_settings( std::ostream& output ){ + + // print configuration + output << "# Configuration created by mouse_m908::print_settings().\n"; + output << "# Currently active profile: " << _profile << "\n"; + + for( int i = 1; i < 6; i++ ){ + + // section header + output << "\n[profile" << i << "]\n"; + + output << "\n# LED settings\n"; + + // color + output << "color="; + output << std::setfill('0') << std::setw(2) << std::hex << (int)_colors[i-1][0]; + output << std::setfill('0') << std::setw(2) << std::hex << (int)_colors[i-1][1]; + output << std::setfill('0') << std::setw(2) << std::hex << (int)_colors[i-1][2]; + output << std::setfill(' ') << std::setw(0) << std::dec << "\n"; + + // brightness + output << "brightness=" << (int)_brightness_levels[i-1] << "\n"; + + // speed + output << "speed=" << (int)_speed_levels[i-1] << "\n"; + + // lightmode + output << "lightmode="; + if( _lightmodes[i-1] == lightmode_off ) + output << "off\n"; + else if( _lightmodes[i-1] == lightmode_breathing ) + output << "breathing\n"; + else if( _lightmodes[i-1] == lightmode_rainbow ) + output << "rainbow\n"; + else if( _lightmodes[i-1] == lightmode_static ) + output << "static\n"; + else if( _lightmodes[i-1] == lightmode_wave ) + output << "wave\n"; + else if( _lightmodes[i-1] == lightmode_alternating ) + output << "alternating\n"; + else if( _lightmodes[i-1] == lightmode_reactive ) + output << "reactive\n"; + else if( _lightmodes[i-1] == lightmode_flashing ) + output << "flashing\n"; + else{ + output << "unknown, please report as bug\n"; + } + + // polling rate (report rate) + output << "\n"; + if( _report_rates[i-1] == r_125Hz ) + output << "report_rate=125\n"; + else if( _report_rates[i-1] == r_250Hz ) + output << "report_rate=250\n"; + else if( _report_rates[i-1] == r_500Hz ) + output << "report_rate=500\n"; + else if( _report_rates[i-1] == r_1000Hz ) + output << "report_rate=1000\n"; + else{ + output << "# report rate unknown, please report as bug\n"; + } + + // scrollspeed + output << "scrollspeed=" << std::hex << (int)_scrollspeeds[i-1] << std::dec << "\n"; + + // dpi + output << "\n# DPI settings\n"; + for( int j = 1; j < 6; j++ ){ + + if( _dpi_enabled[i-1][j] ) + output << "dpi" << j << "_enable=1\n"; + else + output << "dpi" << j << "_enable=0\n"; + + output << std::setfill('0') << std::setw(2) << std::hex; + output << "dpi" << j << "=" << (int)_dpi_levels[i-1][j-1] << "\n"; + output << std::setfill(' ') << std::setw(0) << std::dec; + } + + // button mapping + output << "\n# Button mapping\n"; + + for( int j = 0; j < 20; j++ ){ + + uint8_t b1 = _keymap_data[i-1][j][0]; + uint8_t b2 = _keymap_data[i-1][j][1]; + uint8_t b3 = _keymap_data[i-1][j][2]; + uint8_t b4 = _keymap_data[i-1][j][3]; + bool found_name = false; + + output << _button_names[j] << "="; + + // fire button + if( b1 == 0x99 ){ + + output << "fire:"; + + // button + if( b2 == 0x81 ) + output << "mouse_left:"; + else if( b2 == 0x82 ) + output << "mouse_right:"; + else if( b2 == 0x84 ) + output << "mouse_middle:"; + else{ + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == b2 ){ + + output << keycode.first; + break; + + } + + } + output << ":"; + } + + // repeats + output << (int)b3 << ":"; + + // delay + output << (int)b4 << "\n"; + + found_name = true; + + // keyboard key + } else if( b1 == 0x90 ){ + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == b3 ){ + + output << keycode.first << "\n"; + found_name = true; + break; + + } + + } + + // modifiers + keyboard key + } else if( b1 == 0x8f ){ + + // iterate over _keyboard_modifier_values + for( auto modifier : _keyboard_modifier_values ){ + + if( modifier.second & b2 ){ + output << modifier.first; + } + + } + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == b3 ){ + + output << keycode.first << "\n"; + found_name = true; + break; + + } + + } + + } else{ // mousebutton or special function ? + + // iterate over _keycodes + for( auto keycode : _keycodes ){ + + if( keycode.second[0] == b1 && + keycode.second[1] == b2 && + keycode.second[2] == b3 ){ + + output << keycode.first << "\n"; + found_name = true; + break; + + } + + } + + } + + if( !found_name ){ + output << "unknown, please report as bug: "; + output << " " << std::hex << (int)b1 << " "; + output << " " << std::hex << (int)b2 << " "; + output << " " << std::hex << (int)b3 << " "; + output << " " << std::hex << (int)b4; + output << std::dec << "\n"; + } + + } + } + + // macros + output << "\n# Macros\n"; + for( int i = 0; i < 15; i++ ){ + + // macro undefined? + if( _macro_data[i][8] == 0 && _macro_data[i][9] == 0 && _macro_data[i][10] == 0 ) + continue; + + output << "\n;## macro" << i+1 << "\n"; + + for( long unsigned int j = 8; j < _macro_data[i].size(); ){ + + // failsafe + if( j >= _macro_data[i].size() ) + break; + + if( _macro_data[i][j] == 0x81 ){ // mouse button down + + if( _macro_data[i][j] == 0x01 ) + output << ";# down\tmouse_left\n"; + else if( _macro_data[i][j] == 0x02 ) + output << ";# down\tmouse_right\n"; + else if( _macro_data[i][j] == 0x04 ) + output << ";# down\tmouse_middle\n"; + else{ + output << ";# unknown, please report as bug: "; + output << std::hex << (int)_macro_data[i][j] << " "; + output << std::hex << (int)_macro_data[i][j+1] << " "; + output << std::hex << (int)_macro_data[i][j+2]; + output << std::dec << "\n"; + } + + } else if( _macro_data[i][j] == 0x01 ){ // mouse button up + + if( _macro_data[i][j] == 0x01 ) + output << ";# up\tmouse_left\n"; + else if( _macro_data[i][j] == 0x02 ) + output << ";# up\tmouse_right\n"; + else if( _macro_data[i][j] == 0x04 ) + output << ";# up\tmouse_middle\n"; + else{ + output << ";# unknown, please report as bug: "; + output << std::hex << (int)_macro_data[i][j] << " "; + output << std::hex << (int)_macro_data[i][j+1] << " "; + output << std::hex << (int)_macro_data[i][j+2]; + output << std::dec << "\n"; + } + + } else if( _macro_data[i][j] == 0x84 ){ // keyboard key down + + bool found_name = false; + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == _macro_data[i][j+1] ){ + + output << ";# down\t" << keycode.first << "\n"; + found_name = true; + break; + + } + + } + + if( !found_name ){ + output << ";# unknown, please report as bug: "; + output << std::hex << (int)_macro_data[i][j] << " "; + output << std::hex << (int)_macro_data[i][j+1] << " "; + output << std::hex << (int)_macro_data[i][j+2]; + output << std::dec << "\n"; + } + + } else if( _macro_data[i][j] == 0x04 ){ // keyboard key up + + bool found_name = false; + + // iterate over _keyboard_key_values + for( auto keycode : _keyboard_key_values ){ + + if( keycode.second == _macro_data[i][j+1] ){ + + output << ";# up\t" << keycode.first << "\n"; + found_name = true; + break; + + } + + } + + if( !found_name ){ + output << ";# unknown, please report as bug: "; + output << std::hex << (int)_macro_data[i][j] << " "; + output << std::hex << (int)_macro_data[i][j+1] << " "; + output << std::hex << (int)_macro_data[i][j+2]; + output << std::dec << "\n"; + } + + } else if( _macro_data[i][j] == 0x06 ){ // delay + + output << ";# delay\t" << (int)_macro_data[i][j+1] << "\n"; + + } else if( _macro_data[i][j] == 0x00 ){ // padding + + j++; + + } else{ + output << ";# unknown, please report as bug: "; + output << std::hex << (int)_macro_data[i][j] << " "; + output << std::hex << (int)_macro_data[i][j+1] << " "; + output << std::hex << (int)_macro_data[i][j+2]; + output << std::dec << "\n"; + } + + // increment + j+=3; + + } + + } + + return 0; +} diff --git a/include/mouse_m908.h b/include/mouse_m908.h index c559d16..aa1bdbb 100644 --- a/include/mouse_m908.h +++ b/include/mouse_m908.h @@ -190,7 +190,9 @@ class mouse_m908{ uint8_t get_dpi( m908_profile profile, int level ); m908_report_rate get_report_rate( m908_profile profile ); uint8_t get_macro_repeat( int macro_number ); - + bool get_detach_kernel_driver(); + int get_key_mapping( m908_profile profile, int key, std::string& mapping ); + int get_key_mapping_raw( m908_profile profile, int key, std::array& mapping ); //writer functions (apply settings to mouse) @@ -232,6 +234,11 @@ class mouse_m908{ */ int close_mouse(); + /** + * Print the current configuration in .ini format to output + */ + int print_settings( std::ostream& output ); + //reader functions (get settings from the mouse) /** @@ -284,6 +291,8 @@ class mouse_m908{ static const std::map< std::string, uint8_t > _keyboard_modifier_values; /// Values/keycodes of keyboard keys static std::map< std::string, uint8_t > _keyboard_key_values; + /// Names of the physical buttons + static std::map< int, std::string > _button_names; //usb data packets /// Used for changing the active profile diff --git a/include/readers.cpp b/include/readers.cpp index 6bc66dc..c348d47 100644 --- a/include/readers.cpp +++ b/include/readers.cpp @@ -174,7 +174,7 @@ int mouse_m908::read_and_print_settings( std::ostream& output ){ // print configuration output << "# Configuration created with mouse_m908 -R.\n"; - output << "# This function is experimental, not all settings are read.\n"; + output << "# Reading the scrollspeed is not supported.\n"; output << "# Currently active profile: " << (int)buffer_in1[0][8]+1 << "\n"; for( int i = 1; i < 6; i++ ){ @@ -271,27 +271,6 @@ int mouse_m908::read_and_print_settings( std::ostream& output ){ // button mapping output << "\n# Button mapping\n"; - std::map< int, std::string > button_names = { - { 0, "button_left" }, - { 1, "button_right" }, - { 2, "button_middle" }, - { 3, "button_fire" }, - { 4, "button_dpi_up" }, - { 5, "button_dpi_down" }, - { 6, "button_1" }, - { 7, "button_2" }, - { 8, "button_3" }, - { 9, "button_4" }, - { 10, "button_5" }, - { 11, "button_6" }, - { 12, "button_7" }, - { 13, "button_8" }, - { 14, "button_9" }, - { 15, "button_10" }, - { 16, "button_11" }, - { 17, "button_12" }, - { 18, "scroll_up" }, - { 19, "scroll_down" } }; for( int j = 0; j < 20; j++ ){ @@ -301,7 +280,7 @@ int mouse_m908::read_and_print_settings( std::ostream& output ){ uint8_t b4 = buffer_in3[j+(20*(i-1))][11]; bool found_name = false; - output << button_names[j] << "="; + output << _button_names[j] << "="; // fire button if( b1 == 0x99 ){ diff --git a/include/setters.cpp b/include/setters.cpp index 8eb72cf..2883c37 100644 --- a/include/setters.cpp +++ b/include/setters.cpp @@ -129,6 +129,7 @@ int mouse_m908::set_key_mapping( m908_profile profile, int key, std::string mapp std::string value1 = "", value2 = "", value3 = ""; uint8_t keycode, repeats = 1, delay = 0; + // the repeated value1 line is not a mistake, it skips the "fire:" std::getline( mapping_stream, value1, ':' ); std::getline( mapping_stream, value1, ':' ); std::getline( mapping_stream, value2, ':' );