summaryrefslogtreecommitdiff
path: root/src/common/backend.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/backend.c')
-rw-r--r--src/common/backend.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/src/common/backend.c b/src/common/backend.c
index ccb9c27..23275d6 100644
--- a/src/common/backend.c
+++ b/src/common/backend.c
@@ -81,10 +81,18 @@ uint32_t yasl_display_caps(const struct yasl_display *d)
int yasl_display_dispatch(struct yasl_display *d, int timeout_ms)
{
- if (!d) return -1;
- if (d->ops->display_dispatch_timeout)
- return d->ops->display_dispatch_timeout(d, timeout_ms);
- return -1;
+ if (!d) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (!d->ops->display_dispatch_timeout) {
+ errno = ENOTSUP;
+ return -1;
+ }
+ errno = 0;
+ int result = d->ops->display_dispatch_timeout(d, timeout_ms);
+ if (result < 0 && !errno) errno = EIO;
+ return result;
}
void yasl_display_flush(struct yasl_display *d)
@@ -127,7 +135,12 @@ bool yasl_display_drag_start(struct yasl_display *d, struct yasl_surface *origin
return 0;
if (!origin || origin->display != d)
return false;
- return d->ops->display_drag_start(d, origin, image, l, ud);
+ if (image && (!image->pixels || image->size.x <= 0 || image->size.y <= 0 ||
+ image->size.x > 32767 || image->size.y > 32767 ||
+ (int64_t)image->size.x * image->size.y * 4 > INT32_MAX))
+ return false;
+ const struct yasl_drag_listener empty = {0};
+ return d->ops->display_drag_start(d, origin, image, l ? l : &empty, ud);
}
void yasl_display_drag_cancel(struct yasl_display *d)
@@ -151,7 +164,10 @@ struct yasl_surface *yasl_create_toplevel(struct yasl_display *d,
errno = ENOTSUP;
return NULL;
}
- return d->ops->surface_create_toplevel(d, spec, graphics_device);
+ errno = 0;
+ struct yasl_surface *s = d->ops->surface_create_toplevel(d, spec, graphics_device);
+ if (!s && !errno) errno = ENODEV;
+ return s;
}
struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d,
@@ -160,18 +176,50 @@ struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d,
return yasl_create_toplevel(d, spec, NULL);
}
+static bool popup_spec_valid(const struct yasl_popup_spec *spec)
+{
+ return spec && spec->size.x > 0 && spec->size.y > 0 &&
+ spec->size.x <= 32767 && spec->size.y <= 32767 &&
+ (int64_t)spec->size.x * spec->size.y * 4 <= INT32_MAX &&
+ spec->anchor.width >= 0 && spec->anchor.height >= 0 &&
+ spec->content_offset.x >= 0 && spec->content_offset.y >= 0 &&
+ spec->content_size.x >= 0 && spec->content_size.y >= 0 &&
+ (int64_t)spec->content_offset.x + spec->content_size.x <= spec->size.x &&
+ (int64_t)spec->content_offset.y + spec->content_size.y <= spec->size.y;
+}
+
struct yasl_surface *yasl_surface_create_popup(struct yasl_surface *parent, const struct yasl_popup_spec *spec)
{
- if (!parent || !parent->display->ops->surface_create_popup)
- return 0;
- return parent->display->ops->surface_create_popup(parent, spec);
+ if (!parent || !popup_spec_valid(spec)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (!(yasl_display_caps(parent->display) & YASL_CAP_POPUPS) ||
+ !parent->display->ops->surface_create_popup) {
+ errno = ENOTSUP;
+ return NULL;
+ }
+ errno = 0;
+ struct yasl_surface *s = parent->display->ops->surface_create_popup(parent, spec);
+ if (!s && !errno) errno = ENODEV;
+ return s;
}
bool yasl_surface_popup_reposition(struct yasl_surface *popup, const struct yasl_popup_spec *spec)
{
- if (!popup || !popup->display->ops->surface_popup_reposition)
- return 0;
- return popup->display->ops->surface_popup_reposition(popup, spec);
+ if (!popup || !popup_spec_valid(spec)) {
+ errno = EINVAL;
+ return false;
+ }
+ if (!(yasl_display_caps(popup->display) & YASL_CAP_POPUPS) ||
+ !popup->display->ops->surface_popup_reposition) {
+ errno = ENOTSUP;
+ return false;
+ }
+ errno = 0;
+ bool result = popup->display->ops->surface_popup_reposition(popup, spec);
+ if (!result && !errno) errno = ENODEV;
+ return result;
}
void yasl_surface_destroy(struct yasl_surface *s)