diff --git a/src/.gitignore b/src/.gitignore index 90ac2c3c..024594c8 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -13,3 +13,5 @@ workspaces-protocol.c workspaces-server-protocol.h input-method-protocol.c input-method-server-protocol.h +scaler-server-protocol.h +scaler-protocol.c diff --git a/src/Makefile.am b/src/Makefile.am index 34b70489..446639cc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,6 +36,8 @@ weston_SOURCES = \ input-method-server-protocol.h \ workspaces-protocol.c \ workspaces-server-protocol.h \ + scaler-protocol.c \ + scaler-server-protocol.h \ bindings.c \ animation.c \ noop-renderer.c \ @@ -321,6 +323,8 @@ BUILT_SOURCES = \ input-method-server-protocol.h \ workspaces-server-protocol.h \ workspaces-protocol.c \ + scaler-server-protocol.h \ + scaler-protocol.c \ git-version.h CLEANFILES = $(BUILT_SOURCES) diff --git a/src/compositor.c b/src/compositor.c index d273e3fa..8a6ff386 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -53,6 +53,7 @@ #endif #include "compositor.h" +#include "scaler-server-protocol.h" #include "../shared/os-compatibility.h" #include "git-version.h" #include "version.h" @@ -3401,6 +3402,104 @@ weston_output_transform_coordinate(struct weston_output *output, *y = ty / output->current_scale + wl_fixed_from_int(output->y); } +static void +destroy_surface_scaler(struct wl_resource *resource) +{ +} + +static void +surface_scaler_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +surface_scaler_set(struct wl_client *client, + struct wl_resource *resource, + wl_fixed_t src_x, + wl_fixed_t src_y, + wl_fixed_t src_width, + wl_fixed_t src_height, + int32_t dst_width, + int32_t dst_height) +{ + if (wl_fixed_to_double(src_width) < 0 || + wl_fixed_to_double(src_height) < 0) { + wl_resource_post_error(resource, + WL_SURFACE_SCALER_ERROR_BAD_VALUE, + "source dimensions must be non-negative (%fx%f)", + wl_fixed_to_double(src_width), + wl_fixed_to_double(src_height)); + return; + } + + if (dst_width <= 0 || dst_height <= 0) { + wl_resource_post_error(resource, + WL_SURFACE_SCALER_ERROR_BAD_VALUE, + "destination dimensions must be positive (%dx%d)", + dst_width, dst_height); + return; + } + + /* TODO */ +} + +static const struct wl_surface_scaler_interface surface_scaler_interface = { + surface_scaler_destroy, + surface_scaler_set +}; + +static void +scaler_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +scaler_get_surface_scaler(struct wl_client *client, + struct wl_resource *scaler, + uint32_t id, + struct wl_resource *surface_resource) +{ + struct weston_surface *surface = wl_resource_get_user_data(surface_resource); + struct wl_resource *resource; + + /* TODO: check we don't already have one for this surface */ + resource = wl_resource_create(client, &wl_surface_scaler_interface, + 1, id); + if (resource == NULL) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(resource, &surface_scaler_interface, + surface, destroy_surface_scaler); +} + +static const struct wl_scaler_interface scaler_interface = { + scaler_destroy, + scaler_get_surface_scaler +}; + +static void +bind_scaler(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create(client, &wl_scaler_interface, + 1, id); + if (resource == NULL) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(resource, &scaler_interface, + NULL, NULL); +} + static void compositor_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) @@ -3489,6 +3588,10 @@ weston_compositor_init(struct weston_compositor *ec, ec, bind_subcompositor)) return -1; + if (!wl_global_create(ec->wl_display, &wl_scaler_interface, 1, + ec, bind_scaler)) + return -1; + wl_list_init(&ec->view_list); wl_list_init(&ec->plane_list); wl_list_init(&ec->layer_list);