diff options
author | Harish Krupo <harish.krupo.kps@intel.com> | 2018-12-11 13:45:43 +0530 |
---|---|---|
committer | Daniel Stone <daniel@fooishbar.org> | 2019-11-25 21:54:40 +0000 |
commit | 7bcbab1f2fd53987809a98d212b90fc6b99d71cc (patch) | |
tree | 7dd36232f1b6eebe5b1cd0d95fea747d8714e13f | |
parent | 7e0f20311f60e3d0f117f4d5b227d873047fea78 (diff) |
clients/window: Add viewport destination support
Add support for setting the widget's destination wp viewport.
Setting it in the widget instead of being set directly by the client
ensure that the widget can be identified in widget_find_widget.
v2: Return -1 on error (Pekka)
Scale allocated x and y when viewport is set (Pekka)
Allow user to set -1 for viewport width and height (Pekka)
v3: Use NULL instead of 0 (Daniel)
return 0 if width and height are -1 (Daniel)
Signed-off-by: Harish Krupo <harish.krupo.kps@intel.com>
-rw-r--r-- | clients/meson.build | 2 | ||||
-rw-r--r-- | clients/window.c | 76 | ||||
-rw-r--r-- | clients/window.h | 8 |
3 files changed, 82 insertions, 4 deletions
diff --git a/clients/meson.build b/clients/meson.build index eca13b15..7461cd2e 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -14,6 +14,8 @@ srcs_toytoolkit = [ pointer_constraints_unstable_v1_protocol_c, ivi_application_client_protocol_h, ivi_application_protocol_c, + viewporter_client_protocol_h, + viewporter_protocol_c, ] deps_toytoolkit = [ dep_wayland_client, diff --git a/clients/window.c b/clients/window.c index 06a74321..5f250d52 100644 --- a/clients/window.c +++ b/clients/window.c @@ -82,6 +82,7 @@ typedef void *EGLContext; #include "shared/string-helpers.h" #include "window.h" +#include "viewporter-client-protocol.h" #define ZWP_RELATIVE_POINTER_MANAGER_V1_VERSION 1 #define ZWP_POINTER_CONSTRAINTS_V1_VERSION 1 @@ -147,6 +148,7 @@ struct display { int has_rgb565; int data_device_manager_version; + struct wp_viewporter *viewporter; }; struct window_output { @@ -222,6 +224,7 @@ struct surface { cairo_surface_t *cairo_surface; struct wl_list link; + struct wp_viewport *viewport; }; struct window { @@ -320,6 +323,8 @@ struct widget { * redraw handler is going to do completely custom rendering * such as using EGL directly */ int use_cairo; + int viewport_dest_width; + int viewport_dest_height; }; struct touch_point { @@ -1398,6 +1403,7 @@ display_get_pointer_image(struct display *display, int pointer) static void surface_flush(struct surface *surface) { + struct widget *widget = surface->widget; if (!surface->cairo_surface) return; @@ -1415,6 +1421,12 @@ surface_flush(struct surface *surface) surface->input_region = NULL; } + if (surface->viewport) { + wp_viewport_set_destination(surface->viewport, + widget->viewport_dest_width, + widget->viewport_dest_height); + } + surface->toysurface->swap(surface->toysurface, surface->buffer_transform, surface->buffer_scale, &surface->server_allocation); @@ -1620,6 +1632,8 @@ static struct widget * widget_find_widget(struct widget *widget, int32_t x, int32_t y) { struct widget *child, *target; + int alloc_x, alloc_y, width, height; + double scale; wl_list_for_each(child, &widget->child_list, link) { target = widget_find_widget(child, x, y); @@ -1627,10 +1641,24 @@ widget_find_widget(struct widget *widget, int32_t x, int32_t y) return target; } - if (widget->allocation.x <= x && - x < widget->allocation.x + widget->allocation.width && - widget->allocation.y <= y && - y < widget->allocation.y + widget->allocation.height) { + alloc_x = widget->allocation.x; + alloc_y = widget->allocation.y; + width = widget->allocation.width; + height = widget->allocation.height; + + if (widget->viewport_dest_width != -1 && + widget->viewport_dest_height != -1) { + scale = widget->viewport_dest_width / (double) width; + alloc_x = alloc_x * scale; + width = widget->viewport_dest_width; + + scale = widget->viewport_dest_height / (double) height; + alloc_y = alloc_y * scale; + height = widget->viewport_dest_height; + } + + if (alloc_x <= x && x < alloc_x + width && + alloc_y <= y && y < alloc_y + height) { return widget; } @@ -1668,6 +1696,8 @@ widget_create(struct window *window, struct surface *surface, void *data) widget->tooltip_count = 0; widget->default_cursor = CURSOR_LEFT_PTR; widget->use_cairo = 1; + widget->viewport_dest_width = -1; + widget->viewport_dest_height = -1; return widget; } @@ -2025,6 +2055,39 @@ widget_set_use_cairo(struct widget *widget, widget->use_cairo = use_cairo; } +int +widget_set_viewport_destination(struct widget *widget, int width, int height) +{ + struct window *window = widget->window; + struct display *display = window->display; + struct surface *surface = widget->surface; + if (!display->viewporter) + return -1; + + if (width == -1 && height == -1) { + if (surface->viewport) { + wp_viewport_destroy(surface->viewport); + surface->viewport = NULL; + } + + widget->viewport_dest_width = -1; + widget->viewport_dest_height = -1; + return 0; + } + + if (!surface->viewport) { + surface->viewport = wp_viewporter_get_viewport(display->viewporter, + surface->surface); + if (!surface->viewport) + return -1; + } + + widget->viewport_dest_width = width; + widget->viewport_dest_height = height; + + return 0; +} + cairo_surface_t * window_get_surface(struct window *window) { @@ -5165,6 +5228,7 @@ surface_create(struct window *window) wl_surface_add_listener(surface->surface, &surface_listener, window); wl_list_insert(&window->subsurface_list, &surface->link); + surface->viewport = NULL; return surface; } @@ -6003,6 +6067,10 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, d->subcompositor = wl_registry_bind(registry, id, &wl_subcompositor_interface, 1); + } else if (!strcmp(interface, "wp_viewporter")) { + d->viewporter = + wl_registry_bind(registry, id, + &wp_viewporter_interface, 1); } if (d->global_handler) diff --git a/clients/window.h b/clients/window.h index 57e24331..53bcb083 100644 --- a/clients/window.h +++ b/clients/window.h @@ -613,6 +613,14 @@ widget_schedule_redraw(struct widget *widget); void widget_set_use_cairo(struct widget *widget, int use_cairo); +/* + * Sets the viewport destination for the widget's surface + * return 0 on success and -1 on failure. Set width and height to + * -1 to reset the viewport. + */ +int +widget_set_viewport_destination(struct widget *widget, int width, int height); + struct widget * window_frame_create(struct window *window, void *data); |