Skip to content

Commit

Permalink
Add initial backend for the M601
Browse files Browse the repository at this point in the history
  • Loading branch information
dokutan committed Dec 14, 2023
1 parent 3d9d72e commit 3a2675f
Show file tree
Hide file tree
Showing 14 changed files with 813 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ target_sources(mouse_m908
include/generic/readers.cpp
include/generic/setters.cpp
include/generic/writers.cpp
include/m601/constructor.cpp
include/m601/data.cpp
include/m601/getters.cpp
include/m601/helpers.cpp
include/m601/mouse_m607.h
include/m601/readers.cpp
include/m601/setters.cpp
include/m601/writers.cpp
include/m607/constructor.cpp
include/m607/data.cpp
include/m607/getters.cpp
Expand Down
5 changes: 5 additions & 0 deletions documentation/how-to-add-a-new-device.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ This document contains a list of thing that need to be changed or added when add
- documentation:
- README (supported models)
- create new config in examples/

## Adding support for mice with a different protocol
In addition to the steps mentioned above:
- Implement the open/close mouse methods in helpers.cpp
- Optionally implement load_settings() and update the main function
46 changes: 46 additions & 0 deletions include/m601/constructor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.
*
*/

#include "../rd_mouse.h"

// Constructor, set the default settings
mouse_m601::mouse_m601(){

//default settings
_s_profile = profile_1;
_s_scrollspeeds.fill( 0x01 );
_s_lightmodes.fill( lightmode_static );
_s_colors.fill( {0xff, 0xff, 0xff} );
_s_brightness_levels.fill( 0x03 );
_s_speed_levels.fill( 0x08 );

// dpi
_s_dpi_enabled.fill( {true, true, true, true, true} );
_s_dpi_levels.fill( {{ {0x04, 0x00}, {0x16, 0x00}, {0x2d, 0x00}, {0x43, 0x00}, {0x8c, 0x00} }} );

// // button mapping
// for( int i = 0; i < 5; i++ ){
// for( int j = 0; j < 8; j++ ){
// _s_keymap_data[i][j][0] = _c_data_settings_3[35+(8*i)+j][8];
// _s_keymap_data[i][j][1] = _c_data_settings_3[35+(8*i)+j][9];
// _s_keymap_data[i][j][2] = _c_data_settings_3[35+(8*i)+j][10];
// _s_keymap_data[i][j][3] = _c_data_settings_3[35+(8*i)+j][11];
// }
// }
_s_report_rates.fill( r_125Hz );
}
116 changes: 116 additions & 0 deletions include/m601/data.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* 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.
*
*/

/*
* This file contains internal constants and lookup tables
*/

#include "../rd_mouse.h"

const std::string mouse_m601::_c_name = "601";

// usb device vars
const uint16_t mouse_m601::_c_mouse_vid = 0x258a;
const uint16_t mouse_m601::_c_mouse_pid = 0x1007;

// Names of the physical buttons, TODO!
std::map< int, std::string > mouse_m601::_c_button_names = {
{ 0, "button_left" },
{ 1, "button_right" },
{ 2, "button_middle" },
{ 3, "button_forward" },
{ 4, "button_backward" },
{ 5, "button_dpi" },
{ 6, "button_lightmode" },
{ 7, "scroll_up" },
{ 8, "scroll_down" } };

// Mapping of real DPI values to bytecode
std::map< unsigned int, std::array<uint8_t, 2> > mouse_m601::_c_dpi_codes = {
{ 100, {0x02, 0x00} },
{ 200, {0x04, 0x00} },
{ 300, {0x06, 0x00} },
{ 400, {0x08, 0x00} },
{ 500, {0x0b, 0x00} },
{ 600, {0x0d, 0x00} },
{ 700, {0x0f, 0x00} },
{ 800, {0x12, 0x00} },
{ 900, {0x14, 0x00} },
{ 1000, {0x16, 0x00} },
{ 1100, {0x19, 0x00} },
{ 1200, {0x1b, 0x00} },
{ 1300, {0x1d, 0x00} },
{ 1400, {0x20, 0x00} },
{ 1500, {0x22, 0x00} },
{ 1600, {0x24, 0x00} },
{ 1700, {0x27, 0x00} },
{ 1800, {0x29, 0x00} },
{ 1900, {0x2b, 0x00} },
{ 2000, {0x2e, 0x00} },
{ 2100, {0x30, 0x00} },
{ 2200, {0x32, 0x00} },
{ 2300, {0x34, 0x00} },
{ 2400, {0x37, 0x00} },
{ 2500, {0x39, 0x00} },
{ 2600, {0x3b, 0x00} },
{ 2700, {0x3e, 0x00} },
{ 2800, {0x40, 0x00} },
{ 2900, {0x42, 0x00} },
{ 3000, {0x45, 0x00} },
{ 3100, {0x47, 0x00} },
{ 3200, {0x49, 0x00} },
{ 3300, {0x4c, 0x00} },
{ 3400, {0x4e, 0x00} },
{ 3500, {0x50, 0x00} },
{ 3600, {0x53, 0x00} },
{ 3700, {0x55, 0x00} },
{ 3800, {0x57, 0x00} },
{ 3900, {0x5a, 0x00} },
{ 4000, {0x5c, 0x00} },
{ 4100, {0x5e, 0x00} },
{ 4200, {0x61, 0x00} },
{ 4300, {0x63, 0x00} },
{ 4400, {0x65, 0x00} },
{ 4500, {0x68, 0x00} },
{ 4600, {0x6a, 0x00} },
{ 4700, {0x6c, 0x00} },
{ 4800, {0x6f, 0x00} },
{ 4900, {0x71, 0x00} },
{ 5000, {0x73, 0x00} },
{ 5200, {0x3b, 0x01} },
{ 5400, {0x3e, 0x01} },
{ 5600, {0x40, 0x01} },
{ 5800, {0x42, 0x01} },
{ 6000, {0x45, 0x01} },
{ 6200, {0x47, 0x01} },
{ 6400, {0x49, 0x01} },
{ 6600, {0x4c, 0x01} },
{ 6800, {0x4e, 0x01} },
{ 7000, {0x50, 0x01} },
{ 7200, {0x53, 0x01} }
};

//usb data packets
uint8_t mouse_m601::_c_data_s_profile[6][16] = {
{0x02, 0xf3, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0xf1, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0xf1, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0xf1, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0xf1, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0xf1, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
};
21 changes: 21 additions & 0 deletions include/m601/getters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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.
*
*/

#include "../rd_mouse.h"

// TODO implement getters
175 changes: 175 additions & 0 deletions include/m601/helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* 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.
*
*/

#include "../rd_mouse.h"

//helper functions

//init libusb and open mouse
int mouse_m601::open_mouse(){

//vars
int res = 0;

//libusb init
res = libusb_init( NULL );
if( res < 0 ){
return res;
}

//open device
_i_handle = libusb_open_device_with_vid_pid( NULL, _c_mouse_vid, _c_mouse_pid );
if( !_i_handle ){
return 1;
}

if( _i_detach_kernel_driver ){
//detach kernel driver on interface 0 if active
if( libusb_kernel_driver_active( _i_handle, 0 ) ){
res += libusb_detach_kernel_driver( _i_handle, 0 );
if( res == 0 ){
_i_detached_driver_0 = true;
} else{
return res;
}
}
}

//claim interface 0
res += libusb_claim_interface( _i_handle, 0 );
if( res != 0 ){
return res;
}

return res;
}

// init libusb and open mouse by bus and device
int mouse_m601::open_mouse_bus_device( uint8_t bus, uint8_t device ){

//vars
int res = 0;

//libusb init
res = libusb_init( NULL );
if( res < 0 ){
return res;
}

//open device (_i_handle)
libusb_device **dev_list; // device list
ssize_t num_devs = libusb_get_device_list(NULL, &dev_list); //get device list

if( num_devs < 0 )
return 1;

for( ssize_t i = 0; i < num_devs; i++ ){

// check if correct bus and device
if( bus == libusb_get_bus_number( dev_list[i] ) &&
device == libusb_get_device_address( dev_list[i] ) ){

// open device
if( libusb_open( dev_list[i], &_i_handle ) != 0 ){
return 1;
} else{
break;
}

}

}

//free device list, unreference devices
libusb_free_device_list( dev_list, 1 );


if( _i_detach_kernel_driver ){
//detach kernel driver on interface 0 if active
if( libusb_kernel_driver_active( _i_handle, 0 ) ){
res += libusb_detach_kernel_driver( _i_handle, 0 );
if( res == 0 ){
_i_detached_driver_0 = true;
} else{
return res;
}
}
}

//claim interface 0
res += libusb_claim_interface( _i_handle, 0 );
if( res != 0 ){
return res;
}

return res;
}

//close mouse
int mouse_m601::close_mouse(){

//release interface 0
libusb_release_interface( _i_handle, 0 );

//attach kernel driver for interface 0
if( _i_detached_driver_0 ){
libusb_attach_kernel_driver( _i_handle, 0 );
}

//exit libusb
libusb_exit( NULL );

return 0;
}

// print current configuration
int mouse_m601::print_settings( std::ostream& output ){
// print configuration, TODO
output << "# mouse_m601::print_settings() is not implemented.\n";
return 0;
}

// Load the settings from a config file, TODO implement
int mouse_m601::load_settings( std::string& config_path ){
return 0;
}

int mouse_m601::_i_decode_dpi( std::array<uint8_t, 2>& 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 );
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];
conversion_stream << std::setfill(' ') << std::setw(0) << std::dec;

dpi_string = conversion_stream.str();

return 0;
}
Loading

0 comments on commit 3a2675f

Please sign in to comment.