From 82da52b15b49da3f3c7b4bd85d334ddfaa375ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 17 Dec 2010 09:53:12 -0500 Subject: [PATCH] Update surface.attach and change surface.map to surface.map_toplevel The new map_toplevel() request no longer specifies a position and takes the size from the attached buffer. The attach request now takes a position relative to the top-left corner of the old buffer to let clients specify the relative position of the new buffer. --- clients/dnd.c | 2 +- clients/flower.c | 52 ++++++------ clients/gears.c | 5 +- clients/image.c | 2 +- clients/resizor.c | 3 +- clients/smoke.c | 3 +- clients/terminal.c | 2 +- clients/view.c | 3 +- clients/window.c | 140 +++++++++++++++----------------- clients/window.h | 8 +- compositor/compositor-wayland.c | 9 +- compositor/compositor.c | 41 ++++------ protocol/wayland.xml | 19 ++--- 13 files changed, 131 insertions(+), 158 deletions(-) diff --git a/clients/dnd.c b/clients/dnd.c index e6dd0910..b7f9f397 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -633,7 +633,7 @@ dnd_create(struct display *display) title = g_strdup_printf("Wayland Drag and Drop Demo"); - dnd->window = window_create(display, title, 100, 100, 500, 400); + dnd->window = window_create(display, title, 500, 400); dnd->display = display; dnd->key = 100; diff --git a/clients/flower.c b/clients/flower.c index b919cf5f..de7c1d42 100644 --- a/clients/flower.c +++ b/clients/flower.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "wayland-client.h" @@ -97,31 +98,36 @@ draw_stuff(cairo_surface_t *surface, int width, int height) cairo_destroy(cr); } -struct flower { - struct display *display; - struct window *window; - int x, y, width, height; - int offset; -}; +static int +motion_handler(struct window *window, + struct input *input, uint32_t time, + int32_t x, int32_t y, + int32_t sx, int32_t sy, void *data) +{ + return POINTER_HAND1; +} static void -frame_callback(void *data, uint32_t time) +button_handler(struct window *window, + struct input *input, uint32_t time, + int button, int state, void *data) { - struct flower *flower = data; - - window_move(flower->window, - flower->x + cos((flower->offset + time) / 400.0) * 400 - flower->width / 2, - flower->y + sin((flower->offset + time) / 320.0) * 300 - flower->height / 2); - wl_display_frame_callback(display_get_display(flower->display), - frame_callback, flower); + if (state) + window_move(window, input, time); } +struct flower { + struct display *display; + struct window *window; + int width, height; +}; + int main(int argc, char *argv[]) { cairo_surface_t *s; - struct timespec ts; struct flower flower; struct display *d; + struct timeval tv; d = display_create(&argc, &argv, NULL); if (d == NULL) { @@ -129,18 +135,15 @@ int main(int argc, char *argv[]) return -1; } - flower.x = 512; - flower.y = 384; + gettimeofday(&tv, NULL); + srandom(tv.tv_usec); + flower.width = 200; flower.height = 200; flower.display = d; - flower.window = window_create(d, "flower", flower.x, flower.y, + flower.window = window_create(d, "flower", flower.width, flower.height); - clock_gettime(CLOCK_MONOTONIC, &ts); - srandom(ts.tv_nsec); - flower.offset = random(); - window_set_decoration(flower.window, 0); window_draw(flower.window); s = window_get_surface(flower.window); @@ -154,10 +157,9 @@ int main(int argc, char *argv[]) cairo_surface_destroy(s); window_flush(flower.window); + window_set_motion_handler(flower.window, motion_handler); + window_set_button_handler(flower.window, button_handler); window_set_user_data(flower.window, &flower); - wl_display_frame_callback(display_get_display(d), - frame_callback, &flower); - display_run(d); return 0; diff --git a/clients/gears.c b/clients/gears.c index 7d3c3100..2f2eeda5 100644 --- a/clients/gears.c +++ b/clients/gears.c @@ -340,15 +340,14 @@ frame_callback(void *data, uint32_t time) static struct gears * gears_create(struct display *display) { - const int x = 200, y = 200, width = 450, height = 500; + const int width = 450, height = 500; struct gears *gears; int i; gears = malloc(sizeof *gears); memset(gears, 0, sizeof *gears); gears->d = display; - gears->window = window_create(display, "Wayland Gears", - x, y, width, height); + gears->window = window_create(display, "Wayland Gears", width, height); gears->display = display_get_egl_display(gears->d); if (gears->display == NULL) diff --git a/clients/image.c b/clients/image.c index bb563ede..f9bbeb21 100644 --- a/clients/image.c +++ b/clients/image.c @@ -213,7 +213,7 @@ image_create(struct display *display, uint32_t key, const char *filename) image->filename = g_strdup(filename); - image->window = window_create(display, title, 100 * key, 100 * key, 500, 400); + image->window = window_create(display, title, 500, 400); image->display = display; /* FIXME: Window uses key 1 for moves, need some kind of diff --git a/clients/resizor.c b/clients/resizor.c index d5baf170..f3089834 100644 --- a/clients/resizor.c +++ b/clients/resizor.c @@ -162,8 +162,7 @@ resizor_create(struct display *display) return resizor; memset(resizor, 0, sizeof *resizor); - resizor->window = window_create(display, "Wayland Resizor", - 100, 100, 500, 400); + resizor->window = window_create(display, "Wayland Resizor", 500, 400); resizor->display = display; window_set_key_handler(resizor->window, key_handler); diff --git a/clients/smoke.c b/clients/smoke.c index 43226adf..7052cb44 100644 --- a/clients/smoke.c +++ b/clients/smoke.c @@ -277,8 +277,7 @@ int main(int argc, char *argv[]) smoke.width = 200; smoke.height = 200; smoke.display = d; - smoke.window = window_create(d, "smoke", smoke.x, smoke.y, - smoke.width, smoke.height); + smoke.window = window_create(d, "smoke", smoke.width, smoke.height); window_set_buffer_type(smoke.window, WINDOW_BUFFER_TYPE_SHM); clock_gettime(CLOCK_MONOTONIC, &ts); diff --git a/clients/terminal.c b/clients/terminal.c index 2f12f8ae..ecbf0a4f 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -464,7 +464,7 @@ terminal_create(struct display *display, int fullscreen) terminal->fullscreen = fullscreen; terminal->color_scheme = &jbarnes_colors; terminal->window = window_create(display, "Wayland Terminal", - 500, 100, 500, 400); + 500, 400); terminal->display = display; terminal->margin = 5; diff --git a/clients/view.c b/clients/view.c index 67149fb7..b085c678 100644 --- a/clients/view.c +++ b/clients/view.c @@ -171,8 +171,7 @@ view_create(struct display *display, uint32_t key, const char *filename) view->filename = g_strdup(filename); - view->window = window_create(display, title, - 100 * key, 100 * key, 500, 400); + view->window = window_create(display, title, 500, 400); view->display = display; /* FIXME: Window uses key 1 for moves, need some kind of diff --git a/clients/window.c b/clients/window.c index 1bbc1b8c..22cbd287 100644 --- a/clients/window.c +++ b/clients/window.c @@ -86,7 +86,7 @@ struct window { struct display *display; struct wl_surface *surface; const char *title; - struct rectangle allocation, saved_allocation, pending_allocation; + struct rectangle allocation, saved_allocation, server_allocation; int resize_edges; int redraw_scheduled; int minimum_width, minimum_height; @@ -97,6 +97,7 @@ struct window { struct input *keyboard_device; uint32_t name; enum window_buffer_type buffer_type; + int mapped; EGLImageKHR *image; cairo_surface_t *cairo_surface, *pending_surface; @@ -128,6 +129,22 @@ enum { POINTER_UNSET }; +enum window_location { + WINDOW_INTERIOR = 0, + WINDOW_RESIZING_TOP = 1, + WINDOW_RESIZING_BOTTOM = 2, + WINDOW_RESIZING_LEFT = 4, + WINDOW_RESIZING_TOP_LEFT = 5, + WINDOW_RESIZING_BOTTOM_LEFT = 6, + WINDOW_RESIZING_RIGHT = 8, + WINDOW_RESIZING_TOP_RIGHT = 9, + WINDOW_RESIZING_BOTTOM_RIGHT = 10, + WINDOW_RESIZING_MASK = 15, + WINDOW_EXTERIOR = 16, + WINDOW_TITLEBAR = 17, + WINDOW_CLIENT_AREA = 18, +}; + const char *option_xkb_layout = "us"; const char *option_xkb_variant = ""; const char *option_xkb_options = ""; @@ -547,6 +564,7 @@ window_attach_surface(struct window *window) { struct display *display = window->display; struct wl_buffer *buffer; + int32_t x, y; if (window->pending_surface != NULL) return; @@ -556,15 +574,31 @@ window_attach_surface(struct window *window) buffer = display_get_buffer_for_surface(display, window->pending_surface); - wl_surface_attach(window->surface, buffer); + if (window->resize_edges & WINDOW_RESIZING_LEFT) + x = window->server_allocation.width - + window->allocation.width; + else + x = 0; - wl_surface_map(window->surface, - window->allocation.x, - window->allocation.y, - window->allocation.width, - window->allocation.height); + if (window->resize_edges & WINDOW_RESIZING_TOP) + y = window->server_allocation.height - + window->allocation.height; + else + y = 0; + window->server_allocation = window->allocation; + window->resize_edges = 0; + wl_surface_attach(window->surface, buffer, x, y); wl_display_sync_callback(display->display, free_surface, window); + + if (!window->mapped) { + wl_surface_map_toplevel(window->surface); + window->mapped = 1; + } + + wl_surface_damage(window->surface, 0, 0, + window->allocation.width, + window->allocation.height); } void @@ -687,28 +721,15 @@ window_get_surface(struct window *window) return cairo_surface_reference(window->cairo_surface); } -enum window_location { - WINDOW_INTERIOR = 0, - WINDOW_RESIZING_TOP = 1, - WINDOW_RESIZING_BOTTOM = 2, - WINDOW_RESIZING_LEFT = 4, - WINDOW_RESIZING_TOP_LEFT = 5, - WINDOW_RESIZING_BOTTOM_LEFT = 6, - WINDOW_RESIZING_RIGHT = 8, - WINDOW_RESIZING_TOP_RIGHT = 9, - WINDOW_RESIZING_BOTTOM_RIGHT = 10, - WINDOW_RESIZING_MASK = 15, - WINDOW_EXTERIOR = 16, - WINDOW_TITLEBAR = 17, - WINDOW_CLIENT_AREA = 18, -}; - static int get_pointer_location(struct window *window, int32_t x, int32_t y) { int vlocation, hlocation, location; const int grip_size = 8; + if (!window->decoration) + return WINDOW_CLIENT_AREA; + if (x < window->margin) hlocation = WINDOW_EXTERIOR; else if (window->margin <= x && x < window->margin + grip_size) @@ -996,6 +1017,13 @@ window_create_drag(struct window *window) return wl_shell_create_drag(window->display->shell); } +void +window_move(struct window *window, struct input *input, uint32_t time) +{ + wl_shell_move(window->display->shell, + window->surface, input->input_device, time); +} + void window_activate_drag(struct wl_drag *drag, struct window *window, struct input *input, uint32_t time) @@ -1006,27 +1034,18 @@ window_activate_drag(struct wl_drag *drag, struct window *window, static void handle_configure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, - struct wl_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height) + struct wl_surface *surface, int32_t width, int32_t height) { struct window *window = wl_surface_get_user_data(surface); window->resize_edges = edges; - window->pending_allocation.x = x; - window->pending_allocation.y = y; - window->pending_allocation.width = width; - window->pending_allocation.height = height; - - if (edges & WINDOW_TITLEBAR) { - window->allocation.x = window->pending_allocation.x; - window->allocation.y = window->pending_allocation.y; - } else if (edges & WINDOW_RESIZING_MASK) { - if (window->resize_handler) - (*window->resize_handler)(window, - window->user_data); - else if (window->redraw_handler) - window_schedule_redraw(window); - } + window->allocation.width = width; + window->allocation.height = height; + + if (window->resize_handler) + (*window->resize_handler)(window, window->user_data); + if (window->redraw_handler) + window_schedule_redraw(window); } static const struct wl_shell_listener shell_listener = { @@ -1051,21 +1070,11 @@ void window_set_child_size(struct window *window, struct rectangle *rectangle) { - int32_t width, height; - if (!window->fullscreen) { - width = rectangle->width + 20 + window->margin * 2; - height = rectangle->height + 60 + window->margin * 2; - - if (window->resize_edges & WINDOW_RESIZING_LEFT) - window->allocation.x += - window->allocation.width - width; - if (window->resize_edges & WINDOW_RESIZING_TOP) - window->allocation.y += - window->allocation.height - height; - - window->allocation.width = width; - window->allocation.height = height; + window->allocation.width = + rectangle->width + 20 + window->margin * 2; + window->allocation.height = + rectangle->height + 60 + window->margin * 2; } } @@ -1098,13 +1107,9 @@ idle_redraw(void *data) { struct window *window = data; - if (window->resize_edges) - window->allocation = window->pending_allocation; - window->redraw_handler(window, window->user_data); window->redraw_scheduled = 0; - window->resize_edges = 0; return FALSE; } @@ -1190,19 +1195,6 @@ window_set_keyboard_focus_handler(struct window *window, window->keyboard_focus_handler = handler; } -void -window_move(struct window *window, int32_t x, int32_t y) -{ - window->allocation.x = x; - window->allocation.y = y; - - wl_surface_map(window->surface, - window->allocation.x - window->margin, - window->allocation.y - window->margin, - window->allocation.width, - window->allocation.height); -} - void window_damage(struct window *window, int32_t x, int32_t y, int32_t width, int32_t height) @@ -1212,7 +1204,7 @@ window_damage(struct window *window, int32_t x, int32_t y, struct window * window_create(struct display *display, const char *title, - int32_t x, int32_t y, int32_t width, int32_t height) + int32_t width, int32_t height) { struct window *window; @@ -1224,8 +1216,8 @@ window_create(struct display *display, const char *title, window->display = display; window->title = strdup(title); window->surface = wl_compositor_create_surface(display->compositor); - window->allocation.x = x; - window->allocation.y = y; + window->allocation.x = 0; + window->allocation.y = 0; window->allocation.width = width; window->allocation.height = height; window->saved_allocation = window->allocation; diff --git a/clients/window.h b/clients/window.h index 74e95b6e..341f6022 100644 --- a/clients/window.h +++ b/clients/window.h @@ -125,7 +125,10 @@ typedef void (*display_drag_offer_handler_t)(struct wl_drag_offer *offer, struct window * window_create(struct display *display, const char *title, - int32_t x, int32_t y, int32_t width, int32_t height); + int32_t width, int32_t height); + +void +window_move(struct window *window, struct input *input, uint32_t time); void window_draw(struct window *window); @@ -142,9 +145,6 @@ window_copy_image(struct window *window, void window_schedule_redraw(struct window *window); -void -window_move(struct window *window, int32_t x, int32_t y); - void window_damage(struct window *window, int32_t x, int32_t y, int32_t width, int32_t height); diff --git a/compositor/compositor-wayland.c b/compositor/compositor-wayland.c index 40dee581..b216ebdd 100644 --- a/compositor/compositor-wayland.c +++ b/compositor/compositor-wayland.c @@ -193,7 +193,8 @@ wayland_compositor_present(struct wlsc_compositor *base) output->rbo[output->current]); wl_surface_attach(output->parent.surface, - output->parent.buffer[output->current ^ 1]); + output->parent.buffer[output->current ^ 1], + 0, 0); wl_surface_damage(output->parent.surface, 0, 0, output->base.width, output->base.height); } @@ -264,10 +265,8 @@ wayland_compositor_create_output(struct wayland_compositor *c, output->rbo[output->current]); wl_surface_attach(output->parent.surface, - output->parent.buffer[output->current]); - wl_surface_map(output->parent.surface, - output->base.x, output->base.y, - output->base.width, output->base.height); + output->parent.buffer[output->current], 0, 0); + wl_surface_map_toplevel(output->parent.surface); glClearColor(0, 0, 0, 0.5); diff --git a/compositor/compositor.c b/compositor/compositor.c index 0e1323f8..d9b81d87 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -419,27 +419,31 @@ surface_destroy(struct wl_client *client, static void surface_attach(struct wl_client *client, - struct wl_surface *surface, struct wl_buffer *buffer) + struct wl_surface *surface, struct wl_buffer *buffer, + int32_t x, int32_t y) { struct wlsc_surface *es = (struct wlsc_surface *) surface; buffer->attach(buffer, surface); es->buffer = buffer; + es->x += x; + es->y += y; + es->width = buffer->width; + es->height = buffer->height; + wlsc_surface_update_matrix(es); } static void -surface_map(struct wl_client *client, - struct wl_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height) +surface_map_toplevel(struct wl_client *client, + struct wl_surface *surface) { struct wlsc_surface *es = (struct wlsc_surface *) surface; - es->x = x; - es->y = y; - es->width = width; - es->height = height; + es->x = 10 + random() % 400; + es->y = 10 + random() % 400; wlsc_surface_update_matrix(es); + wl_list_insert(es->compositor->surface_list.prev, &es->link); wlsc_compositor_schedule_repaint(es->compositor); } @@ -457,7 +461,7 @@ surface_damage(struct wl_client *client, const static struct wl_surface_interface surface_interface = { surface_destroy, surface_attach, - surface_map, + surface_map_toplevel, surface_damage }; @@ -557,17 +561,9 @@ move_grab_motion(struct wl_grab *grab, struct wlsc_move_grab *move = (struct wlsc_move_grab *) grab; struct wlsc_surface *es = (struct wlsc_surface *) grab->input_device->pointer_focus; - struct wlsc_compositor *ec = - (struct wlsc_compositor *) grab->input_device->compositor; es->x = x + move->dx; es->y = y + move->dy; - wl_client_post_event(es->surface.client, &ec->shell.object, - WL_SHELL_CONFIGURE, - time, WLSC_DEVICE_GRAB_MOVE, - &es->surface, es->x, es->y, - es->width, es->height); - wlsc_surface_update_matrix(es); } @@ -630,33 +626,27 @@ resize_grab_motion(struct wl_grab *grab, struct wlsc_compositor *ec = (struct wlsc_compositor *) device->compositor; struct wl_surface *surface = device->pointer_focus; - int32_t sx, sy, width, height; + int32_t width, height; if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_LEFT) { - sx = x + resize->dx; width = device->grab_x - x + resize->width; } else if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_RIGHT) { - sx = device->grab_x + resize->dx; width = x - device->grab_x + resize->width; } else { - sx = device->grab_x + resize->dx; width = resize->width; } if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_TOP) { - sy = y + resize->dy; height = device->grab_y - y + resize->height; } else if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_BOTTOM) { - sy = device->grab_y + resize->dy; height = y - device->grab_y + resize->height; } else { - sy = device->grab_y + resize->dy; height = resize->height; } wl_client_post_event(surface->client, &ec->shell.object, WL_SHELL_CONFIGURE, time, resize->edges, - surface, sx, sy, width, height); + surface, width, height); } static void @@ -814,7 +804,6 @@ compositor_create_surface(struct wl_client *client, return; } - wl_list_insert(ec->surface_list.prev, &surface->link); surface->surface.resource.destroy = destroy_surface; surface->surface.resource.object.id = id; diff --git a/protocol/wayland.xml b/protocol/wayland.xml index 62d8a663..8799a64e 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -172,11 +172,8 @@ received. --> - - + - - @@ -281,20 +278,18 @@ - + - - - - - - + + +