Outputs can now be rotated, flipped, and shifted by using the new move method of the output interface. --- clients/window.c | 3 +- compositor/compositor-wayland.c | 4 +- compositor/compositor.c | 97 ++++++++++++++++++++++++++++---------- compositor/compositor.h | 3 +- 4 files changed, 77 insertions(+), 30 deletions(-)
diff --git a/clients/window.c b/clients/window.c index 9d0b753..33dbc94 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1523,7 +1523,8 @@ window_set_buffer_type(struct window *window, enum window_buffer_type type) static void display_handle_geometry(void *data, struct wl_output *output, - int32_t x, int32_t y, int32_t width, int32_t height) + int32_t x, int32_t y, uint32_t tflags, + uint32_t width, uint32_t height) { struct display *display = data; diff --git a/compositor/compositor-wayland.c b/compositor/compositor-wayland.c index 4093f2a..508ea88 100644 --- a/compositor/compositor-wayland.c +++ b/compositor/compositor-wayland.c @@ -283,8 +283,8 @@ cleanup_output: static void display_handle_geometry(void *data, struct wl_output *output, - int32_t x, int32_t y, - int32_t width, int32_t height) + int32_t x, int32_t y, uint32_t tflags, + uint32_t width, uint32_t height) { struct wayland_compositor *c = data; diff --git a/compositor/compositor.c b/compositor/compositor.c index df25407..4f0912f 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -113,6 +113,16 @@ wlsc_matrix_scale(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z) } static void +wlsc_matrix_rotate_90ccw(struct wlsc_matrix *matrix) +{ + struct wlsc_matrix rot = { + { 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 } + }; + + wlsc_matrix_multiply(matrix, &rot); +} + +static void wlsc_matrix_transform(struct wlsc_matrix *matrix, struct wlsc_vector *v) { int i, j; @@ -649,7 +659,7 @@ wlsc_output_damage(struct wlsc_output *output) pixman_region32_union_rect(&compositor->damage_region, &compositor->damage_region, output->x, output->y, - output->width, output->height); + output->swidth, output->sheight); wlsc_compositor_schedule_repaint(compositor); } @@ -687,8 +697,8 @@ fade_output(struct wlsc_output *output, surface.compositor = compositor; surface.x = output->x; surface.y = output->y; - surface.width = output->width; - surface.height = output->height; + surface.width = output->swidth; + surface.height = output->sheight; surface.texture = GL_NONE; if (tint <= 1.0) @@ -727,7 +737,7 @@ wlsc_output_repaint(struct wlsc_output *output) pixman_region32_intersect_rect(&new_damage, &ec->damage_region, output->x, output->y, - output->width, output->height); + output->swidth, output->sheight); pixman_region32_subtract(&ec->damage_region, &ec->damage_region, &new_damage); pixman_region32_union(&total_damage, &new_damage, @@ -754,8 +764,8 @@ wlsc_output_repaint(struct wlsc_output *output) } } - if (es->width < output->width || - es->height < output->height) + if (es->width < output->swidth || + es->height < output->sheight) glClear(GL_COLOR_BUFFER_BIT); wlsc_surface_draw(es, output, &total_damage); } else { @@ -893,9 +903,10 @@ wlsc_surface_assign_output(struct wlsc_surface *es) struct wlsc_output *tmp = es->output; es->output = NULL; + wl_list_for_each(output, &ec->output_list, link) { - if (output->x < es->x && es->x < output->x + output->width && - output->y < es->y && es->y < output->y + output->height) { + if (output->x < es->x && es->x < output->x + output->swidth && + output->y < es->y && es->y < output->y + output->sheight) { if (output != tmp) printf("assiging surface %p to output %p\n", es, output); @@ -928,8 +939,8 @@ surface_attach(struct wl_client *client, es->buffer = buffer; switch (es->map_type) { case WLSC_SURFACE_MAP_FULLSCREEN: - es->x = (es->fullscreen_output->width - es->width) / 2; - es->y = (es->fullscreen_output->height - es->height) / 2; + es->x = (es->fullscreen_output->swidth - es->width) / 2; + es->y = (es->fullscreen_output->sheight - es->height) / 2; break; default: es->x += x; @@ -1034,8 +1045,8 @@ surface_map_fullscreen(struct wl_client *client, struct wl_surface *surface) es->saved_x = es->x; es->saved_y = es->y; - es->x = (output->width - es->width) / 2; - es->y = (output->height - es->height) / 2; + es->x = (output->swidth - es->width) / 2; + es->y = (output->sheight - es->height) / 2; es->fullscreen_output = output; wlsc_surface_update_matrix(es); wlsc_surface_damage(es); @@ -1259,10 +1270,10 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) wlsc_compositor_wake(ec); wl_list_for_each(output, &ec->output_list, link) { - if (output->x <= x && x <= output->x + output->width) + if (output->x <= x && x <= output->x + output->swidth) x_valid = 1; - if (output->y <= y && y <= output->y + output->height) + if (output->y <= y && y <= output->y + output->sheight) y_valid = 1; /* FIXME: calculate this only on output addition/deletion */ @@ -1271,10 +1282,10 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) if (output->y < min_y) min_y = output->y; - if (output->x + output->width > max_x) - max_x = output->x + output->width; - if (output->y + output->height > max_y) - max_y = output->y + output->height; + if (output->x + output->swidth > max_x) + max_x = output->x + output->swidth; + if (output->y + output->sheight > max_y) + max_y = output->y + output->sheight; } if (!x_valid) { @@ -1631,7 +1642,7 @@ wlsc_output_post_geometry(struct wl_client *client, wl_client_post_event(client, global, WL_OUTPUT_GEOMETRY, - output->x, output->y, + output->x, output->y, output->transform_flags, output->width, output->height); } @@ -1757,14 +1768,25 @@ void wlsc_output_move(struct wlsc_output *output, int x, int y) { struct wlsc_compositor *c = output->compositor; - int flip; + int hflip; + int vflip; output->x = x; output->y = y; + if (output->transform_flags & WL_OUTPUT_CWROTATE) { + output->sheight = output->width; + output->swidth = output->height; + } else { + output->sheight = output->height; + output->swidth = output->width; + } + if (output->background) { output->background->x = x; output->background->y = y; + output->background->height = output->sheight; + output->background->width = output->swidth; wlsc_surface_update_matrix(output->background); } @@ -1772,19 +1794,39 @@ wlsc_output_move(struct wlsc_output *output, int x, int y) wlsc_matrix_init(&output->matrix); wlsc_matrix_translate(&output->matrix, - -output->x - output->width / 2.0, - -output->y - output->height / 2.0, 0); + -output->x - output->swidth / 2.0, + -output->y - output->sheight / 2.0, 0); + + hflip = (output->transform_flags & WL_OUTPUT_HORIZFLIP) ? -1 : 1; + vflip = (output->flags & WL_OUTPUT_FLIPPED) ? -1 : 1; + vflip *= (output->transform_flags & WL_OUTPUT_VERTFLIP) ? -1 : 1; - flip = (output->flags & WL_OUTPUT_FLIPPED) ? -1 : 1; wlsc_matrix_scale(&output->matrix, - 2.0 / output->width, - flip * 2.0 / output->height, 1); + hflip * 2.0 / output->swidth, + vflip * 2.0 / output->sheight, 1); + + if (output->transform_flags & WL_OUTPUT_CWROTATE) + wlsc_matrix_rotate_90ccw(&output->matrix); pixman_region32_union_rect(&c->damage_region, &c->damage_region, - x, y, output->width, output->height); + x, y, output->swidth, output->sheight); } +static void +output_move(struct wl_client *client, struct wl_output *output, int x, int y, + uint32_t transform_flags) +{ + struct wlsc_output *wlsc_output = (struct wlsc_output *)output; + + wlsc_output->transform_flags = transform_flags; + wlsc_output_move(wlsc_output, x, y); +} + +const static struct wl_output_interface output_interface = { + output_move, +}; + void wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c, int x, int y, int width, int height, uint32_t flags) @@ -1794,6 +1836,8 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c, output->y = y; output->width = width; output->height = height; + output->swidth = width; + output->sheight = height; output->background = background_create(output, option_background); @@ -1803,6 +1847,7 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c, wlsc_output_move(output, x, y); output->object.interface = &wl_output_interface; + output->object.implementation = (void (**)(void))&output_interface; wl_display_add_object(c->wl_display, &output->object); wl_display_add_global(c->wl_display, &output->object, wlsc_output_post_geometry); diff --git a/compositor/compositor.h b/compositor/compositor.h index bbbae98..88ed115 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -45,9 +45,10 @@ struct wlsc_output { struct wlsc_compositor *compositor; struct wlsc_surface *background; struct wlsc_matrix matrix; - int32_t x, y, width, height; + int32_t x, y, width, height, swidth, sheight; pixman_region32_t previous_damage_region; uint32_t flags; + uint32_t transform_flags; int repaint_needed; int finished; -- 1.7.5 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel