mirror of
https://gitlab.freedesktop.org/emersion/libliftoff.git
synced 2024-11-16 19:47:55 +01:00
plane: check value for range/enum/bitmask properties
We need to drop the assert from apply_current(): the new value may be outside the range for instance. Closes: https://gitlab.freedesktop.org/emersion/libliftoff/-/issues/47
This commit is contained in:
parent
46f35829e0
commit
0b910624f5
2 changed files with 70 additions and 1 deletions
1
alloc.c
1
alloc.c
|
@ -519,7 +519,6 @@ apply_current(struct liftoff_device *device, drmModeAtomicReq *req)
|
|||
|
||||
liftoff_list_for_each(plane, &device->planes, link) {
|
||||
ret = plane_apply(plane, plane->layer, req);
|
||||
assert(ret != -EINVAL);
|
||||
if (ret != 0) {
|
||||
drmModeAtomicSetCursor(req, cursor);
|
||||
return ret;
|
||||
|
|
70
plane.c
70
plane.c
|
@ -181,6 +181,55 @@ plane_get_property(struct liftoff_plane *plane, const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
check_range_prop(const drmModePropertyRes *prop, uint64_t value)
|
||||
{
|
||||
if (value < prop->values[0] || value > prop->values[1]) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
check_enum_prop(const drmModePropertyRes *prop, uint64_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < prop->count_enums; i++) {
|
||||
if (prop->enums[i].value == value) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
check_bitmask_prop(const drmModePropertyRes *prop, uint64_t value)
|
||||
{
|
||||
int i;
|
||||
uint64_t mask;
|
||||
|
||||
mask = 0;
|
||||
for (i = 0; i < prop->count_enums; i++) {
|
||||
mask |= 1 << prop->enums[i].value;
|
||||
}
|
||||
|
||||
if ((value & ~mask) != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
check_signed_range_prop(const drmModePropertyRes *prop, uint64_t value)
|
||||
{
|
||||
if ((int64_t) value < (int64_t) prop->values[0] ||
|
||||
(int64_t) value > (int64_t) prop->values[1]) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
plane_set_prop(struct liftoff_plane *plane, drmModeAtomicReq *req,
|
||||
const drmModePropertyRes *prop, uint64_t value)
|
||||
|
@ -191,6 +240,27 @@ plane_set_prop(struct liftoff_plane *plane, drmModeAtomicReq *req,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Manually check the property value if we can: this may avoid
|
||||
* unnecessary test commits */
|
||||
ret = 0;
|
||||
switch (drmModeGetPropertyType(prop)) {
|
||||
case DRM_MODE_PROP_RANGE:
|
||||
ret = check_range_prop(prop, value);
|
||||
break;
|
||||
case DRM_MODE_PROP_ENUM:
|
||||
ret = check_enum_prop(prop, value);
|
||||
break;
|
||||
case DRM_MODE_PROP_BITMASK:
|
||||
ret = check_bitmask_prop(prop, value);
|
||||
break;
|
||||
case DRM_MODE_PROP_SIGNED_RANGE:
|
||||
ret = check_signed_range_prop(prop, value);
|
||||
break;
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drmModeAtomicAddProperty(req, plane->id, prop->prop_id, value);
|
||||
if (ret < 0) {
|
||||
liftoff_log(LIFTOFF_ERROR, "drmModeAtomicAddProperty: %s",
|
||||
|
|
Loading…
Reference in a new issue