diff --git a/src/driver-etekcity.c b/src/driver-etekcity.c index ebb5e1d5..91a18d87 100644 --- a/src/driver-etekcity.c +++ b/src/driver-etekcity.c @@ -324,79 +324,6 @@ etekcity_button_to_action(struct ratbag_profile *profile, return etekcity_raw_to_button_action(data); } -static void -etekcity_read_profile(struct ratbag_profile *profile, unsigned int index) -{ - struct ratbag_device *device = profile->device; - struct etekcity_data *drv_data; - struct ratbag_resolution *resolution; - struct etekcity_settings_report *setting_report; - uint8_t *buf; - unsigned int report_rate; - int dpi_x, dpi_y, hz; - int rc; - - assert(index <= ETEKCITY_PROFILE_MAX); - - drv_data = ratbag_get_drv_data(device); - - setting_report = &drv_data->settings[index]; - buf = (uint8_t*)setting_report; - etekcity_set_config_profile(device, index, ETEKCITY_CONFIG_SETTINGS); - rc = ratbag_hidraw_raw_request(device, ETEKCITY_REPORT_ID_SETTINGS, - buf, ETEKCITY_REPORT_SIZE_SETTINGS, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - - if (rc < ETEKCITY_REPORT_SIZE_SETTINGS) - return; - - /* first retrieve the report rate, it is set per profile */ - switch (setting_report->report_rate) { - case 0x00: report_rate = 125; break; - case 0x01: report_rate = 250; break; - case 0x02: report_rate = 500; break; - case 0x03: report_rate = 1000; break; - default: - log_error(device->ratbag, - "error while reading the report rate of the mouse (0x%02x)\n", - buf[26]); - report_rate = 0; - } - - ratbag_profile_for_each_resolution(profile, resolution) { - dpi_x = setting_report->xres[resolution->index] * 50; - dpi_y = setting_report->yres[resolution->index] * 50; - hz = report_rate; - if (!(setting_report->dpi_mask & (1 << resolution->index))) { - /* the profile is disabled, overwrite it */ - dpi_x = 0; - dpi_y = 0; - hz = 0; - } - - ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); - ratbag_resolution_set_cap(resolution, - RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); - resolution->is_active = (resolution->index == setting_report->current_dpi); - } - - - buf = drv_data->profiles[index]; - etekcity_set_config_profile(device, index, ETEKCITY_CONFIG_KEY_MAPPING); - rc = ratbag_hidraw_raw_request(device, ETEKCITY_REPORT_ID_KEY_MAPPING, - buf, ETEKCITY_REPORT_SIZE_PROFILE, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - - msleep(10); - - if (rc < ETEKCITY_REPORT_SIZE_PROFILE) - return; - - log_raw(device->ratbag, "profile: %d %s:%d\n", - buf[2], - __FILE__, __LINE__); -} - static int etekcity_write_profile(struct ratbag_profile *profile) { @@ -491,6 +418,82 @@ etekcity_read_button(struct ratbag_button *button) } } +static void +etekcity_read_profile(struct ratbag_profile *profile) +{ + struct ratbag_device *device = profile->device; + struct etekcity_data *drv_data; + struct ratbag_resolution *resolution; + struct ratbag_button *button; + struct etekcity_settings_report *setting_report; + uint8_t *buf; + unsigned int report_rate; + int dpi_x, dpi_y, hz; + int rc; + + assert(profile->index <= ETEKCITY_PROFILE_MAX); + + drv_data = ratbag_get_drv_data(device); + + setting_report = &drv_data->settings[profile->index]; + buf = (uint8_t*)setting_report; + etekcity_set_config_profile(device, profile->index, ETEKCITY_CONFIG_SETTINGS); + rc = ratbag_hidraw_raw_request(device, ETEKCITY_REPORT_ID_SETTINGS, + buf, ETEKCITY_REPORT_SIZE_SETTINGS, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + + if (rc < ETEKCITY_REPORT_SIZE_SETTINGS) + return; + + /* first retrieve the report rate, it is set per profile */ + switch (setting_report->report_rate) { + case 0x00: report_rate = 125; break; + case 0x01: report_rate = 250; break; + case 0x02: report_rate = 500; break; + case 0x03: report_rate = 1000; break; + default: + log_error(device->ratbag, + "error while reading the report rate of the mouse (0x%02x)\n", + buf[26]); + report_rate = 0; + } + + ratbag_profile_for_each_resolution(profile, resolution) { + dpi_x = setting_report->xres[resolution->index] * 50; + dpi_y = setting_report->yres[resolution->index] * 50; + hz = report_rate; + if (!(setting_report->dpi_mask & (1 << resolution->index))) { + /* the profile is disabled, overwrite it */ + dpi_x = 0; + dpi_y = 0; + hz = 0; + } + + ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); + ratbag_resolution_set_cap(resolution, + RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); + resolution->is_active = (resolution->index == setting_report->current_dpi); + } + + ratbag_profile_for_each_button(profile, button) + etekcity_read_button(button); + + buf = drv_data->profiles[profile->index]; + etekcity_set_config_profile(device, profile->index, ETEKCITY_CONFIG_KEY_MAPPING); + rc = ratbag_hidraw_raw_request(device, ETEKCITY_REPORT_ID_KEY_MAPPING, + buf, ETEKCITY_REPORT_SIZE_PROFILE, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + + msleep(10); + + if (rc < ETEKCITY_REPORT_SIZE_PROFILE) + return; + + log_raw(device->ratbag, "profile: %d %s:%d\n", + buf[2], + __FILE__, __LINE__); +} + static int etekcity_write_macro(struct ratbag_button *button, const struct ratbag_button_action *action) @@ -661,6 +664,9 @@ etekcity_probe(struct ratbag_device *device) ETEKCITY_BUTTON_MAX + 1, ETEKCITY_LED); + ratbag_device_for_each_profile(device, profile) + etekcity_read_profile(profile); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS); @@ -706,10 +712,8 @@ struct ratbag_driver etekcity_driver = { .id = "etekcity", .probe = etekcity_probe, .remove = etekcity_remove, - .read_profile = etekcity_read_profile, .write_profile = etekcity_write_profile, .set_active_profile = etekcity_set_current_profile, - .read_button = etekcity_read_button, .write_button = etekcity_write_button, .write_resolution_dpi = etekcity_write_resolution_dpi, }; diff --git a/src/driver-gskill.c b/src/driver-gskill.c index ea08922b..d212cba2 100644 --- a/src/driver-gskill.c +++ b/src/driver-gskill.c @@ -972,67 +972,6 @@ gskill_write_button_macro(struct ratbag_device *device, return 0; } - -static int -gskill_probe(struct ratbag_device *device) -{ - struct gskill_data *drv_data = NULL; - struct ratbag_profile *profile; - unsigned int active_idx; - int ret; - - ret = ratbag_open_hidraw(device); - if (ret) - return ret; - - drv_data = zalloc(sizeof(*drv_data)); - ratbag_set_drv_data(device, drv_data); - - ret = gskill_get_firmware_version(device); - if (ret < 0) - goto err; - - log_debug(device->ratbag, - "Firmware version: %d\n", ret); - - ret = gskill_get_profile_count(device); - if (ret < 0) - goto err; - drv_data->profile_count = ret; - - ratbag_device_init_profiles(device, GSKILL_PROFILE_MAX, GSKILL_NUM_DPI, - GSKILL_BUTTON_MAX, GSKILL_NUM_LED); - - ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_QUERY_CONFIGURATION); - ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON); - ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY); - ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS); - ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_DISABLE_PROFILE); - - ret = gskill_get_active_profile_idx(device); - if (ret < 0) - goto err; - - active_idx = ret; - list_for_each(profile, &device->profiles, link) { - if (profile->index == active_idx) { - profile->is_active = true; - break; - } - } - - return 0; - -err: - if (drv_data) { - ratbag_set_drv_data(device, NULL); - free(drv_data); - } - - ratbag_close_hidraw(device); - return ret; -} - static void gskill_read_resolutions(struct ratbag_profile *profile, struct gskill_profile_report *report) @@ -1083,7 +1022,7 @@ gskill_read_profile_name(struct ratbag_device *device, } static void -gskill_read_profile(struct ratbag_profile *profile, unsigned int index) +gskill_read_profile(struct ratbag_profile *profile) { struct ratbag_device *device = profile->device; struct gskill_data *drv_data = ratbag_get_drv_data(device); @@ -1092,7 +1031,7 @@ gskill_read_profile(struct ratbag_profile *profile, unsigned int index) uint8_t checksum; int rc, retries; - if (index >= drv_data->profile_count) { + if (profile->index >= drv_data->profile_count) { profile->is_enabled = false; return; } @@ -1106,7 +1045,7 @@ gskill_read_profile(struct ratbag_profile *profile, unsigned int index) * mouse we're doing something wrong. */ for (retries = 0; retries < 3; retries++) { - rc = gskill_select_profile(device, index, false); + rc = gskill_select_profile(device, profile->index, false); if (rc < 0) return; @@ -1124,12 +1063,11 @@ gskill_read_profile(struct ratbag_profile *profile, unsigned int index) return; } - if (report->profile_num == index) + if (report->profile_num == profile->index) break; log_debug(device->ratbag, - "Mouse send wrong profile %d instead of %d, retrying...\n", - profile->index, index); + "Mouse send wrong profile, retrying...\n"); } checksum = gskill_calculate_checksum((uint8_t*)report, sizeof(*report)); @@ -1430,6 +1368,73 @@ gskill_update_profile(struct ratbag_profile *profile) return 0; } +static int +gskill_probe(struct ratbag_device *device) +{ + struct gskill_data *drv_data = NULL; + struct ratbag_profile *profile; + unsigned int active_idx; + int ret; + + ret = ratbag_open_hidraw(device); + if (ret) + return ret; + + drv_data = zalloc(sizeof(*drv_data)); + ratbag_set_drv_data(device, drv_data); + + ret = gskill_get_firmware_version(device); + if (ret < 0) + goto err; + + log_debug(device->ratbag, + "Firmware version: %d\n", ret); + + ret = gskill_get_profile_count(device); + if (ret < 0) + goto err; + drv_data->profile_count = ret; + + ratbag_device_init_profiles(device, GSKILL_PROFILE_MAX, GSKILL_NUM_DPI, + GSKILL_BUTTON_MAX, GSKILL_NUM_LED); + + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_QUERY_CONFIGURATION); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_DISABLE_PROFILE); + + ret = gskill_get_active_profile_idx(device); + if (ret < 0) + goto err; + + active_idx = ret; + ratbag_device_for_each_profile(device, profile) { + struct ratbag_button *button; + + gskill_read_profile(profile); + + ratbag_profile_for_each_button(profile, button) + gskill_read_button(button); + + if (profile->index == active_idx) { + profile->is_active = true; + break; + } + } + + return 0; + +err: + if (drv_data) { + ratbag_set_drv_data(device, NULL); + free(drv_data); + } + + ratbag_close_hidraw(device); + return ret; +} + static int gskill_commit(struct ratbag_device *device) { @@ -1507,8 +1512,6 @@ struct ratbag_driver gskill_driver = { .id = "gskill", .probe = gskill_probe, .remove = gskill_remove, - .read_profile = gskill_read_profile, .commit = gskill_commit, .set_active_profile = gskill_set_active_profile, - .read_button = gskill_read_button, }; diff --git a/src/driver-hidpp10.c b/src/driver-hidpp10.c index 94999c14..e50802ba 100644 --- a/src/driver-hidpp10.c +++ b/src/driver-hidpp10.c @@ -347,9 +347,10 @@ hidpp10drv_set_current_profile(struct ratbag_device *device, unsigned int index) } static void -hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) +hidpp10drv_read_profile(struct ratbag_profile *profile) { struct ratbag_device *device = profile->device; + struct ratbag_button *button; struct hidpp10drv_data *drv_data; struct hidpp10_device *hidpp10; struct hidpp10_profile p = {0}; @@ -360,7 +361,7 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) drv_data = ratbag_get_drv_data(device); hidpp10 = drv_data->dev; - rc = hidpp10_get_profile(hidpp10, index, &p); + rc = hidpp10_get_profile(hidpp10, profile->index, &p); if (rc) return; @@ -400,6 +401,9 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) max = hidpp10_dpi_table_get_max_dpi(hidpp10); ratbag_resolution_set_range(res, min, max); } + + ratbag_profile_for_each_button(profile, button) + hidpp10drv_read_button(button); } static int @@ -531,6 +535,7 @@ hidpp10drv_probe(struct ratbag_device *device) const char *typestr; int device_idx = HIDPP_WIRED_DEVICE_IDX; unsigned int profile_count = 1; + struct ratbag_profile *profile; rc = ratbag_find_hidraw(device, hidpp10drv_test_hidraw); if (rc) @@ -618,6 +623,9 @@ hidpp10drv_probe(struct ratbag_device *device) profile->is_active = true; } + ratbag_device_for_each_profile(device, profile) + hidpp10drv_read_profile(profile); + return 0; err: free(drv_data); @@ -649,8 +657,6 @@ struct ratbag_driver hidpp10_driver = { .id = "hidpp10", .probe = hidpp10drv_probe, .remove = hidpp10drv_remove, - .read_profile = hidpp10drv_read_profile, .set_active_profile = hidpp10drv_set_current_profile, - .read_button = hidpp10drv_read_button, .commit = hidpp10drv_commit, }; diff --git a/src/driver-hidpp20.c b/src/driver-hidpp20.c index 0f2f8d59..9814f772 100644 --- a/src/driver-hidpp20.c +++ b/src/driver-hidpp20.c @@ -831,7 +831,7 @@ hidpp20drv_read_leds(struct ratbag_device *device) } static void -hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index) +hidpp20drv_read_profile_8100(struct ratbag_profile *profile) { struct ratbag_device *device = profile->device; struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); @@ -839,10 +839,10 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index) struct hidpp20_profile *p; int dpi_index = 0xff; - profile->is_enabled = drv_data->profiles->profiles[index].enabled; + profile->is_enabled = drv_data->profiles->profiles[profile->index].enabled; profile->is_active = false; - if ((int)index == hidpp20drv_current_profile(device)) + if ((int)profile->index == hidpp20drv_current_profile(device)) profile->is_active = true; if (profile->is_active) @@ -851,7 +851,7 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index) if (dpi_index < 0) dpi_index = 0xff; - p = &drv_data->profiles->profiles[index]; + p = &drv_data->profiles->profiles[profile->index]; ratbag_profile_for_each_resolution(profile, res) { struct hidpp20_sensor *sensor; @@ -879,18 +879,27 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index) } static void -hidpp20drv_read_profile(struct ratbag_profile *profile, unsigned int index) +hidpp20drv_read_profile(struct ratbag_profile *profile) { struct ratbag_device *device = profile->device; struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); + struct ratbag_led *led; + struct ratbag_button *button; - if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) - return hidpp20drv_read_profile_8100(profile, index); + if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) { + hidpp20drv_read_profile_8100(profile); + } else { + hidpp20drv_read_resolution_dpi(profile); + hidpp20drv_read_special_key_mouse(device); - hidpp20drv_read_resolution_dpi(profile); - hidpp20drv_read_special_key_mouse(device); + profile->is_active = (profile->index == 0); + } - profile->is_active = (index == 0); + ratbag_profile_for_each_led(profile, led) + hidpp20drv_read_led(led); + + ratbag_profile_for_each_button(profile, button) + hidpp20drv_read_button(button); } static int @@ -1159,6 +1168,22 @@ hidpp20drv_remove(struct ratbag_device *device) free(drv_data); } +static void +hidpp20drv_init_device(struct ratbag_device *device, + struct hidpp20drv_data *drv_data) +{ + struct ratbag_profile *profile; + + ratbag_device_init_profiles(device, + drv_data->num_profiles, + drv_data->num_resolutions, + drv_data->num_buttons, + drv_data->num_leds); + + ratbag_device_for_each_profile(device, profile) + hidpp20drv_read_profile(profile); +} + static int hidpp20drv_probe(struct ratbag_device *device) { @@ -1209,11 +1234,7 @@ hidpp20drv_probe(struct ratbag_device *device) if (rc) goto err; - ratbag_device_init_profiles(device, - drv_data->num_profiles, - drv_data->num_resolutions, - drv_data->num_buttons, - drv_data->num_leds); + hidpp20drv_init_device(device, drv_data); return rc; err: @@ -1227,8 +1248,5 @@ struct ratbag_driver hidpp20_driver = { .probe = hidpp20drv_probe, .remove = hidpp20drv_remove, .commit = hidpp20drv_commit, - .read_profile = hidpp20drv_read_profile, .set_active_profile = hidpp20drv_set_current_profile, - .read_button = hidpp20drv_read_button, - .read_led = hidpp20drv_read_led, }; diff --git a/src/driver-logitech-g300.c b/src/driver-logitech-g300.c index b829abeb..0c9d2f25 100644 --- a/src/driver-logitech-g300.c +++ b/src/driver-logitech-g300.c @@ -289,59 +289,6 @@ logitech_g300_set_current_resolution(struct ratbag_device *device, unsigned int return ret == sizeof(buf) ? 0 : ret; } -static void -logitech_g300_read_profile(struct ratbag_profile *profile, unsigned int index) -{ - struct ratbag_device *device = profile->device; - struct logitech_g300_data *drv_data = device->drv_data; - struct logitech_g300_profile_data *pdata; - struct logitech_g300_profile_report *report; - struct ratbag_resolution *resolution; - unsigned int hz; - uint8_t report_id; - int rc; - - assert(index <= LOGITECH_G300_PROFILE_MAX); - - pdata = &drv_data->profile_data[index]; - report = &pdata->report; - - switch (index) { - case 0: report_id = LOGITECH_G300_REPORT_ID_PROFILE_0; break; - case 1: report_id = LOGITECH_G300_REPORT_ID_PROFILE_1; break; - case 2: report_id = LOGITECH_G300_REPORT_ID_PROFILE_2; break; - } - - rc = ratbag_hidraw_raw_request(device, report_id, - (uint8_t*)report, - sizeof(*report), - HID_FEATURE_REPORT, - HID_REQ_GET_REPORT); - - if (rc < (int)sizeof(*report)) { - log_error(device->ratbag, - "Error while requesting profile: %d\n", rc); - return; - } - - hz = logitech_g300_raw_to_frequency(report->frequency); - - ratbag_profile_for_each_resolution(profile, resolution) { - struct logitech_g300_resolution *res = - &report->dpi_levels[resolution->index]; - - resolution->dpi_x = res->dpi * 250; - resolution->dpi_y = res->dpi * 250; - resolution->hz = hz; - resolution->is_default = res->is_default; - resolution->is_active = res->is_default; - - ratbag_resolution_set_range(resolution, - LOGITECH_G300_DPI_MIN, - LOGITECH_G300_DPI_MAX); - } -} - static void logitech_g300_read_button(struct ratbag_button *button) { @@ -397,6 +344,67 @@ logitech_g300_read_led(struct ratbag_led *led) led->color.blue = profile_report->led_blue * 255; } +static void +logitech_g300_read_profile(struct ratbag_profile *profile) +{ + struct ratbag_device *device = profile->device; + struct logitech_g300_data *drv_data = device->drv_data; + struct logitech_g300_profile_data *pdata; + struct logitech_g300_profile_report *report; + struct ratbag_resolution *resolution; + unsigned int hz; + uint8_t report_id; + int rc; + struct ratbag_button *button; + struct ratbag_led *led; + + assert(profile->index <= LOGITECH_G300_PROFILE_MAX); + + pdata = &drv_data->profile_data[profile->index]; + report = &pdata->report; + + switch (profile->index) { + case 0: report_id = LOGITECH_G300_REPORT_ID_PROFILE_0; break; + case 1: report_id = LOGITECH_G300_REPORT_ID_PROFILE_1; break; + case 2: report_id = LOGITECH_G300_REPORT_ID_PROFILE_2; break; + } + + rc = ratbag_hidraw_raw_request(device, report_id, + (uint8_t*)report, + sizeof(*report), + HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + + if (rc < (int)sizeof(*report)) { + log_error(device->ratbag, + "Error while requesting profile: %d\n", rc); + return; + } + + hz = logitech_g300_raw_to_frequency(report->frequency); + + ratbag_profile_for_each_resolution(profile, resolution) { + struct logitech_g300_resolution *res = + &report->dpi_levels[resolution->index]; + + resolution->dpi_x = res->dpi * 250; + resolution->dpi_y = res->dpi * 250; + resolution->hz = hz; + resolution->is_default = res->is_default; + resolution->is_active = res->is_default; + + ratbag_resolution_set_range(resolution, + LOGITECH_G300_DPI_MIN, + LOGITECH_G300_DPI_MAX); + } + + ratbag_profile_for_each_button(profile, button) + logitech_g300_read_button(button); + + ratbag_profile_for_each_led(profile, led) + logitech_g300_read_led(led); +} + static int logitech_g300_test_hidraw(struct ratbag_device *device) { @@ -409,6 +417,7 @@ logitech_g300_probe(struct ratbag_device *device) int rc; struct logitech_g300_data *drv_data = NULL; int active_idx; + struct ratbag_profile *profile; rc = ratbag_find_hidraw(device, logitech_g300_test_hidraw); if (rc) @@ -424,6 +433,9 @@ logitech_g300_probe(struct ratbag_device *device) LOGITECH_G300_BUTTON_MAX + 1, LOGITECH_G300_NUM_LED); + ratbag_device_for_each_profile(device, profile) + logitech_g300_read_profile(profile); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_RESOLUTION); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_PROFILE); @@ -570,9 +582,6 @@ struct ratbag_driver logitech_g300_driver = { .id = "logitech_g300", .probe = logitech_g300_probe, .remove = logitech_g300_remove, - .read_profile = logitech_g300_read_profile, .commit = logitech_g300_commit, .set_active_profile = logitech_g300_set_active_profile, - .read_button = logitech_g300_read_button, - .read_led = logitech_g300_read_led, }; diff --git a/src/driver-roccat.c b/src/driver-roccat.c index a4c68b3f..0479b292 100644 --- a/src/driver-roccat.c +++ b/src/driver-roccat.c @@ -391,83 +391,6 @@ roccat_button_to_action(struct ratbag_profile *profile, return roccat_raw_to_button_action(data); } -static void -roccat_read_profile(struct ratbag_profile *profile, unsigned int index) -{ - struct ratbag_device *device = profile->device; - struct roccat_data *drv_data; - struct ratbag_resolution *resolution; - struct roccat_settings_report *setting_report; - uint8_t *buf; - unsigned int report_rate; - int dpi_x, dpi_y, hz; - int rc; - - assert(index <= ROCCAT_PROFILE_MAX); - - drv_data = ratbag_get_drv_data(device); - - setting_report = &drv_data->settings[index]; - buf = (uint8_t*)setting_report; - roccat_set_config_profile(device, index, ROCCAT_CONFIG_SETTINGS); - rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_SETTINGS, - buf, ROCCAT_REPORT_SIZE_SETTINGS, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - - if (rc < ROCCAT_REPORT_SIZE_SETTINGS) - return; - - /* first retrieve the report rate, it is set per profile */ - switch (setting_report->report_rate) { - case 0x00: report_rate = 125; break; - case 0x01: report_rate = 250; break; - case 0x02: report_rate = 500; break; - case 0x03: report_rate = 1000; break; - default: - log_error(device->ratbag, - "error while reading the report rate of the mouse (0x%02x)\n", - buf[26]); - report_rate = 0; - } - - ratbag_profile_for_each_resolution(profile, resolution) { - dpi_x = setting_report->xres[resolution->index] * 50; - dpi_y = setting_report->yres[resolution->index] * 50; - hz = report_rate; - if (!(setting_report->dpi_mask & (1 << resolution->index))) { - /* the profile is disabled, overwrite it */ - dpi_x = 0; - dpi_y = 0; - hz = 0; - } - - ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); - ratbag_resolution_set_cap(resolution, - RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); - resolution->is_active = (resolution->index == setting_report->current_dpi); - } - - buf = drv_data->profiles[index]; - roccat_set_config_profile(device, index, ROCCAT_CONFIG_KEY_MAPPING); - rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_KEY_MAPPING, - buf, ROCCAT_REPORT_SIZE_PROFILE, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - - msleep(10); - - if (rc < ROCCAT_REPORT_SIZE_PROFILE) - return; - - if (!roccat_crc_is_valid(device, buf, ROCCAT_REPORT_SIZE_PROFILE)) - log_error(device->ratbag, - "Error while reading profile %d, continuing...\n", - profile->index); - - log_raw(device->ratbag, "profile: %d %s:%d\n", - buf[2], - __FILE__, __LINE__); -} - static int roccat_write_profile(struct ratbag_profile *profile) { @@ -769,6 +692,87 @@ roccat_write_resolution_dpi(struct ratbag_resolution *resolution, return rc; } +static void +roccat_read_profile(struct ratbag_profile *profile) +{ + struct ratbag_device *device = profile->device; + struct roccat_data *drv_data; + struct ratbag_resolution *resolution; + struct ratbag_button *button; + struct roccat_settings_report *setting_report; + uint8_t *buf; + unsigned int report_rate; + int dpi_x, dpi_y, hz; + int rc; + + assert(profile->index <= ROCCAT_PROFILE_MAX); + + drv_data = ratbag_get_drv_data(device); + + setting_report = &drv_data->settings[profile->index]; + buf = (uint8_t*)setting_report; + roccat_set_config_profile(device, profile->index, ROCCAT_CONFIG_SETTINGS); + rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_SETTINGS, + buf, ROCCAT_REPORT_SIZE_SETTINGS, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + + if (rc < ROCCAT_REPORT_SIZE_SETTINGS) + return; + + /* first retrieve the report rate, it is set per profile */ + switch (setting_report->report_rate) { + case 0x00: report_rate = 125; break; + case 0x01: report_rate = 250; break; + case 0x02: report_rate = 500; break; + case 0x03: report_rate = 1000; break; + default: + log_error(device->ratbag, + "error while reading the report rate of the mouse (0x%02x)\n", + buf[26]); + report_rate = 0; + } + + ratbag_profile_for_each_resolution(profile, resolution) { + dpi_x = setting_report->xres[resolution->index] * 50; + dpi_y = setting_report->yres[resolution->index] * 50; + hz = report_rate; + if (!(setting_report->dpi_mask & (1 << resolution->index))) { + /* the profile is disabled, overwrite it */ + dpi_x = 0; + dpi_y = 0; + hz = 0; + } + + ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); + ratbag_resolution_set_cap(resolution, + RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); + resolution->is_active = (resolution->index == setting_report->current_dpi); + } + + ratbag_profile_for_each_button(profile, button) + roccat_read_button(button); + + buf = drv_data->profiles[profile->index]; + roccat_set_config_profile(device, profile->index, ROCCAT_CONFIG_KEY_MAPPING); + rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_KEY_MAPPING, + buf, ROCCAT_REPORT_SIZE_PROFILE, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + + msleep(10); + + if (rc < ROCCAT_REPORT_SIZE_PROFILE) + return; + + if (!roccat_crc_is_valid(device, buf, ROCCAT_REPORT_SIZE_PROFILE)) + log_error(device->ratbag, + "Error while reading profile %d, continuing...\n", + profile->index); + + log_raw(device->ratbag, "profile: %d %s:%d\n", + buf[2], + __FILE__, __LINE__); +} + static int roccat_probe(struct ratbag_device *device) { @@ -796,6 +800,9 @@ roccat_probe(struct ratbag_device *device) ROCCAT_BUTTON_MAX + 1, ROCCAT_LED_MAX); + ratbag_device_for_each_profile(device, profile) + roccat_read_profile(profile); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS); @@ -841,10 +848,8 @@ struct ratbag_driver roccat_driver = { .id = "roccat", .probe = roccat_probe, .remove = roccat_remove, - .read_profile = roccat_read_profile, .write_profile = roccat_write_profile, .set_active_profile = roccat_set_current_profile, - .read_button = roccat_read_button, .write_button = roccat_write_button, .write_resolution_dpi = roccat_write_resolution_dpi, }; diff --git a/src/driver-test.c b/src/driver-test.c index 2bc3978c..c74ac9d3 100644 --- a/src/driver-test.c +++ b/src/driver-test.c @@ -29,57 +29,6 @@ #include "libratbag-private.h" #include "libratbag-test.h" -static void -test_read_profile(struct ratbag_profile *profile, unsigned int index) -{ - struct ratbag_test_device *d = ratbag_get_drv_data(profile->device); - struct ratbag_test_profile *p; - struct ratbag_test_resolution *r; - unsigned int i; - bool active_set = false; - bool default_set = false; - - assert(index < d->num_profiles); - - p = &d->profiles[index]; - for (i = 0; i < d->num_resolutions; i++) { - _cleanup_resolution_ struct ratbag_resolution *res; - - r = &p->resolutions[i]; - - res = ratbag_profile_get_resolution(profile, i); - assert(res); - ratbag_resolution_set_resolution(res, r->xres, r->yres, r->hz); - res->is_active = r->active; - if (r->active) - active_set = true; - res->is_default = r->dflt; - if (r->dflt) - default_set = true; - ratbag_resolution_set_cap(res, r->caps); - res->hz = r->hz; - } - - /* special case triggered by the test suite when num_resolutions is 0 */ - if (d->num_resolutions) { - _cleanup_resolution_ struct ratbag_resolution *res; - - res = ratbag_profile_get_resolution(profile, 0); - assert(res); - if (!active_set) - res->is_active = true; - if (!default_set) - res->is_default = true; - } - - profile->is_active = p->active; - profile->is_enabled = !p->disabled; - - for (i = 0; i < ARRAY_LENGTH(p->caps) && p->caps[i]; i++) { - ratbag_profile_set_cap(profile, p->caps[i]); - } -} - static int test_write_profile(struct ratbag_profile *profile) { @@ -215,10 +164,70 @@ test_fake_probe(struct ratbag_device *device) return -ENODEV; } +static void +test_read_profile(struct ratbag_profile *profile) +{ + struct ratbag_test_device *d = ratbag_get_drv_data(profile->device); + struct ratbag_test_profile *p; + struct ratbag_test_resolution *r; + struct ratbag_button *button; + struct ratbag_led *led; + unsigned int i; + bool active_set = false; + bool default_set = false; + + assert(profile->index < d->num_profiles); + + p = &d->profiles[profile->index]; + for (i = 0; i < d->num_resolutions; i++) { + _cleanup_resolution_ struct ratbag_resolution *res; + + r = &p->resolutions[i]; + + res = ratbag_profile_get_resolution(profile, i); + assert(res); + ratbag_resolution_set_resolution(res, r->xres, r->yres, r->hz); + res->is_active = r->active; + if (r->active) + active_set = true; + res->is_default = r->dflt; + if (r->dflt) + default_set = true; + ratbag_resolution_set_cap(res, r->caps); + res->hz = r->hz; + } + + /* special case triggered by the test suite when num_resolutions is 0 */ + if (d->num_resolutions) { + _cleanup_resolution_ struct ratbag_resolution *res; + + res = ratbag_profile_get_resolution(profile, 0); + assert(res); + if (!active_set) + res->is_active = true; + if (!default_set) + res->is_default = true; + } + + ratbag_profile_for_each_button(profile, button) + test_read_button(button); + + ratbag_profile_for_each_led(profile, led) + test_read_led(led); + + profile->is_active = p->active; + profile->is_enabled = !p->disabled; + + for (i = 0; i < ARRAY_LENGTH(p->caps) && p->caps[i]; i++) { + ratbag_profile_set_cap(profile, p->caps[i]); + } +} + static int test_probe(struct ratbag_device *device, const void *data) { struct ratbag_test_device *test_device; + struct ratbag_profile *profile; test_device = zalloc(sizeof(*test_device)); memcpy(test_device, data, sizeof(*test_device)); @@ -235,6 +244,9 @@ test_probe(struct ratbag_device *device, const void *data) ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_DISABLE_PROFILE); } + ratbag_device_for_each_profile(device, profile) + test_read_profile(profile); + return 0; } @@ -258,11 +270,8 @@ struct ratbag_driver test_driver = { .test_probe = test_probe, .remove = test_remove, .get_svg_name = test_get_svg_name, - .read_profile = test_read_profile, .write_profile = test_write_profile, .set_active_profile = test_set_active_profile, - .read_button = test_read_button, - .read_led = test_read_led, .write_button = test_write_button, .write_resolution_dpi = NULL, .write_led = test_write_led, diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 815f27f9..33079f16 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -174,17 +174,6 @@ struct ratbag_driver { */ const char *(*get_svg_name)(const struct ratbag_device *device); - /** - * Callback called when a read profile is requested by the - * caller of the library. - * - * The driver should probe here the device for the requested - * profile and populate the related information. - * There is no need to populate the various struct ratbag_button - * as they are allocated when the user needs it. - */ - void (*read_profile)(struct ratbag_profile *profile, unsigned int index); - /* * FIXME: This function is deprecated and should be removed. Once * we've updated all the device drivers to stop using it we'll remove @@ -200,19 +189,6 @@ struct ratbag_driver { */ int (*set_active_profile)(struct ratbag_device *device, unsigned int index); - /** - * For the given button, fill in the struct ratbag_button - * with the available information. - * - * For devices with profiles, profile will not be NULL. For - * device without, profile will be set to NULL. - * - * For devices with profile, there should not be the need to - * actually read the profile from the device. The caller - * should make sure that the profile is up to date. - */ - void (*read_button)(struct ratbag_button *button); - /* * FIXME: This function is deprecated and should be removed. Once * we've updated all the device drivers to stop using it we'll remove @@ -229,12 +205,6 @@ struct ratbag_driver { int (*write_resolution_dpi)(struct ratbag_resolution *resolution, int dpi_x, int dpi_y); - /** - * For the given led, fill in the struct ratbag_led - * with the available information. - */ - void (*read_led)(struct ratbag_led *led); - /* * FIXME: This function is deprecated and should be removed. Once * we've updated all the device drivers to stop using it we'll remove diff --git a/src/libratbag.c b/src/libratbag.c index bb9405ac..f7803edb 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -295,6 +295,8 @@ ratbag_sanity_check_device(struct ratbag_device *device) _cleanup_led_ struct ratbag_led *p0_led = ratbag_profile_get_led(p0, j); _cleanup_led_ struct ratbag_led *led = ratbag_profile_get_led(p, j); + assert(led->type != RATBAG_LED_TYPE_UNKNOWN); + if (p0_led->type != led->type) { log_bug_libratbag(ratbag, "%s: mismatching LED types (profile %d led %d)\n", @@ -597,19 +599,16 @@ ratbag_unref(struct ratbag *ratbag) static struct ratbag_button * ratbag_create_button(struct ratbag_profile *profile, unsigned int index) { - struct ratbag_device *device = profile->device; struct ratbag_button *button; button = zalloc(sizeof(*button)); button->refcount = 0; button->profile = profile; button->index = index; + button->type = RATBAG_BUTTON_TYPE_UNKNOWN; list_insert(&profile->buttons, &button->link); - if (device->driver->read_button) - device->driver->read_button(button); - return button; } @@ -630,42 +629,9 @@ ratbag_create_led(struct ratbag_profile *profile, unsigned int index) list_insert(&profile->leds, &led->link); - /* If you init a LED, you need to provide this function */ - assert(device->driver->read_led); - device->driver->read_led(led); - - /* The driver must fill this in correctly */ - assert(led->type != RATBAG_LED_TYPE_UNKNOWN); - return led; } -static int -ratbag_profile_init_buttons(struct ratbag_profile *profile, unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; i++) - ratbag_create_button(profile, i); - - profile->device->num_buttons = count; - - return 0; -} - -static int -ratbag_profile_init_leds(struct ratbag_profile *profile, unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; i++) - ratbag_create_led(profile, i); - - profile->device->num_leds = count; - - return 0; -} - LIBRATBAG_EXPORT int ratbag_profile_has_capability(const struct ratbag_profile *profile, enum ratbag_profile_capability cap) @@ -715,14 +681,17 @@ ratbag_create_profile(struct ratbag_device *device, list_init(&profile->leds); list_init(&profile->resolutions); + profile->device->num_buttons = num_buttons; + profile->device->num_leds = num_leds; + for (i = 0; i < num_resolutions; i++) ratbag_create_resolution(profile, i); - assert(device->driver->read_profile); - device->driver->read_profile(profile, index); + for (i = 0; i < num_buttons; i++) + ratbag_create_button(profile, i); - ratbag_profile_init_buttons(profile, num_buttons); - ratbag_profile_init_leds(profile, num_leds); + for (i = 0; i < num_leds; i++) + ratbag_create_led(profile, i); return profile; }