diff --git a/examples/example_m913.ini b/examples/example_m913.ini index f99612b..228327e 100644 --- a/examples/example_m913.ini +++ b/examples/example_m913.ini @@ -1,24 +1,39 @@ # Example configuration for the M913 mouse # If a particular option is not specified a default value will be used -# Currently only one profile is supported +# The M913 has two profiles that can be switched using the 'mode switch' button on the bottom of the mouse. +# However writing or reading the settings can only be done for the active profile, therefore only profile1 is used in the config. [profile1] +# LED mode: off, static, breathing, rainbow (only off and rainbow work) +lightmode=rainbow +# LED color (doesnt' work) +color=00ff00 +# LED brightness: 0-255 (doesn't work) +brightness=50 + # DPI levels # valid are 100-16000 in steps of 100 dpi1=100 -dpi2=200 -dpi3=300 -dpi4=8000 +dpi2=3000 +dpi3=4000 +dpi4=6000 dpi5=16000 -# Button mapping -# currently supported: forward, back, left, middle, right, led_toggle, polling_rate, none +# Enable or disable DPI levels +# On the M913 disabling a level will disable all higher levels as well. +# e.g. to disable dpi4 and dpi5 uncomment the next line +# dpi4_enable=0 + +# Button mapping, currently supported: +# left, middle, right, forward, back +# led_toggle, report_rate, default, none +# dpi-, dpi+, dpi-cycle button_left=left button_right=right button_middle=middle button_fire=left -button_1=left +button_1=backward button_2=forward button_3=led_toggle button_4=none diff --git a/include/m913/constructor.cpp b/include/m913/constructor.cpp index e3fda79..75a9a6d 100644 --- a/include/m913/constructor.cpp +++ b/include/m913/constructor.cpp @@ -22,7 +22,7 @@ mouse_m913::mouse_m913(){ //default settings - _s_profile = profile_1; + _s_profile = rd_mouse::rd_profile::profile_1; _s_scrollspeeds.fill( 0x01 ); _s_lightmodes.fill( lightmode_static ); _s_colors.fill( {0xff, 0xff, 0xff} ); diff --git a/include/m913/data.cpp b/include/m913/data.cpp index 01677e8..37d8c29 100644 --- a/include/m913/data.cpp +++ b/include/m913/data.cpp @@ -33,8 +33,8 @@ std::set< uint16_t > mouse_m913::_c_all_pids = { // Names of the physical buttons std::map< int, std::string > mouse_m913::_c_button_names = { - { 0, "button_1" }, // ok - { 1, "button_2" }, // ok + { 0, "button_1" }, + { 1, "button_2" }, { 2, "button_3" }, { 3, "button_4" }, { 4, "button_5" }, @@ -55,11 +55,15 @@ std::map< std::string, std::array > mouse_m913::_c_keycodes = { { "left", { 0x01, 0x01, 0x00, 0x53 } }, { "right", { 0x01, 0x02, 0x00, 0x52 } }, { "middle", { 0x01, 0x04, 0x00, 0x50 } }, - { "back", { 0x01, 0x08, 0x00, 0x4c } }, + { "backward", { 0x01, 0x08, 0x00, 0x4c } }, { "forward", { 0x01, 0x10, 0x00, 0x44 } }, { "led_toggle", { 0x08, 0x00, 0x00, 0x4d } }, - { "polling_rate", { 0x08, 0x00, 0x00, 0x4e } }, - { "none", { 0x05, 0x00, 0x00, 0x50 } } + { "report_rate", { 0x07, 0x00, 0x00, 0x4e } }, + { "dpi-", { 0x02, 0x03, 0x00, 0x50 } }, + { "dpi+", { 0x02, 0x02, 0x00, 0x51 } }, + { "dpi-cycle", { 0x02, 0x01, 0x00, 0x52 } }, + { "default", { 0x05, 0x00, 0x00, 0x50 } }, + { "none", { 0x00, 0x00, 0x00, 0x55 } }, }; // DPI → bytecode @@ -227,10 +231,8 @@ std::map< int, std::array > mouse_m913::_c_dpi_codes = { }; //usb data packets -uint8_t mouse_m913::_c_data_settings[29][17] = { - {0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49}, - {0x08, 0x07, 0x00, 0x01, 0x20, 0x08, 0x02, 0x80, 0x04, 0x00, 0x40, 0x04, 0x00, 0x8b, 0x00, 0x00, 0xc8}, - {0x08, 0x07, 0x00, 0x01, 0x40, 0x08, 0x02, 0x81, 0x20, 0x00, 0x41, 0x20, 0x00, 0x51, 0x00, 0x00, 0xa8}, +uint8_t mouse_m913::_c_data_unknown_1[9][17] = { + {0x08, 0x07, 0x00, 0x01, 0x60, 0x08, 0x02, 0x81, 0x21, 0x00, 0x41, 0x21, 0x00, 0x4f, 0x00, 0x00, 0x88}, {0x08, 0x07, 0x00, 0x01, 0x80, 0x08, 0x02, 0x81, 0x22, 0x00, 0x41, 0x22, 0x00, 0x4d, 0x00, 0x00, 0x68}, {0x08, 0x07, 0x00, 0x01, 0xa0, 0x08, 0x02, 0x81, 0x23, 0x00, 0x41, 0x23, 0x00, 0x4b, 0x00, 0x00, 0x48}, {0x08, 0x07, 0x00, 0x02, 0x00, 0x08, 0x02, 0x81, 0x24, 0x00, 0x41, 0x24, 0x00, 0x49, 0x00, 0x00, 0xe7}, @@ -239,6 +241,9 @@ uint8_t mouse_m913::_c_data_settings[29][17] = { {0x08, 0x07, 0x00, 0x02, 0xa0, 0x08, 0x02, 0x81, 0x27, 0x00, 0x41, 0x27, 0x00, 0x43, 0x00, 0x00, 0x47}, {0x08, 0x07, 0x00, 0x02, 0xc0, 0x08, 0x02, 0x81, 0x57, 0x00, 0x41, 0x57, 0x00, 0xe3, 0x00, 0x00, 0x27}, {0x08, 0x07, 0x00, 0x02, 0xe0, 0x08, 0x02, 0x81, 0x56, 0x00, 0x41, 0x56, 0x00, 0xe5, 0x00, 0x00, 0x07}, +}; + +uint8_t mouse_m913::_c_data_button_mapping[8][17] = { {0x08, 0x07, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x50, 0x00, 0x00, 0x34}, {0x08, 0x07, 0x00, 0x00, 0x68, 0x08, 0x05, 0x00, 0x00, 0x50, 0x01, 0x08, 0x00, 0x4c, 0x00, 0x00, 0x2c}, {0x08, 0x07, 0x00, 0x00, 0x70, 0x08, 0x05, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x50, 0x00, 0x00, 0x24}, @@ -247,14 +252,118 @@ uint8_t mouse_m913::_c_data_settings[29][17] = { {0x08, 0x07, 0x00, 0x00, 0x88, 0x08, 0x01, 0x04, 0x00, 0x50, 0x04, 0x14, 0x03, 0x3a, 0x00, 0x00, 0x0c}, {0x08, 0x07, 0x00, 0x00, 0x90, 0x08, 0x05, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x50, 0x00, 0x00, 0x04}, {0x08, 0x07, 0x00, 0x00, 0x98, 0x08, 0x05, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x50, 0x00, 0x00, 0xfc}, +}; + +uint8_t mouse_m913::_c_data_dpi[4][17]= { {0x08, 0x07, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x55, 0x02, 0x02, 0x00, 0x51, 0x00, 0x00, 0x88}, {0x08, 0x07, 0x00, 0x00, 0x14, 0x08, 0x03, 0x03, 0x00, 0x4f, 0x04, 0x04, 0x00, 0x4d, 0x00, 0x00, 0x80}, {0x08, 0x07, 0x00, 0x00, 0x1c, 0x04, 0x05, 0x05, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1}, {0x08, 0x07, 0x00, 0x00, 0x02, 0x02, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed}, +}; + +uint8_t mouse_m913::_c_data_unknown_2[3][17] = { {0x08, 0x07, 0x00, 0x00, 0x2c, 0x08, 0xff, 0x00, 0x00, 0x56, 0x00, 0x00, 0xff, 0x56, 0x00, 0x00, 0x68}, {0x08, 0x07, 0x00, 0x00, 0x34, 0x08, 0x00, 0xff, 0x00, 0x56, 0xff, 0xff, 0x00, 0x57, 0x00, 0x00, 0x60}, {0x08, 0x07, 0x00, 0x00, 0x3c, 0x04, 0xff, 0x55, 0x7d, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1}, +}; + +uint8_t mouse_m913::_c_data_led_static[3][17] = { + {0x08, 0x07, 0x00, 0x00, 0x54, 0x08, 0xff, 0x00, 0x00, 0x57, 0x01, 0x54, 0xff, 0x56, 0x00, 0x00, 0xeb}, + {0x08, 0x07, 0x00, 0x00, 0x00, 0x02, 0x02, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef}, + {0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49}, +}; + +uint8_t mouse_m913::_c_data_led_breathing[3][17] = { + {0x08, 0x07, 0x00, 0x00, 0x54, 0x08, 0xff, 0x00, 0x00, 0x57, 0x01, 0x54, 0xff, 0x56, 0x00, 0x00, 0xeb}, + {0x08, 0x07, 0x00, 0x00, 0x5c, 0x02, 0x03, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93}, + {0x08, 0x07, 0x00, 0x00, 0x00, 0x02, 0x01, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef}, +}; + +uint8_t mouse_m913::_c_data_led_off[2][17] = { + {0x08, 0x07, 0x00, 0x00, 0x58, 0x02, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97}, + {0x08, 0x07, 0x00, 0x00, 0x00, 0x02, 0x01, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef}, +}; + +uint8_t mouse_m913::_c_data_led_rainbow[3][17] = { {0x08, 0x07, 0x00, 0x00, 0x54, 0x08, 0xff, 0x00, 0xff, 0x57, 0x03, 0x52, 0x80, 0xd5, 0x00, 0x00, 0xeb}, {0x08, 0x07, 0x00, 0x00, 0x5c, 0x02, 0x03, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93}, - {0x08, 0x07, 0x00, 0x00, 0x00, 0x02, 0x02, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef} + {0x08, 0x07, 0x00, 0x00, 0x00, 0x02, 0x02, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef}, }; + +// TODO! remove? +uint8_t mouse_m913::_c_data_unknown_3[1][17] = { + //{0x08, 0x07, 0x00, 0x00, 0x5c, 0x02, 0x03, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93}, + {0x08, 0x07, 0x00, 0x00, 0x00, 0x02, 0x02, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef}, +}; + +uint8_t mouse_m913::_c_data_read[69][17] = { + {0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a}, + {0x08, 0x01, 0x00, 0x00, 0x00, 0x04, 0x34, 0x2e, 0x4c, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43}, + {0x08, 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f}, + {0x08, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49}, + {0x08, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b}, + {0x08, 0x08, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31}, + {0x08, 0x08, 0x00, 0x00, 0x14, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27}, + {0x08, 0x08, 0x00, 0x00, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}, + {0x08, 0x08, 0x00, 0x00, 0x28, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13}, + {0x08, 0x08, 0x00, 0x00, 0x32, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09}, + {0x08, 0x08, 0x00, 0x00, 0x3c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + {0x08, 0x08, 0x00, 0x00, 0x46, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5}, + {0x08, 0x08, 0x00, 0x00, 0x50, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb}, + {0x08, 0x08, 0x00, 0x00, 0x5a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1}, + {0x08, 0x08, 0x00, 0x00, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7}, + {0x08, 0x08, 0x00, 0x00, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd}, + {0x08, 0x08, 0x00, 0x00, 0x78, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3}, + {0x08, 0x08, 0x00, 0x00, 0x82, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9}, + {0x08, 0x08, 0x00, 0x00, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf}, + {0x08, 0x08, 0x00, 0x00, 0x96, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5}, + {0x08, 0x08, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a}, + {0x08, 0x08, 0x00, 0x01, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30}, + {0x08, 0x08, 0x00, 0x01, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a}, + {0x08, 0x08, 0x00, 0x01, 0x2a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0x08, 0x08, 0x00, 0x01, 0x40, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa}, + {0x08, 0x08, 0x00, 0x01, 0x4a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0}, + {0x08, 0x08, 0x00, 0x01, 0x60, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda}, + {0x08, 0x08, 0x00, 0x01, 0x6a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0}, + {0x08, 0x08, 0x00, 0x01, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba}, + {0x08, 0x08, 0x00, 0x01, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0}, + {0x08, 0x08, 0x00, 0x01, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a}, + {0x08, 0x08, 0x00, 0x01, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90}, + {0x08, 0x08, 0x00, 0x01, 0xc0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a}, + {0x08, 0x08, 0x00, 0x01, 0xca, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70}, + {0x08, 0x08, 0x00, 0x01, 0xe0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a}, + {0x08, 0x08, 0x00, 0x01, 0xea, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50}, + {0x08, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39}, + {0x08, 0x08, 0x00, 0x02, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f}, + {0x08, 0x08, 0x00, 0x02, 0x20, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19}, + {0x08, 0x08, 0x00, 0x02, 0x2a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f}, + {0x08, 0x08, 0x00, 0x02, 0x40, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9}, + {0x08, 0x08, 0x00, 0x02, 0x4a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef}, + {0x08, 0x08, 0x00, 0x02, 0x60, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9}, + {0x08, 0x08, 0x00, 0x02, 0x6a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf}, + {0x08, 0x08, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9}, + {0x08, 0x08, 0x00, 0x02, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf}, + {0x08, 0x08, 0x00, 0x02, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99}, + {0x08, 0x08, 0x00, 0x02, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f}, + {0x08, 0x08, 0x00, 0x02, 0xc0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}, + {0x08, 0x08, 0x00, 0x02, 0xca, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f}, + {0x08, 0x08, 0x00, 0x02, 0xe0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59}, + {0x08, 0x08, 0x00, 0x02, 0xea, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f}, + {0x08, 0x08, 0x00, 0x03, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37}, + {0x08, 0x08, 0x00, 0x04, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6}, + {0x08, 0x08, 0x00, 0x06, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34}, + {0x08, 0x08, 0x00, 0x07, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3}, + {0x08, 0x08, 0x00, 0x09, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31}, + {0x08, 0x08, 0x00, 0x0a, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0}, + {0x08, 0x08, 0x00, 0x0c, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e}, + {0x08, 0x08, 0x00, 0x0d, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xad}, + {0x08, 0x08, 0x00, 0x0f, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b}, + {0x08, 0x08, 0x00, 0x10, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa}, + {0x08, 0x08, 0x00, 0x12, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28}, + {0x08, 0x08, 0x00, 0x13, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7}, + {0x08, 0x08, 0x00, 0x15, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25}, + {0x08, 0x08, 0x00, 0x16, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4}, + {0x08, 0x08, 0x00, 0x18, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22}, + {0x08, 0x08, 0x00, 0x19, 0x81, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1}, + {0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49}, +}; \ No newline at end of file diff --git a/include/m913/getters.cpp b/include/m913/getters.cpp index 7dd79d7..21201f6 100644 --- a/include/m913/getters.cpp +++ b/include/m913/getters.cpp @@ -27,7 +27,15 @@ uint8_t mouse_m913::get_scrollspeed( rd_profile profile ){ } mouse_m913::rd_lightmode mouse_m913::get_lightmode( rd_profile profile ){ - return _s_lightmodes[profile]; + mouse_m913::rd_lightmode l = mouse_m913::rd_lightmode::lightmode_static; + switch(_s_lightmodes[profile]){ + case mouse_m913::m913_lightmode::lightmode_off: l = mouse_m913::rd_lightmode::lightmode_off; break; + case mouse_m913::m913_lightmode::lightmode_breathing: l = mouse_m913::rd_lightmode::lightmode_breathing; break; + case mouse_m913::m913_lightmode::lightmode_rainbow: l = mouse_m913::rd_lightmode::lightmode_rainbow; break; + default: l = mouse_m913::rd_lightmode::lightmode_static; break; + } + + return l; } void mouse_m913::get_color( rd_profile profile, std::array &color ){ diff --git a/include/m913/helpers.cpp b/include/m913/helpers.cpp index 0afdf38..ff75684 100644 --- a/include/m913/helpers.cpp +++ b/include/m913/helpers.cpp @@ -20,6 +20,11 @@ //helper functions +// Maps rd_profile to m913_profile +mouse_m913::m913_profile mouse_m913::rd_profile_to_m913_profile( rd_profile profile ){ + return profile == rd_mouse::rd_profile::profile_1 ? mouse_m913::m913_profile::profile_1 : mouse_m913::m913_profile::profile_2; +} + //init libusb and open mouse int mouse_m913::open_mouse(){ @@ -183,7 +188,7 @@ int mouse_m913::print_settings( std::ostream& output ){ output << "# Configuration created by mouse_m913::print_settings().\n"; output << "# Currently active profile: " << _s_profile << "\n"; - for( int i = 1; i < 6; i++ ){ + for( int i = 1; i < 3; i++ ){ // section header output << "\n[profile" << i << "]\n"; @@ -213,14 +218,6 @@ int mouse_m913::print_settings( std::ostream& output ){ output << "rainbow\n"; else if( _s_lightmodes[i-1] == lightmode_static ) output << "static\n"; - else if( _s_lightmodes[i-1] == lightmode_wave ) - output << "wave\n"; - else if( _s_lightmodes[i-1] == lightmode_alternating ) - output << "alternating\n"; - else if( _s_lightmodes[i-1] == lightmode_reactive ) - output << "reactive\n"; - else if( _s_lightmodes[i-1] == lightmode_flashing ) - output << "flashing\n"; else{ output << "unknown, please report as bug\n"; } @@ -252,7 +249,7 @@ int mouse_m913::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]}; std::string dpi_string = ""; if( _i_decode_dpi( dpi_bytes, dpi_string ) == 0 ) @@ -298,3 +295,61 @@ int mouse_m913::print_settings( std::ostream& output ){ return 0; } + +// decode the button mapping +int mouse_m913::_i_decode_button_mapping( const std::array& bytes, std::string& mapping ){ + int ret = 1; + std::stringstream mapping_stream; + + // known keycode ? + for( auto keycode : _c_keycodes ){ + if( + bytes.at(0) == keycode.second.at(0) && + bytes.at(1) == keycode.second.at(1) && + bytes.at(2) == keycode.second.at(2) && + bytes.at(3) == keycode.second.at(3) + ){ + ret = 0; + mapping_stream << keycode.first; + } + } + + // unknown keycode + if( ret != 0 ){ + mapping_stream + << "unknown, please report as bug: " + << " " << std::hex << (int)bytes.at(0) << " " + << " " << std::hex << (int)bytes.at(1) << " " + << " " << std::hex << (int)bytes.at(2) << " " + << " " << std::hex << (int)bytes.at(3) + << std::dec; + } + + mapping = mapping_stream.str(); + return ret; +} + +int mouse_m913::_i_decode_dpi( const 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_value.second[2] == dpi_bytes[2] ){ + dpi_string = std::to_string( dpi_value.first ); + return 0; + } + + } + + // unknown dpi value + std::stringstream conversion_stream; + + 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] << std::setw(2) << (int)dpi_bytes[2]; + conversion_stream << std::setfill(' ') << std::setw(0) << std::dec; + + dpi_string = conversion_stream.str(); + + return 0; +} \ No newline at end of file diff --git a/include/m913/mouse_m913.h b/include/m913/mouse_m913.h index 4672944..d64c289 100644 --- a/include/m913/mouse_m913.h +++ b/include/m913/mouse_m913.h @@ -250,6 +250,51 @@ class mouse_m913 : public rd_mouse{ std::map< int, std::string >& button_names(){ return _c_button_names; } private: + /// The M913 has only two profiles. + enum m913_profile{ + profile_1 = 0, + profile_2 = 1, + }; + + /// The M913 has different light modes from the other mice + enum m913_lightmode{ + lightmode_off, + lightmode_static, + lightmode_breathing, + lightmode_rainbow + }; + + uint8_t _c_brightness_min = 0x00; + uint8_t _c_brightness_max = 0xff; + + /// Maps rd_profile to m913_profile + m913_profile rd_profile_to_m913_profile( rd_profile profile ); + + /// Write raw data + int write_data(uint8_t data[][17], size_t rows); + + /// Write the button mapping to the mouse + int write_button_mapping( m913_profile profile ); + + /// Write the DPI settings to the mouse + int write_dpi_settings( m913_profile profile ); + + /// Write the LED settings to the mouse + int write_led_settings( m913_profile profile ); + + /** \brief Decodes the bytes describing a button mapping + * \arg bytes the 4 bytes descriping the mapping + * \arg mapping string to hold the result + * \return 0 if valid button mapping + * \see _i_encode_button_mapping + */ + static int _i_decode_button_mapping( const std::array& bytes, std::string& mapping ); + + /** Convert raw dpi bytes to a string representation (doesn't validate dpi value) + * This function overloads the implementation from rd_mouse and supports actual DPI values. + * \return 0 if no error + */ + static int _i_decode_dpi( const std::array& dpi_bytes, std::string& dpi_string ); /// Names of the physical buttons static std::map< int, std::string > _c_button_names; @@ -271,20 +316,39 @@ class mouse_m913 : public rd_mouse{ //setting vars rd_profile _s_profile; - std::array _s_scrollspeeds; - std::array _s_lightmodes; - std::array, 5> _s_colors; - 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, 16>, 5> _s_keymap_data; - std::array _s_report_rates; + std::array _s_scrollspeeds; + std::array _s_lightmodes; + std::array, 2> _s_colors; + std::array _s_brightness_levels; + std::array _s_speed_levels; + std::array, 2> _s_dpi_enabled; + std::array, 5>, 2> _s_dpi_levels; + std::array, 16>, 2> _s_keymap_data; + std::array _s_report_rates; std::array, 15> _s_macro_data; //usb data packets - /// Used for sending the settings - static uint8_t _c_data_settings[29][17]; + /// Unknown function + static uint8_t _c_data_unknown_1[9][17]; + /// button mapping + static uint8_t _c_data_button_mapping[8][17]; + /// DPI values + static uint8_t _c_data_dpi[4][17]; + /// Unknown function + static uint8_t _c_data_unknown_2[3][17]; + /// LED settings + static uint8_t _c_data_led_static[3][17]; + /// LED settings + static uint8_t _c_data_led_breathing[3][17]; + /// LED settings + static uint8_t _c_data_led_off[2][17]; + /// LED settings + static uint8_t _c_data_led_rainbow[3][17]; + /// Unknown function + static uint8_t _c_data_unknown_3[1][17]; + /// Used to read the settigs from the mouse + static uint8_t _c_data_read[69][17]; + }; #endif diff --git a/include/m913/readers.cpp b/include/m913/readers.cpp index 19388d4..b8826f6 100644 --- a/include/m913/readers.cpp +++ b/include/m913/readers.cpp @@ -21,16 +21,111 @@ //reader functions (get settings from mouse) int mouse_m913::dump_settings( std::ostream& output ){ - output << "Not implemented, missing data\n"; - return 0; + int ret = 0; + + size_t rows = sizeof(_c_data_read) / sizeof(_c_data_read[0]); + uint8_t buffer_in[17]; + for( size_t i = 0; i < rows; i++ ){ + ret += libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0308, 0x0001, _c_data_read[i], 17, 1000 ); + ret += libusb_interrupt_transfer( _i_handle, 0x82, buffer_in, 17, NULL, 1000 ); + + for( size_t j = 0; j < 17; j++ ) + output << std::hex << std::setw(2) << std::setfill('0') << (int)buffer_in[j] << " "; + output << "\n"; + } + + output << std::dec << std::setw(0) << std::setfill(' '); + + return ret; } int mouse_m913::read_and_print_settings( std::ostream& output ){ - output << "Not implemented, missing data\n"; - return 0; + int ret = 0; + + // read settings + size_t rows = sizeof(_c_data_read) / sizeof(_c_data_read[0]); + uint8_t buffer_in[rows][17]; + for( size_t i = 0; i < rows; i++ ){ + ret += libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0308, 0x0001, _c_data_read[i], 17, 1000 ); + ret += libusb_interrupt_transfer( _i_handle, 0x82, buffer_in[i], 17, NULL, 1000 ); + } + + // decode and print the settings + output + << "# Configuration created with mouse_m908 -R.\n" + << "# This configuration can be send to the mouse with mouse_m908 -c.\n" + << "# Note: this feature is incomplete for the M913.\n\n"; + + output + << "# The M913 has two profiles that can be switched using the 'mode switch' button on the bottom of the mouse.\n" + << "# Reading the settings can only be done for the active profile, therefore only profile1 is used in this config.\n" + << "[profile1]\n\n"; + + output << "report_rate="; + switch(buffer_in[4][6]){ + case 0x1: output << "1000\n"; break; + case 0x2: output << "500\n"; break; + case 0x4: output << "250\n"; break; + case 0x8: output << "125\n"; break; + default: output << "unknown\n"; break; + } + + // DPI + output << "\n# DPI settings\n"; + output << "# Currently active DPI level: " << (int)(buffer_in[2][6] + 1) << "\n"; + std::string dpi = ""; + _i_decode_dpi({buffer_in[5][8], buffer_in[5][9], buffer_in[5][11]}, dpi); + output << "dpi1=" << dpi << "\n"; + _i_decode_dpi({buffer_in[5][12], buffer_in[5][13], buffer_in[5][15]}, dpi); + output << "dpi2=" << dpi << "\n"; + _i_decode_dpi({buffer_in[6][6], buffer_in[6][7], buffer_in[6][9]}, dpi); + output << "dpi3=" << dpi << "\n"; + _i_decode_dpi({buffer_in[6][10], buffer_in[6][11], buffer_in[6][13]}, dpi); + output << "dpi4=" << dpi << "\n"; + _i_decode_dpi({buffer_in[6][14], buffer_in[6][15], buffer_in[7][7]}, dpi); + output << "dpi5=" << dpi << "\n"; + + // button mapping + output << "\n# Button mapping\n"; + std::string mapping = ""; + + _i_decode_button_mapping({buffer_in[16][10], buffer_in[16][11], buffer_in[16][12], buffer_in[16][13]}, mapping); + output << "button_left=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[16][6], buffer_in[16][7], buffer_in[16][8], buffer_in[16][9]}, mapping); + output << "button_right=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[17][12], buffer_in[17][13], buffer_in[17][14], buffer_in[17][15]}, mapping); + output << "button_middle=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[18][6], buffer_in[18][7], buffer_in[18][8], buffer_in[18][9]}, mapping); + output << "button_fire=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[13][12], buffer_in[13][13], buffer_in[13][14], buffer_in[13][15]}, mapping); + output << "button_1=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[14][6], buffer_in[14][7], buffer_in[14][8], buffer_in[14][9]}, mapping); + output << "button_2=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[14][10], buffer_in[14][11], buffer_in[14][12], buffer_in[14][13]}, mapping); + output << "button_3=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[14][14], buffer_in[14][15], buffer_in[15][6], buffer_in[15][7]}, mapping); + output << "button_4=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[15][8], buffer_in[15][9], buffer_in[15][10], buffer_in[15][11]}, mapping); + output << "button_5=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[15][12], buffer_in[15][13], buffer_in[15][14], buffer_in[15][15]}, mapping); + output << "button_6=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[16][14], buffer_in[16][15], buffer_in[17][6], buffer_in[17][7]}, mapping); + output << "button_7=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[17][8], buffer_in[17][9], buffer_in[17][10], buffer_in[17][11]}, mapping); + output << "button_8=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[18][10], buffer_in[18][11], buffer_in[18][12], buffer_in[18][13]}, mapping); + output << "button_9=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[18][14], buffer_in[18][15], buffer_in[19][6], buffer_in[19][7]}, mapping); + output << "button_10=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[19][8], buffer_in[19][9], buffer_in[19][10], buffer_in[19][11]}, mapping); + output << "button_11=" << mapping << "\n"; + _i_decode_button_mapping({buffer_in[19][12], buffer_in[19][13], buffer_in[19][14], buffer_in[19][15]}, mapping); + output << "button_12=" << mapping << "\n"; + + return ret; } int mouse_m913::read_settings(){ - // missing data - return 0; + // currently not implemented + return 1; } diff --git a/include/m913/setters.cpp b/include/m913/setters.cpp index 86ee7fa..bdb750f 100644 --- a/include/m913/setters.cpp +++ b/include/m913/setters.cpp @@ -32,18 +32,26 @@ int mouse_m913::set_scrollspeed( rd_profile profile, uint8_t speed ){ return 1; } - _s_scrollspeeds[profile] = speed; + _s_scrollspeeds[rd_profile_to_m913_profile(profile)] = speed; return 0; } int mouse_m913::set_lightmode( rd_profile profile, rd_lightmode lightmode ){ - _s_lightmodes[profile] = lightmode; + mouse_m913::m913_lightmode l = mouse_m913::m913_lightmode::lightmode_static; + switch(lightmode){ + case rd_mouse::rd_lightmode::lightmode_off: l = mouse_m913::m913_lightmode::lightmode_off; break; + case rd_mouse::rd_lightmode::lightmode_breathing: l = mouse_m913::m913_lightmode::lightmode_breathing; break; + case rd_mouse::rd_lightmode::lightmode_rainbow: l = mouse_m913::m913_lightmode::lightmode_rainbow; break; + default: l = mouse_m913::m913_lightmode::lightmode_static; break; + } + + _s_lightmodes[rd_profile_to_m913_profile(profile)] = l; return 0; } int mouse_m913::set_color( rd_profile profile, std::array color ){ - _s_colors[profile] = color; + _s_colors[rd_profile_to_m913_profile(profile)] = color; return 0; } @@ -54,7 +62,7 @@ int mouse_m913::set_brightness( rd_profile profile, uint8_t brightness ){ return 1; } - _s_brightness_levels[profile] = brightness; + _s_brightness_levels[rd_profile_to_m913_profile(profile)] = brightness; return 0; } @@ -65,7 +73,7 @@ int mouse_m913::set_speed( rd_profile profile, uint8_t speed ){ return 1; } - _s_speed_levels[profile] = speed; + _s_speed_levels[rd_profile_to_m913_profile(profile)] = speed; return 0; } @@ -76,19 +84,19 @@ int mouse_m913::set_dpi_enable( rd_profile profile, int level, bool enabled ){ return 1; } - _s_dpi_enabled[profile][level] = enabled; + _s_dpi_enabled[rd_profile_to_m913_profile(profile)][level] = enabled; // check if at least one level enabled int sum = 0; for( int i = _c_level_min; i <= _c_level_max; i++ ){ - if( _s_dpi_enabled[profile][i] ){ + if( _s_dpi_enabled[rd_profile_to_m913_profile(profile)][i] ){ sum++; } } // if no level enabled: reenable specified level if( sum == 0 ){ - _s_dpi_enabled[profile][level] = true; + _s_dpi_enabled[rd_profile_to_m913_profile(profile)][level] = true; return 1; } @@ -102,7 +110,7 @@ int mouse_m913::set_dpi( rd_profile profile, int level, std::string dpi ){ return 1; // current assumption: only one profile - profile = profile_1; + profile = rd_mouse::rd_profile::profile_1; // check format: 0xABCD (raw bytes), TODO! enable or remove /* @@ -128,7 +136,7 @@ int mouse_m913::set_dpi( rd_profile profile, int level, std::string dpi ){ if( _c_dpi_codes.find( std::stoi(dpi) ) != _c_dpi_codes.end() ){ - _s_dpi_levels[profile][level] = _c_dpi_codes.at( std::stoi(dpi) ); + _s_dpi_levels[rd_profile_to_m913_profile(profile)][level] = _c_dpi_codes.at( std::stoi(dpi) ); return 0; } } @@ -143,17 +151,17 @@ int mouse_m913::set_dpi( rd_profile profile, int level, std::array d return 1; // current assumption: only one profile - profile = profile_1; + profile = rd_mouse::rd_profile::profile_1; - _s_dpi_levels[profile][level] = dpi; + _s_dpi_levels[rd_profile_to_m913_profile(profile)][level] = dpi; return 0; } int mouse_m913::set_key_mapping( rd_profile profile, int key, std::array mapping ){ - _s_keymap_data[profile][key][0] = mapping[0]; - _s_keymap_data[profile][key][1] = mapping[1]; - _s_keymap_data[profile][key][2] = mapping[2]; - _s_keymap_data[profile][key][3] = mapping[3]; + _s_keymap_data[rd_profile_to_m913_profile(profile)][key][0] = mapping[0]; + _s_keymap_data[rd_profile_to_m913_profile(profile)][key][1] = mapping[1]; + _s_keymap_data[rd_profile_to_m913_profile(profile)][key][2] = mapping[2]; + _s_keymap_data[rd_profile_to_m913_profile(profile)][key][3] = mapping[3]; return 0; } @@ -164,18 +172,18 @@ int mouse_m913::set_key_mapping( rd_profile profile, int key, std::string mappin return 1; // current assumption: only one profile - profile = profile_1; + profile = rd_mouse::rd_profile::profile_1; // the M913 uses different keycodes, therefore the decoding is done here if( _c_keycodes.find(mapping) != _c_keycodes.end() ){ - _s_keymap_data[profile][key] = _c_keycodes[mapping]; + _s_keymap_data[rd_profile_to_m913_profile(profile)][key] = _c_keycodes[mapping]; } return 0; } int mouse_m913::set_report_rate( rd_profile profile, rd_report_rate report_rate ){ - _s_report_rates[profile] = report_rate; + _s_report_rates[rd_profile_to_m913_profile(profile)] = report_rate; return 0; } diff --git a/include/m913/writers.cpp b/include/m913/writers.cpp index 1742b4e..912de9d 100644 --- a/include/m913/writers.cpp +++ b/include/m913/writers.cpp @@ -20,80 +20,208 @@ //writer functions (apply changes to mouse) + + int mouse_m913::write_profile(){ // missing data - throw std::string( "Profiles are not supported for the M913." ); + throw std::string( "Changing profiles is not support for the M913, use the 'mode switch' button on the mouse instead." ); return 0; } +int mouse_m913::write_data(uint8_t data[][17], size_t rows){ + int ret = 0; + uint8_t buffer_in[17]; + + for( size_t i = 0; i < rows; i++ ){ + ret += libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0308, 0x0001, data[i], 17, 1000 ); + ret += libusb_interrupt_transfer( _i_handle, 0x82, buffer_in, 17, NULL, 1000 ); + } + + return ret; +} + +int mouse_m913::write_button_mapping( m913_profile profile ){ + int ret = 0; + + // part 1 (unknown function) + size_t rows_1 = sizeof(_c_data_unknown_1) / sizeof(_c_data_unknown_1[0]); + uint8_t buffer_1[rows_1][17]; + for( size_t i = 0; i < rows_1; i++ ){ + std::copy(std::begin(_c_data_unknown_1[i]), std::end(_c_data_unknown_1[i]), std::begin(buffer_1[i])); + } + ret += write_data(buffer_1, rows_1); + + // part 2 (button mapping) + size_t rows_2 = sizeof(_c_data_button_mapping) / sizeof(_c_data_button_mapping[0]); + uint8_t buffer_2[rows_2][17]; + for( size_t i = 0; i < rows_2; i++ ){ + std::copy(std::begin(_c_data_button_mapping[i]), std::end(_c_data_button_mapping[i]), std::begin(buffer_2[i])); + } + + // two buttons per packet + for( int i=0; i<16; i+=2 ){ + int j = i/2; + + buffer_2[j][6] = _s_keymap_data[profile][i][0]; + buffer_2[j][7] = _s_keymap_data[profile][i][1]; + buffer_2[j][8] = _s_keymap_data[profile][i][2]; + buffer_2[j][9] = _s_keymap_data[profile][i][3]; + + buffer_2[j][10] = _s_keymap_data[profile][i+1][0]; + buffer_2[j][11] = _s_keymap_data[profile][i+1][1]; + buffer_2[j][12] = _s_keymap_data[profile][i+1][2]; + buffer_2[j][13] = _s_keymap_data[profile][i+1][3]; + } + + ret += write_data(buffer_2, rows_2); + + return ret; +} + +int mouse_m913::write_dpi_settings( m913_profile profile ){ + int ret = 0; + + // part 1 (DPI) + size_t rows_1 = sizeof(_c_data_dpi) / sizeof(_c_data_dpi[0]); + uint8_t buffer_1[rows_1][17]; + for( size_t i = 0; i < rows_1; i++ ){ + std::copy(std::begin(_c_data_dpi[i]), std::end(_c_data_dpi[i]), std::begin(buffer_1[i])); + } + + // DPI level 1 + buffer_1[0][6] = _s_dpi_levels[profile][0][0]; + buffer_1[0][7] = _s_dpi_levels[profile][0][1]; + buffer_1[0][9] = _s_dpi_levels[profile][0][2]; + // DPI level 2 + buffer_1[0][10] = _s_dpi_levels[profile][1][0]; + buffer_1[0][11] = _s_dpi_levels[profile][1][1]; + buffer_1[0][13] = _s_dpi_levels[profile][1][2]; + // DPI level 3 + buffer_1[1][6] = _s_dpi_levels[profile][2][0]; + buffer_1[1][7] = _s_dpi_levels[profile][2][1]; + buffer_1[1][9] = _s_dpi_levels[profile][2][2]; + // DPI level 4 + buffer_1[1][10] = _s_dpi_levels[profile][3][0]; + buffer_1[1][11] = _s_dpi_levels[profile][3][1]; + buffer_1[1][13] = _s_dpi_levels[profile][3][2]; + // DPI level 5 + buffer_1[2][6] = _s_dpi_levels[profile][4][0]; + buffer_1[2][7] = _s_dpi_levels[profile][4][1]; + buffer_1[2][9] = _s_dpi_levels[profile][4][2]; + + // enabled DPI levels + uint8_t enabled_dpi_levels_1 = 0x05; + uint8_t enabled_dpi_levels_2 = 0x50; + if(!_s_dpi_enabled.at(profile).at(4)){ + enabled_dpi_levels_1 = 0x04; + enabled_dpi_levels_2 = 0x51; + } + if(!_s_dpi_enabled.at(profile).at(3)){ + enabled_dpi_levels_1 = 0x03; + enabled_dpi_levels_2 = 0x52; + } + if(!_s_dpi_enabled.at(profile).at(2)){ + enabled_dpi_levels_1 = 0x02; + enabled_dpi_levels_2 = 0x53; + } + if(!_s_dpi_enabled.at(profile).at(1)){ + enabled_dpi_levels_1 = 0x01; + enabled_dpi_levels_2 = 0x54; + } + buffer_1[3][6] = enabled_dpi_levels_1; + buffer_1[3][7] = enabled_dpi_levels_2; + + + ret += write_data(buffer_1, rows_1); + + // part 2 (unknown function) + size_t rows_2 = sizeof(_c_data_unknown_2) / sizeof(_c_data_unknown_2[0]); + uint8_t buffer_2[rows_2][17]; + for( size_t i = 0; i < rows_2; i++ ){ + std::copy(std::begin(_c_data_unknown_2[i]), std::end(_c_data_unknown_2[i]), std::begin(buffer_2[i])); + } + ret += write_data(buffer_2, rows_2); + + return ret; +} + +int mouse_m913::write_led_settings( m913_profile profile ){ + int ret = 0; + + if(_s_lightmodes.at(profile) == mouse_m913::m913_lightmode::lightmode_off){ + + // part 1 (LED settings) + size_t rows_1 = sizeof(_c_data_led_off) / sizeof(_c_data_led_off[0]); + uint8_t buffer_1[rows_1][17]; + for( size_t i = 0; i < rows_1; i++ ){ + std::copy(std::begin(_c_data_led_off[i]), std::end(_c_data_led_off[i]), std::begin(buffer_1[i])); + } + + ret += write_data(buffer_1, rows_1); + + }else if(_s_lightmodes.at(profile) == mouse_m913::m913_lightmode::lightmode_breathing){ + + // part 1 (LED settings) + size_t rows_1 = sizeof(_c_data_led_breathing) / sizeof(_c_data_led_breathing[0]); + uint8_t buffer_1[rows_1][17]; + for( size_t i = 0; i < rows_1; i++ ){ + std::copy(std::begin(_c_data_led_breathing[i]), std::end(_c_data_led_breathing[i]), std::begin(buffer_1[i])); + } + + ret += write_data(buffer_1, rows_1); + + }else if(_s_lightmodes.at(profile) == mouse_m913::m913_lightmode::lightmode_rainbow){ + + // part 1 (LED settings) + size_t rows_1 = sizeof(_c_data_led_rainbow) / sizeof(_c_data_led_rainbow[0]); + uint8_t buffer_1[rows_1][17]; + for( size_t i = 0; i < rows_1; i++ ){ + std::copy(std::begin(_c_data_led_rainbow[i]), std::end(_c_data_led_rainbow[i]), std::begin(buffer_1[i])); + } + + ret += write_data(buffer_1, rows_1); + + }else{ // lightmode_static + + // part 1 (LED settings) + size_t rows_1 = sizeof(_c_data_led_static) / sizeof(_c_data_led_static[0]); + uint8_t buffer_1[rows_1][17]; + for( size_t i = 0; i < rows_1; i++ ){ + std::copy(std::begin(_c_data_led_static[i]), std::end(_c_data_led_static[i]), std::begin(buffer_1[i])); + } + + // TODO! fix + buffer_1[0][6] = _s_colors.at(profile).at(0); + buffer_1[0][7] = _s_colors.at(profile).at(1); + buffer_1[0][8] = _s_colors.at(profile).at(2); + + buffer_1[0][12] = _s_brightness_levels[profile]; + + ret += write_data(buffer_1, rows_1); + + } +/* + // part 2 (unknown function) + size_t rows_2 = sizeof(_c_data_unknown_3) / sizeof(_c_data_unknown_3[0]); + uint8_t buffer_2[rows_2][17]; + for( size_t i = 0; i < rows_2; i++ ){ + std::copy(std::begin(_c_data_unknown_3[i]), std::end(_c_data_unknown_3[i]), std::begin(buffer_2[i])); + } + ret += write_data(buffer_2, rows_2); +*/ + return ret; +} + int mouse_m913::write_settings(){ // return value int ret = 0; - // prepare data - int rows = sizeof(_c_data_settings) / sizeof(_c_data_settings[0]); - uint8_t buffer[rows][17]; - for( int i = 0; i < rows; i++ ){ - std::copy(std::begin(_c_data_settings[i]), std::end(_c_data_settings[i]), std::begin(buffer[i])); - } + ret += write_button_mapping(mouse_m913::m913_profile::profile_1); + ret += write_dpi_settings(mouse_m913::m913_profile::profile_1); + ret += write_led_settings(mouse_m913::m913_profile::profile_1); - // TODO! modify buffer to include the actual settings - // DPI level 1 - buffer[19][6] = _s_dpi_levels[profile_1][0][0]; - buffer[19][7] = _s_dpi_levels[profile_1][0][1]; - buffer[19][9] = _s_dpi_levels[profile_1][0][2]; - // DPI level 2 - buffer[19][10] = _s_dpi_levels[profile_1][1][0]; - buffer[19][11] = _s_dpi_levels[profile_1][1][1]; - buffer[19][13] = _s_dpi_levels[profile_1][1][2]; - // DPI level 3 - buffer[20][6] = _s_dpi_levels[profile_1][2][0]; - buffer[20][7] = _s_dpi_levels[profile_1][2][1]; - buffer[20][9] = _s_dpi_levels[profile_1][2][2]; - // DPI level 4 - buffer[20][10] = _s_dpi_levels[profile_1][3][0]; - buffer[20][11] = _s_dpi_levels[profile_1][3][1]; - buffer[20][12] = _s_dpi_levels[profile_1][3][2]; - // DPI level 5 - buffer[21][6] = _s_dpi_levels[profile_1][4][0]; - buffer[21][7] = _s_dpi_levels[profile_1][4][1]; - buffer[21][9] = _s_dpi_levels[profile_1][4][2]; - - // button mapping, two buttons per packet - for( int i=0; i<16; i+=2 ){ - int j = 11+(i/2); - - buffer[j][6] = _s_keymap_data[profile_1][i][0]; - buffer[j][7] = _s_keymap_data[profile_1][i][1]; - buffer[j][8] = _s_keymap_data[profile_1][i][2]; - buffer[j][9] = _s_keymap_data[profile_1][i][3]; - - buffer[j][10] = _s_keymap_data[profile_1][i+1][0]; - buffer[j][11] = _s_keymap_data[profile_1][i+1][1]; - buffer[j][12] = _s_keymap_data[profile_1][i+1][2]; - buffer[j][13] = _s_keymap_data[profile_1][i+1][3]; - } - - // TODO! remove, print hexdump of buffer - /* - for( int i = 0; i < rows; i++ ){ - std::cout << i << "\t: "; - for( int j=0; j < 17; j++ ){ - std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)buffer[i][j] << " "; - } - std::cout << "\n"; - } - */ - - - // send data - uint8_t buffer_in[17]; // holds the received data - int received; // how many bytes were actually received - for( int i = 0; i < rows; i++ ){ - ret += libusb_control_transfer( _i_handle, 0x21, 0x09, 0x0308, 0x0001, buffer[i], 17, 1000 ); - ret += libusb_interrupt_transfer( _i_handle, 0x82, buffer_in, 17, &received, 1000 ); - } + // TODO! profile 2 return ret; }