mouse_m908/include/mouse_m908.h

306 lines
9 KiB
C
Raw Normal View History

2019-11-08 17:10:30 -07: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.
*
*/
//main class
#ifndef MOUSE_M908
#define MOUSE_M908
2020-04-19 06:51:05 -06:00
#include <libusb.h>
2019-11-08 17:10:30 -07:00
#include <map>
#include <array>
#include <string>
#include <algorithm>
#include <exception>
2019-11-30 16:01:15 -07:00
#include <regex>
2019-12-07 17:52:41 -07:00
#include <fstream>
2020-04-19 06:53:31 -06:00
#include <sstream>
2019-12-07 17:52:41 -07:00
#include <utility>
2019-11-08 17:10:30 -07:00
2020-05-05 14:50:31 -06:00
/**
* The main class representing the M908 mouse.
* This class has member functions to open, close and apply settings to the mouse.
*
* There are 3 main types of functions:
* - set_*: setters
* - get_*: getters
* - write_*: write the settings to the mouse
*
* Therefore the general procedure when changing settings on the mouse is as follows:
* 1. open_mouse() or open_mouse_bus_device()
* 2. set_* (this step only changes the internal state of the class)
* 3. write_* (this step sends the internal state of the class to the mouse)
* 4. close_mouse()
*/
2019-11-08 17:10:30 -07:00
class mouse_m908{
public:
2020-05-05 14:50:31 -06:00
// constructor
2019-11-08 17:10:30 -07:00
mouse_m908();
2020-05-08 15:17:44 -06:00
2020-05-05 14:50:31 -06:00
// enums
/// The available profiles
2019-11-08 17:10:30 -07:00
enum m908_profile{
profile_1 = 0,
profile_2 = 1,
profile_3 = 2,
profile_4 = 3,
profile_5 = 4,
};
2020-05-05 14:50:31 -06:00
/// The available led modes
2019-11-08 17:10:30 -07:00
enum m908_lightmode{
lightmode_breathing,
lightmode_rainbow,
lightmode_static,
lightmode_wave,
lightmode_alternating,
lightmode_reactive,
lightmode_flashing,
lightmode_off,
};
2020-05-05 14:50:31 -06:00
/// The available USB report rates (polling rates)
2019-11-11 15:41:35 -07:00
enum m908_report_rate{
r_125Hz,
r_250Hz,
r_500Hz,
r_1000Hz
};
2019-11-08 17:10:30 -07:00
2020-05-08 15:17:44 -06:00
2019-11-08 17:10:30 -07:00
//setter functions
2020-05-08 15:17:44 -06:00
/** Set the currently active profile
*/
2019-11-08 17:10:30 -07:00
int set_profile( m908_profile profile );
2020-05-08 15:17:44 -06:00
/** Set the scrollspeed for the specified profile
* \see _scrollspeed_min
* \see _scrollspeed_max
* \return 0 if successful, 1 if out of bounds
*/
2019-11-08 17:10:30 -07:00
int set_scrollspeed( m908_profile profile, uint8_t speed );
2020-05-08 15:17:44 -06:00
/** Set the led mode for the specified profile
* \see m908_lightmode
* \return 0 if successful
*/
2019-11-08 17:10:30 -07:00
int set_lightmode( m908_profile profile, m908_lightmode lightmode );
2020-05-08 15:17:44 -06:00
/** Set the led color for the specified profile
* \param color color as {r, g, b}
* \return 0 if successful
*/
2019-11-08 17:10:30 -07:00
int set_color( m908_profile profile, std::array<uint8_t, 3> color );
2020-05-08 15:17:44 -06:00
/** Set the led brightness for the specified profile
* \see _brightness_min
* \see _brightness_max
* \return 0 if successful, 1 if out of bounds
*/
2019-11-08 17:10:30 -07:00
int set_brightness( m908_profile profile, uint8_t brightness );
2020-05-08 15:17:44 -06:00
/** Set the led animation speed for the specified profile
* \see _speed_min
* \see _speed_max
* \return 0 if successful, 1 if out of bounds
*/
2019-11-08 17:10:30 -07:00
int set_speed( m908_profile profile, uint8_t speed );
2020-05-08 15:17:44 -06:00
/** Enables/Disables a dpi level for the specified profile
* \see _level_min
* \see _level_max
* \return 0 if successful, 1 if out of bounds
*/
2019-11-08 17:10:30 -07:00
int set_dpi_enable( m908_profile profile, int level, bool enabled );
2020-05-08 15:17:44 -06:00
/** Set the value of a dpi level for the specified profile
* \see _dpi_min
* \see _dpi_max
* \see _level_min
* \see _level_max
* \return 0 if successful, 1 if out of bounds
*/
2019-11-08 17:10:30 -07:00
int set_dpi( m908_profile profile, int level, uint8_t dpi );
2020-05-08 15:17:44 -06:00
/** Set a mapping for a button for the specified profile
* \param mapping 4 bytes for the usb data packets
* \return 0 if successful
*/
int set_key_mapping( m908_profile profile, int key, std::array<uint8_t, 4> mapping );
2020-05-08 15:17:44 -06:00
/** Set a mapping for a button for the specified profile
* \param mapping button name (see keymap.md)
* \return 0 if successful, 1 if mapping is invalid
*/
2019-11-08 17:10:30 -07:00
int set_key_mapping( m908_profile profile, int key, std::string mapping );
2020-05-08 15:17:44 -06:00
/** Set the USB poll rate for the specified profile
* \see m908_report_rate
* \return 0 if successful
*/
2019-11-11 15:41:35 -07:00
int set_report_rate( m908_profile profile, m908_report_rate report_rate );
2020-05-08 15:17:44 -06:00
/** Load the macro from the specified file into the specified slot
* \param macro_number macro slot (1-15)
* \return 0 if successful
*/
2019-12-07 17:52:41 -07:00
int set_macro( int macro_number, std::string file );
2020-05-08 15:17:44 -06:00
/** Set how many times the specified macro should be repeated
* \param macro_number macro slot (1-15)
* \return 0 if successful
*/
int set_macro_repeat( int macro_number, uint8_t repeat );
2020-05-08 15:17:44 -06:00
/** Set whether to try to detach the kernel driver when opening the mouse
*/
int set_detach_kernel_driver( bool detach_kernel_driver );
2019-11-08 17:10:30 -07:00
2020-05-08 15:17:44 -06:00
2019-11-08 17:10:30 -07:00
//getter functions
m908_profile get_profile();
uint8_t get_scrollspeed( m908_profile profile );
m908_lightmode get_lightmode( m908_profile profile );
void get_color( m908_profile profile, std::array<uint8_t, 3> &color );
uint8_t get_brightness( m908_profile profile );
uint8_t get_speed( m908_profile profile );
bool get_dpi_enable( m908_profile profile, int level );
uint8_t get_dpi( m908_profile profile, int level );
2019-11-11 15:41:35 -07:00
m908_report_rate get_report_rate( m908_profile profile );
uint8_t get_macro_repeat( int macro_number );
2019-11-08 17:10:30 -07:00
2020-05-08 15:17:44 -06:00
2019-11-08 17:10:30 -07:00
//writer functions (apply settings to mouse)
2020-05-05 14:50:31 -06:00
/** Write the currently active profile to the mouse
* \return 0 if successful
*/
2019-11-08 17:10:30 -07:00
int write_profile();
2020-05-05 14:50:31 -06:00
/** Write the settings (leds, button mapping, dpi, etc.) to the mouse
* \return 0 if successful
*/
2019-11-08 17:10:30 -07:00
int write_settings();
2020-05-05 14:50:31 -06:00
/** Write a macro to the mouse
* \return 0 if successful
*/
2019-12-07 17:52:41 -07:00
int write_macro( int macro_number );
2020-05-05 14:50:31 -06:00
/** Write the number of repeats for a macro to the mouse
* \return 0 if successful
*/
int write_macro_repeat( int macro_number );
2019-11-08 17:10:30 -07:00
2020-05-08 15:17:44 -06:00
2019-11-08 17:10:30 -07:00
//helper functions
2020-05-05 14:50:31 -06:00
/** Init libusb and open the mouse by its USB VID and PID
* \return 0 if successful
*/
2019-11-08 17:10:30 -07:00
int open_mouse();
2020-05-05 14:50:31 -06:00
/** Init libusb and open the mouse by the USB bus and device adress
* \return 0 if successful
*/
2020-02-07 20:34:17 -07:00
int open_mouse_bus_device( uint8_t bus, uint8_t device );
2020-05-05 14:50:31 -06:00
/** Close the mouse and libusb
* \return 0 if successful (always at the moment)
*/
2019-11-08 17:10:30 -07:00
int close_mouse();
private:
// whether to detach kernel driver
bool _detach_kernel_driver = true;
2019-11-08 17:10:30 -07:00
//usb device vars
2020-05-08 15:17:44 -06:00
static const uint16_t _mouse_vid;
static const uint16_t _mouse_pid;
2019-11-08 17:10:30 -07:00
libusb_device_handle* _handle;
bool _detached_driver_0 = false;
bool _detached_driver_1 = false;
bool _detached_driver_2 = false;
2020-05-08 15:17:44 -06:00
//setting min and max values
static const uint8_t _scrollspeed_min, _scrollspeed_max;
static const uint8_t _brightness_min, _brightness_max;
static const uint8_t _speed_min, _speed_max;
static const uint8_t _level_min, _level_max;
static const uint8_t _dpi_min, _dpi_max;
2019-11-08 17:10:30 -07:00
//setting vars
m908_profile _profile;
std::array<uint8_t, 5> _scrollspeeds;
std::array<m908_lightmode, 5> _lightmodes;
std::array<std::array<uint8_t, 3>, 5> _colors;
std::array<uint8_t, 5> _brightness_levels;
std::array<uint8_t, 5> _speed_levels;
std::array<std::array<bool, 5>, 5> _dpi_enabled;
std::array<std::array<uint8_t, 5>, 5> _dpi_levels;
std::array<std::array<std::array<uint8_t, 4>, 20>, 5> _keymap_data;
2019-11-11 15:41:35 -07:00
std::array<m908_report_rate, 5> _report_rates;
2019-12-07 17:52:41 -07:00
std::array<std::array<uint8_t, 256>, 15> _macro_data;
std::array<uint8_t, 15> _macro_repeat;
2019-11-08 17:10:30 -07:00
//mapping of button names to values
2020-05-08 15:17:44 -06:00
/// Values/keycodes of mouse buttons and special button functions
static std::map< std::string, std::array<uint8_t, 3> > _keycodes;
/// Values of keyboard modifiers
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;
2019-11-08 17:10:30 -07:00
//usb data packets
2020-05-08 15:17:44 -06:00
/// Used for changing the active profile
2020-04-08 07:39:30 -06:00
static uint8_t _data_profile[6][16];
2020-05-08 15:17:44 -06:00
/// Used for sending the settings, part 1/3
2020-04-08 07:39:30 -06:00
static uint8_t _data_settings_1[15][16];
2020-05-08 15:17:44 -06:00
/// Used for sending the settings, part 2/3
2019-11-08 17:10:30 -07:00
static uint8_t _data_settings_2[64];
2020-05-08 15:17:44 -06:00
/// Used for sending the settings, part 3/3
2020-04-08 07:39:30 -06:00
static uint8_t _data_settings_3[140][16];
2020-05-08 15:17:44 -06:00
/// Used for sending a macro, part 1/3
2019-12-07 17:52:41 -07:00
static uint8_t _data_macros_1[16];
2020-05-08 15:17:44 -06:00
/// Used for sending a macro, part 2/3
2019-12-07 17:52:41 -07:00
static uint8_t _data_macros_2[256];
2020-05-08 15:17:44 -06:00
/// Used for sending a macro, part 3/3
2019-12-07 17:52:41 -07:00
static uint8_t _data_macros_3[16];
2020-05-08 15:17:44 -06:00
/// Lookup table for used when specifying which slot to send a macro to
2019-12-07 17:52:41 -07:00
static uint8_t _data_macros_codes[15][2];
2020-05-08 15:17:44 -06:00
/// Used to send the number repeats for a macro
static uint8_t _data_macros_repeat[16];
2019-11-08 17:10:30 -07:00
};
2020-04-08 07:39:30 -06:00
/* the files are now compiled individually
2019-11-08 17:10:30 -07:00
#include "data.cpp"
#include "constructor.cpp"
#include "helpers.cpp"
#include "getters.cpp"
#include "setters.cpp"
#include "writers.cpp"
2020-04-08 07:39:30 -06:00
*/
2019-11-08 17:10:30 -07:00
#endif