summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarish Krupo <harish.krupo.kps@intel.com>2018-12-11 13:45:43 +0530
committerDaniel Stone <daniel@fooishbar.org>2019-11-25 21:54:40 +0000
commit7bcbab1f2fd53987809a98d212b90fc6b99d71cc (patch)
tree7dd36232f1b6eebe5b1cd0d95fea747d8714e13f
parent7e0f20311f60e3d0f117f4d5b227d873047fea78 (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.build2
-rw-r--r--clients/window.c76
-rw-r--r--clients/window.h8
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);