3 #include <wayland-server.h>
4 #include <scaler-server-protocol.h>
7 #include <libds/surface.h>
9 #define SCALER_VERSION 2
11 struct ds_tizen_scaler
13 struct wl_global *global;
15 struct wl_listener display_destroy;
20 struct wl_resource *resource;
21 struct ds_surface_viewport *surface_viewport;
23 struct wl_listener surface_destroy;
24 struct wl_listener surface_commit;
27 static void scaler_bind(struct wl_client *client, void *data, uint32_t version,
29 static void scaler_handle_display_destroy(struct wl_listener *listener,
31 static void viewport_set_source(struct viewport *viewport,
32 wl_fixed_t x_fixed, wl_fixed_t y_fixed,
33 wl_fixed_t width_fixed, wl_fixed_t height_fixed);
34 static void viewport_set_destination(struct viewport *viewport,
35 int32_t width, int32_t height);
37 struct ds_tizen_scaler *
38 ds_tizen_scaler_create(struct wl_display *display)
40 struct ds_tizen_scaler *scaler;
42 scaler = calloc(1, sizeof *scaler);
46 scaler->global = wl_global_create(display, &wl_scaler_interface,
47 SCALER_VERSION, NULL, scaler_bind);
48 if (!scaler->global) {
53 scaler->display_destroy.notify = scaler_handle_display_destroy;
54 wl_display_add_destroy_listener(display, &scaler->display_destroy);
60 viewport_destroy(struct viewport *viewport)
62 ds_surface_viewport_release(viewport->surface_viewport);
64 wl_resource_set_user_data(viewport->resource, NULL);
65 wl_list_remove(&viewport->surface_commit.link);
66 wl_list_remove(&viewport->surface_destroy.link);
71 viewport_handle_destroy(struct wl_client *client, struct wl_resource *resource)
73 wl_resource_destroy(resource);
77 viewport_handle_set(struct wl_client *client, struct wl_resource *resource,
78 wl_fixed_t src_x, wl_fixed_t src_y,
79 wl_fixed_t src_width, wl_fixed_t src_height,
80 int32_t dst_width, int32_t dst_height)
82 struct viewport *viewport;
84 viewport = wl_resource_get_user_data(resource);
86 ds_err("wl_viewport@%d.set sent after wl_surface has been destroyed",
87 wl_resource_get_id(resource));
91 viewport_set_source(viewport, src_x, src_y, src_width, src_height);
92 viewport_set_destination(viewport, dst_width, dst_height);
96 viewport_handle_set_source(struct wl_client *client,
97 struct wl_resource *resource, wl_fixed_t x, wl_fixed_t y,
98 wl_fixed_t width, wl_fixed_t height)
100 struct viewport *viewport;
102 viewport = wl_resource_get_user_data(resource);
104 ds_err("wl_viewport@%d.set_source sent after wl_surface has been "
105 "destroyed", wl_resource_get_id(resource));
109 viewport_set_source(viewport, x, y, width, height);
113 viewport_handle_set_destination(struct wl_client *client,
114 struct wl_resource *resource, int32_t width, int32_t height)
116 struct viewport *viewport;
118 viewport = wl_resource_get_user_data(resource);
120 ds_err("wl_viewport@%d.set_destination sent after wl_surface has been "
121 "destroyed", wl_resource_get_id(resource));
125 viewport_set_destination(viewport, width, height);
128 static const struct wl_viewport_interface viewport_iface = {
129 .destroy = viewport_handle_destroy,
130 .set = viewport_handle_set,
131 .set_source = viewport_handle_set_source,
132 .set_destination = viewport_handle_set_destination,
136 viewport_handle_surface_destroy(struct wl_listener *listener, void *data)
138 struct viewport *viewport;
140 viewport = wl_container_of(listener, viewport, surface_destroy);
141 viewport_destroy(viewport);
145 viewport_handle_resource_destroy(struct wl_resource *resource)
147 struct viewport *viewport;
149 viewport = wl_resource_get_user_data(resource);
151 viewport_destroy(viewport);
155 viewport_handle_surface_commit(struct wl_listener *listener, void *data)
157 struct viewport *viewport;
159 viewport = wl_container_of(listener, viewport, surface_commit);
165 scaler_handle_destroy(struct wl_client *client, struct wl_resource *resource)
167 wl_resource_destroy(resource);
171 scaler_handle_get_viewport(struct wl_client *client,
172 struct wl_resource *resource, uint32_t id,
173 struct wl_resource *surface_resource)
175 struct viewport *viewport;
176 struct ds_surface *surface;
177 struct ds_surface_viewport *surface_viewport;
179 surface = ds_surface_from_resource(surface_resource);
180 surface_viewport = ds_surface_take_viewport(surface);
181 if (!surface_viewport) {
182 wl_resource_post_error(resource, WL_SCALER_ERROR_VIEWPORT_EXISTS,
183 "a viewport for that surface already exists");
187 viewport = calloc(1, sizeof *viewport);
191 viewport->resource = wl_resource_create(client, &wl_viewport_interface,
192 wl_resource_get_version(resource), id);
193 if (!viewport->resource)
196 wl_resource_set_implementation(viewport->resource, &viewport_iface,
197 viewport, viewport_handle_resource_destroy);
199 viewport->surface_viewport = surface_viewport;
201 viewport->surface_destroy.notify = viewport_handle_surface_destroy;
202 ds_surface_add_destroy_listener(surface, &viewport->surface_destroy);
204 viewport->surface_commit.notify = viewport_handle_surface_commit;
205 ds_surface_add_commit_listener(surface, &viewport->surface_commit);
209 wl_resource_post_no_memory(resource);
212 ds_surface_viewport_release(surface_viewport);
215 static const struct wl_scaler_interface scaler_iface = {
216 .destroy = scaler_handle_destroy,
217 .get_viewport = scaler_handle_get_viewport,
221 scaler_bind(struct wl_client *client, void *data, uint32_t version,
224 struct wl_resource *resource;
225 uint32_t bind_version;
227 bind_version = version < SCALER_VERSION ? version : SCALER_VERSION;
228 resource = wl_resource_create(client, &wl_scaler_interface, bind_version,
231 wl_client_post_no_memory(client);
234 wl_resource_set_implementation(resource, &scaler_iface, NULL, NULL);
238 scaler_handle_display_destroy(struct wl_listener *listener, void *data)
240 struct ds_tizen_scaler *scaler;
242 scaler = wl_container_of(listener, scaler, display_destroy);
243 wl_list_remove(&scaler->display_destroy.link);
244 wl_global_destroy(scaler->global);
249 viewport_set_source(struct viewport *viewport,
250 wl_fixed_t x_fixed, wl_fixed_t y_fixed,
251 wl_fixed_t width_fixed, wl_fixed_t height_fixed)
253 double x, y, width, height;
255 x = wl_fixed_to_double(x_fixed);
256 y = wl_fixed_to_double(y_fixed);
257 width = wl_fixed_to_double(width_fixed);
258 height = wl_fixed_to_double(height_fixed);
260 if (width == -1.0 && height == -1.0) {
261 ds_surface_viewport_unset_source(viewport->surface_viewport);
263 else if (x < 0 || y < 0 || width <= 0 || height <= 0) {
264 ds_inf("wl_viewport.set_source sent with invalid values (%f %f %fx%f)",
265 x, y, width, height);
266 if (width <= 0 || height <= 0) {
267 wl_resource_post_error(viewport->resource,
268 WL_VIEWPORT_ERROR_BAD_VALUE,
269 "wl_viewport.set_source sent with invalid values");
273 ds_surface_viewport_set_source(viewport->surface_viewport,
274 x, y, width, height);
279 viewport_set_destination(struct viewport *viewport,
280 int32_t width, int32_t height)
282 if (width == -1 && height == -1) {
283 ds_surface_viewport_unset_destination(viewport->surface_viewport);
285 else if (width <= 0 || height <= 0) {
286 wl_resource_post_error(viewport->resource, WL_VIEWPORT_ERROR_BAD_VALUE,
287 "destination size must be positive (%dx%d)",
291 ds_surface_viewport_set_destination(viewport->surface_viewport,