mouse_m908/include/m908/readers.cpp

456 lines
13 KiB
C++
Raw Normal View History

2020-05-09 14:33:14 -06:00
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
2021-01-21 15:59:43 -07:00
#include "../rd_mouse.h"
2020-05-09 14:33:14 -06:00
//reader functions (get settings from mouse)
2020-05-11 08:49:58 -06:00
int mouse_m908::dump_settings( std::ostream& output ){
2020-05-09 14:33:14 -06:00
//prepare data 1
int rows1 = sizeof(_c_data_read_1) / sizeof(_c_data_read_1[0]);
2020-05-09 14:33:14 -06:00
uint8_t buffer1[rows1][16];
for( int i = 0; i < rows1; i++ ){
std::copy(std::begin(_c_data_read_1[i]), std::end(_c_data_read_1[i]), std::begin(buffer1[i]));
2020-05-09 14:33:14 -06:00
}
//prepare data 2
int rows2 = sizeof(_c_data_read_2) / sizeof(_c_data_read_2[0]);
2020-05-09 14:33:14 -06:00
uint8_t buffer2[rows2][64];
for( int i = 0; i < rows2; i++ ){
std::copy(std::begin(_c_data_read_2[i]), std::end(_c_data_read_2[i]), std::begin(buffer2[i]));
2020-05-09 14:33:14 -06:00
}
//prepare data 3
int rows3 = sizeof(_c_data_read_3) / sizeof(_c_data_read_3[0]);
2020-05-09 14:33:14 -06:00
uint8_t buffer3[rows3][16];
for( int i = 0; i < rows3; i++ ){
std::copy(std::begin(_c_data_read_3[i]), std::end(_c_data_read_3[i]), std::begin(buffer3[i]));
2020-05-09 14:33:14 -06:00
}
2020-05-11 08:49:58 -06:00
output << "Part 1:\n\n";
2020-05-09 14:33:14 -06:00
//send data 1
uint8_t buffer_in1[16];
int num_bytes_in;
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer1[0], 16, 1000 );
2020-05-09 14:33:14 -06:00
for( int i = 1; i < rows1; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer1[i], 16, 1000 );
2020-05-09 14:33:14 -06:00
// control in
num_bytes_in = libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0302, 0x0002, buffer_in1, 16, 1000 );
2020-05-09 14:33:14 -06:00
// hexdump
if ( num_bytes_in > 0 ){
2020-05-11 08:49:58 -06:00
output << std::hex;
2020-05-09 14:33:14 -06:00
for( int j = 0; j < num_bytes_in; j++ ){
2020-05-11 08:49:58 -06:00
output << std::setfill('0') << std::setw(2) << (int)buffer_in1[j] << " ";
2020-05-09 14:33:14 -06:00
}
2020-05-11 08:49:58 -06:00
output << "\n\n" << std::dec << std::setw(0) << std::setfill(' ');
2020-05-09 14:33:14 -06:00
}
}
2020-05-11 08:49:58 -06:00
output << "Part 2:\n\n";
2020-05-09 14:33:14 -06:00
//send data 2
uint8_t buffer_in2[64];
2020-05-09 15:36:23 -06:00
for( int i = 0; i < rows2; i++ ){
2020-05-09 14:33:14 -06:00
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0303, 0x0002, buffer2[i], 64, 1000 );
2020-05-09 14:33:14 -06:00
// control in
num_bytes_in = libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0303, 0x0002, buffer_in2, 64, 1000 );
2020-05-09 14:33:14 -06:00
// hexdump
if ( num_bytes_in > 0 ){
2020-05-11 08:49:58 -06:00
output << std::hex;
2020-05-09 14:33:14 -06:00
for( int j = 0; j < num_bytes_in; j++ ){
2020-05-11 08:49:58 -06:00
output << std::setfill('0') << std::setw(2) << (int)buffer_in2[j] << " ";
2020-05-09 14:33:14 -06:00
}
2020-05-11 08:49:58 -06:00
output << "\n\n" << std::dec << std::setw(0) << std::setfill(' ');
2020-05-09 14:33:14 -06:00
}
}
2020-05-11 08:49:58 -06:00
output << "Part 3:\n\n";
2020-05-09 14:33:14 -06:00
//send data 3
uint8_t buffer_in3[16];
2020-05-09 15:36:23 -06:00
for( int i = 0; i < rows3-1; i++ ){
2020-05-09 14:33:14 -06:00
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer3[i], 16, 1000 );
2020-05-09 14:33:14 -06:00
// control in
num_bytes_in = libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0302, 0x0002, buffer_in3, 16, 1000 );
2020-05-09 14:33:14 -06:00
// hexdump
if ( num_bytes_in > 0 ){
2020-05-11 08:49:58 -06:00
output << std::hex;
2020-05-09 14:33:14 -06:00
for( int j = 0; j < num_bytes_in; j++ ){
2020-05-11 08:49:58 -06:00
output << std::setfill('0') << std::setw(2) << (int)buffer_in3[j] << " ";
2020-05-09 14:33:14 -06:00
}
2020-05-11 08:49:58 -06:00
output << "\n\n" << std::dec << std::setw(0) << std::setfill(' ');
2020-05-09 14:33:14 -06:00
}
}
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer3[100], 16, 1000 );
2020-05-09 14:33:14 -06:00
return 0;
}
2020-05-09 15:36:23 -06:00
2020-05-11 08:49:58 -06:00
int mouse_m908::read_and_print_settings( std::ostream& output ){
2020-05-09 15:36:23 -06:00
//prepare data 1
int rows1 = sizeof(_c_data_read_1) / sizeof(_c_data_read_1[0]);
2020-05-09 15:36:23 -06:00
uint8_t buffer1[rows1][16];
for( int i = 0; i < rows1; i++ ){
std::copy(std::begin(_c_data_read_1[i]), std::end(_c_data_read_1[i]), std::begin(buffer1[i]));
2020-05-09 15:36:23 -06:00
}
//prepare data 2
int rows2 = sizeof(_c_data_read_2) / sizeof(_c_data_read_2[0]);
2020-05-09 15:36:23 -06:00
uint8_t buffer2[rows2][64];
for( int i = 0; i < rows2; i++ ){
std::copy(std::begin(_c_data_read_2[i]), std::end(_c_data_read_2[i]), std::begin(buffer2[i]));
2020-05-09 15:36:23 -06:00
}
//prepare data 3
int rows3 = sizeof(_c_data_read_3) / sizeof(_c_data_read_3[0]);
2020-05-09 15:36:23 -06:00
uint8_t buffer3[rows3][16];
for( int i = 0; i < rows3; i++ ){
std::copy(std::begin(_c_data_read_3[i]), std::end(_c_data_read_3[i]), std::begin(buffer3[i]));
2020-05-09 15:36:23 -06:00
}
//send data 1
2020-06-25 06:03:02 -06:00
uint8_t buffer_in1[8][16] = {{0}};
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer1[0], 16, 1000 );
2020-05-09 15:36:23 -06:00
for( int i = 1; i < rows1; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer1[i], 16, 1000 );
2020-05-09 15:36:23 -06:00
// control in
libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0302, 0x0002, buffer_in1[i-1], 16, 1000 );
2020-05-09 15:36:23 -06:00
}
//send data 2
2020-06-25 06:03:02 -06:00
uint8_t buffer_in2[85][64] = {{0}};
2020-05-09 15:36:23 -06:00
for( int i = 0; i < rows2; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0303, 0x0002, buffer2[i], 64, 1000 );
2020-05-09 15:36:23 -06:00
// control in
libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0303, 0x0002, buffer_in2[i], 64, 1000 );
2020-05-09 15:36:23 -06:00
}
//send data 3
2020-06-25 06:03:02 -06:00
uint8_t buffer_in3[100][16] = {{0}};
2020-05-09 15:36:23 -06:00
for( int i = 0; i < rows3-1; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer3[i], 16, 1000 );
2020-05-09 15:36:23 -06:00
// control in
libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0302, 0x0002, buffer_in3[i], 16, 1000 );
2020-05-09 15:36:23 -06:00
}
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer3[100], 16, 1000 );
2020-05-09 15:36:23 -06:00
// print configuration
2020-05-11 08:49:58 -06:00
output << "# Configuration created with mouse_m908 -R.\n";
output << "# This configuration can be send to the mouse with mouse_m908 -c.\n";
2020-07-20 05:39:33 -06:00
output << "# Note: reading the scrollspeed is not supported by the mouse.\n";
output << "\n# Currently active profile: " << (int)buffer_in1[0][8]+1 << "\n";
2020-05-09 15:36:23 -06:00
for( int i = 1; i < 6; i++ ){
// section header
2020-05-11 08:49:58 -06:00
output << "\n[profile" << i << "]\n";
2020-05-09 15:36:23 -06:00
2020-05-11 08:49:58 -06:00
output << "\n# LED settings\n";
2020-05-09 15:36:23 -06:00
// color
2020-05-11 08:49:58 -06:00
output << "color=";
output << std::setfill('0') << std::setw(2) << std::hex << (int)buffer_in1[i][8];
output << std::setfill('0') << std::setw(2) << std::hex << (int)buffer_in1[i][9];
output << std::setfill('0') << std::setw(2) << std::hex << (int)buffer_in1[i][10];
output << std::setfill(' ') << std::setw(0) << std::dec << "\n";
2020-05-09 15:36:23 -06:00
// brightness
2020-05-11 08:49:58 -06:00
output << "brightness=" << (int)buffer_in1[i][14] << "\n";
2020-05-09 15:36:23 -06:00
// speed
2020-05-11 08:49:58 -06:00
output << "speed=" << (int)buffer_in1[i][13] << "\n";
2020-05-09 15:36:23 -06:00
// lightmode
std::array<uint8_t, 2> lightmode_bytes = {buffer_in1[i][11], buffer_in1[i][13]};
std::string lightmode_string = "";
_i_decode_lightmode(lightmode_bytes, lightmode_string);
output << "lightmode=" << lightmode_string << "\n";
// polling rate (report rate)
uint8_t report_rate_byte = (i < 4) ? buffer_in1[6][6+(2*i)] : buffer_in1[7][(2*i)];
std::string report_rate_string = "";
_i_decode_report_rate(report_rate_byte, report_rate_string);
output << "report_rate=" << report_rate_string << "\n";
2020-05-09 17:48:47 -06:00
// dpi
2020-05-11 08:49:58 -06:00
output << "\n# DPI settings\n";
output << "# Active dpi level for this profile: " << (int)buffer_in2[i-1][8]+1 << "\n";
2020-05-09 17:48:47 -06:00
for( int j = 1; j < 6; j++ ){
// DPI enable
2020-05-11 08:49:58 -06:00
output << "dpi" << j << "_enable=" << (int)buffer_in2[i-1][4+(6*j)] << "\n";
2020-09-22 14:18:34 -06:00
// DPI value
std::array<uint8_t, 2> dpi_bytes = {buffer_in2[i-1][5+(6*j)], buffer_in2[i-1][6+(6*j)]};
std::string dpi_string = "";
if( _i_decode_dpi( dpi_bytes, dpi_string ) == 0 )
2020-09-22 14:18:34 -06:00
output << "dpi" << j << "=" << dpi_string << "\n";
else
output << "\n";
2020-05-09 17:48:47 -06:00
}
// button mapping
2020-05-11 08:49:58 -06:00
output << "\n# Button mapping\n";
2020-05-09 15:36:23 -06:00
2020-05-09 17:48:47 -06:00
for( int j = 0; j < 20; j++ ){
std::array< uint8_t, 4 > bytes = {
buffer_in3[j+(20*(i-1))][8],
buffer_in3[j+(20*(i-1))][9],
buffer_in3[j+(20*(i-1))][10],
buffer_in3[j+(20*(i-1))][11]
};
std::string mapping;
2020-05-09 17:48:47 -06:00
_i_decode_button_mapping( bytes, mapping );
output << _c_button_names[j] << "=" << mapping << std::endl;
2020-05-09 17:48:47 -06:00
}
2020-05-09 15:36:23 -06:00
}
2020-05-10 15:15:03 -06:00
// macros
std::array< std::vector< uint8_t >, 15 > macro_bytes;
2020-05-13 11:28:09 -06:00
int macronumber = 1;
int counter = 0;
2020-05-10 15:15:03 -06:00
// iterate over buffer_in2
for( int i = 5; i < 85; i++ ){
// valid macronumber?
if( macronumber >= 1 && macronumber <= 15 ){
// extract bytes
for( int j = 8; j < 58; j++ ){
macro_bytes[macronumber-1].push_back( buffer_in2[i][j] );
}
}
2020-05-13 11:28:09 -06:00
// increment counter and macronumber
counter++;
if( counter == 4 ){
counter = 0;
macronumber++;
}
2020-05-10 15:15:03 -06:00
}
// decode macros
2020-05-11 08:49:58 -06:00
output << "\n# Macros\n";
2020-05-10 15:15:03 -06:00
for( int i = 0; i < 15; i++ ){
// is macro not defined ?
2020-05-10 15:15:03 -06:00
if( macro_bytes[i][0] == 0 && macro_bytes[i][1] == 0 && macro_bytes[i][2] == 0 )
continue;
// print macro
2020-05-11 08:49:58 -06:00
output << "\n;## macro" << i+1 << "\n";
_i_decode_macro( macro_bytes[i], output, ";# ", 0 );
2020-05-10 15:15:03 -06:00
}
2020-05-09 15:36:23 -06:00
return 0;
}
2020-05-11 14:12:38 -06:00
int mouse_m908::read_settings(){
//prepare data 1
int rows1 = sizeof(_c_data_read_1) / sizeof(_c_data_read_1[0]);
2020-05-11 14:12:38 -06:00
uint8_t buffer1[rows1][16];
for( int i = 0; i < rows1; i++ ){
std::copy(std::begin(_c_data_read_1[i]), std::end(_c_data_read_1[i]), std::begin(buffer1[i]));
2020-05-11 14:12:38 -06:00
}
//prepare data 2
int rows2 = sizeof(_c_data_read_2) / sizeof(_c_data_read_2[0]);
2020-05-11 14:12:38 -06:00
uint8_t buffer2[rows2][64];
for( int i = 0; i < rows2; i++ ){
std::copy(std::begin(_c_data_read_2[i]), std::end(_c_data_read_2[i]), std::begin(buffer2[i]));
2020-05-11 14:12:38 -06:00
}
//prepare data 3
int rows3 = sizeof(_c_data_read_3) / sizeof(_c_data_read_3[0]);
2020-05-11 14:12:38 -06:00
uint8_t buffer3[rows3][16];
for( int i = 0; i < rows3; i++ ){
std::copy(std::begin(_c_data_read_3[i]), std::end(_c_data_read_3[i]), std::begin(buffer3[i]));
2020-05-11 14:12:38 -06:00
}
//send data 1
2020-06-25 06:03:02 -06:00
uint8_t buffer_in1[8][16] = {{0}};
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer1[0], 16, 1000 );
2020-05-11 14:12:38 -06:00
for( int i = 1; i < rows1; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer1[i], 16, 1000 );
2020-05-11 14:12:38 -06:00
// control in
libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0302, 0x0002, buffer_in1[i-1], 16, 1000 );
2020-05-11 14:12:38 -06:00
}
//send data 2
2020-06-25 06:03:02 -06:00
uint8_t buffer_in2[85][64] = {{0}};
2020-05-11 14:12:38 -06:00
for( int i = 0; i < rows2; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0303, 0x0002, buffer2[i], 64, 1000 );
2020-05-11 14:12:38 -06:00
// control in
libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0303, 0x0002, buffer_in2[i], 64, 1000 );
2020-05-11 14:12:38 -06:00
}
//send data 3
2020-06-25 06:03:02 -06:00
uint8_t buffer_in3[100][16] = {{0}};
2020-05-11 14:12:38 -06:00
for( int i = 0; i < rows3-1; i++ ){
// control out
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer3[i], 16, 1000 );
2020-05-11 14:12:38 -06:00
// control in
libusb_control_transfer( _i_handle, 0xa1, 0x01, 0x0302, 0x0002, buffer_in3[i], 16, 1000 );
2020-05-11 14:12:38 -06:00
}
libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0302, 0x0002, buffer3[100], 16, 1000 );
2020-05-11 14:12:38 -06:00
// parse received data
if( buffer_in1[0][8]+1 == 1 )
_s_profile = profile_1;
2020-05-11 14:12:38 -06:00
if( buffer_in1[0][8]+1 == 2 )
_s_profile = profile_2;
2020-05-11 14:12:38 -06:00
if( buffer_in1[0][8]+1 == 3 )
_s_profile = profile_3;
2020-05-11 14:12:38 -06:00
if( buffer_in1[0][8]+1 == 4 )
_s_profile = profile_4;
2020-05-11 14:12:38 -06:00
if( buffer_in1[0][8]+1 == 5 )
_s_profile = profile_5;
2020-05-11 14:12:38 -06:00
for( int i = 1; i < 6; i++ ){
// color
_s_colors[i-1][0] = buffer_in1[i][8];
_s_colors[i-1][1] = buffer_in1[i][9];
_s_colors[i-1][2] = buffer_in1[i][10];
2020-05-11 14:12:38 -06:00
// brightness
_s_brightness_levels[i-1] = buffer_in1[i][14];
2020-05-11 14:12:38 -06:00
// speed
_s_speed_levels[i-1] = buffer_in1[i][13];
2020-05-11 14:12:38 -06:00
// lightmode
std::array<uint8_t, 2> lightmode_bytes = {buffer_in1[i][11], buffer_in1[i][13]};
if( _c_lightmode_values.find(lightmode_bytes) != _c_lightmode_values.end() )
_s_lightmodes[i-1] = _c_lightmode_values.at(lightmode_bytes);
2020-05-11 14:12:38 -06:00
// polling rate (report rate)
uint8_t report_rate_byte = (i < 4) ? buffer_in1[6][6+(2*i)] : buffer_in1[7][(2*i)];
if( _c_report_rate_values.find(report_rate_byte) != _c_report_rate_values.end() )
_s_report_rates[i-1] = _c_report_rate_values.at(report_rate_byte);
2020-05-11 14:12:38 -06:00
// dpi
for( int j = 1; j < 6; j++ ){
if( buffer_in2[i-1][4+(6*j)] )
_s_dpi_enabled[i-1][j-1] = true;
2020-05-11 14:12:38 -06:00
else
_s_dpi_enabled[i-1][j-1] = false;
2020-05-11 14:12:38 -06:00
_s_dpi_levels[i-1][j-1][0] = buffer_in2[i-1][5+(6*j)];
_s_dpi_levels[i-1][j-1][1] = buffer_in2[i-1][6+(6*j)];
2020-05-11 14:12:38 -06:00
}
// button mapping
for( int j = 0; j < 20; j++ ){
_s_keymap_data[i-1][j][0] = buffer_in3[j+(20*(i-1))][8];
_s_keymap_data[i-1][j][1] = buffer_in3[j+(20*(i-1))][9];
_s_keymap_data[i-1][j][2] = buffer_in3[j+(20*(i-1))][10];
_s_keymap_data[i-1][j][3] = buffer_in3[j+(20*(i-1))][11];
2020-05-11 14:12:38 -06:00
}
}
2020-05-13 11:28:09 -06:00
// macros
std::array< std::vector< uint8_t >, 15 > macro_bytes;
int macronumber = 1;
int counter = 0;
2020-05-11 14:12:38 -06:00
// iterate over buffer_in2
for( int i = 5; i < 85; i++ ){
// valid macronumber?
if( macronumber >= 1 && macronumber <= 15 ){
// extract bytes
2020-05-13 11:28:09 -06:00
for( int j = 8; j < 58; j++ ){ // iterate over individual packet
macro_bytes[macronumber-1].push_back( buffer_in2[i][j] );
2020-05-11 14:12:38 -06:00
}
}
2020-05-13 11:28:09 -06:00
// increment counter and macronumber
counter++;
if( counter == 4 ){
counter = 0;
macronumber++;
}
}
// store extracted bytes in _s_macro_data
2020-05-13 11:28:09 -06:00
for( int i = 0; i < 15; i++ ){ // for each macro in macro_bytes
// for each byte in the macro
for( unsigned int j = 0; j < macro_bytes[i].size(); j++ ){
// failsafe
if( j >= (_s_macro_data[i].size()+8) )
2020-05-13 11:28:09 -06:00
break;
_s_macro_data[i][j+8] = macro_bytes[i][j];
2020-05-13 11:28:09 -06:00
}
2020-05-11 14:12:38 -06:00
}
return 0;
}