Add per-resolution capabilities

Currently only the hooks for x/y resolution, the rest is unimplemented. Also
the etekcity driver needs an update here.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2015-09-01 16:38:19 +10:00
parent 9383097fd2
commit 99a9752104
8 changed files with 198 additions and 21 deletions

View File

@@ -507,10 +507,12 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index)
hz = report_rate;
if (!(setting_report->dpi_mask & (1 << i))) {
/* the profile is disabled, overwrite it */
resolution->dpi = 0;
resolution->dpi_x = 0;
resolution->dpi_y = 0;
resolution->hz = 0;
}
ratbag_resolution_init(profile, i, dpi,hz);
/* FIXME */
ratbag_resolution_init(profile, i, dpi, dpi, hz);
resolution->is_active = (i == setting_report->current_dpi);
}
@@ -622,7 +624,8 @@ etekcity_write_button(struct ratbag_button *button,
}
static int
etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
etekcity_write_resolution_dpi(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y)
{
struct ratbag_profile *profile = resolution->profile;
struct ratbag_device *device = profile->device;
@@ -632,7 +635,9 @@ etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
uint8_t *buf;
int rc;
if (dpi < 50 || dpi > 8200 || dpi % 50)
if (dpi_x < 50 || dpi_x > 8200 || dpi_x % 50)
return -EINVAL;
if (dpi_y < 50 || dpi_y > 8200 || dpi_y % 50)
return -EINVAL;
settings_report = &drv_data->settings[profile->index];
@@ -640,11 +645,10 @@ etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
/* retrieve which resolution is asked to be changed */
index = resolution - profile->resolution.modes;
/* FIXME: allow both x and y dpi to be set */
settings_report->x_sensitivity = 0x0a;
settings_report->y_sensitivity = 0x0a;
settings_report->xres[index] = dpi / 50;
settings_report->yres[index] = dpi / 50;
settings_report->xres[index] = dpi_x / 50;
settings_report->yres[index] = dpi_y / 50;
buf = (uint8_t*)settings_report;
etekcity_set_config_profile(device, profile->index, ETEKCITY_CONFIG_SETTINGS);

View File

@@ -139,10 +139,15 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index)
profile->resolution.num_modes = p.num_dpi_modes;
for (i = 0; i < p.num_dpi_modes; i++) {
/* FIXME: we should expose x/y res separately */
ratbag_resolution_init(profile, i, p.dpi_modes[i].xres,
ratbag_resolution_init(profile, i,
p.dpi_modes[i].xres,
p.dpi_modes[i].yres,
p.refresh_rate);
if (profile->is_active && profile->resolution.modes[i].dpi == xres)
ratbag_resolution_set_cap(&profile->resolution.modes[i],
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
if (profile->is_active &&
profile->resolution.modes[i].dpi_x == xres &&
profile->resolution.modes[i].dpi_y == yres)
profile->resolution.modes[i].is_active = true;
if (i == p.default_dpi_mode)
profile->resolution.modes[i].is_default = true;

View File

@@ -208,8 +208,9 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
drv_data->num_sensors = MAX_RESOLUTIONS;
profile->resolution.num_modes = drv_data->num_sensors;
for (i = 0; i < profile->resolution.num_modes; i++) {
int dpi = drv_data->sensors[i].dpi;
/* FIXME: retrieve the refresh rate */
ratbag_resolution_init(profile, i, drv_data->sensors[i].dpi, 0);
ratbag_resolution_init(profile, i, dpi, dpi, 0);
/* FIXME: we mark all resolutions as active because
* they are from different sensors */
@@ -223,13 +224,15 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
}
static int
hidpp20drv_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
hidpp20drv_write_resolution_dpi(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y)
{
struct ratbag_profile *profile = resolution->profile;
struct ratbag_device *device = profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp20_sensor *sensor;
int rc, i;
int dpi = dpi_x; /* dpi_x == dpi_y if we don't have the individual resolution cap */
if (!(drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201))
return -ENOTSUP;

View File

@@ -27,6 +27,7 @@
#include <linux/input.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "libratbag.h"
#include "libratbag-util.h"
@@ -167,7 +168,8 @@ struct ratbag_driver {
*
* Mandatory if the driver exports RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION.
*/
int (*write_resolution_dpi)(struct ratbag_resolution *resolution, int dpi);
int (*write_resolution_dpi)(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y);
/* private */
struct list link;
@@ -178,10 +180,12 @@ struct ratbag_resolution{
struct ratbag_profile *profile;
int refcount;
void *userdata;
unsigned int dpi; /**< resolution on dpi */
unsigned int dpi_x; /**< x resolution in dpi */
unsigned int dpi_y; /**< y resolution in dpi */
unsigned int hz; /**< report rate in Hz */
bool is_active;
bool is_default;
uint32_t capabilities;
};
struct ratbag_profile {
@@ -309,15 +313,27 @@ ratbag_button_action_match(const struct ratbag_button_action *action,
}
static inline void
ratbag_resolution_init(struct ratbag_profile *profile, int index, int dpi, int hz)
ratbag_resolution_init(struct ratbag_profile *profile, int index,
int dpi_x, int dpi_y, int hz)
{
struct ratbag_resolution *res = &profile->resolution.modes[index];
res->profile = profile;
res->dpi = dpi;
res->dpi_x = dpi_x;
res->dpi_y = dpi_y;
res->hz = hz;
res->is_active = false;
res->is_default = false;
res->capabilities = 0;
}
static inline void
ratbag_resolution_set_cap(struct ratbag_resolution *res,
enum ratbag_resolution_capability cap)
{
assert(cap <= RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
res->capabilities = (1 << cap);
}
/**

View File

@@ -569,7 +569,7 @@ ratbag_create_profile(struct ratbag_device *device,
list_init(&profile->buttons);
for (i = 0; i < MAX_RESOLUTIONS; i++)
ratbag_resolution_init(profile, i, 0, 0);
ratbag_resolution_init(profile, i, 0, 0, 0);
profile->resolution.num_modes = 1;
assert(device->driver->read_profile);
@@ -755,15 +755,48 @@ ratbag_resolution_unref(struct ratbag_resolution *resolution)
return NULL;
}
LIBRATBAG_EXPORT int
ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
enum ratbag_resolution_capability cap)
{
switch (cap) {
case RATBAG_RESOLUTION_CAP_INDIVIDUAL_REPORT_RATE:
case RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION:
break;
default:
return 0;
}
return !!(resolution->capabilities & (1 << cap));
}
LIBRATBAG_EXPORT int
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
unsigned int dpi)
{
struct ratbag_profile *profile = resolution->profile;
resolution->dpi = dpi;
resolution->dpi_x = dpi;
resolution->dpi_y = dpi;
assert(profile->device->driver->write_resolution_dpi);
return profile->device->driver->write_resolution_dpi(resolution, dpi);
return profile->device->driver->write_resolution_dpi(resolution, dpi, dpi);
}
LIBRATBAG_EXPORT int
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
unsigned int x, unsigned int y)
{
struct ratbag_profile *profile = resolution->profile;
if (!ratbag_resolution_has_capability(resolution,
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION))
return -1;
if ((x == 0 && y != 0) || (x != 0 && y == 0))
return -1;
assert(profile->device->driver->write_resolution_dpi);
return profile->device->driver->write_resolution_dpi(resolution, x, y);
}
LIBRATBAG_EXPORT int
@@ -778,7 +811,19 @@ ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
LIBRATBAG_EXPORT int
ratbag_resolution_get_dpi(struct ratbag_resolution *resolution)
{
return resolution->dpi;
return resolution->dpi_x;
}
LIBRATBAG_EXPORT int
ratbag_resolution_get_dpi_x(struct ratbag_resolution *resolution)
{
return resolution->dpi_x;
}
LIBRATBAG_EXPORT int
ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution)
{
return resolution->dpi_y;
}
LIBRATBAG_EXPORT int

View File

@@ -552,10 +552,38 @@ ratbag_resolution_set_user_data(struct ratbag_resolution *resolution, void *user
void*
ratbag_resolution_get_user_data(const struct ratbag_resolution *resolution);
enum ratbag_resolution_capability {
/**
* The report rate can be set per resolution mode. If this property
* is not available, all resolutions within the same profile have
* the same report rate and changing one changes the others.
*/
RATBAG_RESOLUTION_CAP_INDIVIDUAL_REPORT_RATE = 1,
/**
* The resolution can be set for x and y separately.
*/
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION,
};
/**
* @ingroup resolution
*
* Check if a resolution has a specific capability.
*
* @return non-zero if the capability is available, zero otherwise.
*/
int
ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
enum ratbag_resolution_capability cap);
/**
* @ingroup resolution
*
* Set the resolution in DPI for the resolution mode.
* If the resolution has the @ref
* RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability, this function
* sets both x and y resolution to the given value.
*
* A value of 0 for dpi disables the mode.
*
@@ -570,20 +598,84 @@ ratbag_resolution_get_user_data(const struct ratbag_resolution *resolution);
int
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
unsigned int dpi);
/**
* @ingroup resolution
*
* Set the x and y resolution in DPI for the resolution mode.
* If the resolution does not have the @ref
* RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability, this function
* returns an error and does nothing.
*
* A value of 0 for both x and y disables the mode. If either value is 0 and
* the other value is non-zero, this function returns an error and does
* nothing.
*
* If the resolution mode is the currently active mode and the profile is
* the currently active profile, the change takes effect immediately.
*
* @param resolution A previously initialized ratbag resolution with the
* @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability
* @param x The x resolution in dpi
* @param y The y resolution in dpi
*
* @return zero on success, non-zero otherwise
*/
int
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
unsigned int x, unsigned int y);
/**
* @ingroup resolution
*
* Get the resolution in DPI for the resolution mode.
* If the resolution has the @ref
* RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability, this function
* returns the x resolution, see ratbag_resolution_get_dpi_x().
*
* A value of 0 for dpi indicates the mode is disabled.
*
* @param resolution A previously initialized ratbag resolution
*
* @return zero on success, non-zero otherwise
* @return The resolution in dpi
*/
int
ratbag_resolution_get_dpi(struct ratbag_resolution *resolution);
/**
* @ingroup resolution
*
* Get the x resolution in DPI for the resolution mode. If the resolution
* does not have the @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION
* capability, this function is identical to ratbag_resolution_get_dpi().
*
* A value of 0 for dpi indicates the mode is disabled.
*
* @param resolution A previously initialized ratbag resolution with the
* @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability
*
* @return The resolution in dpi
*/
int
ratbag_resolution_get_dpi_x(struct ratbag_resolution *resolution);
/**
* @ingroup resolution
*
* Get the y resolution in DPI for the resolution mode. If the resolution
* does not have the @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION
* capability, this function is identical to ratbag_resolution_get_dpi().
*
* A value of 0 for dpi indicates the mode is disabled.
*
* @param resolution A previously initialized ratbag resolution with the
* @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability
*
* @return The resolution in dpi
*/
int
ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution);
/**
* @ingroup resolution
*

View File

@@ -40,14 +40,18 @@ global:
ratbag_profile_set_active;
ratbag_profile_unref;
ratbag_resolution_get_dpi;
ratbag_resolution_get_dpi_x;
ratbag_resolution_get_dpi_y;
ratbag_resolution_get_report_rate;
ratbag_resolution_get_user_data;
ratbag_resolution_has_capability;
ratbag_resolution_is_active;
ratbag_resolution_is_default;
ratbag_resolution_ref;
ratbag_resolution_set_active;
ratbag_resolution_set_default;
ratbag_resolution_set_dpi;
ratbag_resolution_set_dpi_xy;
ratbag_resolution_set_report_rate;
ratbag_resolution_set_user_data;
ratbag_resolution_unref;

View File

@@ -332,6 +332,14 @@ ratbag_cmd_info(struct ratbag *ratbag, uint32_t flags, int argc, char **argv)
rate = ratbag_resolution_get_report_rate(res);
if (dpi == 0)
printf(" %d: <disabled>\n", j);
else if (ratbag_resolution_has_capability(res,
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION))
printf(" %d: %dx%ddpi @ %dHz%s%s\n", j,
ratbag_resolution_get_dpi_x(res),
ratbag_resolution_get_dpi_y(res),
rate,
ratbag_resolution_is_active(res) ? " (active)" : "",
ratbag_resolution_is_default(res) ? " (default)" : "");
else
printf(" %d: %ddpi @ %dHz%s%s\n", j, dpi, rate,
ratbag_resolution_is_active(res) ? " (active)" : "",