From f26de4bb29e61e8ddd70c237c5f9ec2dec16ba8e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 4 Oct 2017 19:00:10 +1000 Subject: [PATCH] Change driver probe() as a flat function Previously, probe() would call ratbag_init_profiles() which in turn would call the various function pointers in the driver to fill in profiles, buttons and leds (the latter while filling in profiles). This made the probe() function harder to understand than necessary and unreliable because it wasn't always clear which bits were already set up while some driver function was called and which ones weren't yet. This patch switches to a flat probe(). The driver still needs to call ratbag_init_profiles(), libratbag sets up everything (to default values). Then the driver can fill in the rest as it wants. This patch still makes use of the current infrastructure, the drivers just call the read_profile and read_button functions manually now. Fixes #370 Signed-off-by: Peter Hutterer --- src/driver-etekcity.c | 154 ++++++++++++++++++----------------- src/driver-gskill.c | 141 ++++++++++++++++---------------- src/driver-hidpp10.c | 14 +++- src/driver-hidpp20.c | 54 ++++++++---- src/driver-logitech-g300.c | 121 ++++++++++++++------------- src/driver-roccat.c | 163 +++++++++++++++++++------------------ src/driver-test.c | 117 ++++++++++++++------------ src/libratbag-private.h | 30 ------- src/libratbag.c | 51 +++--------- 9 files changed, 419 insertions(+), 426 deletions(-) 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; }