diff --git a/src/driver-etekcity.c b/src/driver-etekcity.c index 62b811b1..ebb5e1d5 100644 --- a/src/driver-etekcity.c +++ b/src/driver-etekcity.c @@ -333,7 +333,6 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index) struct etekcity_settings_report *setting_report; uint8_t *buf; unsigned int report_rate; - unsigned int i; int dpi_x, dpi_y, hz; int rc; @@ -364,22 +363,24 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index) report_rate = 0; } - for (i = 0; i < profile->resolution.num_modes; i++) { - dpi_x = setting_report->xres[i] * 50; - dpi_y = setting_report->yres[i] * 50; + 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 << i))) { + if (!(setting_report->dpi_mask & (1 << resolution->index))) { /* the profile is disabled, overwrite it */ dpi_x = 0; dpi_y = 0; hz = 0; } - resolution = ratbag_resolution_init(profile, i, dpi_x, dpi_y, hz); + + ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); ratbag_resolution_set_cap(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); - resolution->is_active = (i == setting_report->current_dpi); + 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, @@ -594,7 +595,6 @@ etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, struct ratbag_device *device = profile->device; struct etekcity_data *drv_data = ratbag_get_drv_data(device); struct etekcity_settings_report *settings_report; - unsigned int index; uint8_t *buf; int rc; @@ -605,13 +605,10 @@ etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, settings_report = &drv_data->settings[profile->index]; - /* retrieve which resolution is asked to be changed */ - index = resolution - profile->resolution.modes; - settings_report->x_sensitivity = 0x0a; settings_report->y_sensitivity = 0x0a; - settings_report->xres[index] = dpi_x / 50; - settings_report->yres[index] = dpi_y / 50; + settings_report->xres[resolution->index] = dpi_x / 50; + settings_report->yres[resolution->index] = dpi_y / 50; buf = (uint8_t*)settings_report; etekcity_set_config_profile(device, profile->index, ETEKCITY_CONFIG_SETTINGS); diff --git a/src/driver-gskill.c b/src/driver-gskill.c index 99c96129..ea08922b 100644 --- a/src/driver-gskill.c +++ b/src/driver-gskill.c @@ -1038,7 +1038,6 @@ gskill_read_resolutions(struct ratbag_profile *profile, struct gskill_profile_report *report) { struct gskill_profile_data *pdata = profile_to_pdata(profile); - struct ratbag_resolution *resolution; int dpi_x, dpi_y, hz, i; log_debug(profile->device->ratbag, @@ -1048,11 +1047,12 @@ gskill_read_resolutions(struct ratbag_profile *profile, hz = GSKILL_MAX_POLLING_RATE / (report->polling_rate + 1); for (i = 0; i < report->dpi_num; i++) { + _cleanup_resolution_ struct ratbag_resolution *resolution; dpi_x = report->dpi_levels[i].x * GSKILL_DPI_UNIT; dpi_y = report->dpi_levels[i].y * GSKILL_DPI_UNIT; - resolution = ratbag_resolution_init(profile, i, dpi_x, dpi_y, - hz); + resolution = ratbag_profile_get_resolution(profile, i); + ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); resolution->is_active = (i == report->current_dpi_level); pdata->res_idx_to_dev_idx[i] = i; @@ -1162,10 +1162,11 @@ gskill_update_resolutions(struct ratbag_profile *profile) * lost on exit */ for (i = 0; i < GSKILL_NUM_DPI; i++) { - struct ratbag_resolution *res = &profile->resolution.modes[i]; + _cleanup_resolution_ struct ratbag_resolution *res; struct gskill_raw_dpi_level *level = &report->dpi_levels[report->dpi_num]; + res = ratbag_profile_get_resolution(profile, i); if (!res->dpi_x || !res->dpi_y) continue; @@ -1173,8 +1174,8 @@ gskill_update_resolutions(struct ratbag_profile *profile) level->y = res->dpi_y / GSKILL_DPI_UNIT; pdata->res_idx_to_dev_idx[i] = report->dpi_num; - log_debug(device->ratbag, "Profile %d res %ld mapped to %d\n", - profile->index, res - profile->resolution.modes, + log_debug(device->ratbag, "Profile %d res %d mapped to %d\n", + profile->index, res->index, report->dpi_num); report->dpi_num++; diff --git a/src/driver-hidpp10.c b/src/driver-hidpp10.c index c18a9200..94999c14 100644 --- a/src/driver-hidpp10.c +++ b/src/driver-hidpp10.c @@ -355,7 +355,6 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) struct hidpp10_profile p = {0}; struct ratbag_resolution *res; int rc; - unsigned int i; uint16_t xres, yres; uint8_t idx; @@ -378,20 +377,20 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_RESOLUTION); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION); - for (i = 0; i < profile->resolution.num_modes; i++) { + ratbag_profile_for_each_resolution(profile, res) { unsigned int min, max; - res = ratbag_resolution_init(profile, i, - p.dpi_modes[i].xres, - p.dpi_modes[i].yres, - p.refresh_rate); + ratbag_resolution_set_resolution(res, + p.dpi_modes[res->index].xres, + p.dpi_modes[res->index].yres, + p.refresh_rate); ratbag_resolution_set_cap(res, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); if (profile->is_active && res->dpi_x == xres && res->dpi_y == yres) res->is_active = true; - if (i == p.default_dpi_mode) { + if (res->index == p.default_dpi_mode) { res->is_default = true; if (!profile->is_active) res->is_active = true; @@ -470,7 +469,6 @@ hidpp10drv_commit(struct ratbag_device *device) struct ratbag_resolution *active_resolution = NULL; struct hidpp10_profile p; int rc; - unsigned int i; list_for_each(profile, &device->profiles, link) { if (!profile->dirty) @@ -482,11 +480,9 @@ hidpp10drv_commit(struct ratbag_device *device) p.enabled = profile->is_enabled; - for (i = 0; i < profile->resolution.num_modes; i++) { - resolution = &profile->resolution.modes[i]; - - p.dpi_modes[i].xres = resolution->dpi_x; - p.dpi_modes[i].yres = resolution->dpi_y; + ratbag_profile_for_each_resolution(profile, resolution) { + p.dpi_modes[resolution->index].xres = resolution->dpi_x; + p.dpi_modes[resolution->index].yres = resolution->dpi_y; if (profile->is_active && resolution->is_active) active_resolution = resolution; diff --git a/src/driver-hidpp20.c b/src/driver-hidpp20.c index d7a7af96..0f2f8d59 100644 --- a/src/driver-hidpp20.c +++ b/src/driver-hidpp20.c @@ -634,9 +634,7 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile) struct ratbag_device *device = profile->device; struct ratbag *ratbag = device->ratbag; struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); - struct ratbag_resolution *res; int rc; - unsigned int i; if (drv_data->capabilities & HIDPP_CAP_RESOLUTION_2200) { uint16_t resolution; @@ -654,11 +652,13 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile) } if (drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201) { + struct ratbag_resolution *res; + rc = hidpp20drv_read_resolution_dpi_2201(device); if (rc < 0) return rc; - for (i = 0; i < profile->resolution.num_modes; i++) { + ratbag_profile_for_each_resolution(profile, res) { struct hidpp20_sensor *sensor; /* We only look at the first sensor. Multiple @@ -666,7 +666,7 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile) sensor = &drv_data->sensors[0]; /* FIXME: retrieve the refresh rate */ - res = ratbag_resolution_init(profile, i, sensor->dpi, sensor->dpi, 0); + ratbag_resolution_set_resolution(res, sensor->dpi, sensor->dpi, 0); ratbag_resolution_set_range(res, sensor->dpi_min, sensor->dpi_max); /* FIXME: we mark all resolutions as active because @@ -688,14 +688,10 @@ hidpp20drv_update_resolution_dpi_8100(struct ratbag_resolution *resolution, struct ratbag_device *device = profile->device; struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); struct hidpp20_profile *h_profile; - unsigned int index; int dpi = dpi_x; /* dpi_x == dpi_y if we don't have the individual resolution cap */ - /* retrieve which resolution is asked to be changed */ - index = resolution - profile->resolution.modes; - h_profile = &drv_data->profiles->profiles[profile->index]; - h_profile->dpi[index] = dpi; + h_profile->dpi[resolution->index] = dpi; return RATBAG_SUCCESS; } @@ -841,7 +837,6 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index) struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device); struct ratbag_resolution *res; struct hidpp20_profile *p; - unsigned int i; int dpi_index = 0xff; profile->is_enabled = drv_data->profiles->profiles[index].enabled; @@ -858,22 +853,22 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index) p = &drv_data->profiles->profiles[index]; - for (i = 0; i < profile->resolution.num_modes; i++) { + ratbag_profile_for_each_resolution(profile, res) { struct hidpp20_sensor *sensor; /* We only look at the first sensor. Multiple * sensors is too niche to care about right now */ sensor = &drv_data->sensors[0]; - res = ratbag_resolution_init(profile, i, - p->dpi[i], - p->dpi[i], - p->report_rate); + ratbag_resolution_set_resolution(res, + p->dpi[res->index], + p->dpi[res->index], + p->report_rate); if (profile->is_active && - i == (unsigned int)dpi_index) + res->index == (unsigned int)dpi_index) res->is_active = true; - if (i == p->default_dpi) { + if (res->index == p->default_dpi) { res->is_default = true; if (!profile->is_active || dpi_index < 0 || dpi_index > 4) res->is_active = true; @@ -1044,7 +1039,7 @@ hidpp20drv_commit(struct ratbag_device *device) struct ratbag_led *led; struct ratbag_resolution *resolution; int rc; - unsigned int i, dpi_index = 0; + unsigned int dpi_index = 0; list_for_each(profile, &device->profiles, link) { if (!profile->dirty) @@ -1052,10 +1047,9 @@ hidpp20drv_commit(struct ratbag_device *device) drv_data->profiles->profiles[profile->index].enabled = profile->is_enabled; - for (i = 0; i < profile->resolution.num_modes; i++) { - resolution = &profile->resolution.modes[i]; + ratbag_profile_for_each_resolution(profile, resolution) { if (resolution->is_active) - dpi_index = i; + dpi_index = resolution->index; rc = hidpp20drv_update_resolution_dpi(resolution, resolution->dpi_x, diff --git a/src/driver-logitech-g300.c b/src/driver-logitech-g300.c index 2db155e5..b829abeb 100644 --- a/src/driver-logitech-g300.c +++ b/src/driver-logitech-g300.c @@ -217,7 +217,6 @@ logitech_g300_get_active_profile_and_resolution(struct ratbag_device *device) { struct ratbag_profile *profile; struct logitech_g300_F0_report buf; - unsigned int i; int ret; ret = ratbag_hidraw_raw_request(device, 0xF0, (uint8_t*)&buf, @@ -230,12 +229,14 @@ logitech_g300_get_active_profile_and_resolution(struct ratbag_device *device) return -EIO; list_for_each(profile, &device->profiles, link) { + struct ratbag_resolution *resolution; + if (profile->index != buf.profile) continue; profile->is_active = true; - for (i = 0; i < profile->resolution.num_modes; i++) { - profile->resolution.modes[i].is_active = i == buf.resolution; + ratbag_profile_for_each_resolution(profile, resolution) { + resolution->is_active = resolution->index == buf.resolution; } } @@ -247,7 +248,6 @@ logitech_g300_set_active_profile(struct ratbag_device *device, unsigned int inde { struct ratbag_profile *profile; uint8_t buf[] = {LOGITECH_G300_REPORT_ID_SET_ACTIVE, 0x80 | (index << 4), 0x00, 0x00}; - unsigned int i; int ret; if (index > LOGITECH_G300_PROFILE_MAX) @@ -261,11 +261,13 @@ logitech_g300_set_active_profile(struct ratbag_device *device, unsigned int inde /* Update the active resolution. After profile change the default is used. */ list_for_each(profile, &device->profiles, link) { + struct ratbag_resolution *resolution; + if (profile->index != index) continue; - for (i = 0; i < profile->resolution.num_modes; i++) { - profile->resolution.modes[i].is_active = profile->resolution.modes[i].is_default; + ratbag_profile_for_each_resolution(profile, resolution) { + resolution->is_active = resolution->is_default; } } @@ -295,7 +297,7 @@ logitech_g300_read_profile(struct ratbag_profile *profile, unsigned int index) struct logitech_g300_profile_data *pdata; struct logitech_g300_profile_report *report; struct ratbag_resolution *resolution; - unsigned int i, hz; + unsigned int hz; uint8_t report_id; int rc; @@ -324,11 +326,10 @@ logitech_g300_read_profile(struct ratbag_profile *profile, unsigned int index) hz = logitech_g300_raw_to_frequency(report->frequency); - for (i = 0; i < profile->resolution.num_modes; i++) { + ratbag_profile_for_each_resolution(profile, resolution) { struct logitech_g300_resolution *res = - &report->dpi_levels[i]; + &report->dpi_levels[resolution->index]; - resolution = &profile->resolution.modes[i]; resolution->dpi_x = res->dpi * 250; resolution->dpi_y = res->dpi * 250; resolution->hz = hz; @@ -461,29 +462,33 @@ logitech_g300_write_profile(struct ratbag_profile *profile) 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; struct ratbag_button *button; struct ratbag_led *led; uint8_t *buf; - unsigned int hz, i; + unsigned int hz; int rc; pdata = &drv_data->profile_data[profile->index]; report = &pdata->report; - /* The same hz is used for all resolutions */ - hz = profile->resolution.modes[0].hz; - report->frequency = logitech_g300_frequency_to_raw(hz); - - for (i = 0; i < profile->resolution.num_modes; i++) { - struct ratbag_resolution *resolution = &profile->resolution.modes[i]; - struct logitech_g300_resolution *res = &report->dpi_levels[i]; + ratbag_profile_for_each_resolution(profile, resolution) { + struct logitech_g300_resolution *res = + &report->dpi_levels[resolution->index]; res->dpi = resolution->dpi_x / 250; res->is_default = resolution->is_default; if (profile->is_active && resolution->is_active) - logitech_g300_set_current_resolution(device, i); + logitech_g300_set_current_resolution(device, + resolution->index); + + /* The same hz is used for all resolutions */ + if (resolution->index == 0) { + hz = resolution->hz; + report->frequency = logitech_g300_frequency_to_raw(hz); + } } list_for_each(button, &profile->buttons, link) { diff --git a/src/driver-roccat.c b/src/driver-roccat.c index 2691dfc8..a4c68b3f 100644 --- a/src/driver-roccat.c +++ b/src/driver-roccat.c @@ -400,7 +400,6 @@ roccat_read_profile(struct ratbag_profile *profile, unsigned int index) struct roccat_settings_report *setting_report; uint8_t *buf; unsigned int report_rate; - unsigned int i; int dpi_x, dpi_y, hz; int rc; @@ -431,20 +430,21 @@ roccat_read_profile(struct ratbag_profile *profile, unsigned int index) report_rate = 0; } - for (i = 0; i < profile->resolution.num_modes; i++) { - dpi_x = setting_report->xres[i] * 50; - dpi_y = setting_report->yres[i] * 50; + 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 << i))) { + if (!(setting_report->dpi_mask & (1 << resolution->index))) { /* the profile is disabled, overwrite it */ dpi_x = 0; dpi_y = 0; hz = 0; } - resolution = ratbag_resolution_init(profile, i, dpi_x, dpi_y, hz); + + ratbag_resolution_set_resolution(resolution, dpi_x, dpi_y, hz); ratbag_resolution_set_cap(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); - resolution->is_active = (i == setting_report->current_dpi); + resolution->is_active = (resolution->index == setting_report->current_dpi); } buf = drv_data->profiles[index]; @@ -733,7 +733,6 @@ roccat_write_resolution_dpi(struct ratbag_resolution *resolution, struct ratbag_device *device = profile->device; struct roccat_data *drv_data = ratbag_get_drv_data(device); struct roccat_settings_report *settings_report; - unsigned int index; uint8_t *buf; int rc; @@ -744,11 +743,8 @@ roccat_write_resolution_dpi(struct ratbag_resolution *resolution, settings_report = &drv_data->settings[profile->index]; - /* retrieve which resolution is asked to be changed */ - index = resolution - profile->resolution.modes; - - settings_report->xres[index] = dpi_x / 50; - settings_report->yres[index] = dpi_y / 50; + settings_report->xres[resolution->index] = dpi_x / 50; + settings_report->yres[resolution->index] = dpi_y / 50; buf = (uint8_t*)settings_report; diff --git a/src/driver-test.c b/src/driver-test.c index f0a6685c..2bc3978c 100644 --- a/src/driver-test.c +++ b/src/driver-test.c @@ -35,7 +35,6 @@ 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; - struct ratbag_resolution *res; unsigned int i; bool active_set = false; bool default_set = false; @@ -44,9 +43,13 @@ test_read_profile(struct ratbag_profile *profile, unsigned int index) p = &d->profiles[index]; for (i = 0; i < d->num_resolutions; i++) { + _cleanup_resolution_ struct ratbag_resolution *res; + r = &p->resolutions[i]; - res = ratbag_resolution_init(profile, i, r->xres, r->yres, r->hz); + + 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; @@ -59,13 +62,14 @@ test_read_profile(struct ratbag_profile *profile, unsigned int index) /* 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_resolution_unref(res); } profile->is_active = p->active; @@ -225,6 +229,7 @@ test_probe(struct ratbag_device *device, const void *data) test_device->num_resolutions, test_device->num_buttons, test_device->num_leds); + if (test_device->num_profiles > 1) { ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_DISABLE_PROFILE); diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 21efcf59..815f27f9 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -254,6 +254,8 @@ struct ratbag_resolution { struct ratbag_profile *profile; int refcount; void *userdata; + struct list link; + unsigned index; unsigned int dpi_max; /**< max resolution in dpi */ unsigned int dpi_min; /**< min resolution in dpi */ unsigned int dpi_x; /**< x resolution in dpi */ @@ -290,12 +292,11 @@ struct ratbag_profile { struct list buttons; void *drv_data; void *user_data; - struct { - struct ratbag_resolution *modes; - unsigned int num_modes; - } resolution; + struct list resolutions; struct list leds; + unsigned int num_resolutions; + bool is_active; /**< profile is the currently active one */ bool is_enabled; bool dirty; /**< profile changed since last commit */ @@ -311,6 +312,9 @@ struct ratbag_profile { #define ratbag_profile_for_each_led(profile_, led_) \ list_for_each(led_, &(profile_)->leds, link) +#define ratbag_profile_for_each_resolution(profile_, resolution_) \ + list_for_each(resolution_, &(profile_)->resolutions, link) + #define BUTTON_ACTION_NONE \ { .type = RATBAG_BUTTON_ACTION_TYPE_NONE } #define BUTTON_ACTION_BUTTON(num_) \ @@ -461,23 +465,13 @@ ratbag_button_action_match(const struct ratbag_button_action *action, return 0; } -static inline struct ratbag_resolution * -ratbag_resolution_init(struct ratbag_profile *profile, int index, - int dpi_x, int dpi_y, int hz) +static inline void +ratbag_resolution_set_resolution(struct ratbag_resolution *res, + int dpi_x, int dpi_y, int hz) { - struct ratbag_resolution *res = &profile->resolution.modes[index]; - - res->profile = profile; res->dpi_x = dpi_x; res->dpi_y = dpi_y; res->hz = hz; - res->is_active = false; - res->is_default = false; - res->capabilities = 0; - res->dpi_min = 0; - res->dpi_max = 0; - - return res; } static inline void diff --git a/src/libratbag.c b/src/libratbag.c index be0d34d8..bb9405ac 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -62,6 +62,8 @@ static void ratbag_button_destroy(struct ratbag_button *button); static void ratbag_led_destroy(struct ratbag_led *led); +static void +ratbag_resolution_destroy(struct ratbag_resolution *resolution); static void ratbag_default_log_func(struct ratbag *ratbag, @@ -674,6 +676,22 @@ ratbag_profile_has_capability(const struct ratbag_profile *profile, return long_bit_is_set(profile->capabilities, cap); } +static inline void +ratbag_create_resolution(struct ratbag_profile *profile, int index) +{ + struct ratbag_resolution *res; + + res = zalloc(sizeof(*res)); + res->refcount = 0; + res->profile = profile; + res->index = index; + + list_insert(&profile->resolutions, &res->link); + + profile->num_resolutions++; +} + + static struct ratbag_profile * ratbag_create_profile(struct ratbag_device *device, unsigned int index, @@ -688,19 +706,17 @@ ratbag_create_profile(struct ratbag_device *device, profile->refcount = 0; profile->device = device; profile->index = index; - if (num_resolutions) - profile->resolution.modes = zalloc(num_resolutions * - sizeof(*profile->resolution.modes)); - profile->resolution.num_modes = num_resolutions; + profile->num_resolutions = 0; profile->is_enabled = true; profile->name = asprintf_safe("Profile %d", index + 1); list_insert(&device->profiles, &profile->link); list_init(&profile->buttons); list_init(&profile->leds); + list_init(&profile->resolutions); for (i = 0; i < num_resolutions; i++) - ratbag_resolution_init(profile, i, 0, 0, 0); + ratbag_create_resolution(profile, i); assert(device->driver->read_profile); device->driver->read_profile(profile, index); @@ -762,6 +778,7 @@ ratbag_profile_destroy(struct ratbag_profile *profile) { struct ratbag_button *button, *b_next; struct ratbag_led *led, *l_next; + struct ratbag_resolution *res, *r_next; /* if we get to the point where the profile is destroyed, buttons, * resolutions , etc. are at a refcount of 0, so we can destroy @@ -772,7 +789,8 @@ ratbag_profile_destroy(struct ratbag_profile *profile) list_for_each_safe(led, l_next, &profile->leds, link) ratbag_led_destroy(led); - free(profile->resolution.modes); + list_for_each_safe(res, r_next, &profile->resolutions, link) + ratbag_resolution_destroy(res); free(profile->name); @@ -906,7 +924,6 @@ ratbag_old_write_profile(struct ratbag_device *device) struct ratbag_led *led; struct ratbag_resolution *resolution; int rc; - unsigned int i; assert(device->driver->write_profile); @@ -919,9 +936,7 @@ ratbag_old_write_profile(struct ratbag_device *device) return RATBAG_ERROR_DEVICE; if (device->driver->write_resolution_dpi) { - for (i = 0; i < profile->resolution.num_modes; i++) { - resolution = &profile->resolution.modes[i]; - + ratbag_profile_for_each_resolution(profile, resolution) { rc = device->driver->write_resolution_dpi( resolution, resolution->dpi_x, resolution->dpi_y); @@ -1012,12 +1027,13 @@ ratbag_profile_set_active(struct ratbag_profile *profile) LIBRATBAG_EXPORT unsigned int ratbag_profile_get_num_resolutions(struct ratbag_profile *profile) { - return profile->resolution.num_modes; + return profile->num_resolutions; } LIBRATBAG_EXPORT struct ratbag_resolution * ratbag_profile_get_resolution(struct ratbag_profile *profile, unsigned int idx) { + struct ratbag_device *device = profile->device; struct ratbag_resolution *res; unsigned max = ratbag_profile_get_num_resolutions(profile); @@ -1027,9 +1043,15 @@ ratbag_profile_get_resolution(struct ratbag_profile *profile, unsigned int idx) return NULL; } - res = &profile->resolution.modes[idx]; + ratbag_profile_for_each_resolution(profile, res) { + if (res->index == idx) + return ratbag_resolution_ref(res); + } - return ratbag_resolution_ref(res); + log_bug_libratbag(device->ratbag, "Resolution %d, profile %d not found\n", + idx, profile->index); + + return NULL; } LIBRATBAG_EXPORT struct ratbag_resolution * @@ -1120,12 +1142,11 @@ ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution, } } else { struct ratbag_profile *profile = resolution->profile; - unsigned int i; + struct ratbag_resolution *res; /* No indvidual report rate per resolution. Loop through all of * them and update. */ - for (i = 0; i < profile->resolution.num_modes; i++) { - struct ratbag_resolution *res = &profile->resolution.modes[i]; + ratbag_profile_for_each_resolution(profile, res) { if (res->hz != hz) { res->hz = hz; profile->dirty = true; @@ -1182,10 +1203,10 @@ LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_active(struct ratbag_resolution *resolution) { struct ratbag_profile *profile = resolution->profile; - unsigned int i; + struct ratbag_resolution *res; - for (i = 0; i < profile->resolution.num_modes; i++) - profile->resolution.modes[i].is_active = false; + ratbag_profile_for_each_resolution(profile, res) + res->is_active = false; resolution->is_active = true; profile->dirty = true; @@ -1203,12 +1224,10 @@ LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_default(struct ratbag_resolution *resolution) { struct ratbag_profile *profile = resolution->profile; - unsigned int i; + struct ratbag_resolution *other; /* Unset the default on the other resolutions */ - for (i = 0; i < profile->resolution.num_modes; i++) { - struct ratbag_resolution *other = &profile->resolution.modes[i]; - + ratbag_profile_for_each_resolution(profile, other) { if (other == resolution || !other->is_default) continue; @@ -1430,6 +1449,13 @@ ratbag_led_destroy(struct ratbag_led *led) free(led); } +static void +ratbag_resolution_destroy(struct ratbag_resolution *res) +{ + list_remove(&res->link); + free(res); +} + LIBRATBAG_EXPORT struct ratbag_button * ratbag_button_unref(struct ratbag_button *button) {