1
0
forked from drath/libratbag
Files
libratbag-plus/src/driver-marsgaming/marsgaming-commit.c
2023-04-14 14:23:28 +03:00

148 lines
3.9 KiB
C

#include "marsgaming-commit.h"
#include "marsgaming-definitions.h"
#include "marsgaming-probe.h"
#include "marsgaming-query.h"
#include "marsgaming-protocol.h"
#include "marsgaming-buttons.h"
#include "marsgaming-command.h"
static int
marsgaming_commit_button(struct ratbag_button *button)
{
struct marsgaming_profile_drv_data *profile_data = marsgaming_profile_get_drv_data(button->profile);
struct marsgaming_button_info *button_info = &profile_data->buttons_report.buttons[button->index];
const struct marsgaming_optional_button_info button_data = marsgaming_button_of_type(button);
if (button_data.is_present)
*button_info = button_data.button_info;
return 0;
}
static int
marsgaming_commit_led(struct ratbag_led *led)
{
if (!led->dirty)
return 0;
marsgaming_command_profile_set_led(led);
return 0;
}
static int
marsgaming_commit_profile_report_rate(struct ratbag_profile *profile)
{
if (!profile->rate_dirty)
return 0;
uint8_t polling_interval = 1000 / ratbag_profile_get_report_rate(profile);
marsgaming_command_profile_set_polling_interval(profile, polling_interval);
return 0;
}
static int
marsgaming_commit_profile_buttons(struct ratbag_profile *profile)
{
bool buttons_dirty = false;
struct ratbag_button *button;
ratbag_profile_for_each_button(profile, button) {
if (button->dirty) {
buttons_dirty = true;
break;
}
}
if (!buttons_dirty)
return 0;
ratbag_profile_for_each_button(profile, button) {
if (!button->dirty)
continue;
marsgaming_commit_button(button);
}
marsgaming_command_profile_set_buttons(profile);
return 0;
}
static int
marsgaming_commit_profile_leds(struct ratbag_profile *profile)
{
struct ratbag_led *led;
ratbag_profile_for_each_led(profile, led) {
marsgaming_commit_led(led);
}
return 0;
}
static int
marsgaming_commit_profile_resolutions(struct ratbag_profile *profile)
{
bool resolutions_dirty = false;
struct ratbag_resolution *resolution;
ratbag_profile_for_each_resolution(profile, resolution) {
if (resolution->dirty) {
resolutions_dirty = true;
break;
}
}
if (!resolutions_dirty)
return 0;
struct marsgaming_profile_drv_data *profile_data = marsgaming_profile_get_drv_data(profile);
ratbag_profile_for_each_resolution(profile, resolution) {
if (!resolution->dirty)
continue;
// Modify the drv_data report so we can send it to the mouse
struct marsgaming_report_resolution_info *resolution_info = &profile_data->resolutions_report.resolutions[resolution->index];
resolution_info->enabled = true;
resolution_info->x_res = resolution->dpi_x / MARSGAMING_MM4_RES_SCALING;
resolution_info->y_res = resolution->dpi_y / MARSGAMING_MM4_RES_SCALING;
resolution_info->led_bitset = ~((~0x0U) << resolution->index);
}
marsgaming_command_profile_set_resolutions(profile);
return 0;
}
static int
marsgaming_commit_profile(struct ratbag_profile *profile)
{
if (!profile->dirty)
return 0;
marsgaming_commit_profile_report_rate(profile);
marsgaming_commit_profile_resolutions(profile);
marsgaming_commit_profile_buttons(profile);
marsgaming_commit_profile_leds(profile);
return 0;
}
static int
marsgaming_commit_profiles(struct ratbag_device *device)
{
uint8_t current_profile = marsgaming_query_current_profile(device);
struct ratbag_profile *profile;
ratbag_device_for_each_profile(device, profile) {
// The user could change the current profile between probe and commit
// We need to modify the active profile for the led changes to take effect
// Unsure how this will interact with internals of ratbag
profile->is_active = current_profile == profile->index;
marsgaming_commit_profile(profile);
}
return 0;
}
int
marsgaming_commit(struct ratbag_device *device)
{
ratbag_open_hidraw(device);
marsgaming_commit_profiles(device);
marsgaming_release_device(device);
return 0;
}
int
marsgaming_set_active_profile(struct ratbag_device *device, unsigned int profile)
{
marsgaming_command_set_current_profile(device, profile);
return 0;
}