Re: [PATCH V2] Do not assume 64x64 cursor, added support for other sizes (like in AMD Kaveri, 128x128).
On 07/04/2014 04:13 AM, Michel Dänzer wrote: On 03.07.2014 21:27, Ander Conselvan de Oliveira wrote: On 06/25/2014 05:09 PM, Alvaro Fernando García wrote: Init cursor size to 64x64 if drmGetCap() fails. Use Mesa GBM_BO_USE_CURSOR define (which removes 64x64 restriction) Signed-off-by: Alvaro Fernando García --- src/compositor-drm.c | 43 --- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 7d514e4..61ddea1 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -55,6 +55,14 @@ #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 #endif +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 0x8 +#endif + +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + static int option_current_mode = 0; enum output_config { [...] @@ -1554,15 +1577,21 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) return -1; } -flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE; +#ifdef GBM_BO_USE_CURSOR +flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE; +#else +flags = GBM_BO_USE_WRITE; +if (ec->cursor_width == 64 && ec->cursor_height == 64) +flags = GBM_BO_USE_CURSOR_64X64 | flags; +#endif Do we really need this? GBM_BO_USE_CURSOR has the same value as the old _64X64 flag. GBM will check if the dimensions are 64x64 and fail otherwise. No, that check was removed when adding GBM_BO_USE_CURSOR. So this could just be flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE; and a #ifndef GBM_BO_USE_CURSOR #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64 #endif earlier in the file. No, if GBM doesn't define GBM_BO_USE_CURSOR, it will likely fail if the dimensions are not 64x64. And that is what we expect. We shouldn't rely on a buffer allocated with only GBM_BO_USE_WRITE to use as a hardware cursor. My point is that the code I proposed should work with both old and new GBM. For old GBM, if cursor is not 64x64, gbm won't allocate the bo and the check that follows the allocation will disable hardware cursors. If GBM is new enough, everything works. On top of that, it avoids the ifdef in the middle of a function. Ander ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH V2] Do not assume 64x64 cursor, added support for other sizes (like in AMD Kaveri, 128x128).
On 06/25/2014 05:09 PM, Alvaro Fernando García wrote: Init cursor size to 64x64 if drmGetCap() fails. Use Mesa GBM_BO_USE_CURSOR define (which removes 64x64 restriction) Signed-off-by: Alvaro Fernando García --- src/compositor-drm.c | 43 --- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 7d514e4..61ddea1 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -55,6 +55,14 @@ #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 #endif +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 0x8 +#endif + +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + static int option_current_mode = 0; enum output_config { [...] @@ -1554,15 +1577,21 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) return -1; } - flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE; +#ifdef GBM_BO_USE_CURSOR + flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE; +#else + flags = GBM_BO_USE_WRITE; + if (ec->cursor_width == 64 && ec->cursor_height == 64) + flags = GBM_BO_USE_CURSOR_64X64 | flags; +#endif Do we really need this? GBM_BO_USE_CURSOR has the same value as the old _64X64 flag. GBM will check if the dimensions are 64x64 and fail otherwise. So this could just be flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE; and a #ifndef GBM_BO_USE_CURSOR #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64 #endif earlier in the file. Cheers, Ander for (i = 0; i < 2; i++) { if (output->cursor_bo[i]) continue; output->cursor_bo[i] = - gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB, - flags); + gbm_bo_create(ec->gbm, ec->cursor_width, ec->cursor_height, + GBM_FORMAT_ARGB, flags); } if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) { ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: How do I get started?
On 06/29/2014 05:45 PM, Ayan Shafqat wrote: Thanks for your prompt reply, Armin. I am familiar with git scm and have used it for a few projects. What I am interested in are the points below: (1) Coding style guidelines for Wayland. (2) Where to submit patches. The following document covers the above: http://cgit.freedesktop.org/wayland/wayland/tree/doc/Contributing Ander ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: Simple SHM Wayland Client
On 05/30/2014 09:57 AM, Marek Chalupa wrote: Hi, On 29 May 2014 13:59, Philip Rushik mailto:prus...@gmail.com>> wrote: On Thu, May 29, 2014 at 8:02 PM, Marek Chalupa mailto:mchqwe...@gmail.com>> wrote: [...] xdg_surface stuff is not part of libwayland-client and I don't really fully understand what is supposed to be happening here. Also, _wl_fullscreen_shell_present_surface seems strange and is not exported by libwayland-client, and if the example code doesn't use either of those it has to quit. These protocols are not a part of libwayland, but Weston. You can find their specification in weston/protocol directory (those xml files) and you can generate sources from them using wayland-scanner. Then you can link against these sources (namely xdg-shell-protocol.c for xdg_* stuff and fullscreen-shell-procotol.c for the another). But as far as I know, the common wl_surface should be enough for creating a window without borders and buttons in Weston (that's how the weston/tests/weston-test-client-helpers.c works). That's not exactly true. In order for a surface to be displayed on the screen, it needs to have a role. The role of the surface defines what happens when a buffer is attached to it. In the case of the file you mentioned, the role of the surface is set using the wl_test interface. This is not quite clear since it is done by the wl_test::move_surface request. So if you want to use only libwayland-client, as you wrote before, you should not use xdg_shell and fullscreen_shell. What you need to do is: An alternative would be to use wl_shell. While in the long run it is expected that xdg_shell will replace it, it is currently shipped with libwayland-client and should work. You can look at the link below for the commit that changed simple-shm to use xdg_shell instead of wl_shell. http://cgit.freedesktop.org/wayland/weston/commit/?id=dfaf65ba1636e49b850adff34f31de00b5f06bba Cheers, Ander ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] vaapi-recorder: Don't loop trying to write on out of space condition
From: Ander Conselvan de Oliveira The error handling for the function that writes the encoded frame on the disk was bogus, always assuming the buffer supplied to the encoder was too small. That would cause a bigger buffer to be allocated and another attempt to encode the frame was done. In the case of a failure to write to disk (due to ENOSPC, for instance) that would cause an endless loop. --- Possibly related to https://bugs.freedesktop.org/show_bug.cgi?id=69330 --- src/compositor-drm.c | 27 +++ src/vaapi-recorder.c | 42 +- src/vaapi-recorder.h | 2 +- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 5f59789..7d514e4 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2558,6 +2558,18 @@ planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data #ifdef BUILD_VAAPI_RECORDER static void +recorder_destroy(struct drm_output *output) +{ + vaapi_recorder_destroy(output->recorder); + output->recorder = NULL; + + output->base.disable_planes--; + + wl_list_remove(&output->recorder_frame_listener.link); + weston_log("[libva recorder] done\n"); +} + +static void recorder_frame_notify(struct wl_listener *listener, void *data) { struct drm_output *output; @@ -2579,7 +2591,12 @@ recorder_frame_notify(struct wl_listener *listener, void *data) return; } - vaapi_recorder_frame(output->recorder, fd, output->current->stride); + ret = vaapi_recorder_frame(output->recorder, fd, + output->current->stride); + if (ret < 0) { + weston_log("[libva recorder] aborted: %m\n"); + recorder_destroy(output); + } } static void * @@ -2637,13 +2654,7 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, weston_log("[libva recorder] initialized\n"); } else { - vaapi_recorder_destroy(output->recorder); - output->recorder = NULL; - - output->base.disable_planes--; - - wl_list_remove(&output->recorder_frame_listener.link); - weston_log("[libva recorder] done\n"); + recorder_destroy(output); } } #else diff --git a/src/vaapi-recorder.c b/src/vaapi-recorder.c index 0095a42..921494d 100644 --- a/src/vaapi-recorder.c +++ b/src/vaapi-recorder.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -93,6 +94,7 @@ struct vaapi_recorder { int width, height; int frame_count; + int error; int destroying; pthread_t worker_thread; pthread_mutex_t mutex; @@ -761,7 +763,13 @@ encoder_create_output_buffer(struct vaapi_recorder *r) return VA_INVALID_ID; } -static int +enum output_write_status { + OUTPUT_WRITE_SUCCESS, + OUTPUT_WRITE_OVERFLOW, + OUTPUT_WRITE_FATAL +}; + +static enum output_write_status encoder_write_output(struct vaapi_recorder *r, VABufferID output_buf) { VACodedBufferSegment *segment; @@ -770,19 +778,22 @@ encoder_write_output(struct vaapi_recorder *r, VABufferID output_buf) status = vaMapBuffer(r->va_dpy, output_buf, (void **) &segment); if (status != VA_STATUS_SUCCESS) - return -1; + return OUTPUT_WRITE_FATAL; if (segment->status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) { r->encoder.output_size *= 2; vaUnmapBuffer(r->va_dpy, output_buf); - return -1; + return OUTPUT_WRITE_OVERFLOW; } count = write(r->output_fd, segment->buf, segment->size); vaUnmapBuffer(r->va_dpy, output_buf); - return count; + if (count < 0) + return OUTPUT_WRITE_FATAL; + + return OUTPUT_WRITE_SUCCESS; } static void @@ -792,9 +803,8 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input) VABufferID buffers[8]; int count = 0; - - int slice_type; - int ret, i; + int i, slice_type; + enum output_write_status ret; if ((r->frame_count % r->encoder.intra_period) == 0) slice_type = SLICE_TYPE_I; @@ -829,7 +839,10 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input) output_buf = VA_INVALID_ID; vaDestroyBuffer(r->va_dpy, buffers[--count]); - } while (ret < 0); + } while (ret == OUTPUT_WRITE_OVERFLOW); + + if (ret == OUTPUT_WRITE_FATAL) + r->error = errno; for (i = 0; i < count; i++) vaDestroyBuffer(r->va_dpy, buffers[i]); @@ -1138,11 +1151,19 @@ worker_thread_funct
[PATCH weston] editor: Fix cursor positioning with pointer and touch
The calculation off the vertical offset between the widget coordinates and where the text was rendered was wrong. It was using the constant for horizontal offset for that too. --- clients/editor.c | 33 +++-- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/clients/editor.c b/clients/editor.c index 3b00833..f3f6141 100644 --- a/clients/editor.c +++ b/clients/editor.c @@ -1011,7 +1011,17 @@ text_entry_draw_cursor(struct text_entry *entry, cairo_t *cr) cairo_stroke(cr); } -static const int text_offset_left = 10; +static int +text_offset_left(struct rectangle *allocation) +{ + return 10; +} + +static int +text_offset_top(struct rectangle *allocation) +{ + return allocation->height / 2; +} static void text_entry_redraw_handler(struct widget *widget, void *data) @@ -1048,7 +1058,9 @@ text_entry_redraw_handler(struct widget *widget, void *data) cairo_set_source_rgba(cr, 0, 0, 0, 1); - cairo_translate(cr, text_offset_left, allocation.height / 2); + cairo_translate(cr, + text_offset_left(&allocation), + text_offset_top(&allocation)); if (!entry->layout) entry->layout = pango_cairo_create_layout(cr); @@ -1075,6 +1087,7 @@ text_entry_motion_handler(struct widget *widget, { struct text_entry *entry = data; struct rectangle allocation; + int tx, ty; if (!entry->button_pressed) { return CURSOR_IBEAM; @@ -1082,10 +1095,10 @@ text_entry_motion_handler(struct widget *widget, widget_get_allocation(entry->widget, &allocation); - text_entry_set_cursor_position(entry, - x - allocation.x - text_offset_left, - y - allocation.y - text_offset_left, - false); + tx = x - allocation.x - text_offset_left(&allocation); + ty = y - allocation.y - text_offset_top(&allocation); + + text_entry_set_cursor_position(entry, tx, ty, false); return CURSOR_IBEAM; } @@ -1105,8 +1118,8 @@ text_entry_button_handler(struct widget *widget, widget_get_allocation(entry->widget, &allocation); input_get_position(input, &x, &y); - x -= allocation.x + text_offset_left; - y -= allocation.y + text_offset_left; + x -= allocation.x + text_offset_left(&allocation); + y -= allocation.y + text_offset_top(&allocation); editor = window_get_user_data(entry->window); @@ -1149,8 +1162,8 @@ text_entry_touch_handler(struct widget *widget, struct input *input, widget_get_allocation(entry->widget, &allocation); - x = tx - (allocation.x + text_offset_left); - y = ty - (allocation.y + text_offset_left); + x = tx - (allocation.x + text_offset_left(&allocation)); + y = ty - (allocation.y + text_offset_top(&allocation)); editor = window_get_user_data(entry->window); text_entry_activate(entry, seat); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] simple-touch: Handle multiple seats
On 05/07/2014 05:13 PM, Jasper St. Pierre wrote: Looks mostly the same as Ander's patch here: My patch didn't handle global remove properly, so I'd say we should go with this one. Ander http://lists.freedesktop.org/archives/wayland-devel/2014-May/014658.html Same review applies :) On Wed, May 7, 2014 at 10:00 AM, Neil Roberts mailto:n...@linux.intel.com>> wrote: Previously simple-touch would only handle one seat. If there were multiple seats it would lose track of whether there is a touch device available depending on what order the capability events arrive in. This makes it keep a linked list of seats and to track a separate touch device for each seat so that it doesn't matter what order they arrive in. https://bugs.freedesktop.org/show_bug.cgi?id=78365 --- clients/simple-touch.c | 77 +++--- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/clients/simple-touch.c b/clients/simple-touch.c index b5a84d7..a45de46 100644 --- a/clients/simple-touch.c +++ b/clients/simple-touch.c @@ -42,18 +42,25 @@ struct touch { struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; - struct wl_seat *seat; - struct wl_touch *wl_touch; struct wl_pointer *pointer; struct wl_keyboard *keyboard; struct wl_surface *surface; struct wl_shell_surface *shell_surface; struct wl_buffer *buffer; + struct wl_list seats; int has_argb; int width, height; void *data; }; +struct touch_seat { + struct touch *touch; + struct wl_touch *wl_touch; + struct wl_seat *wl_seat; + struct wl_list link; + uint32_t name; +}; + static void create_shm_buffer(struct touch *touch) { @@ -156,7 +163,8 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) { - struct touch *touch = data; + struct touch_seat *seat = data; + struct touch *touch = seat->touch; float x = wl_fixed_to_double(x_w); float y = wl_fixed_to_double(y_w); @@ -173,7 +181,8 @@ static void touch_handle_motion(void *data, struct wl_touch *wl_touch, uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) { - struct touch *touch = data; + struct touch_seat *seat = data; + struct touch *touch = seat->touch; float x = wl_fixed_to_double(x_w); float y = wl_fixed_to_double(y_w); @@ -199,18 +208,18 @@ static const struct wl_touch_listener touch_listener = { }; static void -seat_handle_capabilities(void *data, struct wl_seat *seat, +seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { - struct touch *touch = data; - - if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !touch->wl_touch) { - touch->wl_touch = wl_seat_get_touch(seat); - wl_touch_set_user_data(touch->wl_touch, touch); - wl_touch_add_listener(touch->wl_touch, &touch_listener, touch); - } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && touch->wl_touch) { - wl_touch_destroy(touch->wl_touch); - touch->wl_touch = NULL; + struct touch_seat *seat = data; + + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !seat->wl_touch) { + seat->wl_touch = wl_seat_get_touch(wl_seat); + wl_touch_set_user_data(seat->wl_touch, seat); + wl_touch_add_listener(seat->wl_touch, &touch_listener, seat); + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch) { + wl_touch_destroy(seat->wl_touch); + seat->wl_touch = NULL; } } @@ -243,6 +252,31 @@ static const struct wl_shell_surface_listener shell_surface_listener = { }; static void +add_seat(struct touch *touch, uint32_t name) +{ + struct touch_seat *seat; + + seat = malloc(sizeof *seat); + seat->touch = touch; + seat->wl_seat = wl_registry_bind(touch->registry, name, +&wl_seat_interface, 1); + seat->name = name; + seat->wl_touch = NULL; + wl_seat_add_listener(seat->wl_seat, &seat_listener, seat); + wl_list_insert(&touch->seats, &seat->link); +} + +static void +remove_seat(struct touch_seat *seat) +{ + if (seat->wl_tou
Re: [PATCH weston 2/3] simple-touch: Handle multiple seats properly
On 05/07/2014 05:27 PM, Neil Roberts wrote: Oh no, I didn't notice this patch buried in the patch series and implemented the same thing: http://lists.freedesktop.org/archives/wayland-devel/2014-May/014690.html Ander, it would be really helpful if you could leave a little note on the bug report if you post a patch to reduce that chance that I'll waste time looking at the same bug. Sorry about that. It seems you wrote a better patch than mine anyway, so no harm. :) I'll add comments to the bugs from now on. Cheers, Ander Regards, - Neil Ander Conselvan de Oliveira writes: From: Ander Conselvan de Oliveira If simple-touch ran on a compositor with multiple seats, and the first one happened to have the touch capability while the second one didn't, the handler for seat capabilities would destroy the wl_touch device it created on the first call for the first seat when it was called a again for the second seat that has not touch capabilities. Fix this problem by creating a separate struct for each seat. https://bugs.freedesktop.org/show_bug.cgi?id=78365 --- clients/simple-touch.c | 48 +--- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/clients/simple-touch.c b/clients/simple-touch.c index b5a84d7..d8439ac 100644 --- a/clients/simple-touch.c +++ b/clients/simple-touch.c @@ -36,14 +36,18 @@ #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) +struct seat { + struct touch *touch; + struct wl_seat *seat; + struct wl_touch *wl_touch; +}; + struct touch { struct wl_display *display; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; - struct wl_seat *seat; - struct wl_touch *wl_touch; struct wl_pointer *pointer; struct wl_keyboard *keyboard; struct wl_surface *surface; @@ -199,18 +203,19 @@ static const struct wl_touch_listener touch_listener = { }; static void -seat_handle_capabilities(void *data, struct wl_seat *seat, +seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { - struct touch *touch = data; - - if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !touch->wl_touch) { - touch->wl_touch = wl_seat_get_touch(seat); - wl_touch_set_user_data(touch->wl_touch, touch); - wl_touch_add_listener(touch->wl_touch, &touch_listener, touch); - } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && touch->wl_touch) { - wl_touch_destroy(touch->wl_touch); - touch->wl_touch = NULL; + struct seat *seat = data; + struct touch *touch = seat->touch; + + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !seat->wl_touch) { + seat->wl_touch = wl_seat_get_touch(wl_seat); + wl_touch_set_user_data(seat->wl_touch, touch); + wl_touch_add_listener(seat->wl_touch, &touch_listener, touch); + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch) { + wl_touch_destroy(seat->wl_touch); + seat->wl_touch = NULL; } } @@ -219,6 +224,21 @@ static const struct wl_seat_listener seat_listener = { }; static void +add_seat(struct touch *touch, uint32_t name, uint32_t version) +{ + struct seat *seat; + + seat = malloc(sizeof *seat); + assert(seat); + + seat->touch = touch; + seat->wl_touch = NULL; + seat->seat = wl_registry_bind(touch->registry, name, + &wl_seat_interface, 1); + wl_seat_add_listener(seat->seat, &seat_listener, seat); +} + +static void handle_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) { @@ -261,9 +281,7 @@ handle_global(void *data, struct wl_registry *registry, &wl_shm_interface, 1); wl_shm_add_listener(touch->shm, &shm_listener, touch); } else if (strcmp(interface, "wl_seat") == 0) { - touch->seat = wl_registry_bind(registry, name, - &wl_seat_interface, 1); - wl_seat_add_listener(touch->seat, &seat_listener, touch); + add_seat(touch, name, version); } } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston 1/3] shell: Fix artifacts caused by workspace change animation
On 05/07/2014 04:10 PM, Jasper St. Pierre wrote: Hm, it seems to me that hiding a layer should cause all the regions it occupied to be marked as needing repaint. Fixing the scene graph is better than a one-off at the end of an animation. I agree. I actually sent a patch in January to create a weston_layer_show() function, which would be a natural place to handle this, but it didn't get traction. http://lists.freedesktop.org/archives/wayland-devel/2014-January/012969.html Cheers, Ander On Wed, May 7, 2014 at 4:57 AM, Ander Conselvan de Oliveira mailto:conselv...@gmail.com>> wrote: From: Ander Conselvan de Oliveira mailto:ander.conselvan.de.olive...@intel.com>> Views that extend past the bottom of the output are still visible after the workspace animation ends but before its layer is hidden. When the layer was hidden, nothing would cause those regions to be repainted, leading to artifacts. https://bugs.freedesktop.org/show_bug.cgi?id=78363 --- desktop-shell/shell.c | 9 + 1 file changed, 9 insertions(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index a631c62..fac3120 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1027,8 +1027,17 @@ finish_workspace_change_animation(struct desktop_shell *shell, struct workspace *from, struct workspace *to) { + struct weston_view *view; + weston_compositor_schedule_repaint(shell->compositor); + /* Views that extend past the bottom of the output are still +* visible after the workspace animation ends but before its layer +* is hidden. In that case, we need to damage below those views so +* that the screen is properly repainted. */ + wl_list_for_each(view, &from->layer.view_list, layer_link) + weston_view_damage_below(view); + wl_list_remove(&shell->workspaces.animation.link); workspace_deactivate_transforms(from); workspace_deactivate_transforms(to); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org <mailto:wayland-devel@lists.freedesktop.org> http://lists.freedesktop.org/mailman/listinfo/wayland-devel -- Jasper ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] shell: Don't allow maximized surfaces to be moved with touch
From: Ander Conselvan de Oliveira Moving a maximized surface with the pointer is already not possible, so make the behavior with touch consistent. https://bugs.freedesktop.org/show_bug.cgi?id=78208 --- desktop-shell/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index ea7b3cd..db55ea9 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1453,7 +1453,7 @@ surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat) if (!shsurf) return -1; - if (shsurf->state.fullscreen) + if (shsurf->state.fullscreen || shsurf->state.maximized) return 0; move = malloc(sizeof *move); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 2/3] simple-touch: Handle multiple seats properly
From: Ander Conselvan de Oliveira If simple-touch ran on a compositor with multiple seats, and the first one happened to have the touch capability while the second one didn't, the handler for seat capabilities would destroy the wl_touch device it created on the first call for the first seat when it was called a again for the second seat that has not touch capabilities. Fix this problem by creating a separate struct for each seat. https://bugs.freedesktop.org/show_bug.cgi?id=78365 --- clients/simple-touch.c | 48 +--- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/clients/simple-touch.c b/clients/simple-touch.c index b5a84d7..d8439ac 100644 --- a/clients/simple-touch.c +++ b/clients/simple-touch.c @@ -36,14 +36,18 @@ #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) +struct seat { + struct touch *touch; + struct wl_seat *seat; + struct wl_touch *wl_touch; +}; + struct touch { struct wl_display *display; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; - struct wl_seat *seat; - struct wl_touch *wl_touch; struct wl_pointer *pointer; struct wl_keyboard *keyboard; struct wl_surface *surface; @@ -199,18 +203,19 @@ static const struct wl_touch_listener touch_listener = { }; static void -seat_handle_capabilities(void *data, struct wl_seat *seat, +seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { - struct touch *touch = data; - - if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !touch->wl_touch) { - touch->wl_touch = wl_seat_get_touch(seat); - wl_touch_set_user_data(touch->wl_touch, touch); - wl_touch_add_listener(touch->wl_touch, &touch_listener, touch); - } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && touch->wl_touch) { - wl_touch_destroy(touch->wl_touch); - touch->wl_touch = NULL; + struct seat *seat = data; + struct touch *touch = seat->touch; + + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !seat->wl_touch) { + seat->wl_touch = wl_seat_get_touch(wl_seat); + wl_touch_set_user_data(seat->wl_touch, touch); + wl_touch_add_listener(seat->wl_touch, &touch_listener, touch); + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch) { + wl_touch_destroy(seat->wl_touch); + seat->wl_touch = NULL; } } @@ -219,6 +224,21 @@ static const struct wl_seat_listener seat_listener = { }; static void +add_seat(struct touch *touch, uint32_t name, uint32_t version) +{ + struct seat *seat; + + seat = malloc(sizeof *seat); + assert(seat); + + seat->touch = touch; + seat->wl_touch = NULL; + seat->seat = wl_registry_bind(touch->registry, name, + &wl_seat_interface, 1); + wl_seat_add_listener(seat->seat, &seat_listener, seat); +} + +static void handle_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) { @@ -261,9 +281,7 @@ handle_global(void *data, struct wl_registry *registry, &wl_shm_interface, 1); wl_shm_add_listener(touch->shm, &shm_listener, touch); } else if (strcmp(interface, "wl_seat") == 0) { - touch->seat = wl_registry_bind(registry, name, - &wl_seat_interface, 1); - wl_seat_add_listener(touch->seat, &seat_listener, touch); + add_seat(touch, name, version); } } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 3/3] shell: Fix crash when restoring focus state during workspace change
From: Ander Conselvan de Oliveira The check to avoid calling weston_keyboard_set_focus() for a seat that didn't have a keyboard in restore_focus_state() was cheking the wrong seat (the one from the previous loop). That caused a crash when switching workspaces if there was an extra seat that didn't have a keyboard. https://bugs.freedesktop.org/show_bug.cgi?id=78349 --- desktop-shell/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index fac3120..ea7b3cd 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -731,7 +731,7 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws) wl_list_for_each_safe(seat, next_seat, &pending_seat_list, link) { wl_list_insert(&shell->compositor->seat_list, &seat->link); - if (state->seat->keyboard == NULL) + if (seat->keyboard == NULL) continue; weston_keyboard_set_focus(seat->keyboard, NULL); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 1/3] shell: Fix artifacts caused by workspace change animation
From: Ander Conselvan de Oliveira Views that extend past the bottom of the output are still visible after the workspace animation ends but before its layer is hidden. When the layer was hidden, nothing would cause those regions to be repainted, leading to artifacts. https://bugs.freedesktop.org/show_bug.cgi?id=78363 --- desktop-shell/shell.c | 9 + 1 file changed, 9 insertions(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index a631c62..fac3120 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1027,8 +1027,17 @@ finish_workspace_change_animation(struct desktop_shell *shell, struct workspace *from, struct workspace *to) { + struct weston_view *view; + weston_compositor_schedule_repaint(shell->compositor); + /* Views that extend past the bottom of the output are still +* visible after the workspace animation ends but before its layer +* is hidden. In that case, we need to damage below those views so +* that the screen is properly repainted. */ + wl_list_for_each(view, &from->layer.view_list, layer_link) + weston_view_damage_below(view); + wl_list_remove(&shell->workspaces.animation.link); workspace_deactivate_transforms(from); workspace_deactivate_transforms(to); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] compositor-drm: Don't use vaapi recorder with unsupported formats
From: Ander Conselvan de Oliveira We only support recording with GBM_FORMAT_XRGB888 format, so don't try to record if the output has a differnt format. https://bugs.freedesktop.org/show_bug.cgi?id=78199 --- src/compositor-drm.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 4441308..5f59789 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2611,6 +2611,12 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, struct drm_output, base.link); if (!output->recorder) { + if (output->format != GBM_FORMAT_XRGB) { + weston_log("failed to start vaapi recorder: " + "output format not supported\n"); + return; + } + width = output->base.current_mode->width; height = output->base.current_mode->height; -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH] doc: Added API documentation for wl_display_create function.
On 05/06/2014 04:17 PM, Ander Conselvan de Oliveira wrote: On 05/06/2014 01:22 PM, Srivardhan Hebbar wrote: Signed-off-by: Srivardhan Hebbar --- src/wayland-server.c |9 + 1 file changed, 9 insertions(+) diff --git a/src/wayland-server.c b/src/wayland-server.c index f2b1b42..7b32848 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -788,6 +788,15 @@ bind_display(struct wl_client *client, destroy_client_display_resource); } +/** Create Wayland display object. + * + * \param None + * \return The Wayland display object. Null if failed to create + * + * This creates the wl_display object for the client. + * + * \memberof wl_display We have two objects named wl_display, and the one that is documented as \class wl_display is the client side one. I'm not sure how to tell doxygen that these are two separate things. A quick Google search suggested \addtogroup might help, but I haven't really checked if that is what we want. Never mind. We actually do two separate doxygen passes, one for the server source files and one for the client source files, so this is already separate. Cheers, Ander + */ WL_EXPORT struct wl_display * wl_display_create(void) { ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH] doc: Added API documentation for wl_display_create function.
On 05/06/2014 01:22 PM, Srivardhan Hebbar wrote: Signed-off-by: Srivardhan Hebbar --- src/wayland-server.c |9 + 1 file changed, 9 insertions(+) diff --git a/src/wayland-server.c b/src/wayland-server.c index f2b1b42..7b32848 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -788,6 +788,15 @@ bind_display(struct wl_client *client, destroy_client_display_resource); } +/** Create Wayland display object. + * + * \param None + * \return The Wayland display object. Null if failed to create + * + * This creates the wl_display object for the client. + * + * \memberof wl_display We have two objects named wl_display, and the one that is documented as \class wl_display is the client side one. I'm not sure how to tell doxygen that these are two separate things. A quick Google search suggested \addtogroup might help, but I haven't really checked if that is what we want. Cheers, Ander + */ WL_EXPORT struct wl_display * wl_display_create(void) { ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] window: Ignore input events from subsurfaces
On 05/06/2014 03:40 PM, Pekka Paalanen wrote: On Tue, 6 May 2014 15:25:40 +0300 Ander Conselvan de Oliveira wrote: From: Ander Conselvan de Oliveira Toytoolkit was not designed to handle input from subsurfaces and instead it expects subsurfaces to have an empty input region. That way input events for subsurfaces are generated on the main surface and there is no need to convert coordinates before reporting the event to the user. However it is possible that a subsurface has a non-empty input region, but in that case those events aren't properly processed. The function window_find_widget() assumes the coordinates are in the main surface coordinate space, and ends up chosing the wrong widget. This patch changes the input code to completely ignore input events from subsurfaces. This option was chosen instead of ensuring that the input region on those surfaces is always empty since there's no enforcement that a subsurface should completely overlap with the main surface. If an event happens in the area of the surface that doesn't overlap, the event could cause a completely unrelated surface to be picked. https://bugs.freedesktop.org/show_bug.cgi?id=78207 --- clients/window.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/clients/window.c b/clients/window.c index b7febed..3b57264 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2605,10 +2605,15 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, return; } + window = wl_surface_get_user_data(surface); + if (surface != window->main_surface->surface) { + DBG("Ignoring input event from subsurface %p\n", surface); + return; Ignoring enter on a sub-surface, actually. I assume the explanation is that, that the leave on the main surface already sets pointer_focus to NULL, and here we just avoid setting it, so all following input events get ignored. Ok. + } + input->display->serial = serial; input->pointer_enter_serial = serial; - input->pointer_focus = wl_surface_get_user_data(surface); - window = input->pointer_focus; + input->pointer_focus = window; if (window->resizing) { window->resizing = 0; @@ -2644,12 +2649,12 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer, float sx = wl_fixed_to_double(sx_w); float sy = wl_fixed_to_double(sy_w); - input->sx = sx; - input->sy = sy; - if (!window) return; + input->sx = sx; + input->sy = sy; + /* when making the window smaller - e.g. after a unmaximise we might * still have a pending motion event that the compositor has picked * based on the old surface dimensions @@ -2979,6 +2984,12 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, return; } + if (surface != input->touch_focus->main_surface->surface) { Could touch_focus somehow already be NULL? Yeah, it's possible. If I understand correctly, in that case all touch events are ignored. Like putting two fingers one after the other to the sub-surface? + DBG("Ignoring input event from subsurface %p\n", surface); + input->touch_focus = NULL; If I have a finger down on the main surface somewhere, and put another finger on the tooltip, won't I lose the main surface then? Sorry, I've no idea how multitouch works here. Yeah, the main surface would lose touch focus. The behavior is to change the focus to the last touched surface. So if they were two separate windows, only the second window would get the touch events. At least that's how I understood it. Cheers, Ander + return; + } + if (input->grab) widget = input->grab; else Thanks, pq - Intel Finland Oy Registered Address: PL 281, 00181 Helsinki Business Identity Code: 0357606 - 4 Domiciled in Helsinki This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] window: Ignore input events from subsurfaces
From: Ander Conselvan de Oliveira Toytoolkit was not designed to handle input from subsurfaces and instead it expects subsurfaces to have an empty input region. That way input events for subsurfaces are generated on the main surface and there is no need to convert coordinates before reporting the event to the user. However it is possible that a subsurface has a non-empty input region, but in that case those events aren't properly processed. The function window_find_widget() assumes the coordinates are in the main surface coordinate space, and ends up chosing the wrong widget. This patch changes the input code to completely ignore input events from subsurfaces. This option was chosen instead of ensuring that the input region on those surfaces is always empty since there's no enforcement that a subsurface should completely overlap with the main surface. If an event happens in the area of the surface that doesn't overlap, the event could cause a completely unrelated surface to be picked. https://bugs.freedesktop.org/show_bug.cgi?id=78207 --- clients/window.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/clients/window.c b/clients/window.c index b7febed..3b57264 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2605,10 +2605,15 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, return; } + window = wl_surface_get_user_data(surface); + if (surface != window->main_surface->surface) { + DBG("Ignoring input event from subsurface %p\n", surface); + return; + } + input->display->serial = serial; input->pointer_enter_serial = serial; - input->pointer_focus = wl_surface_get_user_data(surface); - window = input->pointer_focus; + input->pointer_focus = window; if (window->resizing) { window->resizing = 0; @@ -2644,12 +2649,12 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer, float sx = wl_fixed_to_double(sx_w); float sy = wl_fixed_to_double(sy_w); - input->sx = sx; - input->sy = sy; - if (!window) return; + input->sx = sx; + input->sy = sy; + /* when making the window smaller - e.g. after a unmaximise we might * still have a pending motion event that the compositor has picked * based on the old surface dimensions @@ -2979,6 +2984,12 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, return; } + if (surface != input->touch_focus->main_surface->surface) { + DBG("Ignoring input event from subsurface %p\n", surface); + input->touch_focus = NULL; + return; + } + if (input->grab) widget = input->grab; else -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] window.c: Set the input region of the tooltip to empty
From: Ander Conselvan de Oliveira Otherwise it might receive touch events. https://bugs.freedesktop.org/show_bug.cgi?id=78207 --- clients/window.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/window.c b/clients/window.c index b7febed..f667cdf 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1992,6 +1992,7 @@ window_create_tooltip(struct tooltip *tooltip) widget_set_allocation(tooltip->widget, tooltip->x, tooltip->y + offset_y, extents.width + 20, 20 + margin * 2); + widget_input_region_add(tooltip->widget, NULL); return 0; } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] shell: Don't map surfaces of type SHELL_SURFACE_NONE
When commit 07926d90 factored out the code that chooses in which layer a surface is added to, it changed the behavior for surfaces with no type. Instead of not adding it to any layer, the surface is added to the current workspace. This patch restores the old behavior. https://bugs.freedesktop.org/show_bug.cgi?id=77527 --- desktop-shell/shell.c | 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 7631f1b..7e4ceed 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -2127,6 +2127,12 @@ shell_surface_calculate_layer_link (struct shell_surface *shsurf) struct weston_view *parent; switch (shsurf->type) { + case SHELL_SURFACE_XWAYLAND: + return &shsurf->shell->fullscreen_layer.view_list; + + case SHELL_SURFACE_NONE: + return NULL; + case SHELL_SURFACE_POPUP: case SHELL_SURFACE_TOPLEVEL: if (shsurf->state.fullscreen && !shsurf->state.lowered) { @@ -2142,22 +2148,15 @@ shell_surface_calculate_layer_link (struct shell_surface *shsurf) if (parent) return parent->layer_link.prev; } - break; - case SHELL_SURFACE_XWAYLAND: - return &shsurf->shell->fullscreen_layer.view_list; - - case SHELL_SURFACE_NONE: - default: - /* Go to the fallback, below. */ - break; + /* Move the surface to a normal workspace layer so that surfaces +* which were previously fullscreen or transient are no longer +* rendered on top. */ + ws = get_current_workspace(shsurf->shell); + return &ws->layer.view_list; } - /* Move the surface to a normal workspace layer so that surfaces -* which were previously fullscreen or transient are no longer -* rendered on top. */ - ws = get_current_workspace(shsurf->shell); - return &ws->layer.view_list; + assert(0 && "Unknown shell surface type"); } static void @@ -2198,6 +2197,8 @@ shell_surface_update_layer(struct shell_surface *shsurf) new_layer_link = shell_surface_calculate_layer_link(shsurf); + if (new_layer_link == NULL) + return; if (new_layer_link == &shsurf->view->layer_link) return; -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 2/2] shell: Fix crash when a client is destroyed during the resize grab
If a client exists during a resize grab, the resource for the shell surface being resized is destroyed. The shell surface is not destroyed immediately, however, because of the window close animation. In that case, the compositor would crash trying to send configure events to the surface being resized, since it would pass a NULL pointer to wl_resource_post_event(). The code for the resize grab was already able to handle the surface going away, so expand it to also handle the resource going away and fix the crash. https://bugs.freedesktop.org/show_bug.cgi?id=77344 --- desktop-shell/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 6fc797b..82d8166 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1594,7 +1594,7 @@ resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time, weston_pointer_move(pointer, x, y); - if (!shsurf) + if (!shsurf || !shsurf->resource) return; weston_view_from_global_fixed(shsurf->view, -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 1/2] shell: Fix memory leaks caused by the window close animation
In order to do the window close animation, a reference for a destroyed surface is kept. However, the reference count was also increased for unmapped surfaces, in which case the animation wouldn't run. Since the reference count was decremented in the animation done function, it would never be decreased for unmapped surfaces, causing them to not be released. The close animation also changed how shell surfaces are released. The destroy function for its resource was changed to not deallocate the surface, and instead keep it around until the animation finishes and the weston surface is destroyed. The destruction should happen in the destroy listener for the weston surface, but it wouldn't destroy the shell surface in the case the resource was still valid, assuming that it would be freed in the resource destroy function. --- desktop-shell/shell.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index bc4a258..6fc797b 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -3081,8 +3081,8 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data) if (shsurf->resource) wl_resource_destroy(shsurf->resource); - else - destroy_shell_surface(shsurf); + + destroy_shell_surface(shsurf); } static void @@ -3100,15 +3100,17 @@ handle_resource_destroy(struct wl_listener *listener, void *data) container_of(listener, struct shell_surface, resource_destroy_listener); + if (!weston_surface_is_mapped(shsurf->surface)) + return; + shsurf->surface->ref_count++; pixman_region32_fini(&shsurf->surface->pending.input); pixman_region32_init(&shsurf->surface->pending.input); pixman_region32_fini(&shsurf->surface->input); pixman_region32_init(&shsurf->surface->input); - if (weston_surface_is_mapped(shsurf->surface)) - weston_fade_run(shsurf->view, 1.0, 0.0, 300.0, - fade_out_done, shsurf); + weston_fade_run(shsurf->view, 1.0, 0.0, 300.0, + fade_out_done, shsurf); } static void -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 3/4] evdev: Fix assertion error for unplugged output with paired touchscreen
From: Ander Conselvan de Oliveira If the output a touchscreen is paired to is unplugged, events coming from it should be ignored. Commit 17bccaed introduced logic for that in evdev_flush_pending_damage(). However, the break statements it introduced would cause the assertion after the switch statement to fail. That function has the odd behavior that goto's are used to skip the assertion after the switch statement and jump to the hunk of code that marks the event as processed. Only in the case where the event type has an invalid value the assertion should trigger. So this patch fixes the problem by moving the assertion into the default case of the switch and replacing the goto statements with break ones. https://bugs.freedesktop.org/show_bug.cgi?id=73950 --- src/evdev.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 9d97c87..ff951d3 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -100,7 +100,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_motion(master, time, device->rel.dx, device->rel.dy); device->rel.dx = 0; device->rel.dy = 0; - goto handled; + break; case EVDEV_ABSOLUTE_MT_DOWN: if (device->output == NULL) break; @@ -113,7 +113,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) master->slot_map |= 1 << seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); - goto handled; + break; case EVDEV_ABSOLUTE_MT_MOTION: if (device->output == NULL) break; @@ -123,12 +123,12 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) &x, &y); seat_slot = device->mt.slots[slot].seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_MOTION); - goto handled; + break; case EVDEV_ABSOLUTE_MT_UP: seat_slot = device->mt.slots[slot].seat_slot; master->slot_map &= ~(1 << seat_slot); notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); - goto handled; + break; case EVDEV_ABSOLUTE_TOUCH_DOWN: if (device->output == NULL) break; @@ -141,7 +141,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) device->abs.seat_slot = seat_slot; master->slot_map |= 1 << seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); - goto handled; + break; case EVDEV_ABSOLUTE_MOTION: if (device->output == NULL) break; @@ -156,17 +156,16 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) x, y, WL_TOUCH_MOTION); else if (device->seat_caps & EVDEV_SEAT_POINTER) notify_motion_absolute(master, time, x, y); - goto handled; + break; case EVDEV_ABSOLUTE_TOUCH_UP: seat_slot = device->abs.seat_slot; master->slot_map &= ~(1 << seat_slot); notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); - goto handled; + break; + default: + assert(0 && "Unknown pending event type"); } - assert(0 && "Unknown pending event type"); - -handled: device->pending_event = EVDEV_NONE; } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 4/4] input: Fix errors due to initializing input before creating outputs
From: Ander Conselvan de Oliveira Make sure that we don't map a device to an invalid output pointer and intead remap devices when an output is created. v2: fix the error with libinput too. --- src/evdev.c | 2 +- src/libinput-device.c | 2 +- src/libinput-seat.c | 8 ++-- src/udev-seat.c | 8 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index ff951d3..888dfbd 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -601,7 +601,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (!device->output_name) { + if (!device->output_name && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-device.c b/src/libinput-device.c index 753583a..4605a76 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -264,7 +264,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (!device->output_name) { + if (!device->output_name && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-seat.c b/src/libinput-seat.c index 6e83717..b18562e 100644 --- a/src/libinput-seat.c +++ b/src/libinput-seat.c @@ -84,7 +84,7 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } else if (device->output == NULL) { + } else if (device->output == NULL && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); @@ -314,11 +314,15 @@ notify_output_create(struct wl_listener *listener, void *data) struct evdev_device *device; struct weston_output *output = data; - wl_list_for_each(device, &seat->devices_list, link) + wl_list_for_each(device, &seat->devices_list, link) { if (device->output_name && strcmp(output->name, device->output_name) == 0) { evdev_device_set_output(device, output); } + + if (device->output_name == NULL && device->output == NULL) + evdev_device_set_output(device, output); + } } static struct udev_seat * diff --git a/src/udev-seat.c b/src/udev-seat.c index dfeb17f..93984e1 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -125,7 +125,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } else if (device->output == NULL) { + } else if (device->output == NULL && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); @@ -357,11 +357,15 @@ notify_output_create(struct wl_listener *listener, void *data) struct evdev_device *device; struct weston_output *output = data; - wl_list_for_each(device, &seat->devices_list, link) + wl_list_for_each(device, &seat->devices_list, link) { if (device->output_name && strcmp(output->name, device->output_name) == 0) { evdev_device_set_output(device, output); } + + if (device->output_name == NULL && device->output == NULL) + evdev_device_set_output(device, output); + } } static struct udev_seat * -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 2/4] evdev: Discard events from a touchscreen paired with an unplugged output
From: Ander Conselvan de Oliveira Commit 17bccaed intended to make the events coming from a touchscreen paired with an unplugged output to be discarded, while an unpaired one would just choose a different output. However, the logic was inverted causing the opposite to happen. Later in commit 161c6c56, the default behavior was changed to map an output to a default output if the one specified via udev is not present. This change is reverted by this patch. v2: undo the change from commit 161c6c56. v3: deal with libinput too. --- src/evdev.c | 2 +- src/libinput-device.c | 2 +- src/libinput-seat.c | 4 +--- src/udev-seat.c | 4 +--- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index bc8e5ef..9d97c87 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -602,7 +602,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (device->output_name) { + if (!device->output_name) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-device.c b/src/libinput-device.c index a67c119..753583a 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -264,7 +264,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (device->output_name) { + if (!device->output_name) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-seat.c b/src/libinput-seat.c index 8bf538c..6e83717 100644 --- a/src/libinput-seat.c +++ b/src/libinput-seat.c @@ -84,9 +84,7 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } - - if (device->output == NULL) { + } else if (device->output == NULL) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/udev-seat.c b/src/udev-seat.c index 5e018de..dfeb17f 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -125,9 +125,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } - - if (device->output == NULL) { + } else if (device->output == NULL) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 1/4] libinput: Don't process touch events for devices without a valid output
From: Ander Conselvan de Oliveira That would be the case of a touch screen mapped to an output that was unplugged. --- src/libinput-device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libinput-device.c b/src/libinput-device.c index 0ca6c4b..a67c119 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -147,6 +147,9 @@ handle_touch_with_coords(struct libinput_device *libinput_device, uint32_t time; int32_t slot; + if (!device->output) + return; + time = libinput_event_touch_get_time(touch_event); slot = libinput_event_touch_get_seat_slot(touch_event); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston 4/4] input: Fix errors due to initializing input before creating outputs
On 04/23/2014 06:36 PM, Neil Roberts wrote: I think we accientally wrote nearly identical patches at the same time: http://lists.freedesktop.org/archives/wayland-devel/2014-April/014392.html However, I still get the crash with Ander's patch because it looks like it is missing the check for wl_list_empty in the libinput-seat.c version of device_added. I think it would make sense to fix this patch and use it rather than my version because my one assumes the old behaviour where if we can't find an output with the right name for a seat then we default to using any output. This is changed in patch 1 of Ander's series. I think Ander's approach is more robust. Ie, if we can't find an output for a seat that has an explicit output name then we just ignore events for it. However I notice that patch 1 of the series also doesn't make this revert for the libinput-seat.c version of device_added so that will still maintain the behaviour of resorting to a default output from this commit: Shoot, I forgot libinput-seat again. /o\ I'm sending fixed patches now. Thanks, Ander http://cgit.freedesktop.org/wayland/weston/commit/?id=161c6c56944cdfbda - Neil Ander Conselvan de Oliveira writes: From: Ander Conselvan de Oliveira Make sure that we don't map a device to an invalid output pointer and intead remap devices when an output is created. --- src/evdev.c | 2 +- src/libinput-device.c | 2 +- src/libinput-seat.c | 6 +- src/udev-seat.c | 8 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index ff951d3..888dfbd 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -601,7 +601,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (!device->output_name) { + if (!device->output_name && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-device.c b/src/libinput-device.c index 753583a..4605a76 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -264,7 +264,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (!device->output_name) { + if (!device->output_name && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-seat.c b/src/libinput-seat.c index 8bf538c..e900744 100644 --- a/src/libinput-seat.c +++ b/src/libinput-seat.c @@ -316,11 +316,15 @@ notify_output_create(struct wl_listener *listener, void *data) struct evdev_device *device; struct weston_output *output = data; - wl_list_for_each(device, &seat->devices_list, link) + wl_list_for_each(device, &seat->devices_list, link) { if (device->output_name && strcmp(output->name, device->output_name) == 0) { evdev_device_set_output(device, output); } + + if (device->output_name == NULL && device->output == NULL) + evdev_device_set_output(device, output); + } } static struct udev_seat * diff --git a/src/udev-seat.c b/src/udev-seat.c index dfeb17f..93984e1 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -125,7 +125,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } else if (device->output == NULL) { + } else if (device->output == NULL && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); @@ -357,11 +357,15 @@ notify_output_create(struct wl_listener *listener, void *data) struct evdev_device *device; struct weston_output *output = data; - wl_list_for_each(device, &seat->devices_list, link) + wl_list_for_each(device, &seat->devices_list, link) { if (device->output_name && strcmp(output->name, device->output_name) == 0) { evdev_device_set_output(device, output);
[PATCH weston v3 0/4] Input fixes
From: Ander Conselvan de Oliveira Resend of the fixes update to cover libinput usage too. Ander Conselvan de Oliveira (4): libinput: Don't process touch events for devices without a valid output evdev: Discard events from a touchscreen paired with an unplugged output evdev: Fix assertion error for unplugged output with paired touchscreen input: Fix errors due to initializing input before creating outputs src/evdev.c | 21 ++--- src/libinput-device.c | 5 - src/libinput-seat.c | 10 ++ src/udev-seat.c | 10 ++ 4 files changed, 26 insertions(+), 20 deletions(-) -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 4/4] input: Fix errors due to initializing input before creating outputs
From: Ander Conselvan de Oliveira Make sure that we don't map a device to an invalid output pointer and intead remap devices when an output is created. --- src/evdev.c | 2 +- src/libinput-device.c | 2 +- src/libinput-seat.c | 6 +- src/udev-seat.c | 8 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index ff951d3..888dfbd 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -601,7 +601,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (!device->output_name) { + if (!device->output_name && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-device.c b/src/libinput-device.c index 753583a..4605a76 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -264,7 +264,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (!device->output_name) { + if (!device->output_name && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-seat.c b/src/libinput-seat.c index 8bf538c..e900744 100644 --- a/src/libinput-seat.c +++ b/src/libinput-seat.c @@ -316,11 +316,15 @@ notify_output_create(struct wl_listener *listener, void *data) struct evdev_device *device; struct weston_output *output = data; - wl_list_for_each(device, &seat->devices_list, link) + wl_list_for_each(device, &seat->devices_list, link) { if (device->output_name && strcmp(output->name, device->output_name) == 0) { evdev_device_set_output(device, output); } + + if (device->output_name == NULL && device->output == NULL) + evdev_device_set_output(device, output); + } } static struct udev_seat * diff --git a/src/udev-seat.c b/src/udev-seat.c index dfeb17f..93984e1 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -125,7 +125,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } else if (device->output == NULL) { + } else if (device->output == NULL && !wl_list_empty(&c->output_list)) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); @@ -357,11 +357,15 @@ notify_output_create(struct wl_listener *listener, void *data) struct evdev_device *device; struct weston_output *output = data; - wl_list_for_each(device, &seat->devices_list, link) + wl_list_for_each(device, &seat->devices_list, link) { if (device->output_name && strcmp(output->name, device->output_name) == 0) { evdev_device_set_output(device, output); } + + if (device->output_name == NULL && device->output == NULL) + evdev_device_set_output(device, output); + } } static struct udev_seat * -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 3/4] evdev: Fix assertion error for unplugged output with paired touchscreen
From: Ander Conselvan de Oliveira If the output a touchscreen is paired to is unplugged, events coming from it should be ignored. Commit 17bccaed introduced logic for that in evdev_flush_pending_damage(). However, the break statements it introduced would cause the assertion after the switch statement to fail. This function has the odd behavior that goto's are used to skip the assertion after the switch statement and jump to the hunk of code that marks the event as processed. Only in the case where the event type has an invalid value the assertion should trigger. So this patch fixes the problem by moving the assertion in to the default case of the switch and replacing the goto statements with break ones. https://bugs.freedesktop.org/show_bug.cgi?id=73950 --- src/evdev.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 9d97c87..ff951d3 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -100,7 +100,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_motion(master, time, device->rel.dx, device->rel.dy); device->rel.dx = 0; device->rel.dy = 0; - goto handled; + break; case EVDEV_ABSOLUTE_MT_DOWN: if (device->output == NULL) break; @@ -113,7 +113,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) master->slot_map |= 1 << seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); - goto handled; + break; case EVDEV_ABSOLUTE_MT_MOTION: if (device->output == NULL) break; @@ -123,12 +123,12 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) &x, &y); seat_slot = device->mt.slots[slot].seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_MOTION); - goto handled; + break; case EVDEV_ABSOLUTE_MT_UP: seat_slot = device->mt.slots[slot].seat_slot; master->slot_map &= ~(1 << seat_slot); notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); - goto handled; + break; case EVDEV_ABSOLUTE_TOUCH_DOWN: if (device->output == NULL) break; @@ -141,7 +141,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) device->abs.seat_slot = seat_slot; master->slot_map |= 1 << seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); - goto handled; + break; case EVDEV_ABSOLUTE_MOTION: if (device->output == NULL) break; @@ -156,17 +156,16 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) x, y, WL_TOUCH_MOTION); else if (device->seat_caps & EVDEV_SEAT_POINTER) notify_motion_absolute(master, time, x, y); - goto handled; + break; case EVDEV_ABSOLUTE_TOUCH_UP: seat_slot = device->abs.seat_slot; master->slot_map &= ~(1 << seat_slot); notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); - goto handled; + break; + default: + assert(0 && "Unknown pending event type"); } - assert(0 && "Unknown pending event type"); - -handled: device->pending_event = EVDEV_NONE; } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 2/4] evdev: Discard events from a touchscreen paired with an unplugged output
From: Ander Conselvan de Oliveira Commit 17bccaed intended to make the events coming from a touchscreen paired with an unplugged output to be discarded, while an unpaired one would just choose a different output. However, the logic was inverted causing the opposite to happen. Later in commit 161c6c56, the default behavior was changed to map an output to a default output if the one specified via udev is not present. This change is reverted by this patch. --- src/evdev.c | 2 +- src/libinput-device.c | 2 +- src/udev-seat.c | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index bc8e5ef..9d97c87 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -602,7 +602,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (device->output_name) { + if (!device->output_name) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/libinput-device.c b/src/libinput-device.c index a67c119..753583a 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -264,7 +264,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (device->output_name) { + if (!device->output_name) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); diff --git a/src/udev-seat.c b/src/udev-seat.c index 5e018de..dfeb17f 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -125,9 +125,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) evdev_device_set_output(device, output); - } - - if (device->output == NULL) { + } else if (device->output == NULL) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 1/4] libinput: Don't process touch events for devices without a valid output
From: Ander Conselvan de Oliveira That would be the case of a touch screen mapped to an output that was unplugged. --- src/libinput-device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libinput-device.c b/src/libinput-device.c index 0ca6c4b..a67c119 100644 --- a/src/libinput-device.c +++ b/src/libinput-device.c @@ -147,6 +147,9 @@ handle_touch_with_coords(struct libinput_device *libinput_device, uint32_t time; int32_t slot; + if (!device->output) + return; + time = libinput_event_touch_get_time(touch_event); slot = libinput_event_touch_get_seat_slot(touch_event); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 0/4] Input fixes
From: Ander Conselvan de Oliveira Here's a second version of the input fixes I sent before, which new patches and some changes. The first patch makes libinput able to handle touch events on a device without a paired output. The second one inverts the logic for pairing a device on output disconnect to match what was intended in the commit that introduced it. I changed it from the previous version to also change the recent behavior changed introduced during init. The third patch is a resend of a previous one and the fourth fix a crash due to changing input to be initialized before outputs. Thanks, Ander Ander Conselvan de Oliveira (4): libinput: Don't process touch events for devices without a valid output evdev: Discard events from a touchscreen paired with an unplugged output evdev: Fix assertion error for unplugged output with paired touchscreen input: Fix errors due to initializing input before creating outputs src/evdev.c | 21 ++--- src/libinput-device.c | 5 - src/libinput-seat.c | 6 +- src/udev-seat.c | 10 ++ 4 files changed, 25 insertions(+), 17 deletions(-) -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] compositor-drm: Fix crash when setting up seat constrained by an output
On 04/22/2014 08:22 PM, Neil Roberts wrote: It looks like this patch makes Weston crash on touch events. The device_added functions in udev-seat.c and libinput-seat.c try to use the output list in order to assign the output for the newly created device. These functions get called via udev_input_init so I guess that means this function and create_outputs now depend on each other making a chicken and egg situation. If the device_added function can't find an output for the new device then it defaults to first output in the list. However since this patch the output list is now empty at that point so it ends up with a garbage pointer for the output. When the input code tries to handle an absolute event (eg, a touch event) then it tries to get the width and height from the current mode of the output for the device but this is now garbage. For me with libinput this causes it to segfault whereas without libinput it gets garbage width and height values and causes a floating point exception later on. Yeah, I guess I forgot to test with an unmapped touch screen. I think we can just leave the device->output set to NULL in that case, and then fix it when a first output is created. I'll send a patch to do this. Thanks, Ander I haven't looked any further to decide what's the best thing to do. - Neil Ander Conselvan de Oliveira writes: From: Ander Conselvan de Oliveira Commit 58e15865 changed the parameters for udev_get_seat_by_name() to receive a struct udev_input. However, when this gets called from create_output_from_connector() during initialization, the input struct is not yet initialized, leading to a crash. Previously, that function would take only a pointer to the compositor. This patch fixes the crash by initializing input before creating any outputs. https://bugs.freedesktop.org/show_bug.cgi?id=77503 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston 1/2] evdev: Discard events from a touchscreen paired with an unplugged output
On 04/23/2014 04:21 AM, Eoff, Ullysses A wrote: Hmmm... I think there's more to reconcile for touch device pairing/mapping. In device_added(), we assign a default output to a paired device when the the requested output isn't found. That behavior just changed about a day ago to fix another bug. But perhaps I wasn't seeing the big picture at the time when I changed that. I admit that the notify_output_destroy() handler logic felt a little odd to me, though. I think what we want is to restore the previous behavior and make sure the touch event is discarded if the output is NULL. It seems odd to me to map a touch screen that is explicitly mapped to another output. So in the end what we should get in all case is: if the device is mapped to an output that is plugged, we set device->output to that output; if the device is mapped to an output that is not plugged, we set device->output to NULL; if the device is not mapped, we set device->output to the first output. I'll send patches that do this. Thanks Ander Assigning the paired device's output to something (NULL or default) when the requested output doesn't exist should be the same logic as when the paired device's output is unplugged. And possibly the same as when the device doesn't specify a pairing preference. Even before this commit, the logic didn't reconcile with that notion either, afaict. And, of course, when the requested output is hotplugged the paired device's output needs to be reconciled (which is currently the case). U. Artie -Original Message- From: wayland-devel [mailto:wayland-devel-boun...@lists.freedesktop.org] On Behalf Of Ander Conselvan de Oliveira Sent: Tuesday, April 22, 2014 8:02 AM To: wayland-devel@lists.freedesktop.org Cc: Conselvan De Oliveira, Ander Subject: [PATCH weston 1/2] evdev: Discard events from a touchscreen paired with an unplugged output From: Ander Conselvan de Oliveira Commit 17bccaed intended to make the events coming from a touchscreen paired with an unplugged output to be discarded, while an unpaired one would just choose a different output. However, the logic was inverted causing the opposite to happen. --- src/evdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evdev.c b/src/evdev.c index bc8e5ef..9d97c87 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -602,7 +602,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (device->output_name) { + if (!device->output_name) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 1/2] evdev: Discard events from a touchscreen paired with an unplugged output
From: Ander Conselvan de Oliveira Commit 17bccaed intended to make the events coming from a touchscreen paired with an unplugged output to be discarded, while an unpaired one would just choose a different output. However, the logic was inverted causing the opposite to happen. --- src/evdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evdev.c b/src/evdev.c index bc8e5ef..9d97c87 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -602,7 +602,7 @@ notify_output_destroy(struct wl_listener *listener, void *data) struct weston_compositor *c = device->seat->compositor; struct weston_output *output; - if (device->output_name) { + if (!device->output_name) { output = container_of(c->output_list.next, struct weston_output, link); evdev_device_set_output(device, output); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 2/2] evdev: Fix assertion error for unplugged output with paired touchscreen
From: Ander Conselvan de Oliveira If the output a touchscreen is paired to is unplugged, events coming from it should be ignored. Commit 17bccaed introduced logic for that in evdev_flush_pending_damage(). However, the break statements it introduced would cause the assertion after the switch statement to fail. This function has the odd behavior that goto's are used to skip the assertion after the switch statement and jump to the hunk of code that marks the event as processed. Only in the case where the event type has an invalid value the assertion should trigger. So this patch fixes the problem by moving the assertion in to the default case of the switch and replacing the goto statements with break ones. https://bugs.freedesktop.org/show_bug.cgi?id=73950 --- I didn't actually manage to reproduce the bug, but looking at the backtrace and the code in evdev.c that seems like the appropriate fix. Thanks, Ander --- src/evdev.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 9d97c87..ff951d3 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -100,7 +100,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_motion(master, time, device->rel.dx, device->rel.dy); device->rel.dx = 0; device->rel.dy = 0; - goto handled; + break; case EVDEV_ABSOLUTE_MT_DOWN: if (device->output == NULL) break; @@ -113,7 +113,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) master->slot_map |= 1 << seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); - goto handled; + break; case EVDEV_ABSOLUTE_MT_MOTION: if (device->output == NULL) break; @@ -123,12 +123,12 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) &x, &y); seat_slot = device->mt.slots[slot].seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_MOTION); - goto handled; + break; case EVDEV_ABSOLUTE_MT_UP: seat_slot = device->mt.slots[slot].seat_slot; master->slot_map &= ~(1 << seat_slot); notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); - goto handled; + break; case EVDEV_ABSOLUTE_TOUCH_DOWN: if (device->output == NULL) break; @@ -141,7 +141,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) device->abs.seat_slot = seat_slot; master->slot_map |= 1 << seat_slot; notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); - goto handled; + break; case EVDEV_ABSOLUTE_MOTION: if (device->output == NULL) break; @@ -156,17 +156,16 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) x, y, WL_TOUCH_MOTION); else if (device->seat_caps & EVDEV_SEAT_POINTER) notify_motion_absolute(master, time, x, y); - goto handled; + break; case EVDEV_ABSOLUTE_TOUCH_UP: seat_slot = device->abs.seat_slot; master->slot_map &= ~(1 << seat_slot); notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); - goto handled; + break; + default: + assert(0 && "Unknown pending event type"); } - assert(0 && "Unknown pending event type"); - -handled: device->pending_event = EVDEV_NONE; } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH wayland] connection: Don't write past the end of the connection buffer
From: Ander Conselvan de Oliveira If a message was too big to fit in the connection buffer, the code in wl_buffer_put would just write past the end of it. I haven't seen any real world use case that would trigger this bug, but it was possible to trigger it by sending a long enough string to the wl_data_source.offer request. https://bugs.freedesktop.org/show_bug.cgi?id=69267 --- src/connection.c| 25 + tests/connection-test.c | 37 + 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/connection.c b/src/connection.c index 40a2182..63b0592 100644 --- a/src/connection.c +++ b/src/connection.c @@ -61,11 +61,18 @@ struct wl_connection { int want_flush; }; -static void +static int wl_buffer_put(struct wl_buffer *b, const void *data, size_t count) { uint32_t head, size; + if (count > sizeof(b->data)) { + wl_log("Data too big for buffer (%d > %d).\n", + count, sizeof(b->data)); + errno = E2BIG; + return -1; + } + head = MASK(b->head); if (head + count <= sizeof b->data) { memcpy(b->data + head, data, count); @@ -76,6 +83,8 @@ wl_buffer_put(struct wl_buffer *b, const void *data, size_t count) } b->head += count; + + return 0; } static void @@ -243,8 +252,8 @@ decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg) size /= sizeof(int32_t); for (i = 0; i < size; i++) close(((int*)CMSG_DATA(cmsg))[i]); - } else { - wl_buffer_put(buffer, CMSG_DATA(cmsg), size); + } else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) { + return -1; } } @@ -350,7 +359,9 @@ wl_connection_write(struct wl_connection *connection, return -1; } - wl_buffer_put(&connection->out, data, count); + if (wl_buffer_put(&connection->out, data, count) < 0) + return -1; + connection->want_flush = 1; return 0; @@ -367,7 +378,7 @@ wl_connection_queue(struct wl_connection *connection, return -1; } - wl_buffer_put(&connection->out, data, count); + return wl_buffer_put(&connection->out, data, count); return 0; } @@ -394,9 +405,7 @@ wl_connection_put_fd(struct wl_connection *connection, int32_t fd) return -1; } - wl_buffer_put(&connection->fds_out, &fd, sizeof fd); - - return 0; + return wl_buffer_put(&connection->fds_out, &fd, sizeof fd); } const char * diff --git a/tests/connection-test.c b/tests/connection-test.c index 52d235d..1213875 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -235,6 +235,27 @@ expected_fail_marshal(int expected_error, const char *format, ...) assert(errno == expected_error); } +static void +expected_fail_marshal_send(struct marshal_data *data, int expected_error, + const char *format, ...) +{ + struct wl_closure *closure; + static const uint32_t opcode = ; + static struct wl_object sender = { NULL, NULL, 1234 }; + struct wl_message message = { "test", format, NULL }; + va_list ap; + + va_start(ap, format); + closure = wl_closure_vmarshal(&sender, opcode, ap, &message); + va_end(ap); + + assert(closure); + assert(wl_closure_send(closure, data->write_connection) < 0); + assert(errno == expected_error); + + wl_closure_destroy(closure); +} + TEST(connection_marshal_nullables) { struct marshal_data data; @@ -490,6 +511,22 @@ TEST(connection_marshal_alot) release_marshal_data(&data); } +TEST(connection_marshal_too_big) +{ + struct marshal_data data; + char *big_string = malloc(5000); + + memset(big_string, ' ', 4999); + big_string[4999] = '\0'; + + setup_marshal_data(&data); + + expected_fail_marshal_send(&data, E2BIG, "s", big_string); + + release_marshal_data(&data); + free(big_string); +} + static void marshal_helper(const char *format, void *handler, ...) { -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] compositor-drm: Fix crash when setting up seat constrained by an output
From: Ander Conselvan de Oliveira Commit 58e15865 changed the parameters for udev_get_seat_by_name() to receive a struct udev_input. However, when this gets called from create_output_from_connector() during initialization, the input struct is not yet initialized, leading to a crash. Previously, that function would take only a pointer to the compositor. This patch fixes the crash by initializing input before creating any outputs. https://bugs.freedesktop.org/show_bug.cgi?id=77503 --- src/compositor-drm.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 3c15ec3..9a4b311 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2783,9 +2783,15 @@ drm_compositor_create(struct wl_display *display, wl_list_init(&ec->sprite_list); create_sprites(ec); + if (udev_input_init(&ec->input, + &ec->base, ec->udev, param->seat_id) < 0) { + weston_log("failed to create input devices\n"); + goto err_sprite; + } + if (create_outputs(ec, param->connector, drm_device) < 0) { weston_log("failed to create output for %s\n", path); - goto err_sprite; + goto err_udev_input; } /* A this point we have some idea of whether or not we have a working @@ -2795,12 +2801,6 @@ drm_compositor_create(struct wl_display *display, path = NULL; - if (udev_input_init(&ec->input, - &ec->base, ec->udev, param->seat_id) < 0) { - weston_log("failed to create input devices\n"); - goto err_sprite; - } - loop = wl_display_get_event_loop(ec->base.wl_display); ec->drm_source = wl_event_loop_add_fd(loop, ec->drm.fd, @@ -2843,6 +2843,7 @@ err_udev_monitor: udev_monitor_unref(ec->udev_monitor); err_drm_source: wl_event_source_remove(ec->drm_source); +err_udev_input: udev_input_destroy(&ec->input); err_sprite: ec->base.renderer->destroy(&ec->base); -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] compositor-drm: Pass the right stride to the vaapi recorder
It takes the stride in bytes, not pixels. The bug was hidden when using va intel-driver 1.2.1 because it would ignore the stride from user and set the surface state in a wrong way. https://bugs.freedesktop.org/show_bug.cgi?id=77495 --- src/compositor-drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 3c15ec3..5765b40 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2576,7 +2576,7 @@ recorder_frame_notify(struct wl_listener *listener, void *data) return; } - vaapi_recorder_frame(output->recorder, fd, output->current->stride / 4); + vaapi_recorder_frame(output->recorder, fd, output->current->stride); } static void * -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 1/3] animation: Split spring setup out of weston_view_animation_run()
From: Ander Conselvan de Oliveira All the animations override at least one parameter of the spring that is set during the creation of the animation. Some need to do the whole setup again. This patch changes the initialization of a view animation to a three step process. First, the animation is created. Then the caller sets up the spring and calls weston_view_animation_run() to apply the effect of the animation for the first animation frame. --- src/animation.c | 62 ++--- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/animation.c b/src/animation.c index 521e4f1..0c53cdb 100644 --- a/src/animation.c +++ b/src/animation.c @@ -181,13 +181,13 @@ weston_view_animation_frame(struct weston_animation *base, } static struct weston_view_animation * -weston_view_animation_run(struct weston_view *view, - float start, float stop, - weston_view_animation_frame_func_t frame, - weston_view_animation_frame_func_t reset, - weston_view_animation_done_func_t done, - void *data, - void *private) +weston_view_animation_create(struct weston_view *view, +float start, float stop, +weston_view_animation_frame_func_t frame, +weston_view_animation_frame_func_t reset, +weston_view_animation_done_func_t done, +void *data, +void *private) { struct weston_view_animation *animation; @@ -203,14 +203,12 @@ weston_view_animation_run(struct weston_view *view, animation->start = start; animation->stop = stop; animation->private = private; + weston_matrix_init(&animation->transform.matrix); wl_list_insert(&view->geometry.transformation_list, &animation->transform.link); - weston_spring_init(&animation->spring, 200.0, start, stop); - animation->spring.friction = 700; - animation->animation.frame_counter = 0; + animation->animation.frame = weston_view_animation_frame; - weston_view_animation_frame(&animation->animation, NULL, 0); animation->listener.notify = handle_animation_view_destroy; wl_signal_add(&view->destroy_signal, &animation->listener); @@ -222,6 +220,13 @@ weston_view_animation_run(struct weston_view *view, } static void +weston_view_animation_run(struct weston_view_animation *animation) +{ + animation->animation.frame_counter = 0; + weston_view_animation_frame(&animation->animation, NULL, 0); +} + +static void reset_alpha(struct weston_view_animation *animation) { struct weston_view *view = animation->view; @@ -258,9 +263,9 @@ weston_zoom_run(struct weston_view *view, float start, float stop, { struct weston_view_animation *zoom; - zoom = weston_view_animation_run(view, start, stop, -zoom_frame, reset_alpha, -done, data, NULL); + zoom = weston_view_animation_create(view, start, stop, + zoom_frame, reset_alpha, + done, data, NULL); if (zoom == NULL) return NULL; @@ -269,6 +274,8 @@ weston_zoom_run(struct weston_view *view, float start, float stop, zoom->spring.friction = 1400; zoom->spring.previous = start - (stop - start) * 0.03; + weston_view_animation_run(zoom); + return zoom; } @@ -290,20 +297,21 @@ weston_fade_run(struct weston_view *view, { struct weston_view_animation *fade; - fade = weston_view_animation_run(view, start, end, -fade_frame, reset_alpha, -done, data, NULL); + fade = weston_view_animation_create(view, start, end, + fade_frame, reset_alpha, + done, data, NULL); if (fade == NULL) return NULL; - fade->spring.k = 1000.0; - + weston_spring_init(&fade->spring, 1000.0, start, end); fade->spring.friction = 4000; fade->spring.previous = start - (end - start) * 0.1; view->alpha = start; + weston_view_animation_run(fade); + return fade; } @@ -339,7 +347,7 @@ weston_stable_fade_run(struct weston_view *front_view, float start, { struct weston_view_animation *fade; - fade = weston_view_animation_run(front_view, 0, 0, + fade = weston_view_animation_create(front_view, 0, 0, stable_fade_frame, NULL,
[PATCH weston 2/3] animation: Fix input panel slide animation
From: Ander Conselvan de Oliveira The position for the slide animation was calculated assuming the value of the spring was always between 0.0 and 1.0. Commit 3a869019 broke that assumption, and the result was that the panel would be positioned at an invisible part of screen. Since there would be no output repaints scheduled, the result of the animation would only be seen if something else triggered a repaint (such as a mouse cursor movement). This patch changes the values for the slide animation's spring to range between 0.0 and 1.0, thus fixing the position of the panel and the lack of scheduled repaints problem. https://bugs.freedesktop.org/show_bug.cgi?id=77347 --- src/animation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/animation.c b/src/animation.c index 0c53cdb..a29b34a 100644 --- a/src/animation.c +++ b/src/animation.c @@ -389,7 +389,7 @@ weston_slide_run(struct weston_view *view, float start, float stop, if (!animation) return NULL; - weston_spring_init(&animation->spring, 400.0, start, stop); + weston_spring_init(&animation->spring, 400.0, 0.0, 1.0); animation->spring.friction = 600; animation->spring.clip = WESTON_SPRING_BOUNCE; -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 3/3] shell: Destroy a previous input panel animation when showing it again
From: Ander Conselvan de Oliveira It is possible that an input panel will be shown quickly, hidden and shown again, before the animation for the first appeareance finished. In that case, another animation would be created and the effect of the two combined could cause the panel to not appear in the screen. This patch fixes this by keeping a reference to the previous animation and deleting it when a new one is created. --- desktop-shell/input-panel.c | 48 - 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/desktop-shell/input-panel.c b/desktop-shell/input-panel.c index 12fe686..601b289 100644 --- a/desktop-shell/input-panel.c +++ b/desktop-shell/input-panel.c @@ -43,11 +43,41 @@ struct input_panel_surface { struct weston_view *view; struct wl_listener surface_destroy_listener; + struct weston_view_animation *anim; + struct weston_output *output; uint32_t panel; }; static void +input_panel_slide_done(struct weston_view_animation *animation, void *data) +{ + struct input_panel_surface *ipsurf = data; + + ipsurf->anim = NULL; +} + +static void +show_input_panel_surface(struct input_panel_surface *ipsurf) +{ + struct desktop_shell *shell = ipsurf->shell; + + wl_list_insert(&shell->input_panel_layer.view_list, + &ipsurf->view->layer_link); + weston_view_geometry_dirty(ipsurf->view); + weston_view_update_transform(ipsurf->view); + weston_surface_damage(ipsurf->surface); + + if (ipsurf->anim) + weston_view_animation_destroy(ipsurf->anim); + + ipsurf->anim = + weston_slide_run(ipsurf->view, +ipsurf->surface->height * 0.9, 0, +input_panel_slide_done, ipsurf); +} + +static void show_input_panels(struct wl_listener *listener, void *data) { struct desktop_shell *shell = @@ -70,13 +100,8 @@ show_input_panels(struct wl_listener *listener, void *data) &shell->input_panel.surfaces, link) { if (ipsurf->surface->width == 0) continue; - wl_list_insert(&shell->input_panel_layer.view_list, - &ipsurf->view->layer_link); - weston_view_geometry_dirty(ipsurf->view); - weston_view_update_transform(ipsurf->view); - weston_surface_damage(ipsurf->surface); - weston_slide_run(ipsurf->view, ipsurf->surface->height * 0.9, -0, NULL, NULL); + + show_input_panel_surface(ipsurf); } } @@ -135,13 +160,8 @@ input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy) weston_view_set_position(ip_surface->view, x, y); - if (!weston_surface_is_mapped(surface) && shell->showing_input_panels) { - wl_list_insert(&shell->input_panel_layer.view_list, - &ip_surface->view->layer_link); - weston_view_update_transform(ip_surface->view); - weston_surface_damage(surface); - weston_slide_run(ip_surface->view, ip_surface->view->surface->height * 0.9, 0, NULL, NULL); - } + if (!weston_surface_is_mapped(surface) && shell->showing_input_panels) + show_input_panel_surface(ip_surface); } static void -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] shell: Fix view repositioning logic for output move and destroy
From: Ander Conselvan de Oliveira Previously, the repositioning logic would iterate the compositor's list of layers and move the views on those layers. However, that failed in two different ways: it didn't cover hidden workspaces and crashed when the display was locked. This patch changes the logic to explicit iterate over all the layers owned by the shell. The iteration is done through a helper function, shell_for_each_layer(). https://bugs.freedesktop.org/show_bug.cgi?id=76859 https://bugs.freedesktop.org/show_bug.cgi?id=77290 --- desktop-shell/shell.c | 84 --- desktop-shell/shell.h | 8 + 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 63b4d4c..130618c 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5740,27 +5740,35 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) } } +void +shell_for_each_layer(struct desktop_shell *shell, +shell_for_each_layer_func_t func, void *data) +{ + struct workspace **ws; + + func(shell, &shell->fullscreen_layer, data); + func(shell, &shell->panel_layer, data); + func(shell, &shell->background_layer, data); + func(shell, &shell->lock_layer, data); + func(shell, &shell->input_panel_layer, data); + + wl_array_for_each(ws, &shell->workspaces.array) + func(shell, &(*ws)->layer, data); +} + static void -shell_reposition_views_on_output_destroy(struct shell_output *shell_output) +shell_output_destroy_move_layer(struct desktop_shell *shell, + struct weston_layer *layer, + void *data) { - struct desktop_shell *shell = shell_output->shell; - struct weston_output *output = shell_output->output; - struct weston_layer *layer; + struct weston_output *output = data; struct weston_view *view; - /* Move all views in the layers owned by the shell */ - wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) { - wl_list_for_each(view, &layer->view_list, layer_link) { - if (view->output != output) - continue; - - shell_reposition_view_on_output_destroy(view); - } + wl_list_for_each(view, &layer->view_list, layer_link) { + if (view->output != output) + continue; - /* We don't start from the beggining of the layer list, so -* make sure we don't wrap around it. */ - if (layer == &shell->background_layer) - break; + shell_reposition_view_on_output_destroy(view); } } @@ -5769,8 +5777,10 @@ handle_output_destroy(struct wl_listener *listener, void *data) { struct shell_output *output_listener = container_of(listener, struct shell_output, destroy_listener); + struct weston_output *output = output_listener->output; + struct desktop_shell *shell = output_listener->shell; - shell_reposition_views_on_output_destroy(output_listener); + shell_for_each_layer(shell, shell_output_destroy_move_layer, output); wl_list_remove(&output_listener->destroy_listener.link); wl_list_remove(&output_listener->link); @@ -5806,34 +5816,32 @@ handle_output_create(struct wl_listener *listener, void *data) } static void -handle_output_move(struct wl_listener *listener, void *data) +handle_output_move_layer(struct desktop_shell *shell, +struct weston_layer *layer, void *data) { - struct desktop_shell *shell; - struct weston_output *output; - struct weston_layer *layer; + struct weston_output *output = data; struct weston_view *view; float x, y; - shell = container_of(listener, struct desktop_shell, -output_move_listener); - output = data; + wl_list_for_each(view, &layer->view_list, layer_link) { + if (view->output != output) + continue; - /* Move all views in the layers owned by the shell */ - wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) { - wl_list_for_each(view, &layer->view_list, layer_link) { - if (view->output != output) - continue; + x = view->geometry.x + output->move_x; + y = view->geometry.y + output->move_y; + weston_view_set_position(view, x, y); + } +} - x = view->geometry.x + output->move_x; - y = view->geometry.y + output->move_y;
[PATCH weston] shell: Keep shsurf->fullscreen_output set after unset_fullscreen()
When a fullscreen surface gets the maximized state, the function reset_surface_type() is called and that causes unset_fullscreen() to be called. That function would set the value of shsurf->fullscreen_output to NULL. However, since the surface still has the fullscreen state, it will be configured as a fullscreen surface again, and an attempt to access that field would cause the compositor to crash. Fix the crash by keeping the value of fullscreen_output around after unset_fullscreen(). This is safe since the value is only used when a surface has the fullscreen state and is replaced on a new request to make the surface fullscreen. https://bugs.freedesktop.org/show_bug.cgi?id=76867 --- This fixes the crash, but perhaps a better fix would be to not call unset_fullscreen() if the surface still has the fullscreen state. I did this simpler fix for now, since I don't know all the intricate details of the state change logic. Cheers, Ander --- desktop-shell/shell.c | 1 - 1 file changed, 1 deletion(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 09b992c..0680dc1 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -2313,7 +2313,6 @@ unset_fullscreen(struct shell_surface *shsurf) shell_surface_is_top_fullscreen(shsurf)) { restore_output_mode(shsurf->fullscreen_output); } - shsurf->fullscreen_output = NULL; shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; shsurf->fullscreen.framerate = 0; -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH] shell: Damage below child surfaces on move to different workspace
From: Ander Conselvan de Oliveira When moving from a surface from visible workspace to an invisible one via a popup menu, the area below the menu wouldn't be repainted. https://bugs.freedesktop.org/show_bug.cgi?id=76973 --- desktop-shell/shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 466ea93..b6dc975 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -2139,6 +2139,7 @@ shell_surface_update_child_surface_layers (struct shell_surface *shsurf) * stacked above shsurf. */ wl_list_for_each_reverse(child, &shsurf->children_list, children_link) { if (shsurf->view->layer_link.prev != &child->view->layer_link) { + weston_view_damage_below(child->view); weston_view_geometry_dirty(child->view); wl_list_remove(&child->view->layer_link); wl_list_insert(shsurf->view->layer_link.prev, -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] shell: Disarm the screensaver timeout timer on terminate_screensaver()
The timer was left running after the screensaver was terminated. When it triggered, a fade out that would in turn cause the screen to be locked was started. Since that could happen without the compositor emitting the idle signal, there would be no wake signal to make the shell show the lock screen, so the system was left unresponsive until the idle signal actually triggered. https://bugs.freedesktop.org/show_bug.cgi?id=70923 --- desktop-shell/shell.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 466ea93..09b992c 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -3715,6 +3715,12 @@ terminate_screensaver(struct desktop_shell *shell) if (shell->screensaver.process.pid == 0) return; + /* Disarm the screensaver timer, otherwise it may fire when the +* compositor is not in the idle state. In that case, the screen will +* be locked, but the wake_signal won't fire on user input, making the +* system unresponsive. */ + wl_event_source_timer_update(shell->screensaver.timer, 0); + kill(shell->screensaver.process.pid, SIGTERM); } -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH] shell: Allow unresponsive surfaces to be moved again
From: Ander Conselvan de Oliveira Commit c85f1d45 caused the move of an unresponsive surface to be no longer possible, since the grabbed flag would prevent the move grab to start while the busy grab was still active. --- desktop-shell/shell.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index d685bf9..33be969 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1804,6 +1804,9 @@ set_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer) shell_grab_start(grab, &busy_cursor_grab_interface, shsurf, pointer, DESKTOP_SHELL_CURSOR_BUSY); + /* Mark the shsurf as ungrabbed so that button binding is able +* to move it. */ + shsurf->grabbed = 0; } static void -- 1.8.3.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 02/12] shell.c: Restore maximized and fullscreen window on destroyed output
On 03/18/2014 07:39 AM, Zhang, Xiong Y wrote: On Mon, 2014-03-17 at 19:17 +0200, Ander Conselvan de Oliveira wrote: On 03/07/2014 10:27 AM, Xiong Zhang wrote: > When maximized or fullscreen window is on destroyed output, compositor > can't change these windows to normal window without notify client, > otherwise maximize icon or F11 buttion lose its effect after output unplug. > > Instead we keep these window as maximized or fullscreen, just change > it's size to target output. I'm not sure about this. xdg-shell lets us handle this properly and wl_shell should be deprecated at some point, so I'm more inclined to keep the current behavior. Cheers, Ander yes, using xdg-shell, maximize icon and F11 button can take effect after output unplug. But server secretly changes window's state from maximized to unmaximized without notifying client, it's unreasonable. What I meant is that xdg-shell provides mechanism to notify the client if it looses the maximized or fullscreen state. If I understand correctly, xdg-shell is an attempt to do wl_shell right and once it is finished wl_shell will be deprecated. So in my understanding, as long as we do the right thing with xdg-shell we are OK. But as I said, I'm not sure. I don't like the behavior of taking a fullscreen surface from an unplugged output and making it fullscreen in another output. I'd prefer to unfullscreen it. But if we must do something sensible with wl_shell, then I guess this is the way to go. Cheers, Ander If the unplugged output is much larger than remaining output, the maximized window can't been fully displayed on remaining output when the output of maximized window is unplugged. In order to restore this window to normal, user must move this window to see the maximize icon. It isn't convenient for user. thanks. > > Signed-off-by: Xiong Zhang mailto:xiong.y.zh...@intel.com>> > --- > desktop-shell/shell.c | 24 +--- > 1 file changed, 21 insertions(+), 3 deletions(-) > > diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c > index bee1b0b..02dd1b8 100644 > --- a/desktop-shell/shell.c > +++ b/desktop-shell/shell.c > @@ -5534,6 +5534,7 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) >struct shell_surface *shsurf; >float x, y; >int visible; > + struct weston_view *black_view; > >x = view->geometry.x; >y = view->geometry.y; > @@ -5557,6 +5558,8 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) >x = first_output->x + first_output->width / 4; >y = first_output->y + first_output->height / 4; > > + output = first_output; > + >weston_view_set_position(view, x, y); >} else >weston_view_geometry_dirty(view); > @@ -5566,9 +5569,24 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) > >if (shsurf) { >shsurf->saved_position_valid = false; > - shsurf->next_state.maximized = false; > - shsurf->next_state.fullscreen = false; > - shsurf->state_changed = true; > + > + /* Resize maxmized window to target output. */ > + if (shsurf->state.maximized) > + set_maximized(shsurf, output); > + > + /* Resize fullscreen window to target output. */ > + if (shsurf->state.fullscreen) { > + black_view = shsurf->fullscreen.black_view->surface; > + weston_surface_destroy(black_view->surface); > + shsurf->fullscreen.black_view = NULL; > + > + set_fullscreen(shsurf, > + shsurf->fullscreen.type, > + shsurf->fullscreen.framerate, > + output); > + } > + > + shsurf->state_changed = false; >} > } > > ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org <mailto:wayland-devel@lists.freedesktop.org> http://lists.freedesktop.org/mailman/listinfo/wayland-devel - Intel Finland Oy Registered Address: PL 281, 00181 Helsinki Business Identity Code: 0357606 - 4 Domiciled in Helsinki This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 06/12] compositor-drm: Abstract drm_output_set_mode()
That's a good clean up. Cheers, Ander On 03/07/2014 10:27 AM, Xiong Zhang wrote: Signed-off-by: Xiong Zhang --- src/compositor-drm.c | 45 +++-- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 78292a6..dd1c251 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -593,6 +593,26 @@ drm_output_set_gamma(struct weston_output *output_base, } static int +drm_output_set_mode(struct drm_output *output, uint32_t fb_id) +{ + struct drm_compositor *compositor = + (struct drm_compositor *)output->base.compositor; + struct drm_mode *mode; + int ret = 0; + + mode = container_of(output->base.current_mode, + struct drm_mode, base); + ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id, +fb_id, 0, 0, +&output->connector_id, 1, +&mode->mode_info); + if (ret) + weston_log("set mode failed: %m\n"); + + return ret; +} + +static int drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage) { @@ -600,7 +620,6 @@ drm_output_repaint(struct weston_output *output_base, struct drm_compositor *compositor = (struct drm_compositor *) output->base.compositor; struct drm_sprite *s; - struct drm_mode *mode; int ret = 0; if (output->destroy_pending) @@ -611,17 +630,11 @@ drm_output_repaint(struct weston_output *output_base, if (!output->next) return -1; - mode = container_of(output->base.current_mode, struct drm_mode, base); if (!output->current || output->current->stride != output->next->stride) { - ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id, -output->next->fb_id, 0, 0, -&output->connector_id, 1, -&mode->mode_info); - if (ret) { - weston_log("set mode failed: %m\n"); + if (drm_output_set_mode(output, output->next->fb_id)) goto err_pageflip; - } + output_base->set_dpms(output_base, WESTON_DPMS_ON); } @@ -2355,8 +2368,6 @@ static void drm_compositor_set_modes(struct drm_compositor *compositor) { struct drm_output *output; - struct drm_mode *drm_mode; - int ret; wl_list_for_each(output, &compositor->base.output_list, base.link) { if (!output->current) { @@ -2369,17 +2380,7 @@ drm_compositor_set_modes(struct drm_compositor *compositor) continue; } - drm_mode = (struct drm_mode *) output->base.current_mode; - ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id, -output->current->fb_id, 0, 0, -&output->connector_id, 1, -&drm_mode->mode_info); - if (ret < 0) { - weston_log( - "failed to set mode %dx%d for output at %d,%d: %m\n", - drm_mode->base.width, drm_mode->base.height, - output->base.x, output->base.y); - } + drm_output_set_mode(output, output->current->fb_id); } } ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 02/12] shell.c: Restore maximized and fullscreen window on destroyed output
On 03/07/2014 10:27 AM, Xiong Zhang wrote: When maximized or fullscreen window is on destroyed output, compositor can't change these windows to normal window without notify client, otherwise maximize icon or F11 buttion lose its effect after output unplug. Instead we keep these window as maximized or fullscreen, just change it's size to target output. I'm not sure about this. xdg-shell lets us handle this properly and wl_shell should be deprecated at some point, so I'm more inclined to keep the current behavior. Cheers, Ander Signed-off-by: Xiong Zhang --- desktop-shell/shell.c | 24 +--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index bee1b0b..02dd1b8 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5534,6 +5534,7 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) struct shell_surface *shsurf; float x, y; int visible; + struct weston_view *black_view; x = view->geometry.x; y = view->geometry.y; @@ -5557,6 +5558,8 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) x = first_output->x + first_output->width / 4; y = first_output->y + first_output->height / 4; + output = first_output; + weston_view_set_position(view, x, y); } else weston_view_geometry_dirty(view); @@ -5566,9 +5569,24 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) if (shsurf) { shsurf->saved_position_valid = false; - shsurf->next_state.maximized = false; - shsurf->next_state.fullscreen = false; - shsurf->state_changed = true; + + /* Resize maxmized window to target output. */ + if (shsurf->state.maximized) + set_maximized(shsurf, output); + + /* Resize fullscreen window to target output. */ + if (shsurf->state.fullscreen) { + black_view = shsurf->fullscreen.black_view->surface; + weston_surface_destroy(black_view->surface); + shsurf->fullscreen.black_view = NULL; + + set_fullscreen(shsurf, + shsurf->fullscreen.type, + shsurf->fullscreen.framerate, + output); + } + + shsurf->state_changed = false; } } ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 01/12] shell.c: Set dirty for visible views on destroyed output
On 03/07/2014 10:27 AM, Xiong Zhang wrote: The geometry for visible views will keep unchanged, weston_view_set_position() doesn't mark these views as dirty. So there is no chance for them to reassign output, then these views will disappear. Signed-off-by: Xiong Zhang --- desktop-shell/shell.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index fd9ead0..bee1b0b 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5556,9 +5556,11 @@ shell_reposition_view_on_output_destroy(struct weston_view *view) x = first_output->x + first_output->width / 4; y = first_output->y + first_output->height / 4; - } - weston_view_set_position(view, x, y); + weston_view_set_position(view, x, y); + } else + weston_view_geometry_dirty(view); + So we need that so that view->output will be properly updated. Looks good to me. Just a comment on our coding style. If we brace one part of an if statement, we brace the other part two. Cheers, Ander shsurf = get_shell_surface(view->surface); ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] input: Empty the current input region when configuring pointer surfaces
On 02/01/2014 10:00 AM, Pekka Paalanen wrote: On Fri, 31 Jan 2014 16:07:51 +0200 Ander Conselvan de Oliveira wrote: The input region of the cursor surface is set to empty in pointer_cursor_surface_configure(). Since during the commit process this function is called before the pending input region is made current, it empties surface->pending.input instead of surface->input. But pointer_cursor_surface_configure() is also called from pointer_set_cursor() in order to map the cursor even if there isn't a subsequent attach and commit to the cursor surface. In that case, surface->input is never emptied, since the configure function emptied only the pending input region and there wasn't a commit that made it effective. Fix this by emptying both pending and current input regions. The latter shouldn't cause problems since the surface can't have a role prior to being assigned the cursor role, so it shouldn't be mapped in the first place. Also change toytoolkit so that it triggers the bug. https://bugs.freedesktop.org/show_bug.cgi?id=73711 --- clients/window.c | 6 +++--- src/input.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clients/window.c b/clients/window.c index d8d79d0..75e6418 100644 --- a/clients/window.c +++ b/clients/window.c @@ -3458,13 +3458,13 @@ input_set_pointer_image_index(struct input *input, int index) if (!buffer) return; - wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, - input->pointer_surface, - image->hotspot_x, image->hotspot_y); wl_surface_attach(input->pointer_surface, buffer, 0, 0); wl_surface_damage(input->pointer_surface, 0, 0, image->width, image->height); wl_surface_commit(input->pointer_surface); + wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, + input->pointer_surface, + image->hotspot_x, image->hotspot_y); } static const struct wl_callback_listener pointer_surface_listener; diff --git a/src/input.c b/src/input.c index 25ed133..5ce7f39 100644 --- a/src/input.c +++ b/src/input.c @@ -1543,6 +1543,7 @@ pointer_cursor_surface_configure(struct weston_surface *es, weston_view_set_position(pointer->sprite, x, y); empty_region(&es->pending.input); + empty_region(&es->input); if (!weston_surface_is_mapped(es)) { wl_list_insert(&es->compositor->cursor_layer.view_list, Looks good to me! I wonder, do we have a similar problem with drag icon surfaces? There isn't a problem because weston_pointer_start_drag() doesn't map the drag icon. It takes an attach/commit to do it and at that point emptying the pending input region does the trick. The protocol is not clear whether the surface should be mapped/configured when the request is received. If we change this to behave similarly to wl_pointer::set_cursor, then we need a similar fix. I'm not sure if that change would make sense though. Since wl_data_device::start_drag doesn't have a "hotspot" parameter, it is necessary to set the offset from the pointer on the first attach, unless that offset would be (0, 0). So if the drag_surface already has a buffer, the client would have to first attach NULL to be able to ensure the icon wouldn't be rendered in the wrong position due to the attach that sets the offset being processed a frame later than the start_drag request. Thanks, Ander Thanks, pq ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] build: Fix build when Wayland headers are not in standard prefix
The move to a single Makefile.am missed to set a few _CFLAGS variables, causing the build to fail if the Wayland headers are not installed in the standard prefix. --- Makefile.am | 8 1 file changed, 8 insertions(+) diff --git a/Makefile.am b/Makefile.am index 753ff83..06d2434 100644 --- a/Makefile.am +++ b/Makefile.am @@ -547,6 +547,7 @@ weston_info_SOURCES = \ shared/os-compatibility.c \ shared/os-compatibility.h weston_info_LDADD = $(WESTON_INFO_LIBS) +weston_info_CFLAGS = $(CLIENT_CFLAGS) weston_desktop_shell_SOURCES = clients/desktop-shell.c nodist_weston_desktop_shell_SOURCES = \ @@ -835,27 +836,34 @@ nodist_libtest_client_la_SOURCES =\ protocol/wayland-test-protocol.c\ protocol/wayland-test-client-protocol.h libtest_client_la_LIBADD = $(TEST_CLIENT_LIBS) libshared.la libtest-runner.la +libtest_client_la_CFLAGS = $(COMPOSITOR_CFLAGS) bad_buffer_weston_SOURCES = tests/bad-buffer-test.c bad_buffer_weston_LDADD = libtest-client.la +bad_buffer_weston_CFLAGS = $(COMPOSITOR_CFLAGS) keyboard_weston_SOURCES = tests/keyboard-test.c keyboard_weston_LDADD = libtest-client.la +keyboard_weston_CFLAGS = $(COMPOSITOR_CFLAGS) event_weston_SOURCES = tests/event-test.c event_weston_LDADD = libtest-client.la +event_weston_CFLAGS = $(COMPOSITOR_CFLAGS) button_weston_SOURCES = tests/button-test.c button_weston_LDADD = libtest-client.la +button_weston_CFLAGS = $(COMPOSITOR_CFLAGS) text_weston_SOURCES = tests/text-test.c nodist_text_weston_SOURCES = \ protocol/text-protocol.c\ protocol/text-client-protocol.h text_weston_LDADD = libtest-client.la +text_weston_CFLAGS = $(COMPOSITOR_CFLAGS) subsurface_weston_SOURCES = tests/subsurface-test.c subsurface_weston_LDADD = libtest-client.la +subsurface_weston_CFLAGS = $(COMPOSITOR_CFLAGS) if ENABLE_EGL weston_tests += buffer-count.weston -- 1.8.1.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] input: Fix weston_seat_init_keyboard() error path
The pointer seat->keyboard was set before some possible error returns. That pointer was left unchanged in case of failure, pointing to an uninitialized keyboard struct (that was also leaked). If a client sent a wl_seat::get_keyboard request, that would cause Weston to crash. Fix this by setting the seat->keyboard pointer only after the keymap initialization is done and there is no more possibilities for failure. Also plug the memory leaks on the error path. https://bugs.freedesktop.org/show_bug.cgi?id=74035 --- src/input.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/input.c b/src/input.c index 5ce7f39..72c16c0 100644 --- a/src/input.c +++ b/src/input.c @@ -2033,19 +2033,15 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap) return -1; } - seat->keyboard = keyboard; - seat->keyboard_device_count = 1; - keyboard->seat = seat; - #ifdef ENABLE_XKBCOMMON if (seat->compositor->use_xkbcommon) { if (keymap != NULL) { keyboard->xkb_info = weston_xkb_info_create(keymap); if (keyboard->xkb_info == NULL) - return -1; + goto err; } else { if (weston_compositor_build_global_keymap(seat->compositor) < 0) - return -1; + goto err; keyboard->xkb_info = seat->compositor->xkb_info; keyboard->xkb_info->ref_count++; } @@ -2053,16 +2049,27 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap) keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap); if (keyboard->xkb_state.state == NULL) { weston_log("failed to initialise XKB state\n"); - return -1; + goto err; } keyboard->xkb_state.leds = 0; } #endif + seat->keyboard = keyboard; + seat->keyboard_device_count = 1; + keyboard->seat = seat; + seat_send_updated_caps(seat); return 0; + +err: + if (keyboard->xkb_info) + weston_xkb_info_destroy(keyboard->xkb_info); + free(keyboard); + + return -1; } static void -- 1.8.1.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] input: Empty the current input region when configuring pointer surfaces
The input region of the cursor surface is set to empty in pointer_cursor_surface_configure(). Since during the commit process this function is called before the pending input region is made current, it empties surface->pending.input instead of surface->input. But pointer_cursor_surface_configure() is also called from pointer_set_cursor() in order to map the cursor even if there isn't a subsequent attach and commit to the cursor surface. In that case, surface->input is never emptied, since the configure function emptied only the pending input region and there wasn't a commit that made it effective. Fix this by emptying both pending and current input regions. The latter shouldn't cause problems since the surface can't have a role prior to being assigned the cursor role, so it shouldn't be mapped in the first place. Also change toytoolkit so that it triggers the bug. https://bugs.freedesktop.org/show_bug.cgi?id=73711 --- clients/window.c | 6 +++--- src/input.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clients/window.c b/clients/window.c index d8d79d0..75e6418 100644 --- a/clients/window.c +++ b/clients/window.c @@ -3458,13 +3458,13 @@ input_set_pointer_image_index(struct input *input, int index) if (!buffer) return; - wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, - input->pointer_surface, - image->hotspot_x, image->hotspot_y); wl_surface_attach(input->pointer_surface, buffer, 0, 0); wl_surface_damage(input->pointer_surface, 0, 0, image->width, image->height); wl_surface_commit(input->pointer_surface); + wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, + input->pointer_surface, + image->hotspot_x, image->hotspot_y); } static const struct wl_callback_listener pointer_surface_listener; diff --git a/src/input.c b/src/input.c index 25ed133..5ce7f39 100644 --- a/src/input.c +++ b/src/input.c @@ -1543,6 +1543,7 @@ pointer_cursor_surface_configure(struct weston_surface *es, weston_view_set_position(pointer->sprite, x, y); empty_region(&es->pending.input); + empty_region(&es->input); if (!weston_surface_is_mapped(es)) { wl_list_insert(&es->compositor->cursor_layer.view_list, -- 1.8.1.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston 3/4] compositor: Add a visibility switch to weston_layers
Different parts of the shell, such as the workspace implementation, rely on making layers invisible to hide surfaces without discarding the order in which they appear. However, the layers are made invisible by removing them from the compositor's layers list. Instead, add the function weston_layer_show(), which can control the visibility of a layer, while maintaining it in the layers list. That way, it is not necessary to remember the order between layers when making them visible again. This also has the side effect of causing views in a hidden workspace and in an output that has been moved (due to another being unplugged) to be moved correctly. --- desktop-shell/input-panel.c | 6 ++--- desktop-shell/shell.c | 62 - src/compositor.c| 11 src/compositor.h| 4 +++ 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/desktop-shell/input-panel.c b/desktop-shell/input-panel.c index c08a403..5f0025b 100644 --- a/desktop-shell/input-panel.c +++ b/desktop-shell/input-panel.c @@ -63,8 +63,7 @@ show_input_panels(struct wl_listener *listener, void *data) shell->showing_input_panels = true; if (!shell->locked) - wl_list_insert(&shell->panel_layer.link, - &shell->input_panel_layer.link); + weston_layer_show(&shell->input_panel_layer, 1); wl_list_for_each_safe(ipsurf, next, &shell->input_panel.surfaces, link) { @@ -93,8 +92,7 @@ hide_input_panels(struct wl_listener *listener, void *data) shell->showing_input_panels = false; - if (!shell->locked) - wl_list_remove(&shell->input_panel_layer.link); + weston_layer_show(&shell->input_panel_layer, 0); wl_list_for_each_safe(view, next, &shell->input_panel_layer.view_list, layer_link) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index ae06382..888e33b 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -819,13 +819,13 @@ seat_destroyed(struct wl_listener *listener, void *data) } static struct workspace * -workspace_create(void) +workspace_create(struct desktop_shell *shell) { struct workspace *ws = malloc(sizeof *ws); if (ws == NULL) return NULL; - weston_layer_init(&ws->layer, NULL); + weston_layer_init(&ws->layer, &shell->input_panel_layer.link); wl_list_init(&ws->focus_list); wl_list_init(&ws->seat_destroyed_listener.link); @@ -864,7 +864,7 @@ activate_workspace(struct desktop_shell *shell, unsigned int index) struct workspace *ws; ws = get_workspace(shell, index); - wl_list_insert(&shell->panel_layer.link, &ws->layer.link); + weston_layer_show(&ws->layer, 1); shell->workspaces.current = index; } @@ -994,7 +994,7 @@ finish_workspace_change_animation(struct desktop_shell *shell, workspace_deactivate_transforms(to); shell->workspaces.anim_to = NULL; - wl_list_remove(&shell->workspaces.anim_from->layer.link); + weston_layer_show(&shell->workspaces.anim_from->layer, 0); } static void @@ -1076,7 +1076,7 @@ animate_workspace_change(struct desktop_shell *shell, wl_list_insert(&output->animation_list, &shell->workspaces.animation.link); - wl_list_insert(from->layer.link.prev, &to->layer.link); + weston_layer_show(&to->layer, 1); workspace_translate_in(to, 0); @@ -1090,8 +1090,8 @@ update_workspace(struct desktop_shell *shell, unsigned int index, struct workspace *from, struct workspace *to) { shell->workspaces.current = index; - wl_list_insert(&from->layer.link, &to->layer.link); - wl_list_remove(&from->layer.link); + weston_layer_show(&to->layer, 1); + weston_layer_show(&from->layer, 0); } static void @@ -1241,9 +1241,6 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell, if (shell->workspaces.anim_from == to && shell->workspaces.anim_to == from) { - wl_list_remove(&to->layer.link); - wl_list_insert(from->layer.link.prev, &to->layer.link); - reverse_workspace_change_animation(shell, index, from, to); broadcast_current_workspace_state(shell); @@ -3732,19 +3729,15 @@ resume_desktop(struct desktop_shell *shell) terminate_screensaver(shell); - wl_list_remove(&shell->lock_layer.link); - wl_list_insert(&shell->compositor->cursor_layer.link, - &shell->fullscreen_layer.link); - wl_list_insert(&shell->fullscreen_layer.link, - &shell->panel_layer.link); - if (shell->showing_input_panels) { - wl_list_insert(&shell->panel_layer.link, - &shell->input_panel_layer.link); - wl_list_insert(&shell->input
[PATCH weston 2/4] compositor: Remove weston_output::move_signal
Since that signal is per output, it is necessary to track in which output a view is in so that the signal is handled properly. Instead, add a compositor wide output moved signal, that is handled by the shell. The shell iterates over the layers it owns to move views appropriately. --- desktop-shell/shell.c | 34 ++ desktop-shell/shell.h | 1 + src/compositor.c | 42 +- src/compositor.h | 2 +- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index c275543..ae06382 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5472,6 +5472,37 @@ handle_output_create(struct wl_listener *listener, void *data) } static void +handle_output_move(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell; + struct weston_output *output; + struct weston_layer *layer; + struct weston_view *view; + float x, y; + + shell = container_of(listener, struct desktop_shell, +output_move_listener); + output = data; + + /* Move all views in the layers owned by the shell */ + wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) { + wl_list_for_each(view, &layer->view_list, layer_link) { + if (view->output != output) + continue; + + x = view->geometry.x + output->move_x; + y = view->geometry.y + output->move_y; + weston_view_set_position(view, x, y); + } + + /* We don't start from the beggining of the layer list, so +* make sure we don't wrap around it. */ + if (layer == &shell->background_layer) + break; + } +} + +static void setup_output_destroy_handler(struct weston_compositor *ec, struct desktop_shell *shell) { @@ -5484,6 +5515,9 @@ setup_output_destroy_handler(struct weston_compositor *ec, shell->output_create_listener.notify = handle_output_create; wl_signal_add(&ec->output_created_signal, &shell->output_create_listener); + + shell->output_move_listener.notify = handle_output_move; + wl_signal_add(&ec->output_moved_signal, &shell->output_move_listener); } static void diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index dbb2854..4d4f00a 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -184,6 +184,7 @@ struct desktop_shell { enum animation_type focus_animation_type; struct wl_listener output_create_listener; + struct wl_listener output_move_listener; struct wl_list output_list; char *client; diff --git a/src/compositor.c b/src/compositor.c index 18018b1..ff7ee7b 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -347,26 +347,6 @@ static struct weston_subsurface * weston_surface_to_subsurface(struct weston_surface *surface); static void -weston_view_output_move_handler(struct wl_listener *listener, - void *data) -{ - struct weston_view *ev; - struct weston_output *output = data; - - ev = container_of(listener, struct weston_view, - output_move_listener); - - /* the child window's view->geometry is a relative coordinate to -* parent view, no need to move child_view. */ - if (ev->geometry.parent) - return; - - weston_view_set_position(ev, -ev->geometry.x + output->move_x, -ev->geometry.y + output->move_y); -} - -static void weston_view_output_destroy_handler(struct wl_listener *listener, void *data) { @@ -414,10 +394,8 @@ weston_view_output_destroy_handler(struct wl_listener *listener, if (ev->surface->output_destroyed) ev->surface->output_destroyed(ev->surface); - wl_list_remove(&ev->output_move_listener.link); wl_list_remove(&ev->output_destroy_listener.link); - wl_list_init(&ev->output_move_listener.link); wl_list_init(&ev->output_destroy_listener.link); } @@ -456,8 +434,6 @@ weston_view_create(struct weston_surface *surface) view->output = NULL; - view->output_move_listener.notify = weston_view_output_move_handler; - wl_list_init(&view->output_move_listener.link); view->output_destroy_listener.notify = weston_view_output_destroy_handler; wl_list_init(&view->output_destroy_listener.link); @@ -911,20 +887,14 @@ weston_view_assign_output(struct weston_view *ev) } pixman_region32_fini(®ion); - if (ev->output_mask != 0) { - wl_list_remove(&ev->output_move_listener.link); + if (ev->output_
[PATCH weston 4/4] compositor: Move view repositioning logic into shell
Remove the listener for output destroy from weston_view and instead iterate views owned by the shell in its own output destroy listener. This simplifies the code a bit since keeping the view listening for the destroy on the right output was a bit complicated. This also removes the function pointer output_destroyed from weston_view. The only user for it was desktop shell, but now this is all handled in shell.c. --- desktop-shell/shell.c | 86 +-- src/compositor.c | 68 src/compositor.h | 8 - 3 files changed, 70 insertions(+), 92 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 888e33b..fb69794 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -2956,8 +2956,6 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data) static void shell_surface_configure(struct weston_surface *, int32_t, int32_t); -static void -shell_surface_output_destroyed(struct weston_surface *); struct shell_surface * get_shell_surface(struct weston_surface *surface) @@ -2994,7 +2992,6 @@ create_common_surface(void *shell, struct weston_surface *surface, surface->configure = shell_surface_configure; surface->configure_private = shsurf; - surface->output_destroyed = shell_surface_output_destroyed; shsurf->shell = (struct desktop_shell *) shell; shsurf->unresponsive = 0; @@ -4793,19 +4790,6 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) } } -static void -shell_surface_output_destroyed(struct weston_surface *es) -{ - struct shell_surface *shsurf = get_shell_surface(es); - - assert(shsurf); - - shsurf->saved_position_valid = false; - shsurf->next_state.maximized = false; - shsurf->next_state.fullscreen = false; - shsurf->state_changed = true; -} - static void launch_desktop_shell_process(void *data); static void @@ -5425,11 +5409,81 @@ workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time, } static void +shell_reposition_view_on_output_destroy(struct weston_view *view) +{ + struct weston_output *output, *first_output; + struct weston_compositor *ec = view->surface->compositor; + struct shell_surface *shsurf; + float x, y; + int visible; + + x = view->geometry.x; + y = view->geometry.y; + + /* At this point the destroyed output is not in the list anymore. +* If the view is still visible somewhere, we leave where it is, +* otherwise, move it to the first output. */ + visible = 0; + wl_list_for_each(output, &ec->output_list, link) { + if (pixman_region32_contains_point(&output->region, + x, y, NULL)) { + visible = 1; + break; + } + } + + if (!visible) { + first_output = container_of(ec->output_list.next, + struct weston_output, link); + + x = first_output->x + first_output->width / 4; + y = first_output->y + first_output->height / 4; + } + + weston_view_set_position(view, x, y); + + shsurf = get_shell_surface(view->surface); + + if (shsurf) { + shsurf->saved_position_valid = false; + shsurf->next_state.maximized = false; + shsurf->next_state.fullscreen = false; + shsurf->state_changed = true; + } +} + +static void +shell_reposition_views_on_output_destroy(struct shell_output *shell_output) +{ + struct desktop_shell *shell = shell_output->shell; + struct weston_output *output = shell_output->output; + struct weston_layer *layer; + struct weston_view *view; + + /* Move all views in the layers owned by the shell */ + wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) { + wl_list_for_each(view, &layer->view_list, layer_link) { + if (view->output != output) + continue; + + shell_reposition_view_on_output_destroy(view); + } + + /* We don't start from the beggining of the layer list, so +* make sure we don't wrap around it. */ + if (layer == &shell->background_layer) + break; + } +} + +static void handle_output_destroy(struct wl_listener *listener, void *data) { struct shell_output *output_listener = container_of(listener, struct shell_output, destroy_listener); + shell_reposition_views_on_output_destroy(output_listener); + wl_list_remove(&output_listener->destroy_listener.link); wl_list_remove(&output_listener->link); free(output_listener); diff --git a/src/compositor.c b/src/com
[PATCH weston 1/4] input: Remove exported function weston_pointer_verify()
Instead, add a compositor signal that an output has been destroyed and handle that case locally in input.c. --- src/compositor.c | 17 ++--- src/compositor.h | 5 +++-- src/input.c | 20 +--- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 40e4b11..18018b1 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3170,19 +3170,6 @@ weston_compositor_remove_output(struct weston_compositor *compositor, } } -static void -weston_compositor_verify_pointers(struct weston_compositor *ec) -{ - struct weston_seat *seat; - - wl_list_for_each(seat, &ec->seat_list, link) { - if (!seat->pointer) - continue; - - weston_pointer_verify(seat->pointer); - } -} - WL_EXPORT void weston_output_destroy(struct weston_output *output) { @@ -3191,8 +3178,7 @@ weston_output_destroy(struct weston_output *output) weston_compositor_remove_output(output->compositor, output); wl_list_remove(&output->link); - weston_compositor_verify_pointers(output->compositor); - + wl_signal_emit(&output->compositor->output_destroyed_signal, output); wl_signal_emit(&output->destroy_signal, output); free(output->name); @@ -3654,6 +3640,7 @@ weston_compositor_init(struct weston_compositor *ec, wl_signal_init(&ec->update_input_panel_signal); wl_signal_init(&ec->seat_created_signal); wl_signal_init(&ec->output_created_signal); + wl_signal_init(&ec->output_destroyed_signal); wl_signal_init(&ec->session_signal); ec->session_active = 1; diff --git a/src/compositor.h b/src/compositor.h index 22a485f..ced792f 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -329,6 +329,8 @@ struct weston_pointer { wl_fixed_t x, y; uint32_t button_count; + + struct wl_listener output_destroy_listener; }; @@ -375,8 +377,6 @@ weston_pointer_move(struct weston_pointer *pointer, void weston_pointer_set_default_grab(struct weston_pointer *pointer, const struct weston_pointer_grab_interface *interface); -void -weston_pointer_verify(struct weston_pointer *pointer); struct weston_keyboard * weston_keyboard_create(void); @@ -579,6 +579,7 @@ struct weston_compositor { struct wl_signal seat_created_signal; struct wl_signal output_created_signal; + struct wl_signal output_destroyed_signal; struct wl_event_loop *input_loop; struct wl_event_source *input_loop_source; diff --git a/src/input.c b/src/input.c index 157066c..25ed133 100644 --- a/src/input.c +++ b/src/input.c @@ -438,6 +438,9 @@ weston_pointer_reset_state(struct weston_pointer *pointer) pointer->button_count = 0; } +static void +weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data); + WL_EXPORT struct weston_pointer * weston_pointer_create(struct weston_seat *seat) { @@ -465,6 +468,11 @@ weston_pointer_create(struct weston_seat *seat) pointer->x = wl_fixed_from_int(100); pointer->y = wl_fixed_from_int(100); + pointer->output_destroy_listener.notify = + weston_pointer_handle_output_destroy; + wl_signal_add(&seat->compositor->output_destroyed_signal, + &pointer->output_destroy_listener); + return pointer; } @@ -478,6 +486,7 @@ weston_pointer_destroy(struct weston_pointer *pointer) wl_list_remove(&pointer->focus_resource_listener.link); wl_list_remove(&pointer->focus_view_listener.link); + wl_list_remove(&pointer->output_destroy_listener.link); free(pointer); } @@ -871,14 +880,19 @@ weston_pointer_move(struct weston_pointer *pointer, wl_fixed_t x, wl_fixed_t y) /** Verify if the pointer is in a valid position and move it if it isn't. */ -WL_EXPORT void -weston_pointer_verify(struct weston_pointer *pointer) +static void +weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data) { - struct weston_compositor *ec = pointer->seat->compositor; + struct weston_pointer *pointer; + struct weston_compositor *ec; struct weston_output *output, *closest = NULL; int x, y, distance, min = INT_MAX; wl_fixed_t fx, fy; + pointer = container_of(listener, struct weston_pointer, + output_destroy_listener); + ec = pointer->seat->compositor; + x = wl_fixed_to_int(pointer->x); y = wl_fixed_to_int(pointer->y); -- 1.8.1.2 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH] dim-layer: fix dimming for unfocused surfaces
On 01/15/2014 10:30 AM, Emilio Pozuelo Monfort wrote: bump On 07/01/14 17:23, poch...@gmail.com wrote: From: Emilio Pozuelo Monfort Unfocusing a surface should dim it when dim-layer is enabled, but this got broken in commit 83ffd9. --- desktop-shell/shell.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index f85a269..cca96be 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -4141,6 +4141,7 @@ activate(struct desktop_shell *shell, struct weston_surface *es, struct weston_seat *seat) { struct weston_surface *main_surface; + struct weston_view *main_view; struct focus_state *state; struct workspace *ws; struct weston_surface *old_es; @@ -4162,8 +4163,18 @@ activate(struct desktop_shell *shell, struct weston_surface *es, shsurf = get_shell_surface(main_surface); if (shsurf->state.fullscreen) shell_configure_fullscreen(shsurf); - else + else { + ws = get_current_workspace(shell); + main_view = get_default_view(main_surface); + if (main_view) { + wl_list_remove(&main_view->layer_link); + wl_list_insert(&ws->layer.view_list, &main_view->layer_link); + weston_view_damage_below(main_view); + weston_surface_damage(main_view->surface); + } So you're basically rewriting weston_view_restack() here. Wouldn't a better fix be to move the animation logic below the call to shell_surface_update_layer(), which is the place where the surface is restacked after the commit you mentioned. Cheers, Ander + restore_all_output_modes(shell->compositor); + } if (shell->focus_animation_type != ANIMATION_NONE) { ws = get_current_workspace(shell); ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 2/2] compositor: add a masking mechanism to weston_layer
On 01/28/2014 06:36 PM, Giulio Camuffo wrote: 2014-01-28 Ander Conselvan de Oliveira : On 01/27/2014 09:46 PM, Giulio Camuffo wrote: this adds a mechanism to mask the views belonging to a layer to an arbitrary rect, in the global space. The parts that don't fit in that rect will be clipped away. Implemented in the gl and pixman renderers only for now. --- src/compositor.c | 26 +- src/compositor.h | 7 +++ src/gl-renderer.c | 4 src/pixman-renderer.c | 4 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/compositor.c b/src/compositor.c index 9a269e5..25068b8 100644 [...] diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 0e5afbe..899c280 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -521,6 +521,10 @@ draw_view(struct weston_view *ev, struct weston_output *output, pixman_region32_intersect(&repaint, &ev->transform.boundingbox, damage); pixman_region32_subtract(&repaint, &repaint, &ev->clip); + pixman_region32_t mask; + pixman_region32_init_with_extents(&mask, &ev->layer_link.layer->mask); + pixman_region32_intersect(&repaint, &repaint, &mask); + pixman_region32_fini(&mask); There are more things you need to consider in order to clip properly. 1) Opaque region. This is used to avoid rendering obscured parts of surfaces. In compositor_accumulate_damage(), a clip region for each surface is determined as the union of the opaque regions of the surfaces on top of it. That way, the parts of the surface that are covered by other opaque content is not rendered. You can see the effect of this relatively easily. Patch desktop-shell to set a clip for the workspace layer that is smaller than the screen. Then running Weston with the X11 backend (or just make sure you have a software rendered cursor), open a weston-terminal and move it so that it crosses the border of the clipped region. Then move the mouse over the region that should be part of the terminal but is clipped away. Notice how the background is not redrawn properly. In order to fix this, the opaque region used for calculating the surface clip also needs to be clipped. 2) Sprite planes. There's another path through which content can get to the screen. When a view is put on a sprite plane, it complete bypasses the renderer. During the repaint process, the core gives the backend a chance to move views to different planes. At that moment, the backend could configure the sprite plane to clip the surface or just decide to not to use a sprite plane for it. However, it needs the clipping information to make that decision. If I understand correctly, the rpi backend relies heavily on planes. The DRM backend has support for sprite planes too, but it is disabled since it can't work correctly without a patched kernel. You can try it (with a regular kernel) by pressing mod-shift-space followed by 'v'. If you run weston-simple-egl -o, you'll notice the clipping won't work when the surface is in a sprite plane. Given the points above, I believe it would be better to keep the information related to clipping in the weston_view structure. That way the backend and the renderer can be completely unaware of the existence of layers. The clipping information can be propagated from the layers to the views in the beginning of weston_output_repaint() and/or as part of weston_view_update_transform(). What's the difference between using view->layer.mask or using view->mask? I don't seen how the latter helps anything in any way. Besides, if the mask is in the view it should be in view space, but that means adding complexity for no real benefit. What happens if you have a surface with subsurfaces in a layer with a mask? The layer_link for a subsurface is not in any layers, and that causes a crash with your patch. My point was not about writing view->mask instead of view->layer.mask, but that we need to handle all the complexities about clipping in Weston's core. The list of views and the information contained in them is enough for the renderers to produce the correct output. We should avoid making them aware of layers and subsurfaces. Cheers, Ander ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 2/2] compositor: add a masking mechanism to weston_layer
On 01/27/2014 09:46 PM, Giulio Camuffo wrote: this adds a mechanism to mask the views belonging to a layer to an arbitrary rect, in the global space. The parts that don't fit in that rect will be clipped away. Implemented in the gl and pixman renderers only for now. --- src/compositor.c | 26 +- src/compositor.h | 7 +++ src/gl-renderer.c | 4 src/pixman-renderer.c | 4 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/compositor.c b/src/compositor.c index 9a269e5..25068b8 100644 [...] diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 0e5afbe..899c280 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -521,6 +521,10 @@ draw_view(struct weston_view *ev, struct weston_output *output, pixman_region32_intersect(&repaint, &ev->transform.boundingbox, damage); pixman_region32_subtract(&repaint, &repaint, &ev->clip); + pixman_region32_t mask; + pixman_region32_init_with_extents(&mask, &ev->layer_link.layer->mask); + pixman_region32_intersect(&repaint, &repaint, &mask); + pixman_region32_fini(&mask); There are more things you need to consider in order to clip properly. 1) Opaque region. This is used to avoid rendering obscured parts of surfaces. In compositor_accumulate_damage(), a clip region for each surface is determined as the union of the opaque regions of the surfaces on top of it. That way, the parts of the surface that are covered by other opaque content is not rendered. You can see the effect of this relatively easily. Patch desktop-shell to set a clip for the workspace layer that is smaller than the screen. Then running Weston with the X11 backend (or just make sure you have a software rendered cursor), open a weston-terminal and move it so that it crosses the border of the clipped region. Then move the mouse over the region that should be part of the terminal but is clipped away. Notice how the background is not redrawn properly. In order to fix this, the opaque region used for calculating the surface clip also needs to be clipped. 2) Sprite planes. There's another path through which content can get to the screen. When a view is put on a sprite plane, it complete bypasses the renderer. During the repaint process, the core gives the backend a chance to move views to different planes. At that moment, the backend could configure the sprite plane to clip the surface or just decide to not to use a sprite plane for it. However, it needs the clipping information to make that decision. If I understand correctly, the rpi backend relies heavily on planes. The DRM backend has support for sprite planes too, but it is disabled since it can't work correctly without a patched kernel. You can try it (with a regular kernel) by pressing mod-shift-space followed by 'v'. If you run weston-simple-egl -o, you'll notice the clipping won't work when the surface is in a sprite plane. Given the points above, I believe it would be better to keep the information related to clipping in the weston_view structure. That way the backend and the renderer can be completely unaware of the existence of layers. The clipping information can be propagated from the layers to the views in the beginning of weston_output_repaint() and/or as part of weston_view_update_transform(). Cheers, Ander if (!pixman_region32_not_empty(&repaint)) goto out; diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 26f6f27..511dd8b 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -374,6 +374,10 @@ draw_view(struct weston_view *ev, struct weston_output *output, pixman_region32_intersect(&repaint, &ev->transform.boundingbox, damage); pixman_region32_subtract(&repaint, &repaint, &ev->clip); + pixman_region32_t mask; + pixman_region32_init_with_extents(&mask, &ev->layer_link.layer->mask); + pixman_region32_intersect(&repaint, &repaint, &mask); + pixman_region32_fini(&mask); if (!pixman_region32_not_empty(&repaint)) goto out; ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH] compositor: Ensure views on hiden workspace are listening correct output
On 12/19/2013 11:26 AM, Xiong Zhang wrote: The views on hiden workspace can't restored correctly when their output was unplugged. There are two reasons: First: the views on hiden workspace is restored through animation which will change y coordinate continually, if the y coordinate of invisible views are setted to first_output->height/4, these views will be changed to some invisible region by animation. Second: the wrong way to manage view->output_destroy_listener.link. Considering the following serials: a. the view is visible, so the view listen one output signal b. the view is invisible, view->output_mask = 0 and view is still listenering the previous output signal c. the view is visible again. We will add view to previous output signal again without removing the view from the previous output signal. So the listener list of previous output's signal is wrong at this point.When the output is unplgged, the system will dead loop on the listener list of this output signal. Signed-off-by: Xiong Zhang --- src/compositor.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 6ca297a..9929be1 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -383,7 +383,7 @@ weston_view_output_destroy_handler(struct wl_listener *listener, /* the child window's view->geometry is a relative coordinate to * parent view, no need to move child_view. */ - if (ev->geometry.parent) + if (ev->geometry.parent || wl_list_empty(&ec->output_list)) return; x = ev->geometry.x; @@ -406,7 +406,8 @@ weston_view_output_destroy_handler(struct wl_listener *listener, struct weston_output, link); x = first_output->x + first_output->width / 4; - y = first_output->y + first_output->height / 4; + if (y > first_output->y) + y = first_output->y + first_output->height / 4; } We should move this repositioning logic into the shell. I think the proper fix for the workspace case then would be to cause all the hidden surfaces to have their saved positions invalidated and then run the initial positioning algorithm when the user makes them visible by switching workspaces. weston_view_set_position(ev, x, y); @@ -905,7 +906,7 @@ weston_view_assign_output(struct weston_view *ev) } pixman_region32_fini(®ion); - if (ev->output_mask != 0) { + if (!wl_list_empty(&ev->output_destroy_listener.link) && mask != 0) { wl_list_remove(&ev->output_move_listener.link); wl_list_remove(&ev->output_destroy_listener.link); } I sent a patch yesterday to fix a case where we couldn't just wl_list_remove() the listener. Do you still need the wl_list_empty() check after that? Cheers, Ander ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 1/2] compositor: Destroy renderer in weston_compositor_shutdown()
From: Ander Conselvan de Oliveira Currently we destroy the renderer before the outputs are destroyed, but that sometimes leads to an error since a reference to the renderer is necessary in order to destroy a gl_renderer_output. Since destroying the renderer is common among all backends, just move that call into weston_compositor_shutdown() immediately after the outputs being destroyed. --- src/compositor-drm.c |2 -- src/compositor-fbdev.c|2 -- src/compositor-headless.c |2 -- src/compositor-rdp.c |1 - src/compositor-rpi.c |2 -- src/compositor-wayland.c |2 -- src/compositor-x11.c |2 -- src/compositor.c |3 +++ 8 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index f85298a..d637e75 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2336,8 +2336,6 @@ drm_destroy(struct weston_compositor *ec) destroy_sprites(d); - ec->renderer->destroy(ec); - weston_compositor_shutdown(ec); if (d->gbm) diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c index e649d43..0d96269 100644 --- a/src/compositor-fbdev.c +++ b/src/compositor-fbdev.c @@ -797,8 +797,6 @@ fbdev_compositor_destroy(struct weston_compositor *base) udev_input_destroy(&compositor->input); - compositor->base.renderer->destroy(&compositor->base); - /* Destroy the output. */ weston_compositor_shutdown(&compositor->base); diff --git a/src/compositor-headless.c b/src/compositor-headless.c index 5497455..5a5c1e6 100644 --- a/src/compositor-headless.c +++ b/src/compositor-headless.c @@ -141,8 +141,6 @@ headless_destroy(struct weston_compositor *ec) { struct headless_compositor *c = (struct headless_compositor *) ec; - ec->renderer->destroy(ec); - weston_seat_release(&c->fake_seat); weston_compositor_shutdown(ec); diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c index 58342b9..942af50 100644 --- a/src/compositor-rdp.c +++ b/src/compositor-rdp.c @@ -521,7 +521,6 @@ rdp_restore(struct weston_compositor *ec) static void rdp_destroy(struct weston_compositor *ec) { - ec->renderer->destroy(ec); weston_compositor_shutdown(ec); free(ec); diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c index 1d52a94..399090d 100644 --- a/src/compositor-rpi.c +++ b/src/compositor-rpi.c @@ -422,8 +422,6 @@ rpi_compositor_destroy(struct weston_compositor *base) udev_input_destroy(&compositor->input); - compositor->base.renderer->destroy(&compositor->base); - /* destroys outputs, too */ weston_compositor_shutdown(&compositor->base); diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 14ff4af..d2d8942 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -1398,8 +1398,6 @@ wayland_destroy(struct weston_compositor *ec) { struct wayland_compositor *c = (struct wayland_compositor *) ec; - ec->renderer->destroy(ec); - weston_compositor_shutdown(ec); if (c->parent.shm) diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 2ef1b5d..97fe3b1 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -1415,8 +1415,6 @@ x11_destroy(struct weston_compositor *ec) wl_event_source_remove(compositor->xcb_source); x11_input_destroy(compositor); - ec->renderer->destroy(ec); - weston_compositor_shutdown(ec); /* destroys outputs, too */ XCloseDisplay(compositor->dpy); diff --git a/src/compositor.c b/src/compositor.c index ff0f3ab..329ee49 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3734,6 +3734,9 @@ weston_compositor_shutdown(struct weston_compositor *ec) wl_list_for_each_safe(output, next, &ec->output_list, link) output->destroy(output); + if (ec->renderer) + ec->renderer->destroy(ec); + weston_binding_list_destroy_all(&ec->key_binding_list); weston_binding_list_destroy_all(&ec->button_binding_list); weston_binding_list_destroy_all(&ec->touch_binding_list); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 2/2] shell: Handle the desktop shell client destroy signal
From: Ander Conselvan de Oliveira Set the internal pointer for the client to NULL. This fixes a segmentation fault at shutdown, where the shell would hang up before and cause libwayland to call wl_client_destroy(). When the shell was destroyed later, another call to wl_client_destroy() would cause the crash. https://bugs.freedesktop.org/show_bug.cgi?id=72550 --- desktop-shell/shell.c | 16 desktop-shell/shell.h |1 + 2 files changed, 17 insertions(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 3d586ec..714881b 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5008,6 +5008,17 @@ desktop_shell_sigchld(struct weston_process *process, int status) } static void +desktop_shell_client_destroy(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell; + + shell = container_of(listener, struct desktop_shell, +child.client_destroy_listener); + + shell->child.client = NULL; +} + +static void launch_desktop_shell_process(void *data) { struct desktop_shell *shell = data; @@ -5019,6 +5030,11 @@ launch_desktop_shell_process(void *data) if (!shell->child.client) weston_log("not able to start %s\n", shell->client); + + shell->child.client_destroy_listener.notify = + desktop_shell_client_destroy; + wl_client_add_destroy_listener(shell->child.client, + &shell->child.client_destroy_listener); } static void diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index d7c34fc..7a8194d 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -92,6 +92,7 @@ struct desktop_shell { struct weston_process process; struct wl_client *client; struct wl_resource *desktop_shell; + struct wl_listener client_destroy_listener; unsigned deathcount; uint32_t deathstamp; -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH] compositor: Clean up view output move and destroy listeners
From: Ander Conselvan de Oliveira Remove those listeners when the output is destroyed, otherwise they'll point to invalid data that may lead to corruption when assigning a new output for the view. -- This is possibly related to bug 72845. I didn't have enough equipment to try and reproduce it. https://bugs.freedesktop.org/show_bug.cgi?id=72845 --- src/compositor.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index 6ca297a..ff0f3ab 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -413,6 +413,12 @@ weston_view_output_destroy_handler(struct wl_listener *listener, if (ev->surface->output_destroyed) ev->surface->output_destroyed(ev->surface); + + wl_list_remove(&ev->output_move_listener.link); + wl_list_remove(&ev->output_destroy_listener.link); + + wl_list_init(&ev->output_move_listener.link); + wl_list_init(&ev->output_destroy_listener.link); } WL_EXPORT struct weston_view * -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 1/2] screenshooter: Choose output to record from based on keyboard focus
From: Ander Conselvan de Oliveira Record from the output of the surface that has keyboard focus for the seat used to activate the recorder key binding. If there is no focused surface, record from the first one. Also, use the weston_transformed_region() to transform the damage region of the output into the coordinates expected by read_pixels(). https://bugs.freedesktop.org/show_bug.cgi?id=71401 --- src/screenshooter.c | 96 --- 1 file changed, 29 insertions(+), 67 deletions(-) diff --git a/src/screenshooter.c b/src/screenshooter.c index 2d05ad6..0489f92 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -302,60 +302,6 @@ component_delta(uint32_t next, uint32_t prev) } static void -transform_rect(struct weston_output *output, pixman_box32_t *r) -{ - pixman_box32_t s = *r; - - switch (output->transform) { - case WL_OUTPUT_TRANSFORM_FLIPPED: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - s.x1 = output->width - r->x2; - s.x2 = output->width - r->x1; - break; - default: - break; - } - - switch (output->transform) { -case WL_OUTPUT_TRANSFORM_NORMAL: -case WL_OUTPUT_TRANSFORM_FLIPPED: - r->x1 = s.x1; - r->x2 = s.x2; -break; -case WL_OUTPUT_TRANSFORM_90: -case WL_OUTPUT_TRANSFORM_FLIPPED_90: - r->x1 = output->current_mode->width - s.y2; - r->y1 = s.x1; - r->x2 = output->current_mode->width - s.y1; - r->y2 = s.x2; -break; -case WL_OUTPUT_TRANSFORM_180: -case WL_OUTPUT_TRANSFORM_FLIPPED_180: - r->x1 = output->current_mode->width - s.x2; - r->y1 = output->current_mode->height - s.y2; - r->x2 = output->current_mode->width - s.x1; - r->y2 = output->current_mode->height - s.y1; -break; -case WL_OUTPUT_TRANSFORM_270: -case WL_OUTPUT_TRANSFORM_FLIPPED_270: - r->x1 = s.y1; - r->y1 = output->current_mode->height - s.x2; - r->x2 = s.y2; - r->y2 = output->current_mode->height - s.x1; -break; -default: -break; -} - - r->x1 *= output->current_scale; - r->y1 *= output->current_scale; - r->x2 *= output->current_scale; - r->y2 *= output->current_scale; -} - -static void weston_recorder_destroy(struct weston_recorder *recorder); static void @@ -367,7 +313,7 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) struct weston_compositor *compositor = output->compositor; uint32_t msecs = output->frame_time; pixman_box32_t *r; - pixman_region32_t damage; + pixman_region32_t damage, transformed_damage; int i, j, k, n, width, height, run, stride; uint32_t delta, prev, *d, *s, *p, next; struct { @@ -386,15 +332,20 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) outbuf = recorder->tmpbuf; pixman_region32_init(&damage); + pixman_region32_init(&transformed_damage); pixman_region32_intersect(&damage, &output->region, &output->previous_damage); + pixman_region32_translate(&damage, -output->x, -output->y); + weston_transformed_region(output->width, output->height, +output->transform, output->current_scale, +&damage, &transformed_damage); + pixman_region32_fini(&damage); - r = pixman_region32_rectangles(&damage, &n); - if (n == 0) + r = pixman_region32_rectangles(&transformed_damage, &n); + if (n == 0) { + pixman_region32_fini(&transformed_damage); return; - - for (i = 0; i < n; i++) - transform_rect(output, &r[i]); + } header.msecs = msecs; header.nrects = n; @@ -457,7 +408,7 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) #endif } - pixman_region32_fini(&damage); + pixman_region32_fini(&transformed_damage); recorder->count++; if (recorder->destroying) @@ -543,15 +494,18 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *da { struct weston_seat *ws = (struct weston_seat *) seat; struct weston_compositor *ec = ws->compositor; - struct weston_output *output = - container_of(ec-&g
[PATCH 2/2] compositor-x11: Set the name field on weston_outputs
From: Ander Conselvan de Oliveira That way log messages referencing the output are more informative. --- src/compositor-x11.c |4 1 file changed, 4 insertions(+) diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 2ef1b5d..1b178b8 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -871,6 +871,10 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y, output->base.current_mode = &output->mode; output->base.make = "xwayland"; output->base.model = "none"; + + if (configured_name) + output->base.name = strdup(configured_name); + weston_output_init(&output->base, &c->base, x, y, width, height, transform, scale); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH] screenshooter: Record one extra frame when recording stops
From: Ander Conselvan de Oliveira If the compositor hasn't been rendering for a while when the recording stops, the time difference between the last rendered frame and that moment won't be in the encoded video. Fix that by forcing one extra frame to be recorded when the user presses the recorder key binding. https://bugs.freedesktop.org/show_bug.cgi?id=71142 --- src/screenshooter.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/screenshooter.c b/src/screenshooter.c index 0c657bc..2d05ad6 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -267,7 +267,7 @@ struct weston_recorder { uint32_t total; int fd; struct wl_listener frame_listener; - int count; + int count, destroying; }; static uint32_t * @@ -356,6 +356,9 @@ transform_rect(struct weston_output *output, pixman_box32_t *r) } static void +weston_recorder_destroy(struct weston_recorder *recorder); + +static void weston_recorder_frame_notify(struct wl_listener *listener, void *data) { struct weston_recorder *recorder = @@ -456,6 +459,9 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) pixman_region32_fini(&damage); recorder->count++; + + if (recorder->destroying) + weston_recorder_destroy(recorder); } static void @@ -477,6 +483,7 @@ weston_recorder_create(struct weston_output *output, const char *filename) recorder->rect = malloc(size); recorder->total = 0; recorder->count = 0; + recorder->destroying = 0; recorder->output = output; if (do_yflip) @@ -553,7 +560,8 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *da "stopping recorder, total file size %dM, %d frames\n", recorder->total / (1024 * 1024), recorder->count); - weston_recorder_destroy(recorder); + recorder->destroying = 1; + weston_output_schedule_repaint(recorder->output); } else { weston_log("starting recorder, file %s\n", filename); weston_recorder_create(output, filename); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 04/10] compositor-headless, compositor-rdp: Don't call weston_output_move()
From: Ander Conselvan de Oliveira The call to weston_output_move() when creating the output is unnecessary. That is already called by wesotn_output_init(). --- src/compositor-headless.c |2 -- src/compositor-rdp.c |2 -- 2 files changed, 4 deletions(-) diff --git a/src/compositor-headless.c b/src/compositor-headless.c index 9d9f6dd..5497455 100644 --- a/src/compositor-headless.c +++ b/src/compositor-headless.c @@ -114,8 +114,6 @@ headless_compositor_create_output(struct headless_compositor *c, output->base.make = "weston"; output->base.model = "headless"; - weston_output_move(&output->base, 0, 0); - loop = wl_display_get_event_loop(c->base.wl_display); output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output); diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c index 8a302f8..58342b9 100644 --- a/src/compositor-rdp.c +++ b/src/compositor-rdp.c @@ -486,8 +486,6 @@ rdp_compositor_create_output(struct rdp_compositor *c, int width, int height, if (pixman_renderer_output_create(&output->base) < 0) goto out_shadow_surface; - weston_output_move(&output->base, 0, 0); - loop = wl_display_get_event_loop(c->base.wl_display); output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 07/10] compositor; Don't repaint outputs being destroyed
From: Ander Conselvan de Oliveira Set a flag when an output is being destroyed and use that to avoid repainting. This allows functions that schedule an output repaint to be called when the output is being destroyed without causing the compositor to crash. --- src/compositor.c |5 + src/compositor.h |1 + 2 files changed, 6 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index e4eb56d..ed6548c 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1759,6 +1759,9 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs) pixman_region32_t output_damage; int r; + if (output->destroying) + return 0; + /* Rebuild the surface list and update surface transforms up front. */ weston_compositor_build_view_list(ec); @@ -3105,6 +3108,8 @@ weston_compositor_remove_output(struct weston_compositor *compositor, WL_EXPORT void weston_output_destroy(struct weston_output *output) { + output->destroying = 1; + weston_compositor_remove_output(output->compositor, output); wl_list_remove(&output->link); diff --git a/src/compositor.h b/src/compositor.h index 84b0f79..901366f 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -198,6 +198,7 @@ struct weston_output { int move_x, move_y; uint32_t frame_time; int disable_planes; + int destroying; char *make, *model, *serial_number; uint32_t subpixel; -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 05/10] compositor: Move views when outputs are moved
From: "Zhang, Xiong Y" Previously, when an output was moved due to another output being unplugged, the views on the first output would remain in the same position. This patch adds an output_move signal that the views listen too in order to repostion themselves in the event of an unplug. Signed-off-by: Zhang, Xiong Y Signed-off-by: Ander Conselvan de Oliveira --- src/compositor.c | 74 +++--- src/compositor.h |4 +++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 36985d7..2f2c838 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -345,6 +345,26 @@ region_init_infinite(pixman_region32_t *region) static struct weston_subsurface * weston_surface_to_subsurface(struct weston_surface *surface); +static void +weston_view_output_move_handler(struct wl_listener *listener, + void *data) +{ + struct weston_view *ev; + struct weston_output *output = data; + + ev = container_of(listener, struct weston_view, + output_move_listener); + + /* the child window's view->geometry is a relative coordinate to +* parent view, no need to move child_view. */ + if (ev->geometry.parent) + return; + + weston_view_set_position(ev, +ev->geometry.x + output->move_x, +ev->geometry.y + output->move_y); +} + WL_EXPORT struct weston_view * weston_view_create(struct weston_surface *surface) { @@ -380,6 +400,8 @@ weston_view_create(struct weston_surface *surface) view->output = NULL; + view->output_move_listener.notify = weston_view_output_move_handler; + return view; } @@ -727,6 +749,7 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask) } } + static void weston_surface_assign_output(struct weston_surface *es) { @@ -793,6 +816,13 @@ weston_view_assign_output(struct weston_view *ev) } pixman_region32_fini(®ion); + if (ev->output_mask != 0) + wl_list_remove(&ev->output_move_listener.link); + + if (mask != 0) + wl_signal_add(&new_output->move_signal, + &ev->output_move_listener); + ev->output = new_output; ev->output_mask = mask; @@ -1233,6 +1263,8 @@ weston_view_unmap(struct weston_view *view) wl_list_init(&view->layer_link); wl_list_remove(&view->link); wl_list_init(&view->link); + wl_list_remove(&view->output_move_listener.link); + wl_list_init(&view->output_move_listener.link); view->output_mask = 0; weston_surface_assign_output(view->surface); @@ -3152,8 +3184,8 @@ weston_output_transform_scale_init(struct weston_output *output, uint32_t transf output->height /= scale; } -WL_EXPORT void -weston_output_move(struct weston_output *output, int x, int y) +static void +weston_output_init_geometry(struct weston_output *output, int x, int y) { output->x = x; output->y = y; @@ -3165,6 +3197,41 @@ weston_output_move(struct weston_output *output, int x, int y) } WL_EXPORT void +weston_output_move(struct weston_output *output, int x, int y) +{ + pixman_region32_t old_region; + struct wl_resource *resource; + + output->move_x = x - output->x; + output->move_y = y - output->y; + + if (output->move_x == 0 && output->move_y == 0) + return; + + pixman_region32_init(&old_region); + pixman_region32_copy(&old_region, &output->region); + + weston_output_init_geometry(output, x, y); + + output->dirty = 1; + + /* Move views on this output. */ + wl_signal_emit(&output->move_signal, output); + + /* Notify clients of the change for output position. */ + wl_resource_for_each(resource, &output->resource_list) + wl_output_send_geometry(resource, + output->x, + output->y, + output->mm_width, + output->mm_height, + output->subpixel, + output->make, + output->model, + output->transform); +} + +WL_EXPORT void weston_output_init(struct weston_output *output, struct weston_compositor *c, int x, int y, int mm_width, int mm_height, uint32_t transform, int32_t scale) @@ -3180,11 +3247,12 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
[PATCH 09/10] desktop-shell: Invalidate saved position when output is destroyed
From: "Zhang, Xiong Y" If the saved position for a fullscreen or maximized output view is in an output that has been unplugged, the coordinates don't make sense anymore. In that case, invalidate them and use the initial position algorithm when changing them back to the basic state. Signed-off-by: Zhang, Xiong Y Signed-off-by: Ander Conselvan de Oliveira --- desktop-shell/shell.c | 32 +++- src/compositor.c |3 +++ src/compositor.h |6 ++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 9fbac00..f70b310 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -2206,6 +2206,10 @@ set_fullscreen(struct shell_surface *shsurf, } static void +weston_view_set_initial_position(struct weston_view *view, +struct desktop_shell *shell); + +static void unset_fullscreen(struct shell_surface *shsurf) { /* Unset the fullscreen output, driver configuration and transforms. */ @@ -2225,8 +2229,12 @@ unset_fullscreen(struct shell_surface *shsurf) weston_surface_destroy(shsurf->fullscreen.black_view->surface); shsurf->fullscreen.black_view = NULL; - weston_view_set_position(shsurf->view, -shsurf->saved_x, shsurf->saved_y); + if (shsurf->saved_position_valid) + weston_view_set_position(shsurf->view, +shsurf->saved_x, shsurf->saved_y); + else + weston_view_set_initial_position(shsurf->view, shsurf->shell); + if (shsurf->saved_rotation_valid) { wl_list_insert(&shsurf->view->geometry.transformation_list, &shsurf->rotation.transform.link); @@ -2323,9 +2331,12 @@ unset_maximized(struct shell_surface *shsurf) { /* undo all maximized things here */ shsurf->output = get_default_output(shsurf->surface->compositor); - weston_view_set_position(shsurf->view, -shsurf->saved_x, -shsurf->saved_y); + + if (shsurf->saved_position_valid) + weston_view_set_position(shsurf->view, +shsurf->saved_x, shsurf->saved_y); + else + weston_view_set_initial_position(shsurf->view, shsurf->shell); if (shsurf->saved_rotation_valid) { wl_list_insert(&shsurf->view->geometry.transformation_list, @@ -2907,6 +2918,8 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data) static void shell_surface_configure(struct weston_surface *, int32_t, int32_t); +static void +shell_surface_output_destroyed(struct weston_surface *); struct shell_surface * get_shell_surface(struct weston_surface *surface) @@ -2943,6 +2956,7 @@ create_common_surface(void *shell, struct weston_surface *surface, surface->configure = shell_surface_configure; surface->configure_private = shsurf; + surface->output_destroyed = shell_surface_output_destroyed; shsurf->shell = (struct desktop_shell *) shell; shsurf->unresponsive = 0; @@ -4955,6 +4969,14 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) } } +static void +shell_surface_output_destroyed(struct weston_surface *es) +{ + struct shell_surface *shsurf = get_shell_surface(es); + + shsurf->saved_position_valid = false; +} + static void launch_desktop_shell_process(void *data); static void diff --git a/src/compositor.c b/src/compositor.c index af33fda..c4ffb5e 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -409,6 +409,9 @@ weston_view_output_destroy_handler(struct wl_listener *listener, } weston_view_set_position(ev, x, y); + + if (ev->surface->output_destroyed) + ev->surface->output_destroyed(ev->surface); } WL_EXPORT struct weston_view * diff --git a/src/compositor.h b/src/compositor.h index d344e37..f5a0ba4 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -885,6 +885,12 @@ struct weston_surface { void (*configure)(struct weston_surface *es, int32_t sx, int32_t sy); void *configure_private; + /* If non-NULL, this function will be called on surface->output:: +* destroy, after the output is removed from the compositor's +* output list and the remaining outputs moved. +*/ + void (*output_destroyed)(struct weston_surface *surface); + /* Parent's list of its sub-surfaces, weston_subsurface:parent_link. * Contains also the parent itself as a dummy weston_subsurface, * if the list is not empty. -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 06/10] compositor: Ensure views are visible if their output was unplugged
From: "Zhang, Xiong Y" Use the output destroy signal to move the views in the event the output was unplugged. Signed-off-by: Zhang, Xiong Y Signed-off-by: Ander Conselvan de Oliveira --- src/compositor.c | 59 -- src/compositor.h |1 + 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 2f2c838..e4eb56d 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -365,6 +365,52 @@ weston_view_output_move_handler(struct wl_listener *listener, ev->geometry.y + output->move_y); } +static void +weston_view_output_destroy_handler(struct wl_listener *listener, + void *data) +{ + struct weston_view *ev; + struct weston_compositor *ec; + struct weston_output *output, *first_output; + float x, y; + int visible; + + ev = container_of(listener, struct weston_view, + output_destroy_listener); + + ec = ev->surface->compositor; + + /* the child window's view->geometry is a relative coordinate to +* parent view, no need to move child_view. */ + if (ev->geometry.parent) + return; + + x = ev->geometry.x; + y = ev->geometry.y; + + /* At this point the destroyed output is not in the list anymore. +* If the view is still visible somewhere, we leave where it is, +* otherwise, move it to the first output. */ + visible = 0; + wl_list_for_each(output, &ec->output_list, link) { + if (pixman_region32_contains_point(&output->region, + x, y, NULL)) { + visible = 1; + break; + } + } + + if (!visible) { + first_output = container_of(ec->output_list.next, + struct weston_output, link); + + x = first_output->x + first_output->width / 4; + y = first_output->y + first_output->height / 4; + } + + weston_view_set_position(ev, x, y); +} + WL_EXPORT struct weston_view * weston_view_create(struct weston_surface *surface) { @@ -401,6 +447,8 @@ weston_view_create(struct weston_surface *surface) view->output = NULL; view->output_move_listener.notify = weston_view_output_move_handler; + view->output_destroy_listener.notify = + weston_view_output_destroy_handler; return view; } @@ -816,12 +864,17 @@ weston_view_assign_output(struct weston_view *ev) } pixman_region32_fini(®ion); - if (ev->output_mask != 0) + if (ev->output_mask != 0) { wl_list_remove(&ev->output_move_listener.link); + wl_list_remove(&ev->output_destroy_listener.link); + } - if (mask != 0) + if (mask != 0) { wl_signal_add(&new_output->move_signal, &ev->output_move_listener); + wl_signal_add(&new_output->destroy_signal, + &ev->output_destroy_listener); + } ev->output = new_output; ev->output_mask = mask; @@ -1265,6 +1318,8 @@ weston_view_unmap(struct weston_view *view) wl_list_init(&view->link); wl_list_remove(&view->output_move_listener.link); wl_list_init(&view->output_move_listener.link); + wl_list_remove(&view->output_destroy_listener.link); + wl_list_init(&view->output_destroy_listener.link); view->output_mask = 0; weston_surface_assign_output(view->surface); diff --git a/src/compositor.h b/src/compositor.h index 530de71..84b0f79 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -807,6 +807,7 @@ struct weston_view { uint32_t output_mask; struct wl_listener output_move_listener; + struct wl_listener output_destroy_listener; }; struct weston_surface { -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 10/10] shell: Reset fullscreen and maximized state on output unplug
From: Ander Conselvan de Oliveira When a view is moved to another output because its current output was unplugged, remove the fullscreen and maximized state. --- desktop-shell/shell.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index f70b310..c962d26 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -4975,6 +4975,9 @@ shell_surface_output_destroyed(struct weston_surface *es) struct shell_surface *shsurf = get_shell_surface(es); shsurf->saved_position_valid = false; + shsurf->next_state.maximized = false; + shsurf->next_state.fullscreen = false; + shsurf->state_changed = true; } static void launch_desktop_shell_process(void *data); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 03/10] compositor: Move the logic of moving outputs into the core
From: "Zhang, Xiong Y" Instead of having the backends move the remaining outputs when one is destroyed, let the core compositor deal with that. Signed-off-by: Zhang, Xiong Y Signed-off-by: Ander Conselvan de Oliveira --- src/compositor-drm.c |8 src/compositor-x11.c | 20 +++- src/compositor.c | 23 +++ 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 44deaab..f85298a 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -,7 +,6 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device) drmModeRes *resources; struct drm_output *output, *next; int x = 0, y = 0; - int x_offset = 0, y_offset = 0; uint32_t connected = 0, disconnects = 0; int i; @@ -2272,17 +2271,10 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device) if (disconnects) { wl_list_for_each_safe(output, next, &ec->base.output_list, base.link) { - if (x_offset != 0 || y_offset != 0) { - weston_output_move(&output->base, -output->base.x - x_offset, -output->base.y - y_offset); - } - if (disconnects & (1 << output->connector_id)) { disconnects &= ~(1 << output->connector_id); weston_log("connector %d disconnected\n", output->connector_id); - x_offset += output->base.width; drm_output_destroy(&output->base); } } diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 9a36b59..2ef1b5d 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -918,24 +918,10 @@ x11_compositor_find_output(struct x11_compositor *c, xcb_window_t window) static void x11_compositor_delete_window(struct x11_compositor *c, xcb_window_t window) { - struct x11_output *deleted_output, *output, *next; - int x_offset = 0; - - deleted_output = x11_compositor_find_output(c, window); - - wl_list_for_each_safe(output, next, &c->base.output_list, base.link) { - if (x_offset != 0) { - weston_output_move(&output->base, - output->base.x - x_offset, - output->base.y); - weston_output_damage(&output->base); - } + struct x11_output *output; - if (output == deleted_output) { - x_offset += output->base.width; - x11_output_destroy(&output->base); - } - } + output = x11_compositor_find_output(c, window); + x11_output_destroy(&output->base); xcb_flush(c->conn); diff --git a/src/compositor.c b/src/compositor.c index 0e739e3..36985d7 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2993,9 +2993,32 @@ bind_output(struct wl_client *client, wl_output_send_done(resource); } +/* Move other outputs when one is removed so the space remains contiguos. */ +static void +weston_compositor_remove_output(struct weston_compositor *compositor, + struct weston_output *remove_output) +{ + struct weston_output *output; + int offset = 0; + + wl_list_for_each(output, &compositor->output_list, link) { + if (output == remove_output) { + offset = output->width; + continue; + } + + if (offset > 0) { + weston_output_move(output, + output->x - offset, output->y); + output->dirty = 1; + } + } +} + WL_EXPORT void weston_output_destroy(struct weston_output *output) { + weston_compositor_remove_output(output->compositor, output); wl_list_remove(&output->link); wl_signal_emit(&output->destroy_signal, output); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 08/10] compositor: Make pointers visible when an output is unplugged
From: Ander Conselvan de Oliveira Previously, if a pointer was inside an output that was unplugged, it could potentialy end up outside any valid output forever. With this patch, the pointer is moved to the "closest" output to the pointer. --- src/compositor.c | 15 +++ src/compositor.h |2 ++ src/input.c | 76 +- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index ed6548c..af33fda 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3105,6 +3105,19 @@ weston_compositor_remove_output(struct weston_compositor *compositor, } } +static void +weston_compositor_verify_pointers(struct weston_compositor *ec) +{ + struct weston_seat *seat; + + wl_list_for_each(seat, &ec->seat_list, link) { + if (!seat->pointer) + continue; + + weston_pointer_verify(seat->pointer); + } +} + WL_EXPORT void weston_output_destroy(struct weston_output *output) { @@ -3113,6 +3126,8 @@ weston_output_destroy(struct weston_output *output) weston_compositor_remove_output(output->compositor, output); wl_list_remove(&output->link); + weston_compositor_verify_pointers(output->compositor); + wl_signal_emit(&output->destroy_signal, output); free(output->name); diff --git a/src/compositor.h b/src/compositor.h index 901366f..d344e37 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -375,6 +375,8 @@ weston_pointer_move(struct weston_pointer *pointer, void weston_pointer_set_default_grab(struct weston_pointer *pointer, const struct weston_pointer_grab_interface *interface); +void +weston_pointer_verify(struct weston_pointer *pointer); struct weston_keyboard * weston_keyboard_create(void); diff --git a/src/input.c b/src/input.c index f4944b6..07e9d6c 100644 --- a/src/input.c +++ b/src/input.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "../shared/os-compatibility.h" #include "compositor.h" @@ -791,6 +792,28 @@ weston_touch_cancel_grab(struct weston_touch *touch) touch->grab->interface->cancel(touch->grab); } +static void +weston_pointer_clamp_for_output(struct weston_pointer *pointer, + struct weston_output *output, + wl_fixed_t *fx, wl_fixed_t *fy) +{ + int x, y; + + x = wl_fixed_to_int(*fx); + y = wl_fixed_to_int(*fy); + + if (x < output->x) + *fx = wl_fixed_from_int(output->x); + else if (x >= output->x + output->width) + *fx = wl_fixed_from_int(output->x + + output->width - 1); + if (y < output->y) + *fy = wl_fixed_from_int(output->y); + else if (y >= output->y + output->height) + *fy = wl_fixed_from_int(output->y + + output->height - 1); +} + WL_EXPORT void weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy) { @@ -817,18 +840,8 @@ weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t if (!prev) prev = pointer->seat->output; - if (prev && !valid) { - if (x < prev->x) - *fx = wl_fixed_from_int(prev->x); - else if (x >= prev->x + prev->width) - *fx = wl_fixed_from_int(prev->x + - prev->width - 1); - if (y < prev->y) - *fy = wl_fixed_from_int(prev->y); - else if (y >= prev->y + prev->height) - *fy = wl_fixed_from_int(prev->y + - prev->height - 1); - } + if (prev && !valid) + weston_pointer_clamp_for_output(pointer, prev, fx, fy); } /* Takes absolute values */ @@ -856,6 +869,45 @@ weston_pointer_move(struct weston_pointer *pointer, wl_fixed_t x, wl_fixed_t y) wl_signal_emit(&pointer->motion_signal, pointer); } +/** Verify if the pointer is in a valid position and move it if it isn't. + */ +WL_EXPORT void +weston_pointer_verify(struct weston_pointer *pointer) +{ + struct weston_compositor *ec = pointer->seat->compositor; + struct weston_output *output, *closest = NULL; + int x, y, distance, min = INT_MAX; + wl_fixed_t fx, fy; + + x = wl_fixed_to_int(pointer->x); + y = wl_fixed_to_int(pointer->y); + + wl_list_for_each(output, &ec->output_list, link) { + if (pixman_region32_contains_point(&output->region, +
[PATCH 01/10] compositor-x11: Only destroy one output when the close button is pressed
From: Ander Conselvan de Oliveira Instead of terminating the compositor, destroy the output whose close button was clicked and move the other outputs, as is done in the drm backend. --- src/compositor-x11.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/compositor-x11.c b/src/compositor-x11.c index b81dac0..6e507f9 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -916,6 +916,34 @@ x11_compositor_find_output(struct x11_compositor *c, xcb_window_t window) assert(0); } +static void +x11_compositor_delete_window(struct x11_compositor *c, xcb_window_t window) +{ + struct x11_output *deleted_output, *output, *next; + int x_offset = 0; + + deleted_output = x11_compositor_find_output(c, window); + + wl_list_for_each_safe(output, next, &c->base.output_list, base.link) { + if (x_offset != 0) { + weston_output_move(&output->base, + output->base.x - x_offset, + output->base.y); + weston_output_damage(&output->base); + } + + if (output == deleted_output) { + x_offset += output->base.width; + x11_output_destroy(&output->base); + } + } + + xcb_flush(c->conn); + + if (wl_list_empty(&c->base.output_list)) + wl_display_terminate(c->base.wl_display); +} + #ifdef HAVE_XCB_XKB static void update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state) @@ -1115,6 +1143,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data) xcb_focus_in_event_t *focus_in; xcb_expose_event_t *expose; xcb_atom_t atom; + xcb_window_t window; uint32_t *k; uint32_t i, set; uint8_t response_type; @@ -1243,8 +1272,9 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data) case XCB_CLIENT_MESSAGE: client_message = (xcb_client_message_event_t *) event; atom = client_message->data.data32[0]; + window = client_message->window; if (atom == c->atom.wm_delete_window) - wl_display_terminate(c->base.wl_display); + x11_compositor_delete_window(c, window); break; case XCB_FOCUS_IN: -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 02/10] compositor: Remove output from list in weston_output_destroy()
From: Ander Conselvan de Oliveira When destroying ouputs, they would sometimes be removed before the call to weston_output_destory() and sometimes after, depending on the backend. Now the output is remove withing that function so the behavior is standard across all backends. --- src/compositor-drm.c |1 - src/compositor-fbdev.c |1 - src/compositor-rpi.c |1 - src/compositor-x11.c |1 - src/compositor.c |2 ++ 5 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index fbf6e49..44deaab 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1146,7 +1146,6 @@ drm_output_destroy(struct weston_output *output_base) weston_plane_release(&output->cursor_plane); weston_output_destroy(&output->base); - wl_list_remove(&output->base.link); free(output); } diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c index 09f165b..e649d43 100644 --- a/src/compositor-fbdev.c +++ b/src/compositor-fbdev.c @@ -692,7 +692,6 @@ fbdev_output_destroy(struct weston_output *base) } /* Remove the output. */ - wl_list_remove(&output->base.link); weston_output_destroy(&output->base); free(output); diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c index 88ea8e0..1d52a94 100644 --- a/src/compositor-rpi.c +++ b/src/compositor-rpi.c @@ -278,7 +278,6 @@ rpi_output_destroy(struct weston_output *base) */ rpi_flippipe_release(&output->flippipe); - wl_list_remove(&output->base.link); weston_output_destroy(&output->base); vc_dispmanx_display_close(output->display); diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 6e507f9..9a36b59 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -483,7 +483,6 @@ x11_output_destroy(struct weston_output *output_base) struct x11_compositor *compositor = (struct x11_compositor *)output->base.compositor; - wl_list_remove(&output->base.link); wl_event_source_remove(output->finish_frame_timer); if (compositor->use_pixman) { diff --git a/src/compositor.c b/src/compositor.c index 8f4bdef..0e739e3 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2996,6 +2996,8 @@ bind_output(struct wl_client *client, WL_EXPORT void weston_output_destroy(struct weston_output *output) { + wl_list_remove(&output->link); + wl_signal_emit(&output->destroy_signal, output); free(output->name); -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston 03/11] configure.ac: Correctly check for functions and libraries
On 12/09/2013 12:44 PM, Quentin Glidic wrote: On 09/12/2013 11:28, Ander Conselvan de Oliveira wrote: On 12/08/2013 08:45 PM, Quentin Glidic wrote: From: Quentin Glidic AC_SEARCH_LIBS is preferred over AC_CHECK_FUNC and AC_CHECK_LIB Why is it preferred? I am trusting the Autoconf manual[1] on this one. Basically, the double-check we are doing for dlopen is exactly what AC_SEARCH_LIBS is done for: checking in both a library and in libC. That is the kind of information I would like to see in the commit message if I stumble upon this 6 months from now. No need to dig through the Autoconf manual. :) Signed-off-by: Quentin Glidic --- configure.ac | 37 + 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index 40ae145..c169311 100644 --- a/configure.ac +++ b/configure.ac @@ -41,9 +41,13 @@ AC_ARG_VAR([WESTON_SHELL_CLIENT], PKG_PROG_PKG_CONFIG() -AC_CHECK_FUNC([dlopen], [], - AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) -AC_SUBST(DLOPEN_LIBS) +AC_SEARCH_LIBS([dlopen], [dl]) +case "$ac_cv_search_dlopen" in +no) AC_MSG_ERROR([dlopen support required for Weston]) ;; +"none required") ;; +*) DLOPEN_LIBS="$ac_cv_search_dlopen" ;; +esac +AC_SUBST([DLOPEN_LIBS]) AC_CHECK_DECL(SFD_CLOEXEC,[], [AC_MSG_ERROR("SFD_CLOEXEC is needed to compile weston")], @@ -258,13 +262,13 @@ fi AM_CONDITIONAL(ENABLE_VAAPI_RECORDER, test "x$have_libva" = xyes) -AC_CHECK_LIB([jpeg], [jpeg_CreateDecompress], have_jpeglib=yes) -if test x$have_jpeglib = xyes; then - JPEG_LIBS="-ljpeg" -else - AC_ERROR([libjpeg not found]) -fi -AC_SUBST(JPEG_LIBS) +AC_SEARCH_LIBS([jpeg_CreateDecompress], [jpeg]) +case "$ac_cv_search_pam_open_session" in Copy & paste error, you got pam_open_session instead of jpeg_CreateDecompress. Oops, fixed locally. +no) AC_MSG_ERROR([libjpeg required but not found]) ;; +"none required") ;; +*) JPEG_LIBS="$ac_cv_search_jpeg_CreateDecompress" ;; +esac +AC_SUBST([JPEG_LIBS]) Anyway, this seems like a change for the worse IMO. Following Autotools best practices/manual is *never* worse. > Now you're typing jpeg_CreateDecompress three times instead of just one. 8 lines for the new version vs 7 lines for the old one… My point was that having to type the same thing three times is error prone, and the copy & paste error above kind of proves my point. Anyway, if we can turn this into a one line macro that would be much better. > Ideally this could be just a one-liner, since this construct has to be repeated a few times. It is easy enough to create a macro to do the check. If so, do we want the error message to be accurate (e.g. Weston vs clients vs weston-launch)? I think it would be good, if it's just a matter of adding one more parameter. Cheers, Ander Cheers, Ander PKG_CHECK_MODULES(CAIRO, [cairo]) @@ -334,12 +338,13 @@ AS_IF([test "x$have_systemd_login_209" = "xyes"], AC_ARG_ENABLE(weston-launch, [ --enable-weston-launch],, enable_weston_launch=yes) AM_CONDITIONAL(BUILD_WESTON_LAUNCH, test x$enable_weston_launch == xyes) if test x$enable_weston_launch == xyes; then - AC_CHECK_LIB([pam], [pam_open_session], [have_pam=yes], [have_pam=no]) - if test x$have_pam == xno; then -AC_ERROR([weston-launch requires pam]) - fi - PAM_LIBS=-lpam - AC_SUBST(PAM_LIBS) +AC_SEARCH_LIBS([pam_open_session], [pam]) +case "$ac_cv_search_pam_open_session" in +no) AC_MSG_ERROR([pam support required for weston-launch]) ;; +"none required") ;; +*) PAM_LIBS="$ac_cv_search_pam_open_session" ;; +esac +AC_SUBST([PAM_LIBS]) fi if test x$enable_egl = xyes; then [1] http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf.html#Libraries ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston 03/11] configure.ac: Correctly check for functions and libraries
On 12/08/2013 08:45 PM, Quentin Glidic wrote: From: Quentin Glidic AC_SEARCH_LIBS is preferred over AC_CHECK_FUNC and AC_CHECK_LIB Why is it preferred? Signed-off-by: Quentin Glidic --- configure.ac | 37 + 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index 40ae145..c169311 100644 --- a/configure.ac +++ b/configure.ac @@ -41,9 +41,13 @@ AC_ARG_VAR([WESTON_SHELL_CLIENT], PKG_PROG_PKG_CONFIG() -AC_CHECK_FUNC([dlopen], [], - AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) -AC_SUBST(DLOPEN_LIBS) +AC_SEARCH_LIBS([dlopen], [dl]) +case "$ac_cv_search_dlopen" in + no) AC_MSG_ERROR([dlopen support required for Weston]) ;; + "none required") ;; + *) DLOPEN_LIBS="$ac_cv_search_dlopen" ;; +esac +AC_SUBST([DLOPEN_LIBS]) AC_CHECK_DECL(SFD_CLOEXEC,[], [AC_MSG_ERROR("SFD_CLOEXEC is needed to compile weston")], @@ -258,13 +262,13 @@ fi AM_CONDITIONAL(ENABLE_VAAPI_RECORDER, test "x$have_libva" = xyes) -AC_CHECK_LIB([jpeg], [jpeg_CreateDecompress], have_jpeglib=yes) -if test x$have_jpeglib = xyes; then - JPEG_LIBS="-ljpeg" -else - AC_ERROR([libjpeg not found]) -fi -AC_SUBST(JPEG_LIBS) +AC_SEARCH_LIBS([jpeg_CreateDecompress], [jpeg]) +case "$ac_cv_search_pam_open_session" in Copy & paste error, you got pam_open_session instead of jpeg_CreateDecompress. + no) AC_MSG_ERROR([libjpeg required but not found]) ;; + "none required") ;; + *) JPEG_LIBS="$ac_cv_search_jpeg_CreateDecompress" ;; +esac +AC_SUBST([JPEG_LIBS]) Anyway, this seems like a change for the worse IMO. Now you're typing jpeg_CreateDecompress three times instead of just one. Ideally this could be just a one-liner, since this construct has to be repeated a few times. Cheers, Ander PKG_CHECK_MODULES(CAIRO, [cairo]) @@ -334,12 +338,13 @@ AS_IF([test "x$have_systemd_login_209" = "xyes"], AC_ARG_ENABLE(weston-launch, [ --enable-weston-launch],, enable_weston_launch=yes) AM_CONDITIONAL(BUILD_WESTON_LAUNCH, test x$enable_weston_launch == xyes) if test x$enable_weston_launch == xyes; then - AC_CHECK_LIB([pam], [pam_open_session], [have_pam=yes], [have_pam=no]) - if test x$have_pam == xno; then -AC_ERROR([weston-launch requires pam]) - fi - PAM_LIBS=-lpam - AC_SUBST(PAM_LIBS) + AC_SEARCH_LIBS([pam_open_session], [pam]) + case "$ac_cv_search_pam_open_session" in + no) AC_MSG_ERROR([pam support required for weston-launch]) ;; + "none required") ;; + *) PAM_LIBS="$ac_cv_search_pam_open_session" ;; + esac + AC_SUBST([PAM_LIBS]) fi if test x$enable_egl = xyes; then ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: RFC: surface crop and scale protocol extension
On 12/04/2013 09:20 AM, Pekka Paalanen wrote: On Thu, 28 Nov 2013 12:52:15 +0100 Jonny Lamb wrote: Il giorno mar, 26/11/2013 alle 18.19 +0100, Jonny Lamb ha scritto: This is the initial version of the weston implementation of the wl_scaler protocol extension for surface cropping and scaling. It is based on the extension RFC version 3, written by Pekka Paalanen. Some slightly different protocol designs have been proposed for surface cropping and scaling, so with the idea of making the choice as easy as possible I have prepared branches with the different ideas: 1. wl_scaler and wl_surface_scaler interfaces: This is the patchset I already posted to the list which adds the wl_scaler global object and wl_surface_scaler objects are created per surface: http://cgit.freedesktop.org/~jonny/weston/log/?h=scaler (The only difference between this branch and the patches sent to the list is the removal of the "open issues" section in the commit message of the commit that adds the protocol XML.) 2. set_buffer_viewport request on wl_surface: No more extra interfaces but a new request on wl_surface: http://cgit.freedesktop.org/~jonny/wayland/log/?h=scaler-alt http://cgit.freedesktop.org/~jonny/weston/log/?h=scaler-alt 3. wl_scaler and wl_viewport interfaces: Exactly the same as the first proposal here but wl_surface_scaler renamed to wl_viewport: http://cgit.freedesktop.org/~jonny/weston/log/?h=scaler-viewport Choices choices choices! I'm a bit surprised no-one has yet given their opinion as a reply to this. :-o For this one I have even less personal preference than for the wl_fixed_t issue, as long as wl_subsurface is not an option. If everyone is really indifferent here, then let's go with option 3, wl_scaler and wl_viewport, which gives compositor implementations the choice to not implement it. Ok? I'd prefer 2. Is there any good reason a compositor wouldn't implement this? Cheers, Ander ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 1/3] shell: restore app on non default and unplugged output
On 12/04/2013 07:17 AM, Zhang, Xiong Y wrote: Hi, Ander: Thanks for your review. Your idea is feasible. To achieve that, we could add an output_destroyed() function pointer in weston_surface But I think we could add an output_destroyed() function pointer in weston_view not in Weston_surface, because as Jason's idea one surface may have several views, what we moved is view not surface. Because each output has a destroy_signal, we should register view's output_destroy_handler in Weston_view_assign_output(). So when one view is moved from one output to another output, the output_destroyed_handler should register again. Right, it would be more natural to have the function pointer in the view. However, then we need to make sure that whenever a view for that surface is created, it has the proper output_destroyed() pointer set. Since this is related to the surface role, I think it would be good if it was implemented in surface next to the configure function pointer, but I think either way is fine. clamp_coordinate() is a common function and will be used in src/input.c and src/shell.c, I can implement a function weston_coordinate_clamp() in compositor.c and export it, is this OK ? Yep sure. We actually have a similar function that is exported, weston_pointer_clamp(). It doesn't do what you need, since it takes a weston_pointer as argument, but you could split the actual clamping into the function you need and export it. Cheers, Ander Thanks. -Original Message----- From: Ander Conselvan de Oliveira [mailto:conselv...@gmail.com] Sent: Tuesday, December 03, 2013 11:06 PM To: Zhang, Xiong Y Cc: wayland-devel@lists.freedesktop.org Subject: Re: [PATCH 1/3] shell: restore app on non default and unplugged output Hi Xiong, It seems that we need different logic for moving the views depending on the surface role, so I'm thinking this code should actually be part of a surface role implementation. For instance, instead of implementing the logic of moving the pointer surface in the shell, that would go in src/input.c together with the implementation of pointer_cursor_surface_configure(). To achieve that, we could add an output_destroyed() function pointer in weston_surface, that would be called from an output_destroy_listener in weston_view. That should simplify the code below quite a bit since traversing the list of views would be done by the wl_signal_emit() code. The output_destroyed() entry point could receive the new output as a parameter, so the role-specific logic would only have to determine where in that output the new surface should be and move it. And of course handle any role-specific needs, such as warping the pointer. I have some comments about the coding style below. On 12/03/2013 05:25 AM, Xiong Zhang wrote: if the unplugged output isn't the default output, move cursor and APP widow to default output The commit message should be properly capitalized and punctuated. Signed-off-by: Xiong Zhang --- src/shell.c | 190 ++-- 1 file changed, 186 insertions(+), 4 deletions(-) diff --git a/src/shell.c b/src/shell.c index dfcb525..16d22f1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -6061,15 +6061,197 @@ workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time, take_surface_to_workspace_by_seat(shell, seat, new_index); } +/* if (*x, *y) will be moved beyong target_output, clamp it*/ Beyond is misspelled and there's a space missing in the end. I'd also recommend properly capitalizing and punctuating the sentences. /* If (*x, *y) will be removed beyond target_output, clamp it. */ +static int +clamp_coordinate(struct weston_output *target_output, + struct weston_output *original_output, + float *x, float *y) The parameters should be aligned with the parenthesis, i.e., clamp_coordinate(struct weston_output *target_output, struct weston_output *original_output, +{ + int32_t rel_x, rel_y; + int result = 0; + + rel_x = *x - original_output->x; + rel_y = *y - original_output->y; + + if (rel_x > target_output->width) { + *x = original_output->x + target_output->width / 4; + result = 1; + } + if (rel_y > target_output->height) { + *y = original_output->y + target_output->height / 4; + result = 1; + } + return result; +} + +static void +handle_view_on_destroyed_output(struct weston_view *view, + struct weston_output *target_output) { + float new_x, new_y, original_x, original_y; + + /* the child window's view->geometry is a relative coordinate to */ + /* parent view, no need to move child_view */ We format multi-line comments like this: /* First line. * Se
Re: [PATCH 2/3] shell: restore app on default and unplugged output
On 12/03/2013 05:25 AM, Xiong Zhang wrote: if the unplugged output is the first default output, the second output will move to the first working as default output. Mark the surface on unplaugged output as dirty, so on the next output repaint, these views will reassign output and get the right output. when we move output, the views on moved output should be moved also. Because of the page flip intervention, the weston_output_destroy() maybe asynchronous with update_outputs(). So we should change moving following outputs to output_destroy handler. Building up on the idea on my previous email - were we would have an output_destroyed() callback for the view which receives the new output the view should be in - I think we could avoid having different logic for the case where the first output is removed. Instead, we could move the outputs position before calling the callback, so when it calculates the new position for the view that would be final. It sounds like we still need to delay weston_output_move() in the drm backend, so that would be split into a separate patch. Ander Signed-off-by: Xiong Zhang --- src/compositor-drm.c | 8 - src/compositor.c | 18 +++ src/shell.c | 88 3 files changed, 80 insertions(+), 34 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index c34fc1c..158a05f 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2223,7 +2223,6 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device) drmModeRes *resources; struct drm_output *output, *next; int x = 0, y = 0; - int x_offset = 0, y_offset = 0; uint32_t connected = 0, disconnects = 0; int i; @@ -2273,17 +2272,10 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device) if (disconnects) { wl_list_for_each_safe(output, next, &ec->base.output_list, base.link) { - if (x_offset != 0 || y_offset != 0) { - weston_output_move(&output->base, -output->base.x - x_offset, -output->base.y - y_offset); - } - if (disconnects & (1 << output->connector_id)) { disconnects &= ~(1 << output->connector_id); weston_log("connector %d disconnected\n", output->connector_id); - x_offset += output->base.width; drm_output_destroy(&output->base); } } diff --git a/src/compositor.c b/src/compositor.c index 32e72b1..246b02b 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3128,6 +3128,13 @@ weston_output_transform_scale_init(struct weston_output *output, uint32_t transf WL_EXPORT void weston_output_move(struct weston_output *output, int x, int y) { + struct weston_view *view; + struct weston_layer *layer; + int offset_x, offset_y; + + offset_x = x - output->x; + offset_y = y - output->y; + output->x = x; output->y = y; @@ -3135,6 +3142,17 @@ weston_output_move(struct weston_output *output, int x, int y) pixman_region32_init_rect(&output->region, x, y, output->width, output->height); + output->dirty = 1; + + wl_list_for_each(layer, &output->compositor->layer_list, link) { + wl_list_for_each(view, &layer->view_list, layer_link) { + if (view->output == output && + view->geometry.parent == NULL) + weston_view_set_position(view, + view->geometry.x + offset_x, + view->geometry.y + offset_y); + } + } } WL_EXPORT void diff --git a/src/shell.c b/src/shell.c index 16d22f1..3cf87fd 100644 --- a/src/shell.c +++ b/src/shell.c @@ -6084,11 +6084,17 @@ clamp_coordinate(struct weston_output *target_output, return result; } +/* if destroyed output is default output, marking views on this output */ +/* are dirty, so the next repaint will assign a new output to these views */ +/* if destroyed output isn't default output, move views on this output */ +/* to default output */ static void handle_view_on_destroyed_output(struct weston_view *view, - struct weston_output *target_output) + struct weston_output *target_output, + unsigned int move) { float new_x, new_y, original_x, original_y; + int result; /* the child
Re: [PATCH 1/3] shell: restore app on non default and unplugged output
Hi Xiong, It seems that we need different logic for moving the views depending on the surface role, so I'm thinking this code should actually be part of a surface role implementation. For instance, instead of implementing the logic of moving the pointer surface in the shell, that would go in src/input.c together with the implementation of pointer_cursor_surface_configure(). To achieve that, we could add an output_destroyed() function pointer in weston_surface, that would be called from an output_destroy_listener in weston_view. That should simplify the code below quite a bit since traversing the list of views would be done by the wl_signal_emit() code. The output_destroyed() entry point could receive the new output as a parameter, so the role-specific logic would only have to determine where in that output the new surface should be and move it. And of course handle any role-specific needs, such as warping the pointer. I have some comments about the coding style below. On 12/03/2013 05:25 AM, Xiong Zhang wrote: if the unplugged output isn't the default output, move cursor and APP widow to default output The commit message should be properly capitalized and punctuated. Signed-off-by: Xiong Zhang --- src/shell.c | 190 ++-- 1 file changed, 186 insertions(+), 4 deletions(-) diff --git a/src/shell.c b/src/shell.c index dfcb525..16d22f1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -6061,15 +6061,197 @@ workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time, take_surface_to_workspace_by_seat(shell, seat, new_index); } +/* if (*x, *y) will be moved beyong target_output, clamp it*/ Beyond is misspelled and there's a space missing in the end. I'd also recommend properly capitalizing and punctuating the sentences. /* If (*x, *y) will be removed beyond target_output, clamp it. */ +static int +clamp_coordinate(struct weston_output *target_output, + struct weston_output *original_output, + float *x, float *y) The parameters should be aligned with the parenthesis, i.e., clamp_coordinate(struct weston_output *target_output, struct weston_output *original_output, +{ + int32_t rel_x, rel_y; + int result = 0; + + rel_x = *x - original_output->x; + rel_y = *y - original_output->y; + + if (rel_x > target_output->width) { + *x = original_output->x + target_output->width / 4; + result = 1; + } + if (rel_y > target_output->height) { + *y = original_output->y + target_output->height / 4; + result = 1; + } + return result; +} + +static void +handle_view_on_destroyed_output(struct weston_view *view, + struct weston_output *target_output) +{ + float new_x, new_y, original_x, original_y; + + /* the child window's view->geometry is a relative coordinate to */ + /* parent view, no need to move child_view */ We format multi-line comments like this: /* First line. * Second line. */ + if (view->geometry.parent) + return; + + original_x = view->geometry.x; + original_y = view->geometry.y; + + clamp_coordinate(target_output, view->output, + &original_x, &original_y); + + new_x = target_output->x + original_x - view->output->x; + new_y = target_output->y + original_y - view->output->y; + weston_view_set_position(view, new_x, new_y); +} + +static void +normal_view_on_destroyed_output(struct shell_output *shell_output, + struct weston_output *target_output) Parameter alignment. +{ + struct weston_output *del_output = shell_output->output; + struct desktop_shell *shell = shell_output->shell; + struct weston_view *view; + unsigned int i; + struct workspace *ws; + struct shell_surface *shsurf; + enum shell_surface_type surface_type = SHELL_SURFACE_NONE; + struct wl_client *client; + + /*if view on destroyed output, move it to target output*/ Spaces around the comment. + for (i = 0; i < shell->workspaces.num; i++) { + ws = get_workspace(shell, i); + wl_list_for_each(view, &ws->layer.view_list, layer_link) { + if (view->output == del_output) { + handle_view_on_destroyed_output(view, target_output); + surface_type = get_shell_surface_type(view->surface); A blank line here would make the whole block easier to read. + /*if surface is maximized, resize it to target output*/ + if (surface_type == SHELL_SURFACE_MAXIMIZED) { + shsurf = get_shell_surface(view->surface); +
[PATCH] gl-renderer: Fix support for Y_XUXV buffers
From: Ander Conselvan de Oliveira Due to a copy and paste error, the pointer to the vertex shader source was NULL and the program failed to link. --- src/gl-renderer.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 7a535c7..4942ccd 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -1753,7 +1753,7 @@ compile_shaders(struct weston_compositor *ec) gr->texture_shader_y_u_v.fragment_source = texture_fragment_shader_y_u_v; - gr->texture_shader_y_u_v.vertex_source = vertex_shader; + gr->texture_shader_y_xuxv.vertex_source = vertex_shader; gr->texture_shader_y_xuxv.fragment_source = texture_fragment_shader_y_xuxv; -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 1/2] compositor-drm: Add key binding to switch from pixman to GL renderer
From: Ander Conselvan de Oliveira When running with the pixman renderer, the debug binding 'W' (mod-shift-space W) will cause the compositor to load gl-renderer.so and start using it instead of the pixman renderer. --- src/compositor-drm.c | 83 +- src/gl-renderer.c|6 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index d4fc871..5cb0fab 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -596,7 +596,8 @@ drm_output_repaint(struct weston_output *output_base, return -1; mode = container_of(output->base.current_mode, struct drm_mode, base); - if (!output->current) { + if (!output->current || + output->current->stride != output->next->stride) { ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id, output->next->fb_id, 0, 0, &output->connector_id, 1, @@ -1286,15 +1287,15 @@ init_drm(struct drm_compositor *ec, struct udev_device *device) return 0; } -static int -init_egl(struct drm_compositor *ec) +static struct gbm_device * +create_gbm_device(int fd) { - EGLint format; + struct gbm_device *gbm; gl_renderer = weston_load_module("gl-renderer.so", "gl_renderer_interface"); if (!gl_renderer) - return -1; + return NULL; /* GBM will load a dri driver, but even though they need symbols from * libglapi, in some version of Mesa they are not linked to it. Since @@ -1303,14 +1304,34 @@ init_egl(struct drm_compositor *ec) * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */ dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL); - ec->gbm = gbm_create_device(ec->drm.fd); + gbm = gbm_create_device(fd); - if (!ec->gbm) - return -1; + return gbm; +} + +static int +drm_compositor_create_gl_renderer(struct drm_compositor *ec) +{ + EGLint format; format = ec->format; if (gl_renderer->create(&ec->base, ec->gbm, gl_renderer->opaque_attribs, &format) < 0) { + return -1; + } + + return 0; +} + +static int +init_egl(struct drm_compositor *ec) +{ + ec->gbm = create_gbm_device(ec->drm.fd); + + if (!ec->gbm) + return -1; + + if (drm_compositor_create_gl_renderer(ec) < 0) { gbm_device_destroy(ec->gbm); return -1; } @@ -2585,6 +2606,50 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, } #endif +static void +switch_to_gl_renderer(struct drm_compositor *c) +{ + struct drm_output *output; + + if (!c->use_pixman) + return; + + weston_log("Switching to GL renderer\n"); + + c->gbm = create_gbm_device(c->drm.fd); + if (!c->gbm) { + weston_log("Failed to create gbm device. " + "Aborting renderer switch\n"); + return; + } + + wl_list_for_each(output, &c->base.output_list, base.link) + pixman_renderer_output_destroy(&output->base); + + c->base.renderer->destroy(&c->base); + + if (drm_compositor_create_gl_renderer(c) < 0) { + gbm_device_destroy(c->gbm); + weston_log("Failed to create GL renderer. Quitting.\n"); + /* FIXME: we need a function to shutdown cleanly */ + assert(0); + } + + wl_list_for_each(output, &c->base.output_list, base.link) + drm_output_init_egl(output, c); + + c->use_pixman = 0; +} + +static void +renderer_switch_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct drm_compositor *c = (struct drm_compositor *) seat->compositor; + + switch_to_gl_renderer(c); +} + static struct weston_compositor * drm_compositor_create(struct wl_display *display, struct drm_parameters *param, @@ -2734,6 +2799,8 @@ drm_compositor_create(struct wl_display *display, planes_binding, ec); weston_compositor_add_debug_binding(&ec->base, KEY_Q, recorder_binding, ec); + weston_compositor_add_debug_binding(&ec->base, KEY_W, + renderer_switch_binding, ec); return &ec->base; diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 7a535c7..5e1b396 100644 --- a/src/gl-renderer.c +++ b/src/gl-rendere
[PATCH 2/2] gl-renderer: Attach buffer during surface state creation if possible
From: Ander Conselvan de Oliveira When a renderer switch happens, it is possible that when the surface state is created, a buffer for the given surface is already available. In that case, run the attach routine so that the pixel contents are properly set. Otherwise, it would only be set when a new attach request is made for that surface. Also, change the drm backend so that it keeps the buffer reference in the weston_surface when running with the pixman renderer. The pixman renderer keeps a reference to it anyway, so it is never released early. This makes the renderer transition seamless, without leaving a black screen as before. --- src/compositor-drm.c | 26 -- src/gl-renderer.c|8 +++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 5cb0fab..e89c768 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1056,18 +1056,24 @@ drm_assign_planes(struct weston_output *output) pixman_region32_init(&overlap); primary = &c->base.primary_plane; - /* Flag all visible surfaces as keep_buffer = 1 */ - wl_list_for_each(ev, &c->base.view_list, link) - ev->surface->keep_buffer = 1; - wl_list_for_each_safe(ev, next, &c->base.view_list, link) { - /* test whether this buffer can ever go into a plane: -* non-shm, or small enough to be a cursor + struct weston_surface *es = ev->surface; + + /* Test whether this buffer can ever go into a plane: +* non-shm, or small enough to be a cursor. +* +* Also, keep a reference when using the pixman renderer. +* That makes it possible to do a seamless switch to the GL +* renderer and since the pixman renderer keeps a reference +* to the buffer anyway, there is no side effects. */ - if (!ev->surface->buffer_ref.buffer || - (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) && - (ev->geometry.width > 64 || ev->geometry.height > 64))) - ev->surface->keep_buffer = 0; + if (c->use_pixman || + (es->buffer_ref.buffer && + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) || +(ev->geometry.width <= 64 && ev->geometry.height <= 64 + es->keep_buffer = 1; + else + es->keep_buffer = 0; pixman_region32_init(&surface_overlap); pixman_region32_intersect(&surface_overlap, &overlap, diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 5e1b396..218fca4 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -883,7 +883,8 @@ gl_renderer_flush_damage(struct weston_surface *surface) if (!texture_used) return; - if (!pixman_region32_not_empty(&gs->texture_damage)) + if (!pixman_region32_not_empty(&gs->texture_damage) && + !gs->needs_full_upload) goto done; switch (wl_shm_buffer_get_format(buffer->shm_buffer)) { @@ -1240,6 +1241,11 @@ gl_renderer_create_surface(struct weston_surface *surface) wl_signal_add(&gr->destroy_signal, &gs->renderer_destroy_listener); + if (surface->buffer_ref.buffer) { + gl_renderer_attach(surface, surface->buffer_ref.buffer); + gl_renderer_flush_damage(surface); + } + return 0; } -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 0/2 v2] Renderer switch
From: Ander Conselvan de Oliveira V2 of the series I sent earlier today, changed to not require an extra option to allow for seamless switch. Thanks, Ander Ander Conselvan de Oliveira (2): compositor-drm: Add key binding to switch from pixman to GL renderer gl-renderer: Attach buffer during surface state creation if possible src/compositor-drm.c | 109 +- src/gl-renderer.c| 14 ++- 2 files changed, 104 insertions(+), 19 deletions(-) -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 2/3] compositor-drm: Add option to disable early buffer release
On 11/19/2013 01:05 PM, Pekka Paalanen wrote: On Tue, 19 Nov 2013 11:30:11 +0200 Ander Conselvan de Oliveira wrote: From: Ander Conselvan de Oliveira This together with a follow up patch should make it possible to do a runtime renderer switch without causing artifact on the screen. --- man/weston-drm.man |6 ++ src/compositor-drm.c | 27 +-- src/compositor.c |1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/man/weston-drm.man b/man/weston-drm.man index 35d62ae..d3d0b70 100644 --- a/man/weston-drm.man +++ b/man/weston-drm.man @@ -106,6 +106,12 @@ instead of the default seat Launch Weston on tty .I x instead of using the current tty. +.TP +.B \-\-disable\-early\-buffer\-release +Don't release buffers early and instead keep references to them as +long as any surface uses them, even if the compositor has an +internal copy of the buffer contents. This causes some clients to +allocate more memory than necessary. Hi Ander, I wonder, would it make more sense to call that --allow-renderer-switch instead? That way, if you define switching will work only once, then after the switch to the GL renderer you could enable the early release and get rid of the penalties from disabling it. Yeah, that's what I've done in the previous series. But it just occurred to me that the pixman renderer keeps the buffers around anyway (it doesn't copy it) so I could just replace c->disable_buffer_release (or c->allow_renderer_switch) with c->use_pixman and get the same effect without any extra options. How about that? Ander IIRC the use case was to get a compositor up fast with pixman, and then switch to GL - permanently? Thanks, pq . .\" *** .SH ENVIRONMENT diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 5cb0fab..a3c769d 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -103,6 +103,7 @@ struct drm_compositor { int cursors_are_broken; int use_pixman; + int disable_early_release; uint32_t prev_state; @@ -199,6 +200,7 @@ struct drm_parameters { int connector; int tty; int use_pixman; + int disable_early_release; const char *seat_id; }; @@ -1056,18 +1058,20 @@ drm_assign_planes(struct weston_output *output) pixman_region32_init(&overlap); primary = &c->base.primary_plane; - /* Flag all visible surfaces as keep_buffer = 1 */ - wl_list_for_each(ev, &c->base.view_list, link) - ev->surface->keep_buffer = 1; - wl_list_for_each_safe(ev, next, &c->base.view_list, link) { - /* test whether this buffer can ever go into a plane: -* non-shm, or small enough to be a cursor + struct weston_surface *es = ev->surface; + + /* Test whether this buffer can ever go into a plane: +* non-shm, or small enough to be a cursor. Also honor +* the --disable-early-buffer-release option. */ - if (!ev->surface->buffer_ref.buffer || - (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) && - (ev->geometry.width > 64 || ev->geometry.height > 64))) - ev->surface->keep_buffer = 0; + if (c->disable_early_release || + (es->buffer_ref.buffer && + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) || +(ev->geometry.width <= 64 && ev->geometry.height <= 64 + es->keep_buffer = 1; + else + es->keep_buffer = 0; pixman_region32_init(&surface_overlap); pixman_region32_intersect(&surface_overlap, &overlap, @@ -2691,6 +2695,7 @@ drm_compositor_create(struct wl_display *display, free(s); ec->use_pixman = param->use_pixman; + ec->disable_early_release = param->disable_early_release; if (weston_compositor_init(&ec->base, display, argc, argv, config) < 0) { @@ -2839,6 +2844,8 @@ backend_init(struct wl_display *display, int *argc, char *argv[], { WESTON_OPTION_INTEGER, "tty", 0, ¶m.tty }, { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode }, { WESTON_OPTION_BOOLEAN, "use-pixman", 0, ¶m.use_pixman }, + { WESTON_OPTION_BOOLEAN, "disable-early-buffer-release", 0, + ¶m.disable_early_release } }; param.seat_id = default_seat; diff --git a/src/compositor.c b/src/compositor.c index b8e0c6e..a43e3aa 100644 --- a/src/compositor.
[PATCH 3/3] gl-renderer: Attach buffer during surface state creation if possible
From: Ander Conselvan de Oliveira When a renderer switch happens, it is possible that when the surface state is created, a buffer for the given surface is already available. In that case, run the attach routine so that the pixel contents are properly set. Otherwise, it would only be set when a new attach request is made for that surface. This makes the renderer transition seamless, without leaving a black screen as before. (As long as --disable-early-buffer-release is passed to compositor-drm). --- man/weston-drm.man |5 +++-- src/gl-renderer.c |8 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/man/weston-drm.man b/man/weston-drm.man index d3d0b70..0c5f6de 100644 --- a/man/weston-drm.man +++ b/man/weston-drm.man @@ -110,8 +110,9 @@ instead of using the current tty. .B \-\-disable\-early\-buffer\-release Don't release buffers early and instead keep references to them as long as any surface uses them, even if the compositor has an -internal copy of the buffer contents. This causes some clients to -allocate more memory than necessary. +internal copy of the buffer contents. This prevents artifacts when +doing a renderer switch, but causes some clients to allocate more +memory than necessary. . .\" *** .SH ENVIRONMENT diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 5e1b396..218fca4 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -883,7 +883,8 @@ gl_renderer_flush_damage(struct weston_surface *surface) if (!texture_used) return; - if (!pixman_region32_not_empty(&gs->texture_damage)) + if (!pixman_region32_not_empty(&gs->texture_damage) && + !gs->needs_full_upload) goto done; switch (wl_shm_buffer_get_format(buffer->shm_buffer)) { @@ -1240,6 +1241,11 @@ gl_renderer_create_surface(struct weston_surface *surface) wl_signal_add(&gr->destroy_signal, &gs->renderer_destroy_listener); + if (surface->buffer_ref.buffer) { + gl_renderer_attach(surface, surface->buffer_ref.buffer); + gl_renderer_flush_damage(surface); + } + return 0; } -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 2/3] compositor-drm: Add option to disable early buffer release
From: Ander Conselvan de Oliveira This together with a follow up patch should make it possible to do a runtime renderer switch without causing artifact on the screen. --- man/weston-drm.man |6 ++ src/compositor-drm.c | 27 +-- src/compositor.c |1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/man/weston-drm.man b/man/weston-drm.man index 35d62ae..d3d0b70 100644 --- a/man/weston-drm.man +++ b/man/weston-drm.man @@ -106,6 +106,12 @@ instead of the default seat Launch Weston on tty .I x instead of using the current tty. +.TP +.B \-\-disable\-early\-buffer\-release +Don't release buffers early and instead keep references to them as +long as any surface uses them, even if the compositor has an +internal copy of the buffer contents. This causes some clients to +allocate more memory than necessary. . .\" *** .SH ENVIRONMENT diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 5cb0fab..a3c769d 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -103,6 +103,7 @@ struct drm_compositor { int cursors_are_broken; int use_pixman; + int disable_early_release; uint32_t prev_state; @@ -199,6 +200,7 @@ struct drm_parameters { int connector; int tty; int use_pixman; + int disable_early_release; const char *seat_id; }; @@ -1056,18 +1058,20 @@ drm_assign_planes(struct weston_output *output) pixman_region32_init(&overlap); primary = &c->base.primary_plane; - /* Flag all visible surfaces as keep_buffer = 1 */ - wl_list_for_each(ev, &c->base.view_list, link) - ev->surface->keep_buffer = 1; - wl_list_for_each_safe(ev, next, &c->base.view_list, link) { - /* test whether this buffer can ever go into a plane: -* non-shm, or small enough to be a cursor + struct weston_surface *es = ev->surface; + + /* Test whether this buffer can ever go into a plane: +* non-shm, or small enough to be a cursor. Also honor +* the --disable-early-buffer-release option. */ - if (!ev->surface->buffer_ref.buffer || - (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) && - (ev->geometry.width > 64 || ev->geometry.height > 64))) - ev->surface->keep_buffer = 0; + if (c->disable_early_release || + (es->buffer_ref.buffer && + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) || +(ev->geometry.width <= 64 && ev->geometry.height <= 64 + es->keep_buffer = 1; + else + es->keep_buffer = 0; pixman_region32_init(&surface_overlap); pixman_region32_intersect(&surface_overlap, &overlap, @@ -2691,6 +2695,7 @@ drm_compositor_create(struct wl_display *display, free(s); ec->use_pixman = param->use_pixman; + ec->disable_early_release = param->disable_early_release; if (weston_compositor_init(&ec->base, display, argc, argv, config) < 0) { @@ -2839,6 +2844,8 @@ backend_init(struct wl_display *display, int *argc, char *argv[], { WESTON_OPTION_INTEGER, "tty", 0, ¶m.tty }, { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode }, { WESTON_OPTION_BOOLEAN, "use-pixman", 0, ¶m.use_pixman }, + { WESTON_OPTION_BOOLEAN, "disable-early-buffer-release", 0, + ¶m.disable_early_release } }; param.seat_id = default_seat; diff --git a/src/compositor.c b/src/compositor.c index b8e0c6e..a43e3aa 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3692,6 +3692,7 @@ usage(int error_code) " --seat=SEAT\t\tThe seat that weston should run on\n" " --tty=TTY\t\tThe tty to use\n" " --use-pixman\t\tUse the pixman (CPU) renderer\n" + " --disable-early-bufffer-release\tDisable early buffer release\n" " --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n"); fprintf(stderr, -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 1/3] compositor-drm: Add key binding to switch from pixman to GL renderer
From: Ander Conselvan de Oliveira When running with the pixman renderer, the debug binding 'W' (mod-shift-space W) will cause the compositor to load gl-renderer.so and start using it instead of the pixman renderer. --- src/compositor-drm.c | 83 +- src/gl-renderer.c|6 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index d4fc871..5cb0fab 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -596,7 +596,8 @@ drm_output_repaint(struct weston_output *output_base, return -1; mode = container_of(output->base.current_mode, struct drm_mode, base); - if (!output->current) { + if (!output->current || + output->current->stride != output->next->stride) { ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id, output->next->fb_id, 0, 0, &output->connector_id, 1, @@ -1286,15 +1287,15 @@ init_drm(struct drm_compositor *ec, struct udev_device *device) return 0; } -static int -init_egl(struct drm_compositor *ec) +static struct gbm_device * +create_gbm_device(int fd) { - EGLint format; + struct gbm_device *gbm; gl_renderer = weston_load_module("gl-renderer.so", "gl_renderer_interface"); if (!gl_renderer) - return -1; + return NULL; /* GBM will load a dri driver, but even though they need symbols from * libglapi, in some version of Mesa they are not linked to it. Since @@ -1303,14 +1304,34 @@ init_egl(struct drm_compositor *ec) * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */ dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL); - ec->gbm = gbm_create_device(ec->drm.fd); + gbm = gbm_create_device(fd); - if (!ec->gbm) - return -1; + return gbm; +} + +static int +drm_compositor_create_gl_renderer(struct drm_compositor *ec) +{ + EGLint format; format = ec->format; if (gl_renderer->create(&ec->base, ec->gbm, gl_renderer->opaque_attribs, &format) < 0) { + return -1; + } + + return 0; +} + +static int +init_egl(struct drm_compositor *ec) +{ + ec->gbm = create_gbm_device(ec->drm.fd); + + if (!ec->gbm) + return -1; + + if (drm_compositor_create_gl_renderer(ec) < 0) { gbm_device_destroy(ec->gbm); return -1; } @@ -2585,6 +2606,50 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, } #endif +static void +switch_to_gl_renderer(struct drm_compositor *c) +{ + struct drm_output *output; + + if (!c->use_pixman) + return; + + weston_log("Switching to GL renderer\n"); + + c->gbm = create_gbm_device(c->drm.fd); + if (!c->gbm) { + weston_log("Failed to create gbm device. " + "Aborting renderer switch\n"); + return; + } + + wl_list_for_each(output, &c->base.output_list, base.link) + pixman_renderer_output_destroy(&output->base); + + c->base.renderer->destroy(&c->base); + + if (drm_compositor_create_gl_renderer(c) < 0) { + gbm_device_destroy(c->gbm); + weston_log("Failed to create GL renderer. Quitting.\n"); + /* FIXME: we need a function to shutdown cleanly */ + assert(0); + } + + wl_list_for_each(output, &c->base.output_list, base.link) + drm_output_init_egl(output, c); + + c->use_pixman = 0; +} + +static void +renderer_switch_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct drm_compositor *c = (struct drm_compositor *) seat->compositor; + + switch_to_gl_renderer(c); +} + static struct weston_compositor * drm_compositor_create(struct wl_display *display, struct drm_parameters *param, @@ -2734,6 +2799,8 @@ drm_compositor_create(struct wl_display *display, planes_binding, ec); weston_compositor_add_debug_binding(&ec->base, KEY_Q, recorder_binding, ec); + weston_compositor_add_debug_binding(&ec->base, KEY_W, + renderer_switch_binding, ec); return &ec->base; diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 7a535c7..5e1b396 100644 --- a/src/gl-renderer.c +++ b/src/gl-rendere
Re: [PATCH] Do not release buffer when it is going to be used again.
Em 06-11-2013 21:47, Axel Davy escreveu: Solve a bug for some fullscreen clients which wouldn't show up. Signed-off-by: Axel Davy --- src/compositor-drm.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 4f015d1..6a2500b 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -711,7 +711,8 @@ vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, output->vblank_pending = 0; - drm_output_release_fb(output, s->current); + if (s->current != s->next) +drm_output_release_fb(output, s->current); s->current = s->next; s->next = NULL; @@ -735,7 +736,8 @@ page_flip_handler(int fd, unsigned int frame, * we just want to page flip to the current buffer to get an accurate * timestamp */ if (output->page_flip_pending) { - drm_output_release_fb(output, output->current); + if (output->current != output->next) +drm_output_release_fb(output, output->current); We shouldn't have current equals to next in the first place. This can happen when the repaint loop starts, but that's what the 'if (output->page_flip_pending)' is for. In any other case, that implies we are rendering to the front buffer. Ander output->current = output->next; output->next = NULL; } ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 3/3] gbm: Add entry points for mapping and unmapping bos
Add gbm_bo_map() and gbm_bo_unmap(). This lets a user access the contents of a bo using the CPU. --- I'm not sure about the extra flags. We do have GBM_BO_USE_WRITE but that is defined to always work with GBM_BO_USE_CURSOR_64X64. Reusing that would imply that these buffers are always mappable or an API change. --- src/gbm/backends/dri/gbm_dri.c |4 src/gbm/backends/intel/gbm_intel.c | 21 + src/gbm/backends/intel/gbm_intel.h |2 ++ src/gbm/main/gbm.c | 25 + src/gbm/main/gbm.h | 14 ++ src/gbm/main/gbmint.h |2 ++ 6 files changed, 68 insertions(+) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 9998308..bdd1c85 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -315,6 +315,10 @@ gbm_dri_is_format_supported(struct gbm_device *gbm, usage & GBM_BO_USE_RENDERING) return 0; + if (usage & GBM_BO_USE_CPU_WRITE || + usage & GBM_BO_USE_CPU_READ) + return 0; + return 1; } diff --git a/src/gbm/backends/intel/gbm_intel.c b/src/gbm/backends/intel/gbm_intel.c index 9f17df7..f8baa98 100644 --- a/src/gbm/backends/intel/gbm_intel.c +++ b/src/gbm/backends/intel/gbm_intel.c @@ -73,6 +73,24 @@ gbm_intel_bo_write(struct gbm_bo *bo, const void *buf, size_t count) return drm_intel_bo_unmap(ibo->bo); } +static void * +gbm_intel_bo_map(struct gbm_bo *bo) +{ + struct gbm_intel_bo *ibo = gbm_intel_bo(bo); + + drm_intel_bo_map(ibo->bo, 1); + + return ibo->bo->virtual; +} + +static void +gbm_intel_bo_unmap(struct gbm_bo *bo) +{ + struct gbm_intel_bo *ibo = gbm_intel_bo(bo); + + drm_intel_bo_unmap(ibo->bo); +} + static void gbm_intel_bo_destroy(struct gbm_bo *_bo) { @@ -102,6 +120,7 @@ gbm_intel_bo_create_with_bo(struct gbm_device *gbm, return NULL; ibo->bo = bo; + ibo->usage = usage; ibo->base.base.gbm = gbm; ibo->base.base.width = width; @@ -225,6 +244,8 @@ gbm_intel_device_create(int fd) igbm->base.base.bo_export = gbm_intel_bo_export; igbm->base.base.is_format_supported = gbm_intel_is_format_supported; igbm->base.base.bo_write = gbm_intel_bo_write; + igbm->base.base.bo_map = gbm_intel_bo_map; + igbm->base.base.bo_unmap = gbm_intel_bo_unmap; igbm->base.base.bo_destroy = gbm_intel_bo_destroy; igbm->base.base.destroy = gbm_intel_destroy; igbm->base.base.surface_create = gbm_intel_surface_create; diff --git a/src/gbm/backends/intel/gbm_intel.h b/src/gbm/backends/intel/gbm_intel.h index 4691ecc..8136c78 100644 --- a/src/gbm/backends/intel/gbm_intel.h +++ b/src/gbm/backends/intel/gbm_intel.h @@ -46,6 +46,8 @@ struct gbm_intel_device { struct gbm_intel_bo { struct gbm_drm_bo base; + uint32_t usage; + drm_intel_bo *bo; uint32_t name; }; diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index b68ead0..f41b4c9 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -250,6 +250,31 @@ gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) return bo->gbm->bo_write(bo, buf, count); } +/** Map a buffer object in CPU accesible memory + * + * \param bo The buffer object to be mapped + * \return Pointer to the mapped buffer object or NULL on failure + */ +GBM_EXPORT void * +gbm_bo_map(struct gbm_bo *bo) +{ + if (bo->gbm->bo_map) + return bo->gbm->bo_map(bo); + else + return NULL; +} + +/** Unmap a preivously mapped buffer object + * + * \param The buffer object to be unmapped + */ +GBM_EXPORT void +gbm_bo_unmap(struct gbm_bo *bo) +{ + if (bo->gbm->bo_unmap) + bo->gbm->bo_unmap(bo); +} + /** Get the gbm device used to create the buffer object * * \param bo The buffer object diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h index 3854c4c..b3942d3 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -207,6 +207,14 @@ enum gbm_bo_flags { * combinations. */ GBM_BO_USE_WRITE= (1 << 3), + /** +* Buffer can be mapped with gbm_bo_map() for writing. +*/ + GBM_BO_USE_CPU_WRITE = (1 << 4), + /** +* Buffer can be mapped with gbm_bo_map() for reading. +*/ + GBM_BO_USE_CPU_READ = (1 << 5), }; int @@ -262,6 +270,12 @@ gbm_bo_get_handle(struct gbm_bo *bo); int gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count); +void * +gbm_bo_map(struct gbm_bo *bo); + +void +gbm_bo_unmap(struct gbm_bo *bo); + void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, void (*destroy_user_data)(struct gbm_bo *, void *)); diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h index a8cf49e..f17a46f 100644 --- a/src/gbm/main/gbmint.h +++ b/src/gbm/main/gbmint.h @@ -70,6 +70,8 @@ struct gbm_device { void *buffer, uint32_t usage); int (*bo_export)(struct gbm_bo *bo, uint32_t type, void **buffer); int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data); + void *(*bo_map)
[PATCH 1/3] gbm: Add intel backend
This adds an intel backend that doesn't depend on dri. Its usage is limited since the current EGL implementation won't work with this as it is. --- src/gbm/Makefile.am| 12 ++ src/gbm/backends/intel/gbm_intel.c | 227 src/gbm/backends/intel/gbm_intel.h | 74 src/gbm/main/backend.c |2 + src/gbm/main/common_drm.h |1 + 5 files changed, 316 insertions(+) create mode 100644 src/gbm/backends/intel/gbm_intel.c create mode 100644 src/gbm/backends/intel/gbm_intel.h diff --git a/src/gbm/Makefile.am b/src/gbm/Makefile.am index 1282b14..e808b7f 100644 --- a/src/gbm/Makefile.am +++ b/src/gbm/Makefile.am @@ -42,6 +42,18 @@ libgbm_la_LIBADD += \ libgbm_dri.la $(top_builddir)/src/mapi/shared-glapi/libglapi.la $(LIBDRM_LIBS) endif +if HAVE_I965_DRI +noinst_LTLIBRARIES = libgbm_intel.la +libgbm_intel_la_SOURCES = \ + backends/intel/gbm_intel.c + +libgbm_intel_la_CFLAGS = \ + $(AM_CFLAGS) $(INTEL_CFLAGS) + +libgbm_la_LIBADD += \ + libgbm_intel.la $(INTEL_LIBS) +endif + all-local: libgbm.la $(MKDIR_P) $(top_builddir)/$(LIB_DIR); ln -f .libs/libgbm.so.1.0.0 $(top_builddir)/$(LIB_DIR)/libgbm.so diff --git a/src/gbm/backends/intel/gbm_intel.c b/src/gbm/backends/intel/gbm_intel.c new file mode 100644 index 000..dc9f174 --- /dev/null +++ b/src/gbm/backends/intel/gbm_intel.c @@ -0,0 +1,227 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Ander Conselvan de Oliveira + */ + +#include +#include +#include + +#include "gbm_intel.h" + +#include "gbmint.h" + +static int +gbm_intel_is_format_supported(struct gbm_device *gbm, +uint32_t format, +uint32_t usage) +{ + switch (format) { + case GBM_BO_FORMAT_XRGB: + case GBM_FORMAT_XRGB: + break; + case GBM_BO_FORMAT_ARGB: + case GBM_FORMAT_ARGB: + if (usage & GBM_BO_USE_SCANOUT) + return 0; + break; + default: + return 0; + } + + if (usage & GBM_BO_USE_CURSOR_64X64 && + usage & GBM_BO_USE_RENDERING) + return 0; + + return 1; +} + +static int +gbm_intel_bo_write(struct gbm_bo *bo, const void *buf, size_t count) +{ + struct gbm_intel_bo *ibo = gbm_intel_bo(bo); + int ret; + + ret = drm_intel_bo_map(ibo->bo, 1); + if (ret < 0) + return ret; + + memcpy(ibo->bo->virtual, buf, count); + + return drm_intel_bo_unmap(ibo->bo); +} + +static void +gbm_intel_bo_destroy(struct gbm_bo *_bo) +{ + struct gbm_intel_bo *ibo = gbm_intel_bo(_bo); + + drm_intel_bo_unreference(ibo->bo); + + free(ibo); +} + +static inline int +align(int value, int size) +{ + return (value + size - 1) & ~(size - 1); +} + +static struct gbm_intel_bo * +gbm_intel_bo_create_with_bo(struct gbm_device *gbm, +uint32_t width, uint32_t height, uint32_t stride, +uint32_t format, uint32_t usage, +drm_intel_bo *bo) +{ + struct gbm_intel_bo *ibo; + + ibo = calloc(1, sizeof *ibo); + if (!ibo) + return NULL; + + ibo->bo = bo; + + ibo->base.base.gbm = gbm; + ibo->base.base.width = width; + ibo->base.base.height = height; + ibo->base.base.stride = stride; + ibo->base.base.format = format; + ibo->base.base.handle.s32 = ibo->bo->handle; + + return ibo; +} + +static struct gbm_bo * +gbm_intel_bo_create(struct gbm_device *gbm, +uint32_t width, uint32_t height, +uint32_t format, uint32_t usage) +{ + struct gbm_intel_device *igbm = gbm_intel_device(gbm); + struct gbm_intel_bo *ibo; + drm_intel_bo *bo; + int size, stride; + + swi
[PATCH 2/3] egl/dri: Add gbm platform
rge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + *Ander Conselvan de Oliveira + *Kristian Høgsberg + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "egl_dri2.h" + +#include "gbmint.h" + +static struct gbm_bo * +lock_front_buffer(struct gbm_surface *surf) +{ + struct dri2_egl_surface *dri2_surf = surf->priv; + struct gbm_bo *bo; + + if (dri2_surf->current == NULL) { + _eglError(EGL_BAD_SURFACE, "no front buffer"); + return NULL; + } + + bo = dri2_surf->current->bo; + dri2_surf->current->locked = 1; + dri2_surf->current = NULL; + + return bo; +} + +static void +release_buffer(struct gbm_surface *surf, struct gbm_bo *bo) +{ + struct dri2_egl_surface *dri2_surf = surf->priv; + int i; + + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (dri2_surf->color_buffers[i].bo == bo) { +dri2_surf->color_buffers[i].locked = 0; + } + } +} + +static int +has_free_buffers(struct gbm_surface *surf) +{ + struct dri2_egl_surface *dri2_surf = surf->priv; + int i; + + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) + if (!dri2_surf->color_buffers[i].locked) +return 1; + + return 0; +} + +static _EGLSurface * +dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, + _EGLConfig *conf, EGLNativeWindowType window, + const EGLint *attrib_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); + struct dri2_egl_surface *dri2_surf; + struct gbm_surface *surf; + + (void) drv; + + dri2_surf = calloc(1, sizeof *dri2_surf); + if (!dri2_surf) { + _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); + return NULL; + } + + if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) + goto cleanup_surf; + + switch (type) { + case EGL_WINDOW_BIT: + if (!window) + return NULL; + surf = (struct gbm_surface *) window; + dri2_surf->gbm_surf = surf; + dri2_surf->base.Width = surf->width; + dri2_surf->base.Height = surf->height; + surf->priv = dri2_surf; + break; + default: + goto cleanup_surf; + } + + dri2_surf->dri_drawable = + (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, + dri2_conf->dri_double_config, + dri2_surf); + + if (dri2_surf->dri_drawable == NULL) { + _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); + goto cleanup_surf; + } + + return &dri2_surf->base; + + cleanup_surf: + free(dri2_surf); + + return NULL; +} + +static _EGLSurface * +dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativeWindowType window, + const EGLint *attrib_list) +{ + return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf, + window, attrib_list); +} + +static EGLBoolean +dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + int i; + + if (!_eglPutSurface(surf)) + return EGL_TRUE; + + (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); + + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (dri2_surf->color_buffers[i].bo) +gbm_bo_destroy(dri2_surf->color_buffers[i].bo); + } + + for (i = 0; i < __DRI_BUFFER_COUNT; i++) { + if (dri2_surf->dri_buffers[i]) + dri2_dpy->dri2->rel
[RFC] [PATCH 0/3] gbm: Add support for mapping bos
Hi, This is a request for comments on the idea of being able to map gbm bos and how to implement it. The idea here is to take advantage of UMA atchitectures when the contents on the screen are a mix of GPU and CPU rendered. One of the problems of adding a map entry point to gbm is the fact that it relies on the DRI image extension to do all the work. Instead of extending that extension, the proposal here is to support different gbm backends, which may optionally support mapping. However, this requires changes to the EGL implementation, since the current implementation is heavily coupled with gbm's dri backend. The one problem in doing that is that the dri driver and gbm device no longer share the same fd, so another way of sharing buffers between then is necessary. As a stop gap measure I added the ability for gbm to provide gem names (given that dri 2's interface relies on names anyway), but a better solution is needed. This would also let the dependency between libgbm and libEGL to be moved to gbm's dri backend, and open up the possibility of running a Wayland compositor on KMS with a software renderer that would still be able to use overlays. This ties with the fast start patches I submitted to the wayland mailing list. Still talking about Wayland, I have a rough plan on how to make this usable with that too. Since gbm is already Wayland aware to some extent, given that it is able to import wl_buffers into gbm_bos, it seems like a natural extension that it would be able to do the converse. That ability together with an entry point for creating a gbm_device for a given wl_display would be enough for making this available for any wayland client. Any comments on this will be highly appreciated. Thanks, Ander Ander Conselvan de Oliveira (3): gbm: Add intel backend egl/dri: Add gbm platform gbm: Add entry points for mapping and unmapping bos configure.ac|5 +- src/egl/drivers/dri2/Makefile.am|5 + src/egl/drivers/dri2/egl_dri2.c |6 + src/egl/drivers/dri2/egl_dri2.h | 11 +- src/egl/drivers/dri2/platform_gbm.c | 545 +++ src/egl/main/Makefile.am|5 + src/egl/main/egldisplay.c |3 +- src/egl/main/egldisplay.h |1 + src/gbm/Makefile.am | 12 + src/gbm/backends/dri/gbm_dri.c | 11 + src/gbm/backends/intel/gbm_intel.c | 269 + src/gbm/backends/intel/gbm_intel.h | 77 + src/gbm/main/backend.c |2 + src/gbm/main/common_drm.h |1 + src/gbm/main/gbm.c | 54 +++- src/gbm/main/gbm.h | 18 ++ src/gbm/main/gbmint.h |5 + 17 files changed, 1022 insertions(+), 8 deletions(-) create mode 100644 src/egl/drivers/dri2/platform_gbm.c create mode 100644 src/gbm/backends/intel/gbm_intel.c create mode 100644 src/gbm/backends/intel/gbm_intel.h -- 1.7.9.5 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH] Shutdown the compositor before removing graphics
On 11/04/2013 10:39 AM, Cameron Stewart wrote: Otherwise the outputs are removed when they have already been freed. However don't clean up the debug listeners in gl_renderer as these would be cleaned up by the compositor previously. I'm not sure why I didn't notice the error when I wrote the patch that changed the order. If I understood correctly the problem is that gl_renderer_destroy_output() is called after the renderer is destroyed and that causes a crash trying to access ec->renderer. The point of that series was to get to a point where we can destroy a renderer in runtime and make sure everything is cleaned up, so I rather fix this some other way. We have a call to ec->renderer->destroy() in every backend, so perhaps we can move that into weston_compositor_shutdown() just after the outputs are destroyed. Thanks, Ander --- src/compositor-drm.c | 4 ++-- src/compositor-rdp.c | 2 +- src/compositor-rpi.c | 4 ++-- src/compositor-wayland.c | 4 ++-- src/compositor-x11.c | 4 ++-- src/gl-renderer.c| 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 3bdc20b..cced27d 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2328,10 +2328,10 @@ drm_destroy(struct weston_compositor *ec) destroy_sprites(d); - ec->renderer->destroy(ec); - weston_compositor_shutdown(ec); + ec->renderer->destroy(ec); + if (d->gbm) gbm_device_destroy(d->gbm); diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c index 8a302f8..36aa690 100644 --- a/src/compositor-rdp.c +++ b/src/compositor-rdp.c @@ -523,8 +523,8 @@ rdp_restore(struct weston_compositor *ec) static void rdp_destroy(struct weston_compositor *ec) { - ec->renderer->destroy(ec); weston_compositor_shutdown(ec); + ec->renderer->destroy(ec); free(ec); } diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c index f163e01..a1c14e2 100644 --- a/src/compositor-rpi.c +++ b/src/compositor-rpi.c @@ -652,11 +652,11 @@ rpi_compositor_destroy(struct weston_compositor *base) wl_list_for_each_safe(seat, next, &compositor->base.seat_list, link) evdev_input_destroy(seat); - compositor->base.renderer->destroy(&compositor->base); - /* destroys outputs, too */ weston_compositor_shutdown(&compositor->base); + compositor->base.renderer->destroy(&compositor->base); + weston_launcher_destroy(compositor->base.launcher); bcm_host_deinit(); diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index d626ee1..3ca3d6b 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -715,10 +715,10 @@ wayland_destroy(struct weston_compositor *ec) { struct wayland_compositor *c = (struct wayland_compositor *) ec; - ec->renderer->destroy(ec); - weston_compositor_shutdown(ec); + ec->renderer->destroy(ec); + if (c->parent.shm) wl_shm_destroy(c->parent.shm); diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 73e71ed..d045e9d 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -1445,10 +1445,10 @@ x11_destroy(struct weston_compositor *ec) wl_event_source_remove(compositor->xcb_source); x11_input_destroy(compositor); - ec->renderer->destroy(ec); - weston_compositor_shutdown(ec); /* destroys outputs, too */ + ec->renderer->destroy(ec); + XCloseDisplay(compositor->dpy); free(ec); } diff --git a/src/gl-renderer.c b/src/gl-renderer.c index d181c07..29191d5 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -1630,8 +1630,8 @@ gl_renderer_destroy(struct weston_compositor *ec) wl_array_release(&gr->indices); wl_array_release(&gr->vtxcnt); - weston_binding_destroy(gr->fragment_binding); - weston_binding_destroy(gr->fan_binding); + /* We would normally remove the bindings here but they should have +* already been removed when the compositor shutdown */ free(gr); } ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel