diff --git a/examples/example_m711.ini b/examples/example_m711.ini index a679652..b4c63dc 100644 --- a/examples/example_m711.ini +++ b/examples/example_m711.ini @@ -27,9 +27,11 @@ dpi2_enable=1 dpi3_enable=1 dpi4_enable=1 dpi5_enable=0 -# dpi 0x[04-8c][00-01] -dpi1=0x0400 -dpi2=0x1600 +# dpi +# 0x[04-8c][00-01] (same value for x and y) +# 0x[04-8c][00-01][04-8c][00-01] (different values for x and y) +dpi1=X100Y200 +dpi2=0x16000400 dpi3=0x2d00 dpi4=0x4300 dpi5=0x8c00 diff --git a/include/m711/constructor.cpp b/include/m711/constructor.cpp index f3d4364..2975b86 100644 --- a/include/m711/constructor.cpp +++ b/include/m711/constructor.cpp @@ -31,7 +31,7 @@ mouse_m711::mouse_m711(){ // dpi _s_dpi_enabled.fill( {true, true, true, true, true} ); - _s_dpi_levels.fill( {{ {0x04, 0x00}, {0x16, 0x00}, {0x2d, 0x00}, {0x43, 0x00}, {0x8c, 0x00} }} ); + _s_dpi_levels.fill( {{ {0x04, 0x00, 0x04, 0x00}, {0x16, 0x00, 0x04, 0x00}, {0x2d, 0x00, 0x04, 0x00}, {0x43, 0x00, 0x04, 0x00}, {0x8c, 0x00, 0x04, 0x00} }} ); // button mapping for( int i = 0; i < 5; i++ ){ diff --git a/include/m711/getters.cpp b/include/m711/getters.cpp index 226b5d8..0f868b8 100644 --- a/include/m711/getters.cpp +++ b/include/m711/getters.cpp @@ -51,7 +51,7 @@ bool mouse_m711::get_dpi_enable( rd_profile profile, int level ){ return _s_dpi_enabled[profile][level]; } -int mouse_m711::get_dpi( rd_profile profile, int level, std::array& dpi ){ +int mouse_m711::get_dpi( rd_profile profile, int level, std::array& dpi ){ // check DPI level bounds if( level < _c_level_min || level > _c_level_max ) @@ -59,6 +59,8 @@ int mouse_m711::get_dpi( rd_profile profile, int level, std::array& dpi[0] = _s_dpi_levels[profile][level][0]; dpi[1] = _s_dpi_levels[profile][level][1]; + dpi[2] = _s_dpi_levels[profile][level][2]; + dpi[3] = _s_dpi_levels[profile][level][3]; return 0; } diff --git a/include/m711/helpers.cpp b/include/m711/helpers.cpp index ed5a42e..addefe8 100644 --- a/include/m711/helpers.cpp +++ b/include/m711/helpers.cpp @@ -111,7 +111,7 @@ int mouse_m711::print_settings( std::ostream& output ){ output << "dpi" << j << "_enable=0\n"; // DPI value - std::array dpi_bytes = {_s_dpi_levels[i-1][j-1][0], _s_dpi_levels[i-1][j-1][1]}; + std::array dpi_bytes = {_s_dpi_levels[i-1][j-1][0], _s_dpi_levels[i-1][j-1][1], _s_dpi_levels[i-1][j-1][2], _s_dpi_levels[i-1][j-1][3]}; std::string dpi_string = ""; if( _i_decode_dpi( dpi_bytes, dpi_string ) == 0 ) @@ -157,13 +157,21 @@ int mouse_m711::print_settings( std::ostream& output ){ return 0; } -int mouse_m711::_i_decode_dpi( std::array& dpi_bytes, std::string& dpi_string ){ +int mouse_m711::_i_decode_dpi( std::array& dpi_bytes, std::string& dpi_string ){ // is dpi value known? for( auto dpi_value : _c_dpi_codes ){ if( dpi_value.second[0] == dpi_bytes[0] && dpi_value.second[1] == dpi_bytes[1] ){ - dpi_string = std::to_string( dpi_value.first ); + dpi_string = "X" + std::to_string( dpi_value.first ); + break; + } + + } + for( auto dpi_value : _c_dpi_codes ){ + + if( dpi_value.second[0] == dpi_bytes[2] && dpi_value.second[1] == dpi_bytes[3] ){ + dpi_string = "Y" + std::to_string( dpi_value.first ); return 0; } @@ -175,6 +183,7 @@ int mouse_m711::_i_decode_dpi( std::array& dpi_bytes, std::string& d conversion_stream << std::setfill('0') << std::hex; conversion_stream << "0x"; conversion_stream << std::setw(2) << (int)dpi_bytes[0] << std::setw(2) << (int)dpi_bytes[1]; + conversion_stream << std::setw(2) << (int)dpi_bytes[2] << std::setw(2) << (int)dpi_bytes[3]; conversion_stream << std::setfill(' ') << std::setw(0) << std::dec; dpi_string = conversion_stream.str(); diff --git a/include/m711/mouse_m711.h b/include/m711/mouse_m711.h index 8debac0..e300ce1 100644 --- a/include/m711/mouse_m711.h +++ b/include/m711/mouse_m711.h @@ -167,7 +167,7 @@ class mouse_m711 : public rd_mouse{ /// Get dpi level enabled/disabled status of specified profile bool get_dpi_enable( rd_profile profile, int level ); /// Get dpi value of specified level and profile - int get_dpi( rd_profile profile, int level, std::array& dpi ); + int get_dpi( rd_profile profile, int level, std::array& dpi ); /// Get USB poll rate of specified profile rd_report_rate get_report_rate( rd_profile profile ); /// Get macro repeat number of specified profile @@ -279,7 +279,7 @@ class mouse_m711 : public rd_mouse{ std::array _s_brightness_levels; std::array _s_speed_levels; std::array, 5> _s_dpi_enabled; - std::array, 5>, 5> _s_dpi_levels; + std::array, 5>, 5> _s_dpi_levels; std::array, 8>, 5> _s_keymap_data; std::array _s_report_rates; std::array, 15> _s_macro_data; @@ -315,7 +315,7 @@ class mouse_m711 : public rd_mouse{ * This function overloads the implementation from rd_mouse and supports actual DPI values. * \return 0 if no error */ - static int _i_decode_dpi( std::array& dpi_bytes, std::string& dpi_string ); + static int _i_decode_dpi( std::array& dpi_bytes, std::string& dpi_string ); }; #endif diff --git a/include/m711/readers.cpp b/include/m711/readers.cpp index ec6286d..36639a3 100644 --- a/include/m711/readers.cpp +++ b/include/m711/readers.cpp @@ -219,8 +219,8 @@ int mouse_m711::read_and_print_settings( std::ostream& output ){ // DPI enable output << "dpi" << j << "_enable=" << (int)buffer_in2[i-1][4+(6*j)] << "\n"; - // DPI value - std::array dpi_bytes = {buffer_in2[i-1][5+(6*j)], buffer_in2[i-1][6+(6*j)]}; + // DPI value TODO! find the location of last two bytes + std::array dpi_bytes = {buffer_in2[i-1][5+(6*j)], buffer_in2[i-1][6+(6*j)], 0, 0}; std::string dpi_string = ""; if( _i_decode_dpi( dpi_bytes, dpi_string ) == 0 ) diff --git a/include/m711/setters.cpp b/include/m711/setters.cpp index 20a5f2a..d3fa141 100644 --- a/include/m711/setters.cpp +++ b/include/m711/setters.cpp @@ -101,7 +101,7 @@ int mouse_m711::set_dpi( rd_profile profile, int level, std::string dpi ){ if( level < _c_level_min || level > _c_level_max ) return 1; - // check format: 0xABCD (raw bytes) + // check format: 0xABCD (raw bytes, identical value for x and y axis) if( std::regex_match( dpi, std::regex("0x[[:xdigit:]]{4}") ) ){ uint8_t b0 = (uint8_t)stoi( dpi.substr(2,2), 0, 16 ); @@ -113,18 +113,67 @@ int mouse_m711::set_dpi( rd_profile profile, int level, std::string dpi ){ _s_dpi_levels[profile][level][0] = b0; _s_dpi_levels[profile][level][1] = b1; + _s_dpi_levels[profile][level][2] = b0; + _s_dpi_levels[profile][level][3] = b1; return 0; } - // check format: 1234 (real DPI) + // check format: 0xABCD (raw bytes) + else if( std::regex_match( dpi, std::regex("0x[[:xdigit:]]{8}") ) ){ + + uint8_t b0 = (uint8_t)stoi( dpi.substr(2,2), 0, 16 ); + uint8_t b1 = (uint8_t)stoi( dpi.substr(4,2), 0, 16 ); + uint8_t b2 = (uint8_t)stoi( dpi.substr(6,2), 0, 16 ); + uint8_t b3 = (uint8_t)stoi( dpi.substr(8,2), 0, 16 ); + + //check bounds + if( b0 < _c_dpi_min || b0 > _c_dpi_max || b1 < _c_dpi_2_min || b1 > _c_dpi_2_max + || b2 < _c_dpi_min || b2 > _c_dpi_max || b3 < _c_dpi_2_min || b3 > _c_dpi_2_max ){ + return 1; + } + + _s_dpi_levels[profile][level][0] = b0; + _s_dpi_levels[profile][level][1] = b1; + _s_dpi_levels[profile][level][2] = b2; + _s_dpi_levels[profile][level][3] = b3; + + return 0; + + } + + // check format: 1234 (real DPI, identical value for x and y axis) else if( std::regex_match( dpi, std::regex("[[:digit:]]+") ) ){ if( _c_dpi_codes.find( std::stoi(dpi) ) != _c_dpi_codes.end() ){ _s_dpi_levels[profile][level][0] = _c_dpi_codes.at( std::stoi(dpi) )[0]; _s_dpi_levels[profile][level][1] = _c_dpi_codes.at( std::stoi(dpi) )[1]; + _s_dpi_levels[profile][level][2] = _c_dpi_codes.at( std::stoi(dpi) )[0]; + _s_dpi_levels[profile][level][3] = _c_dpi_codes.at( std::stoi(dpi) )[1]; + + return 0; + } + + } + + // check format: 1234 (real DPI) + else if( std::regex_match( dpi, std::regex("X[[:digit:]]+Y[[:digit:]]+") ) ){ + + std::string dpi_x = std::regex_replace(dpi, std::regex("Y[[:digit:]]+"), ""); + dpi_x.erase(0, 1); + + std::string dpi_y = std::regex_replace(dpi, std::regex("X[[:digit:]]+"), ""); + dpi_x.erase(0, 1); + + if( _c_dpi_codes.find( std::stoi(dpi_x) ) != _c_dpi_codes.end() + && _c_dpi_codes.find( std::stoi(dpi_y) ) != _c_dpi_codes.end() ){ + + _s_dpi_levels[profile][level][0] = _c_dpi_codes.at( std::stoi(dpi_x) )[0]; + _s_dpi_levels[profile][level][1] = _c_dpi_codes.at( std::stoi(dpi_x) )[1]; + _s_dpi_levels[profile][level][2] = _c_dpi_codes.at( std::stoi(dpi_y) )[0]; + _s_dpi_levels[profile][level][3] = _c_dpi_codes.at( std::stoi(dpi_y) )[1]; return 0; } diff --git a/include/m711/writers.cpp b/include/m711/writers.cpp index fb4a973..3783a99 100644 --- a/include/m711/writers.cpp +++ b/include/m711/writers.cpp @@ -98,13 +98,12 @@ int mouse_m711::write_settings(){ for( int j = 0; j < 5; j++ ){ buffer3[7+(5*i)+j][8] = _s_dpi_enabled[j][i]; - // TODO! The M711 supports independent DPI values for the x and y axis. - // For now the same value is used for both axes. + // The M711 supports independent DPI values for the x and y axis. buffer3[7+(5*i)+j][9] = _s_dpi_levels[j][i][0]; buffer3[7+(5*i)+j][10] = _s_dpi_levels[j][i][1]; - - buffer3[7+(5*i)+j][11] = _s_dpi_levels[j][i][0]; - buffer3[7+(5*i)+j][12] = _s_dpi_levels[j][i][1]; + + buffer3[7+(5*i)+j][11] = _s_dpi_levels[j][i][2]; + buffer3[7+(5*i)+j][12] = _s_dpi_levels[j][i][3]; } }