diff --git a/src/animation.c b/src/animation.c index 909e2436..5eacb7bf 100644 --- a/src/animation.c +++ b/src/animation.c @@ -34,7 +34,7 @@ WL_EXPORT void weston_spring_init(struct weston_spring *spring, - double k, double current, double target) + double k, double current, double target) { spring->k = k; spring->friction = 400.0; @@ -114,52 +114,52 @@ weston_spring_done(struct weston_spring *spring) fabs(spring->current - spring->target) < 0.002; } -typedef void (*weston_surface_animation_frame_func_t)(struct weston_surface_animation *animation); +typedef void (*weston_view_animation_frame_func_t)(struct weston_view_animation *animation); -struct weston_surface_animation { - struct weston_surface *surface; +struct weston_view_animation { + struct weston_view *view; struct weston_animation animation; struct weston_spring spring; struct weston_transform transform; struct wl_listener listener; float start, stop; - weston_surface_animation_frame_func_t frame; - weston_surface_animation_frame_func_t reset; - weston_surface_animation_done_func_t done; + weston_view_animation_frame_func_t frame; + weston_view_animation_frame_func_t reset; + weston_view_animation_done_func_t done; void *data; }; static void -weston_surface_animation_destroy(struct weston_surface_animation *animation) +weston_view_animation_destroy(struct weston_view_animation *animation) { wl_list_remove(&animation->animation.link); wl_list_remove(&animation->listener.link); wl_list_remove(&animation->transform.link); if (animation->reset) animation->reset(animation); - weston_surface_geometry_dirty(animation->surface); + weston_view_geometry_dirty(animation->view); if (animation->done) animation->done(animation, animation->data); free(animation); } static void -handle_animation_surface_destroy(struct wl_listener *listener, void *data) +handle_animation_view_destroy(struct wl_listener *listener, void *data) { - struct weston_surface_animation *animation = + struct weston_view_animation *animation = container_of(listener, - struct weston_surface_animation, listener); + struct weston_view_animation, listener); - weston_surface_animation_destroy(animation); + weston_view_animation_destroy(animation); } static void -weston_surface_animation_frame(struct weston_animation *base, - struct weston_output *output, uint32_t msecs) +weston_view_animation_frame(struct weston_animation *base, + struct weston_output *output, uint32_t msecs) { - struct weston_surface_animation *animation = + struct weston_view_animation *animation = container_of(base, - struct weston_surface_animation, animation); + struct weston_view_animation, animation); if (base->frame_counter <= 1) animation->spring.timestamp = msecs; @@ -167,32 +167,32 @@ weston_surface_animation_frame(struct weston_animation *base, weston_spring_update(&animation->spring, msecs); if (weston_spring_done(&animation->spring)) { - weston_surface_animation_destroy(animation); + weston_view_animation_destroy(animation); return; } if (animation->frame) animation->frame(animation); - weston_surface_geometry_dirty(animation->surface); - weston_compositor_schedule_repaint(animation->surface->compositor); + weston_view_geometry_dirty(animation->view); + weston_view_schedule_repaint(animation->view); } -static struct weston_surface_animation * -weston_surface_animation_run(struct weston_surface *surface, - float start, float stop, - weston_surface_animation_frame_func_t frame, - weston_surface_animation_frame_func_t reset, - weston_surface_animation_done_func_t done, - void *data) +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) { - struct weston_surface_animation *animation; + struct weston_view_animation *animation; animation = malloc(sizeof *animation); if (!animation) return NULL; - animation->surface = surface; + animation->view = view; animation->frame = frame; animation->reset = reset; animation->done = done; @@ -200,35 +200,35 @@ weston_surface_animation_run(struct weston_surface *surface, animation->start = start; animation->stop = stop; weston_matrix_init(&animation->transform.matrix); - wl_list_insert(&surface->geometry.transformation_list, + wl_list_insert(&view->geometry.transformation_list, &animation->transform.link); weston_spring_init(&animation->spring, 200.0, 0.0, 1.0); animation->spring.friction = 700; animation->animation.frame_counter = 0; - animation->animation.frame = weston_surface_animation_frame; - weston_surface_animation_frame(&animation->animation, NULL, 0); + animation->animation.frame = weston_view_animation_frame; + weston_view_animation_frame(&animation->animation, NULL, 0); - animation->listener.notify = handle_animation_surface_destroy; - wl_signal_add(&surface->destroy_signal, &animation->listener); + animation->listener.notify = handle_animation_view_destroy; + wl_signal_add(&view->destroy_signal, &animation->listener); - wl_list_insert(&surface->output->animation_list, + wl_list_insert(&view->output->animation_list, &animation->animation.link); return animation; } static void -reset_alpha(struct weston_surface_animation *animation) +reset_alpha(struct weston_view_animation *animation) { - struct weston_surface *surface = animation->surface; + struct weston_view *view = animation->view; - surface->alpha = animation->stop; + view->alpha = animation->stop; } static void -zoom_frame(struct weston_surface_animation *animation) +zoom_frame(struct weston_view_animation *animation) { - struct weston_surface *es = animation->surface; + struct weston_view *es = animation->view; float scale; scale = animation->start + @@ -248,15 +248,15 @@ zoom_frame(struct weston_surface_animation *animation) es->alpha = 1.0; } -WL_EXPORT struct weston_surface_animation * -weston_zoom_run(struct weston_surface *surface, float start, float stop, - weston_surface_animation_done_func_t done, void *data) +WL_EXPORT struct weston_view_animation * +weston_zoom_run(struct weston_view *view, float start, float stop, + weston_view_animation_done_func_t done, void *data) { - struct weston_surface_animation *zoom; + struct weston_view_animation *zoom; - zoom = weston_surface_animation_run(surface, start, stop, - zoom_frame, reset_alpha, - done, data); + zoom = weston_view_animation_run(view, start, stop, + zoom_frame, reset_alpha, + done, data); weston_spring_init(&zoom->spring, 300.0, start, stop); zoom->spring.friction = 1400; @@ -266,45 +266,45 @@ weston_zoom_run(struct weston_surface *surface, float start, float stop, } static void -fade_frame(struct weston_surface_animation *animation) +fade_frame(struct weston_view_animation *animation) { if (animation->spring.current > 0.999) - animation->surface->alpha = 1; + animation->view->alpha = 1; else if (animation->spring.current < 0.001 ) - animation->surface->alpha = 0; + animation->view->alpha = 0; else - animation->surface->alpha = animation->spring.current; + animation->view->alpha = animation->spring.current; } -WL_EXPORT struct weston_surface_animation * -weston_fade_run(struct weston_surface *surface, +WL_EXPORT struct weston_view_animation * +weston_fade_run(struct weston_view *view, float start, float end, float k, - weston_surface_animation_done_func_t done, void *data) + weston_view_animation_done_func_t done, void *data) { - struct weston_surface_animation *fade; + struct weston_view_animation *fade; - fade = weston_surface_animation_run(surface, 0, end, - fade_frame, reset_alpha, - done, data); + fade = weston_view_animation_run(view, 0, end, + fade_frame, reset_alpha, + done, data); weston_spring_init(&fade->spring, k, start, end); fade->spring.friction = 1400; fade->spring.previous = -(end - start) * 0.03; - surface->alpha = start; + view->alpha = start; return fade; } WL_EXPORT void -weston_fade_update(struct weston_surface_animation *fade, float target) +weston_fade_update(struct weston_view_animation *fade, float target) { fade->spring.target = target; } static void -slide_frame(struct weston_surface_animation *animation) +slide_frame(struct weston_view_animation *animation) { float scale; @@ -315,15 +315,15 @@ slide_frame(struct weston_surface_animation *animation) weston_matrix_translate(&animation->transform.matrix, 0, scale, 0); } -WL_EXPORT struct weston_surface_animation * -weston_slide_run(struct weston_surface *surface, float start, float stop, - weston_surface_animation_done_func_t done, void *data) +WL_EXPORT struct weston_view_animation * +weston_slide_run(struct weston_view *view, float start, float stop, + weston_view_animation_done_func_t done, void *data) { - struct weston_surface_animation *animation; + struct weston_view_animation *animation; - animation = weston_surface_animation_run(surface, start, stop, - slide_frame, NULL, done, - data); + animation = weston_view_animation_run(view, start, stop, + slide_frame, NULL, done, + data); if (!animation) return NULL; diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 60b4cbad..e32e4a85 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -156,7 +156,7 @@ struct drm_output { struct gbm_bo *cursor_bo[2]; struct weston_plane cursor_plane; struct weston_plane fb_plane; - struct weston_surface *cursor_surface; + struct weston_view *cursor_view; int current_cursor; struct drm_fb *current, *next; struct backlight *backlight; @@ -448,23 +448,23 @@ drm_output_check_scanout_format(struct drm_output *output, } static struct weston_plane * -drm_output_prepare_scanout_surface(struct weston_output *_output, - struct weston_surface *es) +drm_output_prepare_scanout_view(struct weston_output *_output, + struct weston_view *ev) { struct drm_output *output = (struct drm_output *) _output; struct drm_compositor *c = (struct drm_compositor *) output->base.compositor; - struct weston_buffer *buffer = es->buffer_ref.buffer; + struct weston_buffer *buffer = ev->surface->buffer_ref.buffer; struct gbm_bo *bo; uint32_t format; - if (es->geometry.x != output->base.x || - es->geometry.y != output->base.y || + if (ev->geometry.x != output->base.x || + ev->geometry.y != output->base.y || buffer == NULL || c->gbm == NULL || buffer->width != output->base.current_mode->width || buffer->height != output->base.current_mode->height || - output->base.transform != es->buffer_transform || - es->transform.enabled) + output->base.transform != ev->surface->buffer_transform || + ev->transform.enabled) return NULL; bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER, @@ -474,7 +474,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output, if (!bo) return NULL; - format = drm_output_check_scanout_format(output, es, bo); + format = drm_output_check_scanout_format(output, ev->surface, bo); if (format == 0) { gbm_bo_destroy(bo); return NULL; @@ -766,7 +766,7 @@ page_flip_handler(int fd, unsigned int frame, static uint32_t drm_output_check_sprite_format(struct drm_sprite *s, - struct weston_surface *es, struct gbm_bo *bo) + struct weston_view *ev, struct gbm_bo *bo) { uint32_t i, format; @@ -776,9 +776,9 @@ drm_output_check_sprite_format(struct drm_sprite *s, pixman_region32_t r; pixman_region32_init_rect(&r, 0, 0, - es->geometry.width, - es->geometry.height); - pixman_region32_subtract(&r, &r, &es->opaque); + ev->geometry.width, + ev->geometry.height); + pixman_region32_subtract(&r, &r, &ev->surface->opaque); if (!pixman_region32_not_empty(&r)) format = GBM_FORMAT_XRGB8888; @@ -794,15 +794,15 @@ drm_output_check_sprite_format(struct drm_sprite *s, } static int -drm_surface_transform_supported(struct weston_surface *es) +drm_view_transform_supported(struct weston_view *ev) { - return !es->transform.enabled || - (es->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE); + return !ev->transform.enabled || + (ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE); } static struct weston_plane * -drm_output_prepare_overlay_surface(struct weston_output *output_base, - struct weston_surface *es) +drm_output_prepare_overlay_view(struct weston_output *output_base, + struct weston_view *ev) { struct weston_compositor *ec = output_base->compositor; struct drm_compositor *c =(struct drm_compositor *) ec; @@ -817,28 +817,28 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, if (c->gbm == NULL) return NULL; - if (es->buffer_transform != output_base->transform) + if (ev->surface->buffer_transform != output_base->transform) return NULL; - if (es->buffer_scale != output_base->current_scale) + if (ev->surface->buffer_scale != output_base->current_scale) return NULL; if (c->sprites_are_broken) return NULL; - if (es->output_mask != (1u << output_base->id)) + if (ev->output_mask != (1u << output_base->id)) return NULL; - if (es->buffer_ref.buffer == NULL) + if (ev->surface->buffer_ref.buffer == NULL) return NULL; - if (es->alpha != 1.0f) + if (ev->alpha != 1.0f) return NULL; - if (wl_shm_buffer_get(es->buffer_ref.buffer->resource)) + if (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource)) return NULL; - if (!drm_surface_transform_supported(es)) + if (!drm_view_transform_supported(ev)) return NULL; wl_list_for_each(s, &c->sprite_list, link) { @@ -856,12 +856,12 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, return NULL; bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER, - es->buffer_ref.buffer->resource, + ev->surface->buffer_ref.buffer->resource, GBM_BO_USE_SCANOUT); if (!bo) return NULL; - format = drm_output_check_sprite_format(s, es, bo); + format = drm_output_check_sprite_format(s, ev, bo); if (format == 0) { gbm_bo_destroy(bo); return NULL; @@ -873,9 +873,9 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, return NULL; } - drm_fb_set_buffer(s->next, es->buffer_ref.buffer); + drm_fb_set_buffer(s->next, ev->surface->buffer_ref.buffer); - box = pixman_region32_extents(&es->transform.boundingbox); + box = pixman_region32_extents(&ev->transform.boundingbox); s->plane.x = box->x1; s->plane.y = box->y1; @@ -885,7 +885,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, * for us already). */ pixman_region32_init(&dest_rect); - pixman_region32_intersect(&dest_rect, &es->transform.boundingbox, + pixman_region32_intersect(&dest_rect, &ev->transform.boundingbox, &output_base->region); pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y); box = pixman_region32_extents(&dest_rect); @@ -901,36 +901,37 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, pixman_region32_fini(&dest_rect); pixman_region32_init(&src_rect); - pixman_region32_intersect(&src_rect, &es->transform.boundingbox, + pixman_region32_intersect(&src_rect, &ev->transform.boundingbox, &output_base->region); box = pixman_region32_extents(&src_rect); - weston_surface_from_global_fixed(es, - wl_fixed_from_int(box->x1), - wl_fixed_from_int(box->y1), - &sx1, &sy1); - weston_surface_from_global_fixed(es, - wl_fixed_from_int(box->x2), - wl_fixed_from_int(box->y2), - &sx2, &sy2); + weston_view_from_global_fixed(ev, + wl_fixed_from_int(box->x1), + wl_fixed_from_int(box->y1), + &sx1, &sy1); + weston_view_from_global_fixed(ev, + wl_fixed_from_int(box->x2), + wl_fixed_from_int(box->y2), + &sx2, &sy2); if (sx1 < 0) sx1 = 0; if (sy1 < 0) sy1 = 0; - if (sx2 > wl_fixed_from_int(es->geometry.width)) - sx2 = wl_fixed_from_int(es->geometry.width); - if (sy2 > wl_fixed_from_int(es->geometry.height)) - sy2 = wl_fixed_from_int(es->geometry.height); + if (sx2 > wl_fixed_from_int(ev->geometry.width)) + sx2 = wl_fixed_from_int(ev->geometry.width); + if (sy2 > wl_fixed_from_int(ev->geometry.height)) + sy2 = wl_fixed_from_int(ev->geometry.height); tbox.x1 = sx1; tbox.y1 = sy1; tbox.x2 = sx2; tbox.y2 = sy2; - tbox = weston_transformed_rect(wl_fixed_from_int(es->geometry.width), - wl_fixed_from_int(es->geometry.height), - es->buffer_transform, es->buffer_scale, tbox); + tbox = weston_transformed_rect(wl_fixed_from_int(ev->geometry.width), + wl_fixed_from_int(ev->geometry.height), + ev->surface->buffer_transform, + ev->surface->buffer_scale, tbox); s->src_x = tbox.x1 << 8; s->src_y = tbox.y1 << 8; @@ -942,8 +943,8 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, } static struct weston_plane * -drm_output_prepare_cursor_surface(struct weston_output *output_base, - struct weston_surface *es) +drm_output_prepare_cursor_view(struct weston_output *output_base, + struct weston_view *ev) { struct drm_compositor *c = (struct drm_compositor *) output_base->compositor; @@ -953,18 +954,18 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base, return NULL; if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL) return NULL; - if (output->cursor_surface) + if (output->cursor_view) return NULL; - if (es->output_mask != (1u << output_base->id)) + if (ev->output_mask != (1u << output_base->id)) return NULL; if (c->cursors_are_broken) return NULL; - if (es->buffer_ref.buffer == NULL || - !wl_shm_buffer_get(es->buffer_ref.buffer->resource) || - es->geometry.width > 64 || es->geometry.height > 64) + if (ev->surface->buffer_ref.buffer == NULL || + !wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) || + ev->geometry.width > 64 || ev->geometry.height > 64) return NULL; - output->cursor_surface = es; + output->cursor_view = ev; return &output->cursor_plane; } @@ -972,7 +973,7 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base, static void drm_output_set_cursor(struct drm_output *output) { - struct weston_surface *es = output->cursor_surface; + struct weston_view *ev = output->cursor_view; struct drm_compositor *c = (struct drm_compositor *) output->base.compositor; EGLint handle, stride; @@ -981,24 +982,24 @@ drm_output_set_cursor(struct drm_output *output) unsigned char *s; int i, x, y; - output->cursor_surface = NULL; - if (es == NULL) { + output->cursor_view = NULL; + if (ev == NULL) { drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0); return; } - if (es->buffer_ref.buffer && + if (ev->surface->buffer_ref.buffer && pixman_region32_not_empty(&output->cursor_plane.damage)) { pixman_region32_fini(&output->cursor_plane.damage); pixman_region32_init(&output->cursor_plane.damage); output->current_cursor ^= 1; bo = output->cursor_bo[output->current_cursor]; memset(buf, 0, sizeof buf); - stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer); - s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer); - for (i = 0; i < es->geometry.height; i++) + stride = wl_shm_buffer_get_stride(ev->surface->buffer_ref.buffer->shm_buffer); + s = wl_shm_buffer_get_data(ev->surface->buffer_ref.buffer->shm_buffer); + for (i = 0; i < ev->geometry.height; i++) memcpy(buf + i * 64, s + i * stride, - es->geometry.width * 4); + ev->geometry.width * 4); if (gbm_bo_write(bo, buf, sizeof buf) < 0) weston_log("failed update cursor: %m\n"); @@ -1011,8 +1012,8 @@ drm_output_set_cursor(struct drm_output *output) } } - x = (es->geometry.x - output->base.x) * output->base.current_scale; - y = (es->geometry.y - output->base.y) * output->base.current_scale; + x = (ev->geometry.x - output->base.x) * output->base.current_scale; + y = (ev->geometry.y - output->base.y) * output->base.current_scale; if (output->cursor_plane.x != x || output->cursor_plane.y != y) { if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) { weston_log("failed to move cursor: %m\n"); @@ -1029,7 +1030,7 @@ drm_assign_planes(struct weston_output *output) { struct drm_compositor *c = (struct drm_compositor *) output->compositor; - struct weston_surface *es, *next; + struct weston_view *ev, *next; pixman_region32_t overlap, surface_overlap; struct weston_plane *primary, *next_plane; @@ -1048,36 +1049,39 @@ drm_assign_planes(struct weston_output *output) */ pixman_region32_init(&overlap); primary = &c->base.primary_plane; - wl_list_for_each_safe(es, next, &c->base.surface_list, link) { + + /* 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 */ - if ((es->buffer_ref.buffer && - !wl_shm_buffer_get(es->buffer_ref.buffer->resource)) || - (es->geometry.width <= 64 && es->geometry.height <= 64)) - es->keep_buffer = 1; - else - es->keep_buffer = 0; + 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; pixman_region32_init(&surface_overlap); pixman_region32_intersect(&surface_overlap, &overlap, - &es->transform.boundingbox); + &ev->transform.boundingbox); next_plane = NULL; if (pixman_region32_not_empty(&surface_overlap)) next_plane = primary; if (next_plane == NULL) - next_plane = drm_output_prepare_cursor_surface(output, es); + next_plane = drm_output_prepare_cursor_view(output, ev); if (next_plane == NULL) - next_plane = drm_output_prepare_scanout_surface(output, es); + next_plane = drm_output_prepare_scanout_view(output, ev); if (next_plane == NULL) - next_plane = drm_output_prepare_overlay_surface(output, es); + next_plane = drm_output_prepare_overlay_view(output, ev); if (next_plane == NULL) next_plane = primary; - weston_surface_move_to_plane(es, next_plane); + weston_view_move_to_plane(ev, next_plane); if (next_plane == primary) pixman_region32_union(&overlap, &overlap, - &es->transform.boundingbox); + &ev->transform.boundingbox); pixman_region32_fini(&surface_overlap); } diff --git a/src/compositor.c b/src/compositor.c index 3a028bc2..11f582e7 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -93,7 +93,7 @@ weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale); static void -weston_compositor_build_surface_list(struct weston_compositor *compositor); +weston_compositor_build_view_list(struct weston_compositor *compositor); WL_EXPORT int weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode, @@ -347,6 +347,50 @@ region_init_infinite(pixman_region32_t *region) static struct weston_subsurface * weston_surface_to_subsurface(struct weston_surface *surface); +WL_EXPORT struct weston_view * +weston_view_create(struct weston_surface *surface) +{ + struct weston_view *view; + + view = calloc(1, sizeof *view); + if (view == NULL) + return NULL; + + view->surface = surface; + + if (surface->compositor->renderer->create_view && + surface->compositor->renderer->create_view(view) < 0) { + free(view); + return NULL; + } + + /* Assign to surface */ + wl_list_insert(&surface->views, &view->surface_link); + + wl_signal_init(&view->destroy_signal); + wl_list_init(&view->link); + wl_list_init(&view->layer_link); + + view->plane = &surface->compositor->primary_plane; + + pixman_region32_init(&view->clip); + + view->alpha = 1.0; + pixman_region32_init(&view->transform.opaque); + + wl_list_init(&view->geometry.transformation_list); + wl_list_insert(&view->geometry.transformation_list, + &view->transform.position.link); + weston_matrix_init(&view->transform.position.matrix); + wl_list_init(&view->geometry.child_list); + pixman_region32_init(&view->transform.boundingbox); + view->transform.dirty = 1; + + view->output = NULL; + + return view; +} + WL_EXPORT struct weston_surface * weston_surface_create(struct weston_compositor *compositor) { @@ -360,11 +404,7 @@ weston_surface_create(struct weston_compositor *compositor) surface->resource = NULL; - wl_list_init(&surface->link); - wl_list_init(&surface->layer_link); - surface->compositor = compositor; - surface->alpha = 1.0; surface->ref_count = 1; if (compositor->renderer->create_surface(surface) < 0) { @@ -377,23 +417,15 @@ weston_surface_create(struct weston_compositor *compositor) surface->pending.buffer_transform = surface->buffer_transform; surface->pending.buffer_scale = surface->buffer_scale; surface->output = NULL; - surface->plane = &compositor->primary_plane; surface->pending.newly_attached = 0; pixman_region32_init(&surface->damage); pixman_region32_init(&surface->opaque); - pixman_region32_init(&surface->clip); region_init_infinite(&surface->input); - pixman_region32_init(&surface->transform.opaque); - wl_list_init(&surface->frame_callback_list); - wl_list_init(&surface->geometry.transformation_list); - wl_list_insert(&surface->geometry.transformation_list, - &surface->transform.position.link); - weston_matrix_init(&surface->transform.position.matrix); - wl_list_init(&surface->geometry.child_list); - pixman_region32_init(&surface->transform.boundingbox); - surface->transform.dirty = 1; + wl_list_init(&surface->views); + + wl_list_init(&surface->frame_callback_list); surface->pending.buffer_destroy_listener.notify = surface_handle_pending_buffer_destroy; @@ -416,13 +448,13 @@ weston_surface_set_color(struct weston_surface *surface, } WL_EXPORT void -weston_surface_to_global_float(struct weston_surface *surface, - float sx, float sy, float *x, float *y) +weston_view_to_global_float(struct weston_view *view, + float sx, float sy, float *x, float *y) { - if (surface->transform.enabled) { + if (view->transform.enabled) { struct weston_vector v = { { sx, sy, 0.0f, 1.0f } }; - weston_matrix_transform(&surface->transform.matrix, &v); + weston_matrix_transform(&view->transform.matrix, &v); if (fabsf(v.f[3]) < 1e-6) { weston_log("warning: numerical instability in " @@ -436,8 +468,8 @@ weston_surface_to_global_float(struct weston_surface *surface, *x = v.f[0] / v.f[3]; *y = v.f[1] / v.f[3]; } else { - *x = sx + surface->geometry.x; - *y = sy + surface->geometry.y; + *x = sx + view->geometry.x; + *y = sy + view->geometry.y; } } @@ -525,8 +557,8 @@ WL_EXPORT void weston_surface_to_buffer_float(struct weston_surface *surface, float sx, float sy, float *bx, float *by) { - weston_transformed_coord(surface->geometry.width, - surface->geometry.height, + weston_transformed_coord(surface->width, + surface->height, surface->buffer_transform, surface->buffer_scale, sx, sy, bx, by); @@ -538,8 +570,8 @@ weston_surface_to_buffer(struct weston_surface *surface, { float bxf, byf; - weston_transformed_coord(surface->geometry.width, - surface->geometry.height, + weston_transformed_coord(surface->width, + surface->height, surface->buffer_transform, surface->buffer_scale, sx, sy, &bxf, &byf); @@ -551,35 +583,35 @@ WL_EXPORT pixman_box32_t weston_surface_to_buffer_rect(struct weston_surface *surface, pixman_box32_t rect) { - return weston_transformed_rect(surface->geometry.width, - surface->geometry.height, + return weston_transformed_rect(surface->width, + surface->height, surface->buffer_transform, surface->buffer_scale, rect); } WL_EXPORT void -weston_surface_move_to_plane(struct weston_surface *surface, +weston_view_move_to_plane(struct weston_view *view, struct weston_plane *plane) { - if (surface->plane == plane) + if (view->plane == plane) return; - weston_surface_damage_below(surface); - surface->plane = plane; - weston_surface_damage(surface); + weston_view_damage_below(view); + view->plane = plane; + weston_surface_damage(view->surface); } WL_EXPORT void -weston_surface_damage_below(struct weston_surface *surface) +weston_view_damage_below(struct weston_view *view) { pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_subtract(&damage, &surface->transform.boundingbox, - &surface->clip); - pixman_region32_union(&surface->plane->damage, - &surface->plane->damage, &damage); + pixman_region32_subtract(&damage, &view->transform.boundingbox, + &view->clip); + pixman_region32_union(&view->plane->damage, + &view->plane->damage, &damage); pixman_region32_fini(&damage); } @@ -618,7 +650,43 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask) static void weston_surface_assign_output(struct weston_surface *es) { - struct weston_compositor *ec = es->compositor; + struct weston_output *new_output; + struct weston_view *view; + pixman_region32_t region; + uint32_t max, area, mask; + pixman_box32_t *e; + + new_output = NULL; + max = 0; + mask = 0; + pixman_region32_init(®ion); + wl_list_for_each(view, &es->views, surface_link) { + if (!view->output) + continue; + + pixman_region32_intersect(®ion, &view->transform.boundingbox, + &view->output->region); + + e = pixman_region32_extents(®ion); + area = (e->x2 - e->x1) * (e->y2 - e->y1); + + mask |= view->output_mask; + + if (area >= max) { + new_output = view->output; + max = area; + } + } + pixman_region32_fini(®ion); + + es->output = new_output; + weston_surface_update_output_mask(es, mask); +} + +static void +weston_view_assign_output(struct weston_view *ev) +{ + struct weston_compositor *ec = ev->surface->compositor; struct weston_output *output, *new_output; pixman_region32_t region; uint32_t max, area, mask; @@ -629,7 +697,7 @@ weston_surface_assign_output(struct weston_surface *es) mask = 0; pixman_region32_init(®ion); wl_list_for_each(output, &ec->output_list, link) { - pixman_region32_intersect(®ion, &es->transform.boundingbox, + pixman_region32_intersect(®ion, &ev->transform.boundingbox, &output->region); e = pixman_region32_extents(®ion); @@ -645,14 +713,16 @@ weston_surface_assign_output(struct weston_surface *es) } pixman_region32_fini(®ion); - es->output = new_output; - weston_surface_update_output_mask(es, mask); + ev->output = new_output; + ev->output_mask = mask; + + weston_surface_assign_output(ev->surface); } static void -surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy, - int32_t width, int32_t height, - pixman_region32_t *bbox) +view_compute_bbox(struct weston_view *view, int32_t sx, int32_t sy, + int32_t width, int32_t height, + pixman_region32_t *bbox) { float min_x = HUGE_VALF, min_y = HUGE_VALF; float max_x = -HUGE_VALF, max_y = -HUGE_VALF; @@ -673,8 +743,7 @@ surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy, for (i = 0; i < 4; ++i) { float x, y; - weston_surface_to_global_float(surface, - s[i][0], s[i][1], &x, &y); + weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y); if (x < min_x) min_x = x; if (x > max_x) @@ -692,57 +761,57 @@ surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy, } static void -weston_surface_update_transform_disable(struct weston_surface *surface) +weston_view_update_transform_disable(struct weston_view *view) { - surface->transform.enabled = 0; + view->transform.enabled = 0; /* round off fractions when not transformed */ - surface->geometry.x = roundf(surface->geometry.x); - surface->geometry.y = roundf(surface->geometry.y); + view->geometry.x = roundf(view->geometry.x); + view->geometry.y = roundf(view->geometry.y); /* Otherwise identity matrix, but with x and y translation. */ - surface->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE; - surface->transform.position.matrix.d[12] = surface->geometry.x; - surface->transform.position.matrix.d[13] = surface->geometry.y; + view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE; + view->transform.position.matrix.d[12] = view->geometry.x; + view->transform.position.matrix.d[13] = view->geometry.y; - surface->transform.matrix = surface->transform.position.matrix; + view->transform.matrix = view->transform.position.matrix; - surface->transform.inverse = surface->transform.position.matrix; - surface->transform.inverse.d[12] = -surface->geometry.x; - surface->transform.inverse.d[13] = -surface->geometry.y; + view->transform.inverse = view->transform.position.matrix; + view->transform.inverse.d[12] = -view->geometry.x; + view->transform.inverse.d[13] = -view->geometry.y; - pixman_region32_init_rect(&surface->transform.boundingbox, - surface->geometry.x, - surface->geometry.y, - surface->geometry.width, - surface->geometry.height); + pixman_region32_init_rect(&view->transform.boundingbox, + view->geometry.x, + view->geometry.y, + view->geometry.width, + view->geometry.height); - if (surface->alpha == 1.0) { - pixman_region32_copy(&surface->transform.opaque, - &surface->opaque); - pixman_region32_translate(&surface->transform.opaque, - surface->geometry.x, - surface->geometry.y); + if (view->alpha == 1.0) { + pixman_region32_copy(&view->transform.opaque, + &view->surface->opaque); + pixman_region32_translate(&view->transform.opaque, + view->geometry.x, + view->geometry.y); } } static int -weston_surface_update_transform_enable(struct weston_surface *surface) +weston_view_update_transform_enable(struct weston_view *view) { - struct weston_surface *parent = surface->geometry.parent; - struct weston_matrix *matrix = &surface->transform.matrix; - struct weston_matrix *inverse = &surface->transform.inverse; + struct weston_view *parent = view->geometry.parent; + struct weston_matrix *matrix = &view->transform.matrix; + struct weston_matrix *inverse = &view->transform.inverse; struct weston_transform *tform; - surface->transform.enabled = 1; + view->transform.enabled = 1; /* Otherwise identity matrix, but with x and y translation. */ - surface->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE; - surface->transform.position.matrix.d[12] = surface->geometry.x; - surface->transform.position.matrix.d[13] = surface->geometry.y; + view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE; + view->transform.position.matrix.d[12] = view->geometry.x; + view->transform.position.matrix.d[13] = view->geometry.y; weston_matrix_init(matrix); - wl_list_for_each(tform, &surface->geometry.transformation_list, link) + wl_list_for_each(tform, &view->geometry.transformation_list, link) weston_matrix_multiply(matrix, &tform->matrix); if (parent) @@ -750,143 +819,144 @@ weston_surface_update_transform_enable(struct weston_surface *surface) if (weston_matrix_invert(inverse, matrix) < 0) { /* Oops, bad total transformation, not invertible */ - weston_log("error: weston_surface %p" - " transformation not invertible.\n", surface); + weston_log("error: weston_view %p" + " transformation not invertible.\n", view); return -1; } - surface_compute_bbox(surface, 0, 0, surface->geometry.width, - surface->geometry.height, - &surface->transform.boundingbox); + view_compute_bbox(view, 0, 0, view->geometry.width, + view->geometry.height, + &view->transform.boundingbox); return 0; } WL_EXPORT void -weston_surface_update_transform(struct weston_surface *surface) +weston_view_update_transform(struct weston_view *view) { - struct weston_surface *parent = surface->geometry.parent; + struct weston_view *parent = view->geometry.parent; - if (!surface->transform.dirty) + if (!view->transform.dirty) return; if (parent) - weston_surface_update_transform(parent); + weston_view_update_transform(parent); - surface->transform.dirty = 0; + view->transform.dirty = 0; - weston_surface_damage_below(surface); + weston_view_damage_below(view); - pixman_region32_fini(&surface->transform.boundingbox); - pixman_region32_fini(&surface->transform.opaque); - pixman_region32_init(&surface->transform.opaque); + pixman_region32_fini(&view->transform.boundingbox); + pixman_region32_fini(&view->transform.opaque); + pixman_region32_init(&view->transform.opaque); /* transform.position is always in transformation_list */ - if (surface->geometry.transformation_list.next == - &surface->transform.position.link && - surface->geometry.transformation_list.prev == - &surface->transform.position.link && + if (view->geometry.transformation_list.next == + &view->transform.position.link && + view->geometry.transformation_list.prev == + &view->transform.position.link && !parent) { - weston_surface_update_transform_disable(surface); + weston_view_update_transform_disable(view); } else { - if (weston_surface_update_transform_enable(surface) < 0) - weston_surface_update_transform_disable(surface); + if (weston_view_update_transform_enable(view) < 0) + weston_view_update_transform_disable(view); } - weston_surface_damage_below(surface); + weston_view_damage_below(view); - weston_surface_assign_output(surface); + weston_view_assign_output(view); - wl_signal_emit(&surface->compositor->transform_signal, surface); + wl_signal_emit(&view->surface->compositor->transform_signal, + view->surface); } WL_EXPORT void -weston_surface_geometry_dirty(struct weston_surface *surface) +weston_view_geometry_dirty(struct weston_view *view) { - struct weston_surface *child; + struct weston_view *child; /* - * The invariant: if surface->geometry.dirty, then all surfaces - * in surface->geometry.child_list have geometry.dirty too. + * The invariant: if view->geometry.dirty, then all views + * in view->geometry.child_list have geometry.dirty too. * Corollary: if not parent->geometry.dirty, then all ancestors * are not dirty. */ - if (surface->transform.dirty) + if (view->transform.dirty) return; - surface->transform.dirty = 1; + view->transform.dirty = 1; - wl_list_for_each(child, &surface->geometry.child_list, + wl_list_for_each(child, &view->geometry.child_list, geometry.parent_link) - weston_surface_geometry_dirty(child); + weston_view_geometry_dirty(child); } WL_EXPORT void -weston_surface_to_global_fixed(struct weston_surface *surface, - wl_fixed_t sx, wl_fixed_t sy, - wl_fixed_t *x, wl_fixed_t *y) +weston_view_to_global_fixed(struct weston_view *view, + wl_fixed_t vx, wl_fixed_t vy, + wl_fixed_t *x, wl_fixed_t *y) { float xf, yf; - weston_surface_to_global_float(surface, - wl_fixed_to_double(sx), - wl_fixed_to_double(sy), - &xf, &yf); + weston_view_to_global_float(view, + wl_fixed_to_double(vx), + wl_fixed_to_double(vy), + &xf, &yf); *x = wl_fixed_from_double(xf); *y = wl_fixed_from_double(yf); } WL_EXPORT void -weston_surface_from_global_float(struct weston_surface *surface, - float x, float y, float *sx, float *sy) +weston_view_from_global_float(struct weston_view *view, + float x, float y, float *vx, float *vy) { - if (surface->transform.enabled) { + if (view->transform.enabled) { struct weston_vector v = { { x, y, 0.0f, 1.0f } }; - weston_matrix_transform(&surface->transform.inverse, &v); + weston_matrix_transform(&view->transform.inverse, &v); if (fabsf(v.f[3]) < 1e-6) { weston_log("warning: numerical instability in " - "weston_surface_from_global(), divisor = %g\n", + "weston_view_from_global(), divisor = %g\n", v.f[3]); - *sx = 0; - *sy = 0; + *vx = 0; + *vy = 0; return; } - *sx = v.f[0] / v.f[3]; - *sy = v.f[1] / v.f[3]; + *vx = v.f[0] / v.f[3]; + *vy = v.f[1] / v.f[3]; } else { - *sx = x - surface->geometry.x; - *sy = y - surface->geometry.y; + *vx = x - view->geometry.x; + *vy = y - view->geometry.y; } } WL_EXPORT void -weston_surface_from_global_fixed(struct weston_surface *surface, - wl_fixed_t x, wl_fixed_t y, - wl_fixed_t *sx, wl_fixed_t *sy) +weston_view_from_global_fixed(struct weston_view *view, + wl_fixed_t x, wl_fixed_t y, + wl_fixed_t *vx, wl_fixed_t *vy) { - float sxf, syf; + float vxf, vyf; - weston_surface_from_global_float(surface, - wl_fixed_to_double(x), - wl_fixed_to_double(y), - &sxf, &syf); - *sx = wl_fixed_from_double(sxf); - *sy = wl_fixed_from_double(syf); + weston_view_from_global_float(view, + wl_fixed_to_double(x), + wl_fixed_to_double(y), + &vxf, &vyf); + *vx = wl_fixed_from_double(vxf); + *vy = wl_fixed_from_double(vyf); } WL_EXPORT void -weston_surface_from_global(struct weston_surface *surface, - int32_t x, int32_t y, int32_t *sx, int32_t *sy) +weston_view_from_global(struct weston_view *view, + int32_t x, int32_t y, int32_t *vx, int32_t *vy) { - float sxf, syf; + float vxf, vyf; - weston_surface_from_global_float(surface, x, y, &sxf, &syf); - *sx = floorf(sxf); - *sy = floorf(syf); + weston_view_from_global_float(view, x, y, &vxf, &vyf); + *vx = floorf(vxf); + *vy = floorf(vyf); } WL_EXPORT void @@ -899,68 +969,86 @@ weston_surface_schedule_repaint(struct weston_surface *surface) weston_output_schedule_repaint(output); } +WL_EXPORT void +weston_view_schedule_repaint(struct weston_view *view) +{ + struct weston_output *output; + + wl_list_for_each(output, &view->surface->compositor->output_list, link) + if (view->output_mask & (1 << output->id)) + weston_output_schedule_repaint(output); +} + WL_EXPORT void weston_surface_damage(struct weston_surface *surface) { pixman_region32_union_rect(&surface->damage, &surface->damage, - 0, 0, surface->geometry.width, - surface->geometry.height); + 0, 0, surface->width, + surface->height); weston_surface_schedule_repaint(surface); } WL_EXPORT void -weston_surface_configure(struct weston_surface *surface, - float x, float y, int width, int height) +weston_view_configure(struct weston_view *view, + float x, float y, int width, int height) { - surface->geometry.x = x; - surface->geometry.y = y; - surface->geometry.width = width; - surface->geometry.height = height; - weston_surface_geometry_dirty(surface); + view->geometry.x = x; + view->geometry.y = y; + view->geometry.width = width; + view->geometry.height = height; + weston_view_geometry_dirty(view); } WL_EXPORT void -weston_surface_set_position(struct weston_surface *surface, - float x, float y) +weston_view_set_position(struct weston_view *view, float x, float y) { - surface->geometry.x = x; - surface->geometry.y = y; - weston_surface_geometry_dirty(surface); + view->geometry.x = x; + view->geometry.y = y; + weston_view_geometry_dirty(view); } static void transform_parent_handle_parent_destroy(struct wl_listener *listener, void *data) { - struct weston_surface *surface = - container_of(listener, struct weston_surface, + struct weston_view *view = + container_of(listener, struct weston_view, geometry.parent_destroy_listener); - weston_surface_set_transform_parent(surface, NULL); + weston_view_set_transform_parent(view, NULL); } WL_EXPORT void -weston_surface_set_transform_parent(struct weston_surface *surface, - struct weston_surface *parent) +weston_view_set_transform_parent(struct weston_view *view, + struct weston_view *parent) { - if (surface->geometry.parent) { - wl_list_remove(&surface->geometry.parent_destroy_listener.link); - wl_list_remove(&surface->geometry.parent_link); + if (view->geometry.parent) { + wl_list_remove(&view->geometry.parent_destroy_listener.link); + wl_list_remove(&view->geometry.parent_link); } - surface->geometry.parent = parent; + view->geometry.parent = parent; - surface->geometry.parent_destroy_listener.notify = + view->geometry.parent_destroy_listener.notify = transform_parent_handle_parent_destroy; if (parent) { wl_signal_add(&parent->destroy_signal, - &surface->geometry.parent_destroy_listener); + &view->geometry.parent_destroy_listener); wl_list_insert(&parent->geometry.child_list, - &surface->geometry.parent_link); + &view->geometry.parent_link); } - weston_surface_geometry_dirty(surface); + weston_view_geometry_dirty(view); +} + +WL_EXPORT int +weston_view_is_mapped(struct weston_view *view) +{ + if (view->output) + return 1; + else + return 0; } WL_EXPORT int @@ -1018,20 +1106,20 @@ weston_compositor_get_time(void) return tv.tv_sec * 1000 + tv.tv_usec / 1000; } -WL_EXPORT struct weston_surface * -weston_compositor_pick_surface(struct weston_compositor *compositor, - wl_fixed_t x, wl_fixed_t y, - wl_fixed_t *sx, wl_fixed_t *sy) +WL_EXPORT struct weston_view * +weston_compositor_pick_view(struct weston_compositor *compositor, + wl_fixed_t x, wl_fixed_t y, + wl_fixed_t *vx, wl_fixed_t *vy) { - struct weston_surface *surface; + struct weston_view *view; - wl_list_for_each(surface, &compositor->surface_list, link) { - weston_surface_from_global_fixed(surface, x, y, sx, sy); - if (pixman_region32_contains_point(&surface->input, - wl_fixed_to_int(*sx), - wl_fixed_to_int(*sy), + wl_list_for_each(view, &compositor->view_list, link) { + weston_view_from_global_fixed(view, x, y, vx, vy); + if (pixman_region32_contains_point(&view->surface->input, + wl_fixed_to_int(*vx), + wl_fixed_to_int(*vy), NULL)) - return surface; + return view; } return NULL; @@ -1050,29 +1138,48 @@ weston_compositor_repick(struct weston_compositor *compositor) } WL_EXPORT void -weston_surface_unmap(struct weston_surface *surface) +weston_view_unmap(struct weston_view *view) { struct weston_seat *seat; - weston_surface_damage_below(surface); - surface->output = NULL; - wl_list_remove(&surface->layer_link); - wl_list_remove(&surface->link); - wl_list_init(&surface->link); + if (!weston_view_is_mapped(view)) + return; + + weston_view_damage_below(view); + view->output = NULL; + wl_list_remove(&view->layer_link); + wl_list_init(&view->layer_link); + wl_list_remove(&view->link); + wl_list_init(&view->link); + /* We need to do this before torching the output mask */ + weston_view_schedule_repaint(view); + view->output_mask = 0; + weston_surface_assign_output(view->surface); + + if (weston_surface_is_mapped(view->surface)) + return; - wl_list_for_each(seat, &surface->compositor->seat_list, link) { - if (seat->keyboard && seat->keyboard->focus == surface) + wl_list_for_each(seat, &view->surface->compositor->seat_list, link) { + if (seat->keyboard && seat->keyboard->focus == view->surface) weston_keyboard_set_focus(seat->keyboard, NULL); - if (seat->pointer && seat->pointer->focus == surface) + if (seat->pointer && seat->pointer->focus == view) weston_pointer_set_focus(seat->pointer, NULL, wl_fixed_from_int(0), wl_fixed_from_int(0)); - if (seat->touch && seat->touch->focus == surface) + if (seat->touch && seat->touch->focus == view) weston_touch_set_focus(seat, NULL); } +} - weston_surface_schedule_repaint(surface); +WL_EXPORT void +weston_surface_unmap(struct weston_surface *surface) +{ + struct weston_view *view; + + wl_list_for_each(view, &surface->views, surface_link) + weston_view_unmap(view); + surface->output = NULL; } struct weston_frame_callback { @@ -1080,24 +1187,51 @@ struct weston_frame_callback { struct wl_list link; }; +WL_EXPORT void +weston_view_destroy(struct weston_view *view) +{ + wl_signal_emit(&view->destroy_signal, view); + + assert(wl_list_empty(&view->geometry.child_list)); + + if (weston_view_is_mapped(view)) { + weston_view_unmap(view); + weston_compositor_build_view_list(view->surface->compositor); + } + + wl_list_remove(&view->link); + wl_list_remove(&view->layer_link); + + pixman_region32_fini(&view->clip); + pixman_region32_fini(&view->transform.boundingbox); + + weston_view_set_transform_parent(view, NULL); + + if (view->surface->compositor->renderer->destroy_view) + view->surface->compositor->renderer->destroy_view(view); + + wl_list_remove(&view->surface_link); + + free(view); +} WL_EXPORT void weston_surface_destroy(struct weston_surface *surface) { struct weston_compositor *compositor = surface->compositor; struct weston_frame_callback *cb, *next; + struct weston_view *ev, *nv; if (--surface->ref_count > 0) return; wl_signal_emit(&surface->destroy_signal, &surface->resource); - assert(wl_list_empty(&surface->geometry.child_list)); assert(wl_list_empty(&surface->subsurface_list_pending)); assert(wl_list_empty(&surface->subsurface_list)); - if (weston_surface_is_mapped(surface)) - weston_surface_unmap(surface); + wl_list_for_each_safe(ev, nv, &surface->views, surface_link) + weston_view_destroy(ev); wl_list_for_each_safe(cb, next, &surface->pending.frame_callback_list, link) @@ -1114,17 +1248,13 @@ weston_surface_destroy(struct weston_surface *surface) compositor->renderer->destroy_surface(surface); - pixman_region32_fini(&surface->transform.boundingbox); pixman_region32_fini(&surface->damage); pixman_region32_fini(&surface->opaque); - pixman_region32_fini(&surface->clip); pixman_region32_fini(&surface->input); wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link) wl_resource_destroy(cb->resource); - weston_surface_set_transform_parent(surface, NULL); - free(surface); } @@ -1223,12 +1353,12 @@ weston_surface_attach(struct weston_surface *surface, } WL_EXPORT void -weston_surface_restack(struct weston_surface *surface, struct wl_list *below) +weston_view_restack(struct weston_view *view, struct wl_list *below) { - wl_list_remove(&surface->layer_link); - wl_list_insert(below, &surface->layer_link); - weston_surface_damage_below(surface); - weston_surface_damage(surface); + wl_list_remove(&view->layer_link); + wl_list_insert(below, &view->layer_link); + weston_view_damage_below(view); + weston_surface_damage(view->surface); } WL_EXPORT void @@ -1252,43 +1382,53 @@ weston_output_damage(struct weston_output *output) } static void -surface_accumulate_damage(struct weston_surface *surface, - pixman_region32_t *opaque) +surface_flush_damage(struct weston_surface *surface) { if (surface->buffer_ref.buffer && wl_shm_buffer_get(surface->buffer_ref.buffer->resource)) surface->compositor->renderer->flush_damage(surface); - if (surface->transform.enabled) { + empty_region(&surface->damage); +} + +static void +view_accumulate_damage(struct weston_view *view, + pixman_region32_t *opaque) +{ + pixman_region32_t damage; + + pixman_region32_init(&damage); + if (view->transform.enabled) { pixman_box32_t *extents; - extents = pixman_region32_extents(&surface->damage); - surface_compute_bbox(surface, extents->x1, extents->y1, - extents->x2 - extents->x1, - extents->y2 - extents->y1, - &surface->damage); - pixman_region32_translate(&surface->damage, - -surface->plane->x, - -surface->plane->y); + extents = pixman_region32_extents(&view->surface->damage); + view_compute_bbox(view, extents->x1, extents->y1, + extents->x2 - extents->x1, + extents->y2 - extents->y1, + &damage); + pixman_region32_translate(&damage, + -view->plane->x, + -view->plane->y); } else { - pixman_region32_translate(&surface->damage, - surface->geometry.x - surface->plane->x, - surface->geometry.y - surface->plane->y); + pixman_region32_copy(&damage, &view->surface->damage); + pixman_region32_translate(&damage, + view->geometry.x - view->plane->x, + view->geometry.y - view->plane->y); } - pixman_region32_subtract(&surface->damage, &surface->damage, opaque); - pixman_region32_union(&surface->plane->damage, - &surface->plane->damage, &surface->damage); - empty_region(&surface->damage); - pixman_region32_copy(&surface->clip, opaque); - pixman_region32_union(opaque, opaque, &surface->transform.opaque); + pixman_region32_subtract(&damage, &damage, opaque); + pixman_region32_union(&view->plane->damage, + &view->plane->damage, &damage); + pixman_region32_fini(&damage); + pixman_region32_copy(&view->clip, opaque); + pixman_region32_union(opaque, opaque, &view->transform.opaque); } static void compositor_accumulate_damage(struct weston_compositor *ec) { struct weston_plane *plane; - struct weston_surface *es; + struct weston_view *ev; pixman_region32_t opaque, clip; pixman_region32_init(&clip); @@ -1298,11 +1438,11 @@ compositor_accumulate_damage(struct weston_compositor *ec) pixman_region32_init(&opaque); - wl_list_for_each(es, &ec->surface_list, link) { - if (es->plane != plane) + wl_list_for_each(ev, &ec->view_list, link) { + if (ev->plane != plane) continue; - surface_accumulate_damage(es, &opaque); + view_accumulate_damage(ev, &opaque); } pixman_region32_union(&clip, &clip, &opaque); @@ -1311,7 +1451,16 @@ compositor_accumulate_damage(struct weston_compositor *ec) pixman_region32_fini(&clip); - wl_list_for_each(es, &ec->surface_list, link) { + wl_list_for_each(ev, &ec->view_list, link) + ev->surface->touched = 0; + + wl_list_for_each(ev, &ec->view_list, link) { + if (ev->surface->touched) + continue; + ev->surface->touched = 1; + + surface_flush_damage(ev->surface); + /* Both the renderer and the backend have seen the buffer * by now. If renderer needs the buffer, it has its own * reference set. If the backend wants to keep the buffer @@ -1320,56 +1469,122 @@ compositor_accumulate_damage(struct weston_compositor *ec) * reference now, and allow early buffer release. This enables * clients to use single-buffering. */ - if (!es->keep_buffer) - weston_buffer_reference(&es->buffer_ref, NULL); + if (!ev->surface->keep_buffer) + weston_buffer_reference(&ev->surface->buffer_ref, NULL); } } static void -surface_list_add(struct weston_compositor *compositor, - struct weston_surface *surface) +surface_stash_subsurface_views(struct weston_surface *surface) { struct weston_subsurface *sub; - if (wl_list_empty(&surface->subsurface_list)) { - weston_surface_update_transform(surface); - wl_list_insert(compositor->surface_list.prev, &surface->link); - return; + wl_list_for_each(sub, &surface->subsurface_list, parent_link) { + if (sub->surface == surface) + continue; + + wl_list_insert_list(&sub->unused_views, &sub->surface->views); + wl_list_init(&sub->surface->views); + + surface_stash_subsurface_views(sub->surface); } +} + +static void +surface_free_unused_subsurface_views(struct weston_surface *surface) +{ + struct weston_subsurface *sub; + struct weston_view *view, *nv; wl_list_for_each(sub, &surface->subsurface_list, parent_link) { - if (!weston_surface_is_mapped(sub->surface)) + if (sub->surface == surface) continue; - if (sub->surface == surface) { - weston_surface_update_transform(sub->surface); - wl_list_insert(compositor->surface_list.prev, - &sub->surface->link); - } else { - surface_list_add(compositor, sub->surface); + wl_list_for_each_safe(view, nv, &sub->unused_views, surface_link) + weston_view_destroy(view); + + surface_free_unused_subsurface_views(sub->surface); + } +} + +static void +view_list_add_subsurface_view(struct weston_compositor *compositor, + struct weston_subsurface *sub, + struct weston_view *parent) +{ + struct weston_subsurface *child; + struct weston_view *view = NULL, *iv; + + wl_list_for_each(iv, &sub->unused_views, surface_link) { + if (iv->geometry.parent == parent) { + view = iv; + break; } } + + if (view) { + /* Put it back in the surface's list of views */ + wl_list_remove(&view->surface_link); + wl_list_insert(&sub->surface->views, &view->surface_link); + } else { + view = weston_view_create(sub->surface); + weston_view_configure(view, + sub->position.x, + sub->position.y, + sub->surface->width, + sub->surface->height); + weston_view_set_transform_parent(view, parent); + } + + weston_view_update_transform(view); + wl_list_insert(compositor->view_list.next, &view->link); + + wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) + if (child->surface != sub->surface) + view_list_add_subsurface_view(compositor, child, view); } static void -weston_compositor_build_surface_list(struct weston_compositor *compositor) +view_list_add(struct weston_compositor *compositor, + struct weston_view *view) { - struct weston_surface *surface; + struct weston_subsurface *sub; + + weston_view_update_transform(view); + wl_list_insert(compositor->view_list.prev, &view->link); + + wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) + if (sub->surface != view->surface) + view_list_add_subsurface_view(compositor, sub, view); +} + +static void +weston_compositor_build_view_list(struct weston_compositor *compositor) +{ + struct weston_view *view; struct weston_layer *layer; - wl_list_init(&compositor->surface_list); + wl_list_for_each(layer, &compositor->layer_list, link) + wl_list_for_each(view, &layer->view_list, layer_link) + surface_stash_subsurface_views(view->surface); + + wl_list_init(&compositor->view_list); wl_list_for_each(layer, &compositor->layer_list, link) { - wl_list_for_each(surface, &layer->surface_list, layer_link) { - surface_list_add(compositor, surface); + wl_list_for_each(view, &layer->view_list, layer_link) { + view_list_add(compositor, view); } } + + wl_list_for_each(layer, &compositor->layer_list, link) + wl_list_for_each(view, &layer->view_list, layer_link) + surface_free_unused_subsurface_views(view->surface); } static int weston_output_repaint(struct weston_output *output, uint32_t msecs) { struct weston_compositor *ec = output->compositor; - struct weston_surface *es; + struct weston_view *ev; struct weston_animation *animation, *next; struct weston_frame_callback *cb, *cnext; struct wl_list frame_callback_list; @@ -1377,20 +1592,23 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs) int r; /* Rebuild the surface list and update surface transforms up front. */ - weston_compositor_build_surface_list(ec); + weston_compositor_build_view_list(ec); if (output->assign_planes && !output->disable_planes) output->assign_planes(output); else - wl_list_for_each(es, &ec->surface_list, link) - weston_surface_move_to_plane(es, &ec->primary_plane); + wl_list_for_each(ev, &ec->view_list, link) + weston_view_move_to_plane(ev, &ec->primary_plane); wl_list_init(&frame_callback_list); - wl_list_for_each(es, &ec->surface_list, link) { - if (es->output == output) { + wl_list_for_each(ev, &ec->view_list, link) { + /* Note: This operation is safe to do multiple times on the + * same surface. + */ + if (ev->surface->output == output) { wl_list_insert_list(&frame_callback_list, - &es->frame_callback_list); - wl_list_init(&es->frame_callback_list); + &ev->surface->frame_callback_list); + wl_list_init(&ev->surface->frame_callback_list); } } @@ -1476,7 +1694,7 @@ idle_repaint(void *data) WL_EXPORT void weston_layer_init(struct weston_layer *layer, struct wl_list *below) { - wl_list_init(&layer->surface_list); + wl_list_init(&layer->view_list); if (below != NULL) wl_list_insert(below, &layer->link); } @@ -1649,9 +1867,8 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface) static void weston_surface_commit(struct weston_surface *surface) { + struct weston_view *view; pixman_region32_t opaque; - int surface_width = 0; - int surface_height = 0; /* wl_surface.set_buffer_transform */ surface->buffer_transform = surface->pending.buffer_transform; @@ -1663,15 +1880,18 @@ weston_surface_commit(struct weston_surface *surface) if (surface->pending.buffer || surface->pending.newly_attached) weston_surface_attach(surface, surface->pending.buffer); + surface->width = 0; + surface->height = 0; if (surface->buffer_ref.buffer) { - surface_width = weston_surface_buffer_width(surface); - surface_height = weston_surface_buffer_height(surface); + /* This already includes the buffer scale */ + surface->width = weston_surface_buffer_width(surface); + surface->height = weston_surface_buffer_height(surface); } if (surface->configure && surface->pending.newly_attached) surface->configure(surface, surface->pending.sx, surface->pending.sy, - surface_width, surface_height); + surface->width, surface->height); if (surface->pending.buffer) wl_list_remove(&surface->pending.buffer_destroy_listener.link); @@ -1685,20 +1905,21 @@ weston_surface_commit(struct weston_surface *surface) &surface->pending.damage); pixman_region32_intersect_rect(&surface->damage, &surface->damage, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); empty_region(&surface->pending.damage); /* wl_surface.set_opaque_region */ pixman_region32_init_rect(&opaque, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); pixman_region32_intersect(&opaque, &opaque, &surface->pending.opaque); if (!pixman_region32_equal(&opaque, &surface->opaque)) { pixman_region32_copy(&surface->opaque, &opaque); - weston_surface_geometry_dirty(surface); + wl_list_for_each(view, &surface->views, surface_link) + weston_view_geometry_dirty(view); } pixman_region32_fini(&opaque); @@ -1706,8 +1927,8 @@ weston_surface_commit(struct weston_surface *surface) /* wl_surface.set_input_region */ pixman_region32_fini(&surface->input); pixman_region32_init_rect(&surface->input, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); pixman_region32_intersect(&surface->input, &surface->input, &surface->pending.input); @@ -1880,9 +2101,8 @@ static void weston_subsurface_commit_from_cache(struct weston_subsurface *sub) { struct weston_surface *surface = sub->surface; + struct weston_view *view; pixman_region32_t opaque; - int surface_width = 0; - int surface_height = 0; /* wl_surface.set_buffer_transform */ surface->buffer_transform = sub->cached.buffer_transform; @@ -1895,14 +2115,16 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub) weston_surface_attach(surface, sub->cached.buffer_ref.buffer); weston_buffer_reference(&sub->cached.buffer_ref, NULL); + surface->width = 0; + surface->height = 0; if (surface->buffer_ref.buffer) { - surface_width = weston_surface_buffer_width(surface); - surface_height = weston_surface_buffer_height(surface); + surface->width = weston_surface_buffer_width(surface); + surface->height = weston_surface_buffer_height(surface); } if (surface->configure && sub->cached.newly_attached) surface->configure(surface, sub->cached.sx, sub->cached.sy, - surface_width, surface_height); + surface->width, surface->height); sub->cached.sx = 0; sub->cached.sy = 0; sub->cached.newly_attached = 0; @@ -1912,20 +2134,21 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub) &sub->cached.damage); pixman_region32_intersect_rect(&surface->damage, &surface->damage, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); empty_region(&sub->cached.damage); /* wl_surface.set_opaque_region */ pixman_region32_init_rect(&opaque, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); pixman_region32_intersect(&opaque, &opaque, &sub->cached.opaque); if (!pixman_region32_equal(&opaque, &surface->opaque)) { pixman_region32_copy(&surface->opaque, &opaque); - weston_surface_geometry_dirty(surface); + wl_list_for_each(view, &surface->views, surface_link) + weston_view_geometry_dirty(view); } pixman_region32_fini(&opaque); @@ -1933,8 +2156,8 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub) /* wl_surface.set_input_region */ pixman_region32_fini(&surface->input); pixman_region32_init_rect(&surface->input, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); pixman_region32_intersect(&surface->input, &surface->input, &sub->cached.input); @@ -2058,9 +2281,13 @@ static void weston_subsurface_parent_commit(struct weston_subsurface *sub, int parent_is_synchronized) { + struct weston_view *view; if (sub->position.set) { - weston_surface_set_position(sub->surface, - sub->position.x, sub->position.y); + wl_list_for_each(view, &sub->surface->views, surface_link) + weston_view_set_position(view, + sub->position.x, + sub->position.y); + sub->position.set = 0; } @@ -2073,19 +2300,19 @@ subsurface_configure(struct weston_surface *surface, int32_t dx, int32_t dy, int32_t width, int32_t height) { struct weston_compositor *compositor = surface->compositor; + struct weston_view *view; - weston_surface_configure(surface, - surface->geometry.x + dx, - surface->geometry.y + dy, - width, height); + wl_list_for_each(view, &surface->views, surface_link) + weston_view_configure(view, + view->geometry.x + dx, + view->geometry.y + dy, + width, height); /* No need to check parent mappedness, because if parent is not * mapped, parent is not in a visible layer, so this sub-surface * will not be drawn either. */ if (!weston_surface_is_mapped(surface)) { - wl_list_init(&surface->layer_link); - /* Cannot call weston_surface_update_transform(), * because that would call it also for the parent surface, * which might not be mapped yet. That would lead to @@ -2357,6 +2584,8 @@ weston_subsurface_link_surface(struct weston_subsurface *sub, static void weston_subsurface_destroy(struct weston_subsurface *sub) { + struct weston_view *view, *next; + assert(sub->surface); if (sub->resource) { @@ -2364,7 +2593,9 @@ weston_subsurface_destroy(struct weston_subsurface *sub) assert(sub->parent_destroy_listener.notify == subsurface_handle_parent_destroy); - weston_surface_set_transform_parent(sub->surface, NULL); + wl_list_for_each_safe(view, next, &sub->surface->views, surface_link) + weston_view_destroy(view); + if (sub->parent) weston_subsurface_unlink_parent(sub); @@ -2403,6 +2634,8 @@ weston_subsurface_create(uint32_t id, struct weston_surface *surface, if (!sub) return NULL; + wl_list_init(&sub->unused_views); + sub->resource = wl_resource_create(client, &wl_subsurface_interface, 1, id); if (!sub->resource) { @@ -2417,7 +2650,6 @@ weston_subsurface_create(uint32_t id, struct weston_surface *surface, weston_subsurface_link_parent(sub, parent); weston_subsurface_cache_init(sub); sub->synchronized = 1; - weston_surface_set_transform_parent(surface, parent); return sub; } @@ -2455,6 +2687,7 @@ subcompositor_get_subsurface(struct wl_client *client, struct weston_surface *parent = wl_resource_get_user_data(parent_resource); struct weston_subsurface *sub; + struct weston_view *view, *subview; static const char where[] = "get_subsurface: wl_subsurface@"; if (surface == parent) { @@ -2783,7 +3016,7 @@ weston_output_update_matrix(struct weston_output *output) magnification = 1 / (1 - output->zoom.spring_z.current); weston_matrix_init(&camera); weston_matrix_init(&modelview); - weston_output_update_zoom(output, output->zoom.type); + weston_output_update_zoom(output); weston_matrix_translate(&camera, output->zoom.trans_x, -output->zoom.trans_y, 0); weston_matrix_invert(&modelview, &camera); @@ -3012,7 +3245,7 @@ weston_compositor_init(struct weston_compositor *ec, ec, bind_subcompositor)) return -1; - wl_list_init(&ec->surface_list); + wl_list_init(&ec->view_list); wl_list_init(&ec->plane_list); wl_list_init(&ec->layer_list); wl_list_init(&ec->seat_list); @@ -3044,7 +3277,6 @@ weston_compositor_init(struct weston_compositor *ec, ec->ping_handler = NULL; screenshooter_create(ec); - text_cursor_position_notifier_create(ec); text_backend_init(ec); wl_data_device_manager_init(ec->wl_display); diff --git a/src/compositor.h b/src/compositor.h index 51288759..8ae757bb 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -92,6 +92,8 @@ struct weston_shell_interface { struct shell_surface *(*create_shell_surface)(void *shell, struct weston_surface *surface, const struct weston_shell_client *client); + struct weston_view *(*get_primary_view)(void *shell, + struct shell_surface *shsurf); void (*set_toplevel)(struct shell_surface *shsurf); @@ -140,18 +142,12 @@ struct weston_spring { uint32_t clip; }; -enum { - ZOOM_FOCUS_POINTER, - ZOOM_FOCUS_TEXT -}; - struct weston_fixed_point { wl_fixed_t x, y; }; struct weston_output_zoom { int active; - uint32_t type; float increment; float level; float max_level; @@ -163,7 +159,6 @@ struct weston_output_zoom { struct weston_fixed_point from; struct weston_fixed_point to; struct weston_fixed_point current; - struct weston_fixed_point text_cursor; }; /* bit compatible with drm definitions. */ @@ -311,11 +306,11 @@ struct weston_pointer { struct wl_list resource_list; struct wl_list focus_resource_list; - struct weston_surface *focus; + struct weston_view *focus; uint32_t focus_serial; struct wl_signal focus_signal; - struct weston_surface *sprite; + struct weston_view *sprite; struct wl_listener sprite_destroy_listener; int32_t hotspot_x, hotspot_y; @@ -336,7 +331,7 @@ struct weston_touch { struct wl_list resource_list; struct wl_list focus_resource_list; - struct weston_surface *focus; + struct weston_view *focus; uint32_t focus_serial; struct wl_signal focus_signal; @@ -354,7 +349,7 @@ void weston_pointer_destroy(struct weston_pointer *pointer); void weston_pointer_set_focus(struct weston_pointer *pointer, - struct weston_surface *surface, + struct weston_view *view, wl_fixed_t sx, wl_fixed_t sy); void weston_pointer_start_grab(struct weston_pointer *pointer, @@ -384,7 +379,7 @@ void weston_touch_destroy(struct weston_touch *touch); void weston_touch_set_focus(struct weston_seat *seat, - struct weston_surface *surface); + struct weston_view *view); void weston_touch_start_grab(struct weston_touch *device, struct weston_touch_grab *grab); @@ -504,7 +499,7 @@ enum { }; struct weston_layer { - struct wl_list surface_list; + struct wl_list view_list; struct wl_list link; }; @@ -525,10 +520,12 @@ struct weston_renderer { void (*flush_damage)(struct weston_surface *surface); void (*attach)(struct weston_surface *es, struct weston_buffer *buffer); int (*create_surface)(struct weston_surface *surface); + int (*create_view)(struct weston_view *view); void (*surface_set_color)(struct weston_surface *surface, float red, float green, float blue, float alpha); void (*destroy_surface)(struct weston_surface *surface); + void (*destroy_view)(struct weston_view *view); void (*destroy)(struct weston_compositor *ec); }; @@ -574,7 +571,7 @@ struct weston_compositor { struct wl_list output_list; struct wl_list seat_list; struct wl_list layer_list; - struct wl_list surface_list; + struct wl_list view_list; struct wl_list plane_list; struct wl_list key_binding_list; struct wl_list button_binding_list; @@ -685,51 +682,52 @@ struct weston_subsurface { } cached; int synchronized; + + /* Used for constructing the view tree */ + struct wl_list unused_views; }; -/* Using weston_surface transformations +/* Using weston_view transformations * - * To add a transformation to a surface, create a struct weston_transform, and - * add it to the list surface->geometry.transformation_list. Whenever you - * change the list, anything under surface->geometry, or anything in the + * To add a transformation to a view, create a struct weston_transform, and + * add it to the list view->geometry.transformation_list. Whenever you + * change the list, anything under view->geometry, or anything in the * weston_transforms linked into the list, you must call - * weston_surface_geometry_dirty(). + * weston_view_geometry_dirty(). * * The order in the list defines the order of transformations. Let the list * contain the transformation matrices M1, ..., Mn as head to tail. The - * transformation is applied to surface-local coordinate vector p as + * transformation is applied to view-local coordinate vector p as * P = Mn * ... * M2 * M1 * p * to produce the global coordinate vector P. The total transform * Mn * ... * M2 * M1 - * is cached in surface->transform.matrix, and the inverse of it in - * surface->transform.inverse. + * is cached in view->transform.matrix, and the inverse of it in + * view->transform.inverse. * - * The list always contains surface->transform.position transformation, which - * is the translation by surface->geometry.x and y. + * The list always contains view->transform.position transformation, which + * is the translation by view->geometry.x and y. * * If you want to apply a transformation in local coordinates, add your * weston_transform to the head of the list. If you want to apply a * transformation in global coordinates, add it to the tail of the list. * - * If surface->geometry.parent is set, the total transformation of this - * surface will be the parent's total transformation and this transformation + * If view->geometry.parent is set, the total transformation of this + * view will be the parent's total transformation and this transformation * combined: * Mparent * Mn * ... * M2 * M1 */ -struct weston_surface { - struct wl_resource *resource; +struct weston_view { + struct weston_surface *surface; + struct wl_list surface_link; struct wl_signal destroy_signal; - struct weston_compositor *compositor; - pixman_region32_t clip; - pixman_region32_t damage; - pixman_region32_t opaque; /* part of geometry, see below */ - pixman_region32_t input; + struct wl_list link; struct wl_list layer_link; - float alpha; /* part of geometry, see below */ struct weston_plane *plane; - int32_t ref_count; + + pixman_region32_t clip; + float alpha; /* part of geometry, see below */ void *renderer_state; @@ -745,14 +743,14 @@ struct weston_surface { struct wl_list transformation_list; /* managed by weston_surface_set_transform_parent() */ - struct weston_surface *parent; + struct weston_view *parent; struct wl_listener parent_destroy_listener; struct wl_list child_list; /* geometry.parent_link */ struct wl_list parent_link; } geometry; /* State derived from geometry state, read-only. - * This is updated by weston_surface_update_transform(). + * This is updated by weston_view_update_transform(). */ struct { int dirty; @@ -782,6 +780,39 @@ struct weston_surface { * displayed on. */ uint32_t output_mask; +}; + +struct weston_surface { + struct wl_resource *resource; + struct wl_signal destroy_signal; + struct weston_compositor *compositor; + pixman_region32_t damage; + pixman_region32_t opaque; /* part of geometry, see below */ + pixman_region32_t input; + int32_t width, height; + int32_t ref_count; + + /* Not for long-term storage. This exists for book-keeping while + * iterating over surfaces and views + */ + int32_t touched; + + void *renderer_state; + + struct wl_list views; + + /* + * Which output to vsync this surface to. + * Used to determine, whether to send or queue frame events. + * Must be NULL, if 'link' is not in weston_compositor::surface_list. + */ + struct weston_output *output; + + /* + * A more complete representation of all outputs this surface is + * displayed on. + */ + uint32_t output_mask; struct wl_list frame_callback_list; @@ -843,29 +874,29 @@ void weston_version(int *major, int *minor, int *micro); void -weston_surface_update_transform(struct weston_surface *surface); +weston_view_update_transform(struct weston_view *view); void -weston_surface_geometry_dirty(struct weston_surface *surface); +weston_view_geometry_dirty(struct weston_view *view); void -weston_surface_to_global_fixed(struct weston_surface *surface, - wl_fixed_t sx, wl_fixed_t sy, - wl_fixed_t *x, wl_fixed_t *y); +weston_view_to_global_fixed(struct weston_view *view, + wl_fixed_t sx, wl_fixed_t sy, + wl_fixed_t *x, wl_fixed_t *y); void -weston_surface_to_global_float(struct weston_surface *surface, - float sx, float sy, float *x, float *y); +weston_view_to_global_float(struct weston_view *view, + float sx, float sy, float *x, float *y); void -weston_surface_from_global_float(struct weston_surface *surface, - float x, float y, float *sx, float *sy); +weston_view_from_global_float(struct weston_view *view, + float x, float y, float *vx, float *vy); void -weston_surface_from_global(struct weston_surface *surface, - int32_t x, int32_t y, int32_t *sx, int32_t *sy); +weston_view_from_global(struct weston_view *view, + int32_t x, int32_t y, int32_t *vx, int32_t *vy); void -weston_surface_from_global_fixed(struct weston_surface *surface, - wl_fixed_t x, wl_fixed_t y, - wl_fixed_t *sx, wl_fixed_t *sy); +weston_view_from_global_fixed(struct weston_view *view, + wl_fixed_t x, wl_fixed_t y, + wl_fixed_t *vx, wl_fixed_t *vy); int32_t weston_surface_buffer_width(struct weston_surface *surface); int32_t @@ -876,8 +907,7 @@ weston_surface_to_buffer_float(struct weston_surface *surface, float x, float y, float *bx, float *by); WL_EXPORT void weston_surface_to_buffer(struct weston_surface *surface, - int sx, int sy, int *bx, int *by); - + int sx, int sy, int *bx, int *by); pixman_box32_t weston_surface_to_buffer_rect(struct weston_surface *surface, pixman_box32_t rect); @@ -959,10 +989,10 @@ void weston_compositor_offscreen(struct weston_compositor *compositor); void weston_compositor_sleep(struct weston_compositor *compositor); -struct weston_surface * -weston_compositor_pick_surface(struct weston_compositor *compositor, - wl_fixed_t x, wl_fixed_t y, - wl_fixed_t *sx, wl_fixed_t *sy); +struct weston_view * +weston_compositor_pick_view(struct weston_compositor *compositor, + wl_fixed_t x, wl_fixed_t y, + wl_fixed_t *sx, wl_fixed_t *sy); struct weston_binding; @@ -1048,20 +1078,32 @@ weston_compositor_top(struct weston_compositor *compositor); struct weston_surface * weston_surface_create(struct weston_compositor *compositor); +struct weston_view * +weston_view_create(struct weston_surface *surface); + +void +weston_view_destroy(struct weston_view *view); + +void +weston_view_configure(struct weston_view *view, + float x, float y, int width, int height); + void -weston_surface_configure(struct weston_surface *surface, - float x, float y, int width, int height); +weston_view_restack(struct weston_view *surface, struct wl_list *below); void -weston_surface_restack(struct weston_surface *surface, struct wl_list *below); +weston_view_set_position(struct weston_view *view, + float x, float y); void -weston_surface_set_position(struct weston_surface *surface, - float x, float y); +weston_view_set_transform_parent(struct weston_view *view, + struct weston_view *parent); + +int +weston_view_is_mapped(struct weston_view *view); void -weston_surface_set_transform_parent(struct weston_surface *surface, - struct weston_surface *parent); +weston_view_schedule_repaint(struct weston_view *view); int weston_surface_is_mapped(struct weston_surface *surface); @@ -1073,11 +1115,14 @@ void weston_surface_damage(struct weston_surface *surface); void -weston_surface_damage_below(struct weston_surface *surface); +weston_view_damage_below(struct weston_view *view); void -weston_surface_move_to_plane(struct weston_surface *surface, - struct weston_plane *plane); +weston_view_move_to_plane(struct weston_view *view, + struct weston_plane *plane); +void +weston_view_unmap(struct weston_view *view); + void weston_surface_unmap(struct weston_surface *surface); @@ -1100,12 +1145,9 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display, void weston_compositor_shutdown(struct weston_compositor *ec); void -weston_text_cursor_position_notify(struct weston_surface *surface, - wl_fixed_t x, wl_fixed_t y); -void weston_output_init_zoom(struct weston_output *output); void -weston_output_update_zoom(struct weston_output *output, uint32_t type); +weston_output_update_zoom(struct weston_output *output); void weston_output_update_matrix(struct weston_output *output); void @@ -1187,9 +1229,6 @@ screenshooter_create(struct weston_compositor *ec); struct clipboard * clipboard_create(struct weston_seat *seat); -void -text_cursor_position_notifier_create(struct weston_compositor *ec); - int text_backend_init(struct weston_compositor *ec); @@ -1212,23 +1251,23 @@ weston_client_launch(struct weston_compositor *compositor, void weston_watch_process(struct weston_process *process); -struct weston_surface_animation; -typedef void (*weston_surface_animation_done_func_t)(struct weston_surface_animation *animation, void *data); +struct weston_view_animation; +typedef void (*weston_view_animation_done_func_t)(struct weston_view_animation *animation, void *data); -struct weston_surface_animation * -weston_zoom_run(struct weston_surface *surface, float start, float stop, - weston_surface_animation_done_func_t done, void *data); +struct weston_view_animation * +weston_zoom_run(struct weston_view *view, float start, float stop, + weston_view_animation_done_func_t done, void *data); -struct weston_surface_animation * -weston_fade_run(struct weston_surface *surface, +struct weston_view_animation * +weston_fade_run(struct weston_view *view, float start, float end, float k, - weston_surface_animation_done_func_t done, void *data); + weston_view_animation_done_func_t done, void *data); void -weston_fade_update(struct weston_surface_animation *fade, float target); +weston_fade_update(struct weston_view_animation *fade, float target); -struct weston_surface_animation * -weston_slide_run(struct weston_surface *surface, float start, float stop, - weston_surface_animation_done_func_t done, void *data); +struct weston_view_animation * +weston_slide_run(struct weston_view *view, float start, float stop, + weston_view_animation_done_func_t done, void *data); void weston_surface_set_color(struct weston_surface *surface, diff --git a/src/data-device.c b/src/data-device.c index 858235f6..3e22b513 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "compositor.h" @@ -33,11 +34,11 @@ struct weston_drag { struct wl_client *client; struct weston_data_source *data_source; struct wl_listener data_source_listener; - struct weston_surface *focus; + struct weston_view *focus; struct wl_resource *focus_resource; struct wl_listener focus_listener; struct weston_pointer_grab grab; - struct weston_surface *icon; + struct weston_view *icon; struct wl_listener icon_destroy_listener; int32_t dx, dy; }; @@ -178,14 +179,17 @@ drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_ struct wl_list *list; float fx, fy; + assert(es->configure == drag_surface_configure); + if (!weston_surface_is_mapped(es) && es->buffer_ref.buffer) { - if (pointer->sprite && weston_surface_is_mapped(pointer->sprite)) + if (pointer->sprite && weston_view_is_mapped(pointer->sprite)) list = &pointer->sprite->layer_link; else - list = &es->compositor->cursor_layer.surface_list; + list = &es->compositor->cursor_layer.view_list; - wl_list_insert(list, &es->layer_link); - weston_surface_update_transform(es); + wl_list_remove(&drag->icon->layer_link); + wl_list_insert(list, &drag->icon->layer_link); + weston_view_update_transform(drag->icon); empty_region(&es->pending.input); } @@ -194,7 +198,7 @@ drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_ fx = wl_fixed_to_double(pointer->x) + drag->dx; fy = wl_fixed_to_double(pointer->y) + drag->dy; - weston_surface_configure(es, fx, fy, width, height); + weston_view_configure(drag->icon, fx, fy, width, height); } static void @@ -207,7 +211,7 @@ destroy_drag_focus(struct wl_listener *listener, void *data) } static void -weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface, +weston_drag_set_focus(struct weston_drag *drag, struct weston_view *view, wl_fixed_t sx, wl_fixed_t sy) { struct weston_pointer *pointer = drag->grab.pointer; @@ -215,6 +219,11 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface, struct wl_display *display = pointer->seat->compositor->wl_display; uint32_t serial; + if (drag->focus && view && drag->focus->surface == view->surface) { + drag->focus = view; + return; + } + if (drag->focus_resource) { wl_data_device_send_leave(drag->focus_resource); wl_list_remove(&drag->focus_listener.link); @@ -222,15 +231,15 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface, drag->focus = NULL; } - if (!surface) + if (!view || !view->surface->resource) return; if (!drag->data_source && - wl_resource_get_client(surface->resource) != drag->client) + wl_resource_get_client(view->surface->resource) != drag->client) return; resource = wl_resource_find_for_client(&pointer->seat->drag_resource_list, - wl_resource_get_client(surface->resource)); + wl_resource_get_client(view->surface->resource)); if (!resource) return; @@ -243,10 +252,10 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface, return; } - wl_data_device_send_enter(resource, serial, surface->resource, + wl_data_device_send_enter(resource, serial, view->surface->resource, sx, sy, offer); - drag->focus = surface; + drag->focus = view; drag->focus_listener.notify = destroy_drag_focus; wl_resource_add_destroy_listener(resource, &drag->focus_listener); drag->focus_resource = resource; @@ -258,14 +267,14 @@ drag_grab_focus(struct weston_pointer_grab *grab) struct weston_drag *drag = container_of(grab, struct weston_drag, grab); struct weston_pointer *pointer = grab->pointer; - struct weston_surface *surface; + struct weston_view *view; wl_fixed_t sx, sy; - surface = weston_compositor_pick_surface(pointer->seat->compositor, - pointer->x, pointer->y, - &sx, &sy); - if (drag->focus != surface) - weston_drag_set_focus(drag, surface, sx, sy); + view = weston_compositor_pick_view(pointer->seat->compositor, + pointer->x, pointer->y, + &sx, &sy); + if (drag->focus != view) + weston_drag_set_focus(drag, view, sx, sy); } static void @@ -280,14 +289,14 @@ drag_grab_motion(struct weston_pointer_grab *grab, uint32_t time) if (drag->icon) { fx = wl_fixed_to_double(pointer->x) + drag->dx; fy = wl_fixed_to_double(pointer->y) + drag->dy; - weston_surface_set_position(drag->icon, fx, fy); - weston_surface_schedule_repaint(drag->icon); + weston_view_set_position(drag->icon, fx, fy); + weston_view_schedule_repaint(drag->icon); } if (drag->focus_resource) { - weston_surface_from_global_fixed(drag->focus, - pointer->x, pointer->y, - &sx, &sy); + weston_view_from_global_fixed(drag->focus, + pointer->x, pointer->y, + &sx, &sy); wl_data_device_send_motion(drag->focus_resource, time, sx, sy); } @@ -297,12 +306,13 @@ static void data_device_end_drag_grab(struct weston_drag *drag) { if (drag->icon) { - if (weston_surface_is_mapped(drag->icon)) - weston_surface_unmap(drag->icon); + if (weston_view_is_mapped(drag->icon)) + weston_view_unmap(drag->icon); - drag->icon->configure = NULL; - empty_region(&drag->icon->pending.input); + drag->icon->surface->configure = NULL; + empty_region(&drag->icon->surface->pending.input); wl_list_remove(&drag->icon_destroy_listener.link); + weston_view_destroy(drag->icon); } weston_drag_set_focus(drag, NULL, 0, 0); @@ -373,21 +383,28 @@ weston_seat_start_drag(struct weston_seat *seat, drag->grab.interface = &drag_grab_interface; drag->client = client; drag->data_source = source; - drag->icon = icon; - - if (source) { - drag->data_source_listener.notify = destroy_data_device_source; - wl_signal_add(&source->destroy_signal, - &drag->data_source_listener); - } if (icon) { + drag->icon = weston_view_create(icon); + if (drag->icon == NULL) { + free(drag); + return -1; + } + drag->icon_destroy_listener.notify = handle_drag_icon_destroy; wl_signal_add(&icon->destroy_signal, &drag->icon_destroy_listener); icon->configure = drag_surface_configure; icon->configure_private = drag; + } else { + drag->icon = NULL; + } + + if (source) { + drag->data_source_listener.notify = destroy_data_device_source; + wl_signal_add(&source->destroy_signal, + &drag->data_source_listener); } weston_pointer_set_focus(seat->pointer, NULL, @@ -409,7 +426,8 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource, if (seat->pointer->button_count == 0 || seat->pointer->grab_serial != serial || - seat->pointer->focus != wl_resource_get_user_data(origin_resource)) + !seat->pointer->focus || + seat->pointer->focus->surface != wl_resource_get_user_data(origin_resource)) return; /* FIXME: Check that the data source type array isn't empty. */ diff --git a/src/gl-renderer.c b/src/gl-renderer.c index f02445b7..2cb24fac 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -193,7 +193,7 @@ gl_renderer_print_egl_error_state(void) * polygon area. */ static int -calculate_edges(struct weston_surface *es, pixman_box32_t *rect, +calculate_edges(struct weston_view *ev, pixman_box32_t *rect, pixman_box32_t *surf_rect, GLfloat *ex, GLfloat *ey) { @@ -213,8 +213,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect, /* transform surface to screen space: */ for (i = 0; i < surf.n; i++) - weston_surface_to_global_float(es, surf.x[i], surf.y[i], - &surf.x[i], &surf.y[i]); + weston_view_to_global_float(ev, surf.x[i], surf.y[i], + &surf.x[i], &surf.y[i]); /* find bounding box: */ min_x = max_x = surf.x[0]; @@ -238,9 +238,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect, * there will be only four edges. We just need to clip the surface * vertices to the clip rect bounds: */ - if (!es->transform.enabled) { + if (!ev->transform.enabled) return clip_simple(&ctx, &surf, ex, ey); - } /* Transformed case: use a general polygon clipping algorithm to * clip the surface rectangle with each side of 'rect'. @@ -257,11 +256,11 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect, } static int -texture_region(struct weston_surface *es, pixman_region32_t *region, +texture_region(struct weston_view *ev, pixman_region32_t *region, pixman_region32_t *surf_region) { - struct gl_surface_state *gs = get_surface_state(es); - struct weston_compositor *ec = es->compositor; + struct gl_surface_state *gs = get_surface_state(ev->surface); + struct weston_compositor *ec = ev->surface->compositor; struct gl_renderer *gr = get_renderer(ec); GLfloat *v, inv_width, inv_height; unsigned int *vtxcnt, nvtx = 0; @@ -302,18 +301,20 @@ texture_region(struct weston_surface *es, pixman_region32_t *region, * form the intersection of the clip rect and the transformed * surface. */ - n = calculate_edges(es, rect, surf_rect, ex, ey); + n = calculate_edges(ev, rect, surf_rect, ex, ey); if (n < 3) continue; /* emit edge points: */ for (k = 0; k < n; k++) { - weston_surface_from_global_float(es, ex[k], ey[k], &sx, &sy); + weston_view_from_global_float(ev, ex[k], ey[k], + &sx, &sy); /* position: */ *(v++) = ex[k]; *(v++) = ey[k]; /* texcoord: */ - weston_surface_to_buffer_float(es, sx, sy, + weston_surface_to_buffer_float(ev->surface, + sx, sy, &bx, &by); *(v++) = bx * inv_width; if (gs->y_inverted) { @@ -331,9 +332,9 @@ texture_region(struct weston_surface *es, pixman_region32_t *region, } static void -triangle_fan_debug(struct weston_surface *surface, int first, int count) +triangle_fan_debug(struct weston_view *view, int first, int count) { - struct weston_compositor *compositor = surface->compositor; + struct weston_compositor *compositor = view->surface->compositor; struct gl_renderer *gr = get_renderer(compositor); int i; GLushort *buffer; @@ -371,10 +372,10 @@ triangle_fan_debug(struct weston_surface *surface, int first, int count) } static void -repaint_region(struct weston_surface *es, pixman_region32_t *region, +repaint_region(struct weston_view *ev, pixman_region32_t *region, pixman_region32_t *surf_region) { - struct weston_compositor *ec = es->compositor; + struct weston_compositor *ec = ev->surface->compositor; struct gl_renderer *gr = get_renderer(ec); GLfloat *v; unsigned int *vtxcnt; @@ -388,7 +389,7 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region, * polygon for each pair, and store it as a triangle fan if * it has a non-zero area (at least 3 vertices1, actually). */ - nfans = texture_region(es, region, surf_region); + nfans = texture_region(ev, region, surf_region); v = gr->vertices.data; vtxcnt = gr->vtxcnt.data; @@ -404,7 +405,7 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region, for (i = 0, first = 0; i < nfans; i++) { glDrawArrays(GL_TRIANGLE_FAN, first, vtxcnt[i]); if (gr->fan_debug) - triangle_fan_debug(es, first, vtxcnt[i]); + triangle_fan_debug(ev, first, vtxcnt[i]); first += vtxcnt[i]; } @@ -464,28 +465,28 @@ use_shader(struct gl_renderer *gr, struct gl_shader *shader) static void shader_uniforms(struct gl_shader *shader, - struct weston_surface *surface, - struct weston_output *output) + struct weston_view *view, + struct weston_output *output) { int i; - struct gl_surface_state *gs = get_surface_state(surface); + struct gl_surface_state *gs = get_surface_state(view->surface); glUniformMatrix4fv(shader->proj_uniform, 1, GL_FALSE, output->matrix.d); glUniform4fv(shader->color_uniform, 1, gs->color); - glUniform1f(shader->alpha_uniform, surface->alpha); + glUniform1f(shader->alpha_uniform, view->alpha); for (i = 0; i < gs->num_textures; i++) glUniform1i(shader->tex_uniforms[i], i); } static void -draw_surface(struct weston_surface *es, struct weston_output *output, - pixman_region32_t *damage) /* in global coordinates */ +draw_view(struct weston_view *ev, struct weston_output *output, + pixman_region32_t *damage) /* in global coordinates */ { - struct weston_compositor *ec = es->compositor; + struct weston_compositor *ec = ev->surface->compositor; struct gl_renderer *gr = get_renderer(ec); - struct gl_surface_state *gs = get_surface_state(es); + struct gl_surface_state *gs = get_surface_state(ev->surface); /* repaint bounding region in global coordinates: */ pixman_region32_t repaint; /* non-opaque region in surface coordinates: */ @@ -495,8 +496,8 @@ draw_surface(struct weston_surface *es, struct weston_output *output, pixman_region32_init(&repaint); pixman_region32_intersect(&repaint, - &es->transform.boundingbox, damage); - pixman_region32_subtract(&repaint, &repaint, &es->clip); + &ev->transform.boundingbox, damage); + pixman_region32_subtract(&repaint, &repaint, &ev->clip); if (!pixman_region32_not_empty(&repaint)) goto out; @@ -505,13 +506,14 @@ draw_surface(struct weston_surface *es, struct weston_output *output, if (gr->fan_debug) { use_shader(gr, &gr->solid_shader); - shader_uniforms(&gr->solid_shader, es, output); + shader_uniforms(&gr->solid_shader, ev, output); } use_shader(gr, gs->shader); - shader_uniforms(gs->shader, es, output); + shader_uniforms(gs->shader, ev, output); - if (es->transform.enabled || output->zoom.active || output->current_scale != es->buffer_scale) + if (ev->transform.enabled || output->zoom.active || + output->current_scale != ev->surface->buffer_scale) filter = GL_LINEAR; else filter = GL_NEAREST; @@ -525,10 +527,11 @@ draw_surface(struct weston_surface *es, struct weston_output *output, /* blended region is whole surface minus opaque region: */ pixman_region32_init_rect(&surface_blend, 0, 0, - es->geometry.width, es->geometry.height); - pixman_region32_subtract(&surface_blend, &surface_blend, &es->opaque); + ev->geometry.width, ev->geometry.height); + pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque); - if (pixman_region32_not_empty(&es->opaque)) { + /* XXX: Should we be using ev->transform.opaque here? */ + if (pixman_region32_not_empty(&ev->surface->opaque)) { if (gs->shader == &gr->texture_shader_rgba) { /* Special case for RGBA textures with possibly * bad data in alpha channel: use the shader @@ -536,21 +539,21 @@ draw_surface(struct weston_surface *es, struct weston_output *output, * Xwayland surfaces need this. */ use_shader(gr, &gr->texture_shader_rgbx); - shader_uniforms(&gr->texture_shader_rgbx, es, output); + shader_uniforms(&gr->texture_shader_rgbx, ev, output); } - if (es->alpha < 1.0) + if (ev->alpha < 1.0) glEnable(GL_BLEND); else glDisable(GL_BLEND); - repaint_region(es, &repaint, &es->opaque); + repaint_region(ev, &repaint, &ev->surface->opaque); } if (pixman_region32_not_empty(&surface_blend)) { use_shader(gr, gs->shader); glEnable(GL_BLEND); - repaint_region(es, &repaint, &surface_blend); + repaint_region(ev, &repaint, &surface_blend); } pixman_region32_fini(&surface_blend); @@ -560,14 +563,14 @@ out: } static void -repaint_surfaces(struct weston_output *output, pixman_region32_t *damage) +repaint_views(struct weston_output *output, pixman_region32_t *damage) { struct weston_compositor *compositor = output->compositor; - struct weston_surface *surface; + struct weston_view *view; - wl_list_for_each_reverse(surface, &compositor->surface_list, link) - if (surface->plane == &compositor->primary_plane) - draw_surface(surface, output, damage); + wl_list_for_each_reverse(view, &compositor->view_list, link) + if (view->plane == &compositor->primary_plane) + draw_view(view, output, damage); } @@ -762,7 +765,7 @@ gl_renderer_repaint_output(struct weston_output *output, pixman_region32_subtract(&undamaged, &output->region, output_damage); gr->fan_debug = 0; - repaint_surfaces(output, &undamaged); + repaint_views(output, &undamaged); gr->fan_debug = 1; pixman_region32_fini(&undamaged); } @@ -775,7 +778,7 @@ gl_renderer_repaint_output(struct weston_output *output, pixman_region32_union(&total_damage, &buffer_damage, output_damage); - repaint_surfaces(output, &total_damage); + repaint_views(output, &total_damage); pixman_region32_fini(&total_damage); pixman_region32_fini(&buffer_damage); @@ -830,6 +833,8 @@ gl_renderer_flush_damage(struct weston_surface *surface) struct gl_renderer *gr = get_renderer(surface->compositor); struct gl_surface_state *gs = get_surface_state(surface); struct weston_buffer *buffer = gs->buffer_ref.buffer; + struct weston_view *view; + int texture_used; GLenum format; int pixel_type; @@ -850,7 +855,14 @@ gl_renderer_flush_damage(struct weston_surface *surface) * hold the reference to the buffer, in case the surface * migrates back to the primary plane. */ - if (surface->plane != &surface->compositor->primary_plane) + texture_used = 0; + wl_list_for_each(view, &surface->views, surface_link) { + if (view->plane == &surface->compositor->primary_plane) { + texture_used = 1; + break; + } + } + if (!texture_used) return; if (!pixman_region32_not_empty(&gs->texture_damage)) diff --git a/src/input.c b/src/input.c index 9648f62e..5ad247a9 100644 --- a/src/input.c +++ b/src/input.c @@ -96,18 +96,18 @@ static void default_grab_focus(struct weston_pointer_grab *grab) { struct weston_pointer *pointer = grab->pointer; - struct weston_surface *surface; + struct weston_view *view; wl_fixed_t sx, sy; if (pointer->button_count > 0) return; - surface = weston_compositor_pick_surface(pointer->seat->compositor, - pointer->x, pointer->y, - &sx, &sy); + view = weston_compositor_pick_view(pointer->seat->compositor, + pointer->x, pointer->y, + &sx, &sy); - if (pointer->focus != surface) - weston_pointer_set_focus(pointer, surface, sx, sy); + if (pointer->focus != view) + weston_pointer_set_focus(pointer, view, sx, sy); } static void @@ -120,9 +120,9 @@ default_grab_motion(struct weston_pointer_grab *grab, uint32_t time) resource_list = &pointer->focus_resource_list; wl_resource_for_each(resource, resource_list) { - weston_surface_from_global_fixed(pointer->focus, - pointer->x, pointer->y, - &sx, &sy); + weston_view_from_global_fixed(pointer->focus, + pointer->x, pointer->y, + &sx, &sy); wl_pointer_send_motion(resource, time, sx, sy); } } @@ -133,7 +133,7 @@ default_grab_button(struct weston_pointer_grab *grab, { struct weston_pointer *pointer = grab->pointer; struct weston_compositor *compositor = pointer->seat->compositor; - struct weston_surface *surface; + struct weston_view *view; struct wl_resource *resource; uint32_t serial; enum wl_pointer_button_state state = state_w; @@ -154,12 +154,11 @@ default_grab_button(struct weston_pointer_grab *grab, if (pointer->button_count == 0 && state == WL_POINTER_BUTTON_STATE_RELEASED) { - surface = weston_compositor_pick_surface(compositor, - pointer->x, - pointer->y, - &sx, &sy); + view = weston_compositor_pick_view(compositor, + pointer->x, pointer->y, + &sx, &sy); - weston_pointer_set_focus(pointer, surface, sx, sy); + weston_pointer_set_focus(pointer, view, sx, sy); } } @@ -186,7 +185,7 @@ default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time, serial = wl_display_next_serial(display); wl_resource_for_each(resource, resource_list) wl_touch_send_down(resource, serial, time, - touch->focus->resource, + touch->focus->surface->resource, touch_id, sx, sy); } } @@ -295,6 +294,15 @@ find_resource_for_surface(struct wl_list *list, struct weston_surface *surface) return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource)); } +static struct wl_resource * +find_resource_for_view(struct wl_list *list, struct weston_view *view) +{ + if (!view) + return NULL; + + return find_resource_for_surface(list, view->surface); +} + static void default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, @@ -311,9 +319,9 @@ default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, wl_keyboard_send_modifiers(resource, serial, mods_depressed, mods_latched, mods_locked, group); } - if (pointer && pointer->focus && pointer->focus != keyboard->focus) { + if (pointer && pointer->focus && pointer->focus->surface != keyboard->focus) { struct wl_client *pointer_client = - wl_resource_get_client(pointer->focus->resource); + wl_resource_get_client(pointer->focus->surface->resource); send_modifiers_to_client_in_list(pointer_client, &keyboard->resource_list, serial, @@ -330,12 +338,13 @@ static const struct weston_keyboard_grab_interface static void pointer_unmap_sprite(struct weston_pointer *pointer) { - if (weston_surface_is_mapped(pointer->sprite)) - weston_surface_unmap(pointer->sprite); + if (weston_surface_is_mapped(pointer->sprite->surface)) + weston_surface_unmap(pointer->sprite->surface); wl_list_remove(&pointer->sprite_destroy_listener.link); - pointer->sprite->configure = NULL; - pointer->sprite->configure_private = NULL; + pointer->sprite->surface->configure = NULL; + pointer->sprite->surface->configure_private = NULL; + weston_view_destroy(pointer->sprite); pointer->sprite = NULL; } @@ -461,7 +470,7 @@ seat_send_updated_caps(struct weston_seat *seat) WL_EXPORT void weston_pointer_set_focus(struct weston_pointer *pointer, - struct weston_surface *surface, + struct weston_view *view, wl_fixed_t sx, wl_fixed_t sy) { struct weston_keyboard *kbd = pointer->seat->keyboard; @@ -469,27 +478,33 @@ weston_pointer_set_focus(struct weston_pointer *pointer, struct wl_display *display = pointer->seat->compositor->wl_display; uint32_t serial; struct wl_list *focus_resource_list; + int different_surface = 0; + + if ((!pointer->focus && view) || + (pointer->focus && !view) || + (pointer->focus && pointer->focus->surface != view->surface)) + different_surface = 1; focus_resource_list = &pointer->focus_resource_list; - if (!wl_list_empty(focus_resource_list) && pointer->focus != surface) { + if (!wl_list_empty(focus_resource_list) && different_surface) { serial = wl_display_next_serial(display); wl_resource_for_each(resource, focus_resource_list) { wl_pointer_send_leave(resource, serial, - pointer->focus->resource); + pointer->focus->surface->resource); } move_resources(&pointer->resource_list, focus_resource_list); } - if (find_resource_for_surface(&pointer->resource_list, surface) && - pointer->focus != surface) { + if (find_resource_for_view(&pointer->resource_list, view) && + different_surface) { struct wl_client *surface_client = - wl_resource_get_client(surface->resource); + wl_resource_get_client(view->surface->resource); serial = wl_display_next_serial(display); - if (kbd && kbd->focus != pointer->focus) + if (kbd && kbd->focus != view->surface) send_modifiers_to_client_in_list(surface_client, &kbd->resource_list, serial, @@ -502,14 +517,14 @@ weston_pointer_set_focus(struct weston_pointer *pointer, wl_resource_for_each(resource, focus_resource_list) { wl_pointer_send_enter(resource, serial, - surface->resource, + view->surface->resource, sx, sy); } pointer->focus_serial = serial; } - pointer->focus = surface; + pointer->focus = view; wl_signal_emit(&pointer->focus_signal, pointer); } @@ -676,13 +691,13 @@ move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y) if (output->zoom.active && pixman_region32_contains_point(&output->region, ix, iy, NULL)) - weston_output_update_zoom(output, ZOOM_FOCUS_POINTER); + weston_output_update_zoom(output); if (pointer->sprite) { - weston_surface_set_position(pointer->sprite, - ix - pointer->hotspot_x, - iy - pointer->hotspot_y); - weston_surface_schedule_repaint(pointer->sprite); + weston_view_set_position(pointer->sprite, + ix - pointer->hotspot_x, + iy - pointer->hotspot_y); + weston_view_schedule_repaint(pointer->sprite); } } @@ -906,8 +921,7 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key, { struct weston_compositor *compositor = seat->compositor; struct weston_keyboard *keyboard = seat->keyboard; - struct weston_surface *focus = - (struct weston_surface *) keyboard->focus; + struct weston_surface *focus = keyboard->focus; struct weston_keyboard_grab *grab = keyboard->grab; uint32_t serial = wl_display_next_serial(compositor->wl_display); uint32_t *k, *end; @@ -1045,28 +1059,30 @@ notify_keyboard_focus_out(struct weston_seat *seat) } WL_EXPORT void -weston_touch_set_focus(struct weston_seat *seat, struct weston_surface *surface) +weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view) { struct wl_list *focus_resource_list; focus_resource_list = &seat->touch->focus_resource_list; - if (seat->touch->focus == surface) + if (seat->touch->focus->surface == view->surface) { + seat->touch->focus = view; return; + } if (!wl_list_empty(focus_resource_list)) { move_resources(&seat->touch->resource_list, focus_resource_list); } - if (surface) { + if (view) { struct wl_client *surface_client = - wl_resource_get_client(surface->resource); + wl_resource_get_client(view->surface->resource); move_resources_for_client(focus_resource_list, &seat->touch->resource_list, surface_client); } - seat->touch->focus = surface; + seat->touch->focus = view; } /** @@ -1084,7 +1100,7 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id, struct weston_compositor *ec = seat->compositor; struct weston_touch *touch = seat->touch; struct weston_touch_grab *grab = touch->grab; - struct weston_surface *es; + struct weston_view *ev; wl_fixed_t sx, sy; /* Update grab's global coordinates. */ @@ -1099,15 +1115,15 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id, seat->num_tp++; - /* the first finger down picks the surface, and all further go - * to that surface for the remainder of the touch session i.e. + /* the first finger down picks the view, and all further go + * to that view for the remainder of the touch session i.e. * until all touch points are up again. */ if (seat->num_tp == 1) { - es = weston_compositor_pick_surface(ec, x, y, &sx, &sy); - weston_touch_set_focus(seat, es); + ev = weston_compositor_pick_view(ec, x, y, &sx, &sy); + weston_touch_set_focus(seat, ev); } else if (touch->focus) { - es = (struct weston_surface *) touch->focus; - weston_surface_from_global_fixed(es, x, y, &sx, &sy); + ev = touch->focus; + weston_view_from_global_fixed(ev, x, y, &sx, &sy); } else { /* Unexpected condition: We have non-initial touch but * there is no focused surface. @@ -1129,11 +1145,11 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id, break; case WL_TOUCH_MOTION: - es = (struct weston_surface *) touch->focus; - if (!es) + ev = touch->focus; + if (!ev) break; - weston_surface_from_global_fixed(es, x, y, &sx, &sy); + weston_view_from_global_fixed(ev, x, y, &sx, &sy); grab->interface->motion(grab, time, touch_id, sx, sy); break; case WL_TOUCH_UP: @@ -1159,7 +1175,7 @@ pointer_cursor_surface_configure(struct weston_surface *es, if (width == 0) return; - assert(es == pointer->sprite); + assert(es == pointer->sprite->surface); pointer->hotspot_x -= dx; pointer->hotspot_y -= dy; @@ -1167,14 +1183,14 @@ pointer_cursor_surface_configure(struct weston_surface *es, x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x; y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y; - weston_surface_configure(pointer->sprite, x, y, width, height); + weston_view_configure(pointer->sprite, x, y, width, height); empty_region(&es->pending.input); if (!weston_surface_is_mapped(es)) { - wl_list_insert(&es->compositor->cursor_layer.surface_list, - &es->layer_link); - weston_surface_update_transform(es); + wl_list_insert(&es->compositor->cursor_layer.view_list, + &pointer->sprite->layer_link); + weston_view_update_transform(pointer->sprite); } } @@ -1191,17 +1207,17 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource, if (pointer->focus == NULL) return; - /* pointer->focus->resource can be NULL. Surfaces like the + /* pointer->focus->surface->resource can be NULL. Surfaces like the black_surface used in shell.c for fullscreen don't have a resource, but can still have focus */ - if (pointer->focus->resource == NULL) + if (pointer->focus->surface->resource == NULL) return; - if (wl_resource_get_client(pointer->focus->resource) != client) + if (wl_resource_get_client(pointer->focus->surface->resource) != client) return; if (pointer->focus_serial - serial > UINT32_MAX / 2) return; - if (surface && surface != pointer->sprite) { + if (surface && pointer->sprite && surface != pointer->sprite->surface) { if (surface->configure) { wl_resource_post_error(surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -1222,7 +1238,7 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource, surface->configure = pointer_cursor_surface_configure; surface->configure_private = pointer; - pointer->sprite = surface; + pointer->sprite = weston_view_create(surface); pointer->hotspot_x = x; pointer->hotspot_y = y; @@ -1266,24 +1282,21 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource, wl_resource_set_implementation(cr, &pointer_interface, seat->pointer, unbind_resource); - if (seat->pointer->focus && seat->pointer->focus->resource && - wl_resource_get_client(seat->pointer->focus->resource) == client) { - struct weston_surface *surface; + if (seat->pointer->focus && seat->pointer->focus->surface->resource && + wl_resource_get_client(seat->pointer->focus->surface->resource) == client) { wl_fixed_t sx, sy; - surface = (struct weston_surface *) seat->pointer->focus; - weston_surface_from_global_fixed(surface, - seat->pointer->x, - seat->pointer->y, - &sx, - &sy); + weston_view_from_global_fixed(seat->pointer->focus, + seat->pointer->x, + seat->pointer->y, + &sx, &sy); wl_list_remove(wl_resource_get_link(cr)); wl_list_insert(&seat->pointer->focus_resource_list, wl_resource_get_link(cr)); wl_pointer_send_enter(cr, seat->pointer->focus_serial, - surface->resource, + seat->pointer->focus->surface->resource, sx, sy); } } @@ -1309,7 +1322,7 @@ should_send_modifiers_to_client(struct weston_seat *seat, if (seat->pointer && seat->pointer->focus && - wl_resource_get_client(seat->pointer->focus->resource) == client) + wl_resource_get_client(seat->pointer->focus->surface->resource) == client) return 1; return 0; @@ -1406,7 +1419,7 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource, } if (seat->touch->focus && - wl_resource_get_client(seat->touch->focus->resource) == client) { + wl_resource_get_client(seat->touch->focus->surface->resource) == client) { wl_list_insert(&seat->touch->resource_list, wl_resource_get_link(cr)); } else { diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 987c5393..85fcd4c2 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -223,16 +223,16 @@ region_global_to_output(struct weston_output *output, pixman_region32_t *region) #define D2F(v) pixman_double_to_fixed((double)v) static void -repaint_region(struct weston_surface *es, struct weston_output *output, +repaint_region(struct weston_view *ev, struct weston_output *output, pixman_region32_t *region, pixman_region32_t *surf_region, pixman_op_t pixman_op) { struct pixman_renderer *pr = (struct pixman_renderer *) output->compositor->renderer; - struct pixman_surface_state *ps = get_surface_state(es); + struct pixman_surface_state *ps = get_surface_state(ev->surface); struct pixman_output_state *po = get_output_state(output); pixman_region32_t final_region; - float surface_x, surface_y; + float view_x, view_y; pixman_transform_t transform; pixman_fixed_t fw, fh; @@ -246,11 +246,11 @@ repaint_region(struct weston_surface *es, struct weston_output *output, pixman_region32_copy(&final_region, surf_region); /* Convert from surface to global coordinates */ - if (!es->transform.enabled) { - pixman_region32_translate(&final_region, es->geometry.x, es->geometry.y); + if (!ev->transform.enabled) { + pixman_region32_translate(&final_region, ev->geometry.x, ev->geometry.y); } else { - weston_surface_to_global_float(es, 0, 0, &surface_x, &surface_y); - pixman_region32_translate(&final_region, (int)surface_x, (int)surface_y); + weston_view_to_global_float(ev, 0, 0, &view_x, &view_y); + pixman_region32_translate(&final_region, (int)view_x, (int)view_y); } /* We need to paint the intersection */ @@ -314,22 +314,22 @@ repaint_region(struct weston_surface *es, struct weston_output *output, pixman_double_to_fixed (output->x), pixman_double_to_fixed (output->y)); - if (es->transform.enabled) { + if (ev->transform.enabled) { /* Pixman supports only 2D transform matrix, but Weston uses 3D, * so we're omitting Z coordinate here */ pixman_transform_t surface_transform = {{ - { D2F(es->transform.matrix.d[0]), - D2F(es->transform.matrix.d[4]), - D2F(es->transform.matrix.d[12]), + { D2F(ev->transform.matrix.d[0]), + D2F(ev->transform.matrix.d[4]), + D2F(ev->transform.matrix.d[12]), }, - { D2F(es->transform.matrix.d[1]), - D2F(es->transform.matrix.d[5]), - D2F(es->transform.matrix.d[13]), + { D2F(ev->transform.matrix.d[1]), + D2F(ev->transform.matrix.d[5]), + D2F(ev->transform.matrix.d[13]), }, - { D2F(es->transform.matrix.d[3]), - D2F(es->transform.matrix.d[7]), - D2F(es->transform.matrix.d[15]), + { D2F(ev->transform.matrix.d[3]), + D2F(ev->transform.matrix.d[7]), + D2F(ev->transform.matrix.d[15]), } }}; @@ -337,15 +337,15 @@ repaint_region(struct weston_surface *es, struct weston_output *output, pixman_transform_multiply (&transform, &surface_transform, &transform); } else { pixman_transform_translate(&transform, NULL, - pixman_double_to_fixed ((double)-es->geometry.x), - pixman_double_to_fixed ((double)-es->geometry.y)); + pixman_double_to_fixed ((double)-ev->geometry.x), + pixman_double_to_fixed ((double)-ev->geometry.y)); } - fw = pixman_int_to_fixed(es->geometry.width); - fh = pixman_int_to_fixed(es->geometry.height); + fw = pixman_int_to_fixed(ev->geometry.width); + fh = pixman_int_to_fixed(ev->geometry.height); - switch (es->buffer_transform) { + switch (ev->surface->buffer_transform) { case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_180: @@ -357,7 +357,7 @@ repaint_region(struct weston_surface *es, struct weston_output *output, break; } - switch (es->buffer_transform) { + switch (ev->surface->buffer_transform) { default: case WL_OUTPUT_TRANSFORM_NORMAL: case WL_OUTPUT_TRANSFORM_FLIPPED: @@ -380,12 +380,12 @@ repaint_region(struct weston_surface *es, struct weston_output *output, } pixman_transform_scale(&transform, NULL, - pixman_double_to_fixed ((double)es->buffer_scale), - pixman_double_to_fixed ((double)es->buffer_scale)); + pixman_double_to_fixed ((double)ev->surface->buffer_scale), + pixman_double_to_fixed ((double)ev->surface->buffer_scale)); pixman_image_set_transform(ps->image, &transform); - if (es->transform.enabled || output->current_scale != es->buffer_scale) + if (ev->transform.enabled || output->current_scale != ev->surface->buffer_scale) pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR, NULL, 0); else pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0); @@ -417,10 +417,10 @@ repaint_region(struct weston_surface *es, struct weston_output *output, } static void -draw_surface(struct weston_surface *es, struct weston_output *output, - pixman_region32_t *damage) /* in global coordinates */ +draw_view(struct weston_view *ev, struct weston_output *output, + pixman_region32_t *damage) /* in global coordinates */ { - struct pixman_surface_state *ps = get_surface_state(es); + struct pixman_surface_state *ps = get_surface_state(ev->surface); /* repaint bounding region in global coordinates: */ pixman_region32_t repaint; /* non-opaque region in surface coordinates: */ @@ -432,8 +432,8 @@ draw_surface(struct weston_surface *es, struct weston_output *output, pixman_region32_init(&repaint); pixman_region32_intersect(&repaint, - &es->transform.boundingbox, damage); - pixman_region32_subtract(&repaint, &repaint, &es->clip); + &ev->transform.boundingbox, damage); + pixman_region32_subtract(&repaint, &repaint, &ev->clip); if (!pixman_region32_not_empty(&repaint)) goto out; @@ -444,21 +444,21 @@ draw_surface(struct weston_surface *es, struct weston_output *output, } /* TODO: Implement repaint_region_complex() using pixman_composite_trapezoids() */ - if (es->transform.enabled && - es->transform.matrix.type != WESTON_MATRIX_TRANSFORM_TRANSLATE) { - repaint_region(es, output, &repaint, NULL, PIXMAN_OP_OVER); + if (ev->transform.enabled && + ev->transform.matrix.type != WESTON_MATRIX_TRANSFORM_TRANSLATE) { + repaint_region(ev, output, &repaint, NULL, PIXMAN_OP_OVER); } else { /* blended region is whole surface minus opaque region: */ pixman_region32_init_rect(&surface_blend, 0, 0, - es->geometry.width, es->geometry.height); - pixman_region32_subtract(&surface_blend, &surface_blend, &es->opaque); + ev->geometry.width, ev->geometry.height); + pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque); - if (pixman_region32_not_empty(&es->opaque)) { - repaint_region(es, output, &repaint, &es->opaque, PIXMAN_OP_SRC); + if (pixman_region32_not_empty(&ev->surface->opaque)) { + repaint_region(ev, output, &repaint, &ev->surface->opaque, PIXMAN_OP_SRC); } if (pixman_region32_not_empty(&surface_blend)) { - repaint_region(es, output, &repaint, &surface_blend, PIXMAN_OP_OVER); + repaint_region(ev, output, &repaint, &surface_blend, PIXMAN_OP_OVER); } pixman_region32_fini(&surface_blend); } @@ -471,11 +471,11 @@ static void repaint_surfaces(struct weston_output *output, pixman_region32_t *damage) { struct weston_compositor *compositor = output->compositor; - struct weston_surface *surface; + struct weston_view *view; - wl_list_for_each_reverse(surface, &compositor->surface_list, link) - if (surface->plane == &compositor->primary_plane) - draw_surface(surface, output, damage); + wl_list_for_each_reverse(view, &compositor->view_list, link) + if (view->plane == &compositor->primary_plane) + draw_view(view, output, damage); } static void diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c index a95cc604..ea48b087 100644 --- a/src/rpi-renderer.c +++ b/src/rpi-renderer.c @@ -104,13 +104,8 @@ enum buffer_type { struct rpir_surface { struct weston_surface *surface; - /* If link is empty, the surface is guaranteed to not be on screen, - * i.e. updates removing Elements have completed. - */ - struct wl_list link; - - DISPMANX_ELEMENT_HANDLE_T handle; - int layer; + struct wl_list views; + int visible_views; int need_swap; int single_buffer; @@ -127,6 +122,20 @@ struct rpir_surface { enum buffer_type buffer_type; }; +struct rpir_view { + struct rpir_surface *surface; + struct wl_list surface_link; + struct weston_view *view; + + /* If link is empty, the view is guaranteed to not be on screen, + * i.e. updates removing Elements have completed. + */ + struct wl_list link; + + DISPMANX_ELEMENT_HANDLE_T handle; + int layer; +}; + struct rpir_output { DISPMANX_DISPLAY_HANDLE_T display; @@ -134,10 +143,10 @@ struct rpir_output { struct weston_matrix matrix; /* all Elements currently on screen */ - struct wl_list surface_list; /* struct rpir_surface::link */ + struct wl_list view_list; /* struct rpir_surface::link */ /* Elements just removed, waiting for update completion */ - struct wl_list surface_cleanup_list; /* struct rpir_surface::link */ + struct wl_list view_cleanup_list; /* struct rpir_surface::link */ struct rpi_resource capture_buffer; uint8_t *capture_data; @@ -164,6 +173,12 @@ to_rpir_surface(struct weston_surface *surface) return surface->renderer_state; } +static inline struct rpir_view * +to_rpir_view(struct weston_view *view) +{ + return view->renderer_state; +} + static inline struct rpir_output * to_rpir_output(struct weston_output *output) { @@ -356,9 +371,8 @@ rpir_surface_create(struct rpi_renderer *renderer) if (!surface) return NULL; - wl_list_init(&surface->link); + surface->visible_views = 0; surface->single_buffer = renderer->single_buffer; - surface->handle = DISPMANX_NO_HANDLE; rpi_resource_init(&surface->resources[0]); rpi_resource_init(&surface->resources[1]); surface->front = &surface->resources[0]; @@ -376,15 +390,18 @@ rpir_surface_create(struct rpi_renderer *renderer) static void rpir_surface_destroy(struct rpir_surface *surface) { - wl_list_remove(&surface->link); - - if (surface->handle != DISPMANX_NO_HANDLE) + if (surface->visible_views) weston_log("ERROR rpi: destroying on-screen element\n"); + assert(wl_list_empty(&surface->views)); + + if (surface->surface) + surface->surface->renderer_state = NULL; + pixman_region32_fini(&surface->prev_damage); rpi_resource_release(&surface->resources[0]); rpi_resource_release(&surface->resources[1]); - DBG("rpir_surface %p destroyed (%u)\n", surface, surface->handle); + DBG("rpir_surface %p destroyed (%u)\n", surface, surface->visible_views); if (surface->egl_back != NULL) { weston_buffer_reference(&surface->egl_back->buffer_ref, NULL); @@ -436,6 +453,46 @@ rpir_surface_damage(struct rpir_surface *surface, struct weston_buffer *buffer, return ret; } +static struct rpir_view * +rpir_view_create(struct rpir_surface *surface) +{ + struct rpir_view *view; + + view = calloc(1, sizeof *view); + if (!view) + return NULL; + + view->surface = surface; + wl_list_insert(&surface->views, &view->surface_link); + + wl_list_init(&view->link); + view->handle = DISPMANX_NO_HANDLE; + + return view; +} + +static void +rpir_view_destroy(struct rpir_view *view) +{ + wl_list_remove(&view->link); + + if (view->handle != DISPMANX_NO_HANDLE) { + view->surface->visible_views--; + weston_log("ERROR rpi: destroying on-screen element\n"); + } + + if (view->view) + view->view->renderer_state = NULL; + + wl_list_remove(&view->surface_link); + if (wl_list_empty(&view->surface->views) && view->surface->surface == NULL) + rpir_surface_destroy(view->surface); + + DBG("rpir_view %p destroyed (%d)\n", view, view->handle); + + free(view); +} + static void matrix_type_str(struct weston_matrix *matrix, char *buf, int len) { @@ -495,13 +552,13 @@ warn_bad_matrix(struct weston_matrix *total, struct weston_matrix *output, /*#define SURFACE_TRANSFORM */ static int -rpir_surface_compute_rects(struct rpir_surface *surface, - VC_RECT_T *src_rect, VC_RECT_T *dst_rect, - VC_IMAGE_TRANSFORM_T *flipmask) +rpir_view_compute_rects(struct rpir_view *view, + VC_RECT_T *src_rect, VC_RECT_T *dst_rect, + VC_IMAGE_TRANSFORM_T *flipmask) { - struct weston_output *output_base = surface->surface->output; + struct weston_output *output_base = view->view->surface->output; struct rpir_output *output = to_rpir_output(output_base); - struct weston_matrix matrix = surface->surface->transform.matrix; + struct weston_matrix matrix = view->view->transform.matrix; VC_IMAGE_TRANSFORM_T flipt = 0; int src_x, src_y; int dst_x, dst_y; @@ -523,14 +580,15 @@ rpir_surface_compute_rects(struct rpir_surface *surface, src_x = 0 << 16; src_y = 0 << 16; - if (surface->buffer_type == BUFFER_TYPE_EGL) { - struct weston_buffer *buffer = surface->egl_front->buffer_ref.buffer; + if (view->surface->buffer_type == BUFFER_TYPE_EGL) { + struct weston_buffer *buffer = + view->surface->egl_front->buffer_ref.buffer; src_width = buffer->width << 16; src_height = buffer->height << 16; } else { - src_width = surface->front->width << 16; - src_height = surface->front->height << 16; + src_width = view->surface->front->width << 16; + src_height = view->surface->front->height << 16; } weston_matrix_multiply(&matrix, &output->matrix); @@ -541,7 +599,7 @@ rpir_surface_compute_rects(struct rpir_surface *surface, if (matrix.type >= WESTON_MATRIX_TRANSFORM_ROTATE) { #endif warn_bad_matrix(&matrix, &output->matrix, - &surface->surface->transform.matrix); + &view->view->transform.matrix); } else { if (matrix.type & WESTON_MATRIX_TRANSFORM_ROTATE) { if (fabsf(matrix.d[0]) < 1e-4f && @@ -552,13 +610,13 @@ rpir_surface_compute_rects(struct rpir_surface *surface, /* no transpose */ } else { warn_bad_matrix(&matrix, &output->matrix, - &surface->surface->transform.matrix); + &view->view->transform.matrix); } } } - p2.f[0] = surface->surface->geometry.width; - p2.f[1] = surface->surface->geometry.height; + p2.f[0] = view->view->geometry.width; + p2.f[1] = view->view->geometry.height; /* transform top-left and bot-right corner into screen coordinates */ weston_matrix_transform(&matrix, &p1); @@ -680,9 +738,9 @@ rpir_surface_compute_rects(struct rpir_surface *surface, src_width = int_max(src_width, 0); src_height = int_max(src_height, 0); - DBG("rpir_surface %p %dx%d: p1 %f, %f; p2 %f, %f\n", surface, - surface->surface->geometry.width, - surface->surface->geometry.height, + DBG("rpir_view %p %dx%d: p1 %f, %f; p2 %f, %f\n", view, + view->view->geometry.width, + view->view->geometry.height, p1.f[0], p1.f[1], p2.f[0], p2.f[1]); DBG("src rect %d;%d, %d;%d, %d;%dx%d;%d\n", src_x >> 16, src_x & 0xffff, @@ -706,7 +764,7 @@ rpir_surface_compute_rects(struct rpir_surface *surface, } /* EGL buffers will be upside-down related to what DispmanX expects */ - if (surface->buffer_type == BUFFER_TYPE_EGL) + if (view->surface->buffer_type == BUFFER_TYPE_EGL) flipt ^= TRANSFORM_VFLIP; vc_dispmanx_rect_set(src_rect, src_x, src_y, src_width, src_height); @@ -760,8 +818,8 @@ rpir_surface_get_resource(struct rpir_surface *surface) } static int -rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, - DISPMANX_UPDATE_HANDLE_T update, int layer) +rpir_view_dmx_add(struct rpir_view *view, struct rpir_output *output, + DISPMANX_UPDATE_HANDLE_T update, int layer) { /* Do not use DISPMANX_FLAGS_ALPHA_PREMULT here. * If you define PREMULT and ALPHA_MIX, the hardware will not @@ -771,7 +829,7 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, VC_DISPMANX_ALPHA_T alphasetup = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_MIX, - float2uint8(surface->surface->alpha), /* opacity 0-255 */ + float2uint8(view->view->alpha), /* opacity 0-255 */ 0 /* mask resource handle */ }; VC_RECT_T dst_rect; @@ -780,18 +838,17 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, int ret; DISPMANX_RESOURCE_HANDLE_T resource_handle; - resource_handle = rpir_surface_get_resource(surface); + resource_handle = rpir_surface_get_resource(view->surface); if (resource_handle == DISPMANX_NO_HANDLE) { weston_log("%s: no buffer yet, aborting\n", __func__); return 0; } - ret = rpir_surface_compute_rects(surface, &src_rect, &dst_rect, - &flipmask); + ret = rpir_view_compute_rects(view, &src_rect, &dst_rect, &flipmask); if (ret < 0) return 0; - surface->handle = vc_dispmanx_element_add( + view->handle = vc_dispmanx_element_add( update, output->display, layer, @@ -802,37 +859,42 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, &alphasetup, NULL /* clamp */, vc_image2dispmanx_transform(flipmask)); - DBG("rpir_surface %p add %u, alpha %f resource %d\n", surface, - surface->handle, surface->surface->alpha, resource_handle); + DBG("rpir_surface %p add %u, alpha %f resource %d\n", view, + view->handle, view->view->alpha, resource_handle); + + if (view->handle == DISPMANX_NO_HANDLE) + return -1; + + view->surface->visible_views++; return 1; } static void -rpir_surface_dmx_swap(struct rpir_surface *surface, - DISPMANX_UPDATE_HANDLE_T update) +rpir_view_dmx_swap(struct rpir_view *view, + DISPMANX_UPDATE_HANDLE_T update) { VC_RECT_T rect; pixman_box32_t *r; /* XXX: skip, iff resource was not reallocated, and single-buffering */ - vc_dispmanx_element_change_source(update, surface->handle, - surface->front->handle); + vc_dispmanx_element_change_source(update, view->handle, + view->surface->front->handle); /* This is current damage now, after rpir_surface_damage() */ - r = pixman_region32_extents(&surface->prev_damage); + r = pixman_region32_extents(&view->surface->prev_damage); vc_dispmanx_rect_set(&rect, r->x1, r->y1, r->x2 - r->x1, r->y2 - r->y1); - vc_dispmanx_element_modified(update, surface->handle, &rect); - DBG("rpir_surface %p swap\n", surface); + vc_dispmanx_element_modified(update, view->handle, &rect); + DBG("rpir_view %p swap\n", view); } static int -rpir_surface_dmx_move(struct rpir_surface *surface, - DISPMANX_UPDATE_HANDLE_T update, int layer) +rpir_view_dmx_move(struct rpir_view *view, + DISPMANX_UPDATE_HANDLE_T update, int layer) { - uint8_t alpha = float2uint8(surface->surface->alpha); + uint8_t alpha = float2uint8(view->view->alpha); VC_RECT_T dst_rect; VC_RECT_T src_rect; VC_IMAGE_TRANSFORM_T flipmask; @@ -840,28 +902,27 @@ rpir_surface_dmx_move(struct rpir_surface *surface, /* XXX: return early, if all attributes stay the same */ - if (surface->buffer_type == BUFFER_TYPE_EGL) { + if (view->surface->buffer_type == BUFFER_TYPE_EGL) { DISPMANX_RESOURCE_HANDLE_T resource_handle; - resource_handle = rpir_surface_get_resource(surface); + resource_handle = rpir_surface_get_resource(view->surface); if (resource_handle == DISPMANX_NO_HANDLE) { weston_log("%s: no buffer yet, aborting\n", __func__); return 0; } vc_dispmanx_element_change_source(update, - surface->handle, + view->handle, resource_handle); } - ret = rpir_surface_compute_rects(surface, &src_rect, &dst_rect, - &flipmask); + ret = rpir_view_compute_rects(view, &src_rect, &dst_rect, &flipmask); if (ret < 0) return 0; ret = vc_dispmanx_element_change_attributes( update, - surface->handle, + view->handle, ELEMENT_CHANGE_LAYER | ELEMENT_CHANGE_OPACITY | ELEMENT_CHANGE_TRANSFORM | @@ -875,7 +936,7 @@ rpir_surface_dmx_move(struct rpir_surface *surface, /* This really is DISPMANX_TRANSFORM_T, no matter * what the header says. */ vc_image2dispmanx_transform(flipmask)); - DBG("rpir_surface %p move\n", surface); + DBG("rpir_view %p move\n", view); if (ret) return -1; @@ -884,15 +945,16 @@ rpir_surface_dmx_move(struct rpir_surface *surface, } static void -rpir_surface_dmx_remove(struct rpir_surface *surface, - DISPMANX_UPDATE_HANDLE_T update) +rpir_view_dmx_remove(struct rpir_view *view, + DISPMANX_UPDATE_HANDLE_T update) { - if (surface->handle == DISPMANX_NO_HANDLE) + if (view->handle == DISPMANX_NO_HANDLE) return; - vc_dispmanx_element_remove(update, surface->handle); - DBG("rpir_surface %p remove %u\n", surface, surface->handle); - surface->handle = DISPMANX_NO_HANDLE; + vc_dispmanx_element_remove(update, view->handle); + DBG("rpir_view %p remove %u\n", view, view->handle); + view->handle = DISPMANX_NO_HANDLE; + view->surface->visible_views--; } static void @@ -900,23 +962,31 @@ rpir_surface_swap_pointers(struct rpir_surface *surface) { struct rpi_resource *tmp; - tmp = surface->front; - surface->front = surface->back; - surface->back = tmp; - surface->need_swap = 0; + if (surface->buffer_type == BUFFER_TYPE_EGL) { + if (surface->egl_back != NULL) { + assert(surface->egl_old_front == NULL); + surface->egl_old_front = surface->egl_front; + surface->egl_front = surface->egl_back; + surface->egl_back = NULL; + } + } else { + tmp = surface->front; + surface->front = surface->back; + surface->back = tmp; + } DBG("new back %p, new front %p\n", surface->back, surface->front); } static int -is_surface_not_visible(struct weston_surface *surface) +is_view_not_visible(struct weston_view *view) { /* Return true, if surface is guaranteed to be totally obscured. */ int ret; pixman_region32_t unocc; pixman_region32_init(&unocc); - pixman_region32_subtract(&unocc, &surface->transform.boundingbox, - &surface->clip); + pixman_region32_subtract(&unocc, &view->transform.boundingbox, + &view->clip); ret = !pixman_region32_not_empty(&unocc); pixman_region32_fini(&unocc); @@ -924,81 +994,55 @@ is_surface_not_visible(struct weston_surface *surface) } static void -rpir_surface_update(struct rpir_surface *surface, struct rpir_output *output, - DISPMANX_UPDATE_HANDLE_T update, int layer) +rpir_view_update(struct rpir_view *view, struct rpir_output *output, + DISPMANX_UPDATE_HANDLE_T update, int layer) { - int need_swap = surface->need_swap; int ret; int obscured; - if (surface->buffer_type == BUFFER_TYPE_EGL) { - if (surface->egl_back != NULL) { - assert(surface->egl_old_front == NULL); - surface->egl_old_front = surface->egl_front; - surface->egl_front = surface->egl_back; - surface->egl_back = NULL; - } - if (surface->egl_front->buffer_ref.buffer == NULL) { - weston_log("warning: client unreffed current front buffer\n"); - - wl_list_remove(&surface->link); - if (surface->handle == DISPMANX_NO_HANDLE) { - wl_list_init(&surface->link); - } else { - rpir_surface_dmx_remove(surface, update); - wl_list_insert(&output->surface_cleanup_list, - &surface->link); - } - - goto out; - } - } else { - if (need_swap) - rpir_surface_swap_pointers(surface); - } - obscured = is_surface_not_visible(surface->surface); + obscured = is_view_not_visible(view->view); if (obscured) { - DBG("rpir_surface %p totally obscured.\n", surface); + DBG("rpir_view %p totally obscured.\n", view); - wl_list_remove(&surface->link); - if (surface->handle == DISPMANX_NO_HANDLE) { - wl_list_init(&surface->link); + wl_list_remove(&view->link); + if (view->handle == DISPMANX_NO_HANDLE) { + wl_list_init(&view->link); } else { - rpir_surface_dmx_remove(surface, update); - wl_list_insert(&output->surface_cleanup_list, - &surface->link); + rpir_view_dmx_remove(view, update); + wl_list_insert(&output->view_cleanup_list, + &view->link); } goto out; } - if (surface->handle == DISPMANX_NO_HANDLE) { - ret = rpir_surface_dmx_add(surface, output, update, layer); + if (view->handle == DISPMANX_NO_HANDLE) { + ret = rpir_view_dmx_add(view, output, update, layer); if (ret == 0) { - wl_list_remove(&surface->link); - wl_list_init(&surface->link); + wl_list_remove(&view->link); + wl_list_init(&view->link); } else if (ret < 0) { - weston_log("ERROR rpir_surface_dmx_add() failed.\n"); + weston_log("ERROR rpir_view_dmx_add() failed.\n"); } } else { - if (need_swap) - rpir_surface_dmx_swap(surface, update); + if (view->surface->need_swap) + rpir_view_dmx_swap(view, update); - ret = rpir_surface_dmx_move(surface, update, layer); + ret = rpir_view_dmx_move(view, update, layer); if (ret == 0) { - rpir_surface_dmx_remove(surface, update); + rpir_view_dmx_remove(view, update); - wl_list_remove(&surface->link); - wl_list_insert(&output->surface_cleanup_list, - &surface->link); + wl_list_remove(&view->link); + wl_list_insert(&output->view_cleanup_list, + &view->link); } else if (ret < 0) { - weston_log("ERROR rpir_surface_dmx_move() failed.\n"); + weston_log("ERROR rpir_view_dmx_move() failed.\n"); } } out: - surface->layer = layer; + view->layer = layer; } static int @@ -1105,15 +1149,15 @@ static void rpir_output_dmx_remove_all(struct rpir_output *output, DISPMANX_UPDATE_HANDLE_T update) { - struct rpir_surface *surface; + struct rpir_view *view; - while (!wl_list_empty(&output->surface_list)) { - surface = container_of(output->surface_list.next, - struct rpir_surface, link); - rpir_surface_dmx_remove(surface, update); + while (!wl_list_empty(&output->view_list)) { + view = container_of(output->view_list.next, + struct rpir_view, link); + rpir_view_dmx_remove(view, update); - wl_list_remove(&surface->link); - wl_list_insert(&output->surface_cleanup_list, &surface->link); + wl_list_remove(&view->link); + wl_list_insert(&output->view_cleanup_list, &view->link); } } @@ -1186,8 +1230,8 @@ rpi_renderer_repaint_output(struct weston_output *base, { struct weston_compositor *compositor = base->compositor; struct rpir_output *output = to_rpir_output(base); - struct weston_surface *ws; - struct rpir_surface *surface; + struct weston_view *wv; + struct rpir_view *view; struct wl_list done_list; int layer = 1; @@ -1199,27 +1243,59 @@ rpi_renderer_repaint_output(struct weston_output *base, free(output->capture_data); output->capture_data = NULL; + /* Swap resources on surfaces as needed */ + wl_list_for_each_reverse(wv, &compositor->view_list, link) + wv->surface->touched = 0; + + wl_list_for_each_reverse(wv, &compositor->view_list, link) { + view = to_rpir_view(wv); + + if (!wv->surface->touched) { + wv->surface->touched = 1; + + if (view->surface->need_swap) + rpir_surface_swap_pointers(view->surface); + } + + if (view->surface->egl_front->buffer_ref.buffer == NULL) { + weston_log("warning: client unreffed current front buffer\n"); + + wl_list_remove(&view->link); + if (view->handle == DISPMANX_NO_HANDLE) { + wl_list_init(&view->link); + } else { + rpir_view_dmx_remove(view, output->update); + wl_list_insert(&output->view_cleanup_list, + &view->link); + } + } + } + /* update all renderable surfaces */ wl_list_init(&done_list); - wl_list_for_each_reverse(ws, &compositor->surface_list, link) { - if (ws->plane != &compositor->primary_plane) + wl_list_for_each_reverse(wv, &compositor->view_list, link) { + if (wv->plane != &compositor->primary_plane) continue; - surface = to_rpir_surface(ws); - assert(!wl_list_empty(&surface->link) || - surface->handle == DISPMANX_NO_HANDLE); + view = to_rpir_view(wv); + assert(!wl_list_empty(&view->link) || + view->handle == DISPMANX_NO_HANDLE); - wl_list_remove(&surface->link); - wl_list_insert(&done_list, &surface->link); - rpir_surface_update(surface, output, output->update, layer++); + wl_list_remove(&view->link); + wl_list_insert(&done_list, &view->link); + rpir_view_update(view, output, output->update, layer++); } + /* Mark all surfaces as swapped */ + wl_list_for_each_reverse(wv, &compositor->view_list, link) + to_rpir_surface(wv->surface)->need_swap = 0; + /* Remove all surfaces that are still on screen, but were * not rendered this time. */ rpir_output_dmx_remove_all(output, output->update); - wl_list_insert_list(&output->surface_list, &done_list); + wl_list_insert_list(&output->view_list, &done_list); output->update = DISPMANX_NO_HANDLE; /* The frame_signal is emitted in rpi_renderer_finish_frame(), @@ -1263,7 +1339,7 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer) /* XXX: need to check if in middle of update */ rpi_resource_release(surface->back); - if (surface->handle == DISPMANX_NO_HANDLE) + if (!surface->visible_views) /* XXX: cannot do this, if middle of an update */ rpi_resource_release(surface->front); @@ -1336,6 +1412,23 @@ rpi_renderer_create_surface(struct weston_surface *base) return 0; } +static int +rpi_renderer_create_view(struct weston_view *base) +{ + struct rpir_surface *surface = to_rpir_surface(base->surface); + struct rpir_view *view; + + assert(base->renderer_state == NULL); + + view = rpir_view_create(surface); + if (!view) + return -1; + + view->view = base; + base->renderer_state = view; + return 0; +} + static void rpi_renderer_surface_set_color(struct weston_surface *base, float red, float green, float blue, float alpha) @@ -1390,13 +1483,27 @@ rpi_renderer_destroy_surface(struct weston_surface *base) surface->surface = NULL; base->renderer_state = NULL; - /* If guaranteed to not be on screen, just detroy it. */ - if (wl_list_empty(&surface->link)) + if (wl_list_empty(&surface->views)) rpir_surface_destroy(surface); +} - /* Otherwise, the surface is either on screen and needs +static void +rpi_renderer_destroy_view(struct weston_view *base) +{ + struct rpir_view *view = to_rpir_view(base); + + assert(view); + assert(view->view == base); + if (!view) + return; + + /* If guaranteed to not be on screen, just detroy it. */ + if (wl_list_empty(&view->link)) + rpir_view_destroy(view); + + /* Otherwise, the view is either on screen and needs * to be removed by a repaint update, or it is in the - * surface_cleanup_list, and will be destroyed by + * view_cleanup_list, and will be destroyed by * rpi_renderer_finish_frame(). */ } @@ -1440,8 +1547,10 @@ rpi_renderer_create(struct weston_compositor *compositor, renderer->base.flush_damage = rpi_renderer_flush_damage; renderer->base.attach = rpi_renderer_attach; renderer->base.create_surface = rpi_renderer_create_surface; + renderer->base.create_view = rpi_renderer_create_view; renderer->base.surface_set_color = rpi_renderer_surface_set_color; renderer->base.destroy_surface = rpi_renderer_destroy_surface; + renderer->base.destroy_view = rpi_renderer_destroy_view; renderer->base.destroy = rpi_renderer_destroy; #ifdef ENABLE_EGL @@ -1504,8 +1613,8 @@ rpi_renderer_output_create(struct weston_output *base, output->display = display; output->update = DISPMANX_NO_HANDLE; - wl_list_init(&output->surface_list); - wl_list_init(&output->surface_cleanup_list); + wl_list_init(&output->view_list); + wl_list_init(&output->view_cleanup_list); rpi_resource_init(&output->capture_buffer); base->renderer_state = output; @@ -1516,7 +1625,7 @@ WL_EXPORT void rpi_renderer_output_destroy(struct weston_output *base) { struct rpir_output *output = to_rpir_output(base); - struct rpir_surface *surface; + struct rpir_view *view; DISPMANX_UPDATE_HANDLE_T update; rpi_resource_release(&output->capture_buffer); @@ -1527,12 +1636,10 @@ rpi_renderer_output_destroy(struct weston_output *base) rpir_output_dmx_remove_all(output, update); vc_dispmanx_update_submit_sync(update); - while (!wl_list_empty(&output->surface_cleanup_list)) { - surface = container_of(output->surface_cleanup_list.next, - struct rpir_surface, link); - if (surface->surface) - surface->surface->renderer_state = NULL; - rpir_surface_destroy(surface); + while (!wl_list_empty(&output->view_cleanup_list)) { + view = container_of(output->view_cleanup_list.next, + struct rpir_view, link); + rpir_view_destroy(view); } free(output); @@ -1553,41 +1660,41 @@ rpi_renderer_finish_frame(struct weston_output *base) { struct rpir_output *output = to_rpir_output(base); struct weston_compositor *compositor = base->compositor; - struct weston_surface *ws; - struct rpir_surface *surface; + struct weston_view *wv; + struct rpir_view *view; - while (!wl_list_empty(&output->surface_cleanup_list)) { - surface = container_of(output->surface_cleanup_list.next, - struct rpir_surface, link); + while (!wl_list_empty(&output->view_cleanup_list)) { + view = container_of(output->view_cleanup_list.next, + struct rpir_view, link); - if (surface->surface) { - /* The weston_surface still exists, but is + if (view->view) { + /* The weston_view still exists, but is * temporarily not visible, and hence its Element * was removed. The current front buffer contents * must be preserved. */ - if (!surface->single_buffer) - rpi_resource_release(surface->back); + if (!view->surface->visible_views) + rpi_resource_release(view->surface->back); - wl_list_remove(&surface->link); - wl_list_init(&surface->link); + wl_list_remove(&view->link); + wl_list_init(&view->link); } else { - rpir_surface_destroy(surface); + rpir_view_destroy(view); } } - wl_list_for_each(ws, &compositor->surface_list, link) { - surface = to_rpir_surface(ws); + wl_list_for_each(wv, &compositor->view_list, link) { + view = to_rpir_view(wv); - if (surface->buffer_type != BUFFER_TYPE_EGL) + if (view->surface->buffer_type != BUFFER_TYPE_EGL) continue; - if(surface->egl_old_front == NULL) + if (view->surface->egl_old_front == NULL) continue; - weston_buffer_reference(&surface->egl_old_front->buffer_ref, NULL); - free(surface->egl_old_front); - surface->egl_old_front = NULL; + weston_buffer_reference(&view->surface->egl_old_front->buffer_ref, NULL); + free(view->surface->egl_old_front); + view->surface->egl_old_front = NULL; } wl_signal_emit(&base->frame_signal, base); diff --git a/src/shell.c b/src/shell.c index e0c35272..96638704 100644 --- a/src/shell.c +++ b/src/shell.c @@ -79,6 +79,7 @@ struct input_panel_surface { struct wl_list link; struct weston_surface *surface; + struct weston_view *view; struct wl_listener surface_destroy_listener; struct weston_output *output; @@ -155,8 +156,8 @@ struct desktop_shell { } input_panel; struct { - struct weston_surface *surface; - struct weston_surface_animation *animation; + struct weston_view *view; + struct weston_view_animation *animation; enum fade_type type; struct wl_event_source *startup_timer; } fade; @@ -186,6 +187,7 @@ struct shell_surface { struct wl_signal destroy_signal; struct weston_surface *surface; + struct weston_view *view; struct wl_listener surface_destroy_listener; struct weston_surface *parent; struct desktop_shell *shell; @@ -218,7 +220,7 @@ struct shell_surface { enum wl_shell_surface_fullscreen_method type; struct weston_transform transform; /* matrix from x, y */ uint32_t framerate; - struct weston_surface *black_surface; + struct weston_view *black_view; } fullscreen; struct ping_timer *ping_timer; @@ -299,17 +301,17 @@ static bool shell_surface_is_top_fullscreen(struct shell_surface *shsurf) { struct desktop_shell *shell; - struct weston_surface *top_fs_es; + struct weston_view *top_fs_ev; shell = shell_surface_get_shell(shsurf); - if (wl_list_empty(&shell->fullscreen_layer.surface_list)) + if (wl_list_empty(&shell->fullscreen_layer.view_list)) return false; - top_fs_es = container_of(shell->fullscreen_layer.surface_list.next, - struct weston_surface, + top_fs_ev = container_of(shell->fullscreen_layer.view_list.next, + struct weston_view, layer_link); - return (shsurf == get_shell_surface(top_fs_es)); + return (shsurf == get_shell_surface(top_fs_ev->surface)); } static void @@ -323,6 +325,26 @@ destroy_shell_grab_shsurf(struct wl_listener *listener, void *data) grab->shsurf = NULL; } +static struct weston_view * +get_default_view(struct weston_surface *surface) +{ + struct shell_surface *shsurf; + struct weston_view *view; + + if (!surface || wl_list_empty(&surface->views)) + return NULL; + + shsurf = get_shell_surface(surface); + if (shsurf) + return shsurf->view; + + wl_list_for_each(view, &surface->views, surface_link) + if (weston_view_is_mapped(view)) + return view; + + return container_of(surface->views.next, struct weston_view, surface_link); +} + static void popup_grab_end(struct weston_pointer *pointer); @@ -347,7 +369,8 @@ shell_grab_start(struct shell_grab *grab, if (shell->child.desktop_shell) { desktop_shell_send_grab_cursor(shell->child.desktop_shell, cursor); - weston_pointer_set_focus(pointer, shell->grab_surface, + weston_pointer_set_focus(pointer, + get_default_view(shell->grab_surface), wl_fixed_from_int(0), wl_fixed_from_int(0)); } @@ -380,7 +403,8 @@ shell_touch_grab_start(struct shell_touch_grab *grab, weston_touch_start_grab(touch, &grab->grab); if (shell->child.desktop_shell) - weston_touch_set_focus(touch->seat, shell->grab_surface); + weston_touch_set_focus(touch->seat, + get_default_view(shell->grab_surface)); } static void @@ -393,7 +417,7 @@ shell_touch_grab_end(struct shell_touch_grab *grab) } static void -center_on_output(struct weston_surface *surface, +center_on_output(struct weston_view *view, struct weston_output *output); static enum weston_keyboard_modifier @@ -481,17 +505,17 @@ focus_state_surface_destroy(struct wl_listener *listener, void *data) struct focus_state, surface_destroy_listener); struct desktop_shell *shell; - struct weston_surface *main_surface; - struct weston_surface *surface, *next; + struct weston_surface *main_surface, *next; + struct weston_view *view; main_surface = weston_surface_get_main_surface(state->keyboard_focus); next = NULL; - wl_list_for_each(surface, &state->ws->layer.surface_list, layer_link) { - if (surface == main_surface) + wl_list_for_each(view, &state->ws->layer.view_list, layer_link) { + if (view->surface == main_surface) continue; - next = surface; + next = view->surface; break; } @@ -630,7 +654,7 @@ workspace_create(void) static int workspace_is_empty(struct workspace *ws) { - return wl_list_empty(&ws->layer.surface_list); + return wl_list_empty(&ws->layer.view_list); } static struct workspace * @@ -666,53 +690,53 @@ get_output_height(struct weston_output *output) } static void -surface_translate(struct weston_surface *surface, double d) +view_translate(struct weston_view *view, double d) { - struct shell_surface *shsurf = get_shell_surface(surface); + struct shell_surface *shsurf = get_shell_surface(view->surface); struct weston_transform *transform; transform = &shsurf->workspace_transform; if (wl_list_empty(&transform->link)) - wl_list_insert(surface->geometry.transformation_list.prev, + wl_list_insert(view->geometry.transformation_list.prev, &shsurf->workspace_transform.link); weston_matrix_init(&shsurf->workspace_transform.matrix); weston_matrix_translate(&shsurf->workspace_transform.matrix, 0.0, d, 0.0); - weston_surface_geometry_dirty(surface); + weston_view_geometry_dirty(view); } static void workspace_translate_out(struct workspace *ws, double fraction) { - struct weston_surface *surface; + struct weston_view *view; unsigned int height; double d; - wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { - height = get_output_height(surface->output); + wl_list_for_each(view, &ws->layer.view_list, layer_link) { + height = get_output_height(view->surface->output); d = height * fraction; - surface_translate(surface, d); + view_translate(view, d); } } static void workspace_translate_in(struct workspace *ws, double fraction) { - struct weston_surface *surface; + struct weston_view *view; unsigned int height; double d; - wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { - height = get_output_height(surface->output); + wl_list_for_each(view, &ws->layer.view_list, layer_link) { + height = get_output_height(view->surface->output); if (fraction > 0) d = -(height - height * fraction); else d = height + height * fraction; - surface_translate(surface, d); + view_translate(view, d); } } @@ -746,16 +770,16 @@ reverse_workspace_change_animation(struct desktop_shell *shell, static void workspace_deactivate_transforms(struct workspace *ws) { - struct weston_surface *surface; + struct weston_view *view; struct shell_surface *shsurf; - wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { - shsurf = get_shell_surface(surface); + wl_list_for_each(view, &ws->layer.view_list, layer_link) { + shsurf = get_shell_surface(view->surface); if (!wl_list_empty(&shsurf->workspace_transform.link)) { wl_list_remove(&shsurf->workspace_transform.link); wl_list_init(&shsurf->workspace_transform.link); } - weston_surface_geometry_dirty(surface); + weston_view_geometry_dirty(view); } } @@ -881,7 +905,7 @@ change_workspace(struct desktop_shell *shell, unsigned int index) return; /* Don't change workspace when there is any fullscreen surfaces. */ - if (!wl_list_empty(&shell->fullscreen_layer.surface_list)) + if (!wl_list_empty(&shell->fullscreen_layer.view_list)) return; from = get_current_workspace(shell); @@ -913,7 +937,7 @@ change_workspace(struct desktop_shell *shell, unsigned int index) static bool workspace_has_only(struct workspace *ws, struct weston_surface *surface) { - struct wl_list *list = &ws->layer.surface_list; + struct wl_list *list = &ws->layer.view_list; struct wl_list *e; if (wl_list_empty(list)) @@ -924,20 +948,20 @@ workspace_has_only(struct workspace *ws, struct weston_surface *surface) if (e->next != list) return false; - return container_of(e, struct weston_surface, layer_link) == surface; + return container_of(e, struct weston_view, layer_link)->surface == surface; } static void -move_surface_to_workspace(struct desktop_shell *shell, - struct weston_surface *surface, - uint32_t workspace) +move_view_to_workspace(struct desktop_shell *shell, + struct weston_view *view, + uint32_t workspace) { struct workspace *from; struct workspace *to; struct weston_seat *seat; struct weston_surface *focus; - assert(weston_surface_get_main_surface(surface) == surface); + assert(weston_surface_get_main_surface(view->surface) == view->surface); if (workspace == shell->workspaces.current) return; @@ -948,20 +972,20 @@ move_surface_to_workspace(struct desktop_shell *shell, from = get_current_workspace(shell); to = get_workspace(shell, workspace); - wl_list_remove(&surface->layer_link); - wl_list_insert(&to->layer.surface_list, &surface->layer_link); + wl_list_remove(&view->layer_link); + wl_list_insert(&to->layer.view_list, &view->layer_link); - drop_focus_state(shell, from, surface); + drop_focus_state(shell, from, view->surface); wl_list_for_each(seat, &shell->compositor->seat_list, link) { if (!seat->keyboard) continue; focus = weston_surface_get_main_surface(seat->keyboard->focus); - if (focus == surface) + if (focus == view->surface) weston_keyboard_set_focus(seat->keyboard, NULL); } - weston_surface_damage_below(surface); + weston_view_damage_below(view); } static void @@ -970,21 +994,23 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell, unsigned int index) { struct weston_surface *surface; + struct weston_view *view; struct shell_surface *shsurf; struct workspace *from; struct workspace *to; struct focus_state *state; surface = weston_surface_get_main_surface(seat->keyboard->focus); - if (surface == NULL || + view = get_default_view(surface); + if (view == NULL || index == shell->workspaces.current) return; from = get_current_workspace(shell); to = get_workspace(shell, index); - wl_list_remove(&surface->layer_link); - wl_list_insert(&to->layer.surface_list, &surface->layer_link); + wl_list_remove(&view->layer_link); + wl_list_insert(&to->layer.view_list, &view->layer_link); replace_focus_state(shell, to, seat); drop_focus_state(shell, from, surface); @@ -1034,9 +1060,13 @@ workspace_manager_move_surface(struct wl_client *client, struct weston_surface *surface = wl_resource_get_user_data(surface_resource); struct weston_surface *main_surface; + struct weston_view *view; main_surface = weston_surface_get_main_surface(surface); - move_surface_to_workspace(shell, main_surface, workspace); + view = get_default_view(main_surface); + if (!view) + return; + move_view_to_workspace(shell, view, workspace); } static const struct workspace_manager_interface workspace_manager_implementation = { @@ -1107,8 +1137,9 @@ touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time, es = shsurf->surface; - weston_surface_configure(es, dx, dy, - es->geometry.width, es->geometry.height); + weston_view_configure(shsurf->view, dx, dy, + shsurf->view->geometry.width, + shsurf->view->geometry.height); weston_compositor_schedule_repaint(es->compositor); } @@ -1134,9 +1165,9 @@ surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat) if (!move) return -1; - move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) - + move->dx = wl_fixed_from_double(shsurf->view->geometry.x) - seat->touch->grab_x; - move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) - + move->dy = wl_fixed_from_double(shsurf->view->geometry.y) - seat->touch->grab_y; shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf, @@ -1156,19 +1187,17 @@ move_grab_motion(struct weston_pointer_grab *grab, uint32_t time) struct weston_move_grab *move = (struct weston_move_grab *) grab; struct weston_pointer *pointer = grab->pointer; struct shell_surface *shsurf = move->base.shsurf; - struct weston_surface *es; int dx = wl_fixed_to_int(pointer->x + move->dx); int dy = wl_fixed_to_int(pointer->y + move->dy); if (!shsurf) return; - es = shsurf->surface; - - weston_surface_configure(es, dx, dy, - es->geometry.width, es->geometry.height); + weston_view_configure(shsurf->view, dx, dy, + shsurf->view->geometry.width, + shsurf->view->geometry.height); - weston_compositor_schedule_repaint(es->compositor); + weston_compositor_schedule_repaint(shsurf->surface->compositor); } static void @@ -1208,9 +1237,9 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat) if (!move) return -1; - move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) - + move->dx = wl_fixed_from_double(shsurf->view->geometry.x) - seat->pointer->grab_x; - move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) - + move->dy = wl_fixed_from_double(shsurf->view->geometry.y) - seat->pointer->grab_y; shell_grab_start(&move->base, &move_grab_interface, shsurf, @@ -1230,13 +1259,13 @@ shell_surface_move(struct wl_client *client, struct wl_resource *resource, if (seat->pointer && seat->pointer->button_count > 0 && seat->pointer->grab_serial == serial) { - surface = weston_surface_get_main_surface(seat->pointer->focus); + surface = weston_surface_get_main_surface(seat->pointer->focus->surface); if ((surface == shsurf->surface) && (surface_move(shsurf, seat) < 0)) wl_resource_post_no_memory(resource); } else if (seat->touch && seat->touch->grab_serial == serial) { - surface = weston_surface_get_main_surface(seat->touch->focus); + surface = weston_surface_get_main_surface(seat->touch->focus->surface); if ((surface == shsurf->surface) && (surface_touch_move(shsurf, seat) < 0)) wl_resource_post_no_memory(resource); @@ -1262,11 +1291,11 @@ resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time) if (!shsurf) return; - weston_surface_from_global_fixed(shsurf->surface, - pointer->grab_x, pointer->grab_y, - &from_x, &from_y); - weston_surface_from_global_fixed(shsurf->surface, - pointer->x, pointer->y, &to_x, &to_y); + weston_view_from_global_fixed(shsurf->view, + pointer->grab_x, pointer->grab_y, + &from_x, &from_y); + weston_view_from_global_fixed(shsurf->view, + pointer->x, pointer->y, &to_x, &to_y); width = resize->width; if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) { @@ -1332,15 +1361,15 @@ surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x, struct weston_subsurface *subsurface; pixman_region32_init_rect(®ion, 0, 0, - surface->geometry.width, - surface->geometry.height); + surface->width, + surface->height); wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { pixman_region32_union_rect(®ion, ®ion, subsurface->position.x, subsurface->position.y, - subsurface->surface->geometry.width, - subsurface->surface->geometry.height); + subsurface->surface->width, + subsurface->surface->height); } box = pixman_region32_extents(®ion); @@ -1396,7 +1425,7 @@ shell_surface_resize(struct wl_client *client, struct wl_resource *resource, if (shsurf->type == SHELL_SURFACE_FULLSCREEN) return; - surface = weston_surface_get_main_surface(seat->pointer->focus); + surface = weston_surface_get_main_surface(seat->pointer->focus->surface); if (seat->pointer->button_count == 0 || seat->pointer->grab_serial != serial || surface != shsurf->surface) @@ -1414,14 +1443,14 @@ busy_cursor_grab_focus(struct weston_pointer_grab *base) { struct shell_grab *grab = (struct shell_grab *) base; struct weston_pointer *pointer = base->pointer; - struct weston_surface *surface; + struct weston_view *view; wl_fixed_t sx, sy; - surface = weston_compositor_pick_surface(pointer->seat->compositor, - pointer->x, pointer->y, - &sx, &sy); + view = weston_compositor_pick_view(pointer->seat->compositor, + pointer->x, pointer->y, + &sx, &sy); - if (!grab->shsurf || grab->shsurf->surface != surface) + if (!grab->shsurf || grab->shsurf->surface != view->surface) end_busy_cursor(grab->shsurf, pointer); } @@ -1501,7 +1530,7 @@ ping_timeout_handler(void *data) shsurf->unresponsive = 1; wl_list_for_each(seat, &shsurf->surface->compositor->seat_list, link) - if (seat->pointer->focus == shsurf->surface) + if (seat->pointer->focus->surface == shsurf->surface) set_busy_cursor(shsurf, seat->pointer); return 1; @@ -1541,22 +1570,22 @@ static void handle_pointer_focus(struct wl_listener *listener, void *data) { struct weston_pointer *pointer = data; - struct weston_surface *surface = pointer->focus; + struct weston_view *view = pointer->focus; struct weston_compositor *compositor; struct shell_surface *shsurf; uint32_t serial; - if (!surface) + if (!view) return; - compositor = surface->compositor; - shsurf = get_shell_surface(surface); + compositor = view->surface->compositor; + shsurf = get_shell_surface(view->surface); if (shsurf && shsurf->unresponsive) { set_busy_cursor(shsurf, pointer); } else { serial = wl_display_next_serial(compositor->wl_display); - ping_handler(surface, serial); + ping_handler(view->surface, serial); } } @@ -1661,21 +1690,21 @@ shell_unset_fullscreen(struct shell_surface *shsurf) shsurf->fullscreen.framerate = 0; wl_list_remove(&shsurf->fullscreen.transform.link); wl_list_init(&shsurf->fullscreen.transform.link); - if (shsurf->fullscreen.black_surface) - weston_surface_destroy(shsurf->fullscreen.black_surface); - shsurf->fullscreen.black_surface = NULL; + if (shsurf->fullscreen.black_view) + weston_surface_destroy(shsurf->fullscreen.black_view->surface); + shsurf->fullscreen.black_view = NULL; shsurf->fullscreen_output = NULL; - weston_surface_set_position(shsurf->surface, - shsurf->saved_x, shsurf->saved_y); + weston_view_set_position(shsurf->view, + shsurf->saved_x, shsurf->saved_y); if (shsurf->saved_rotation_valid) { - wl_list_insert(&shsurf->surface->geometry.transformation_list, + wl_list_insert(&shsurf->view->geometry.transformation_list, &shsurf->rotation.transform.link); shsurf->saved_rotation_valid = false; } ws = get_current_workspace(shsurf->shell); - wl_list_remove(&shsurf->surface->layer_link); - wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link); + wl_list_remove(&shsurf->view->layer_link); + wl_list_insert(&ws->layer.view_list, &shsurf->view->layer_link); } static void @@ -1684,19 +1713,19 @@ shell_unset_maximized(struct shell_surface *shsurf) struct workspace *ws; /* undo all maximized things here */ shsurf->output = get_default_output(shsurf->surface->compositor); - weston_surface_set_position(shsurf->surface, - shsurf->saved_x, - shsurf->saved_y); + weston_view_set_position(shsurf->view, + shsurf->saved_x, + shsurf->saved_y); if (shsurf->saved_rotation_valid) { - wl_list_insert(&shsurf->surface->geometry.transformation_list, - &shsurf->rotation.transform.link); + wl_list_insert(&shsurf->view->geometry.transformation_list, + &shsurf->rotation.transform.link); shsurf->saved_rotation_valid = false; } ws = get_current_workspace(shsurf->shell); - wl_list_remove(&shsurf->surface->layer_link); - wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link); + wl_list_remove(&shsurf->view->layer_link); + wl_list_insert(&ws->layer.view_list, &shsurf->view->layer_link); } static int @@ -1724,8 +1753,8 @@ reset_shell_surface_type(struct shell_surface *surface) static void set_surface_type(struct shell_surface *shsurf) { - struct weston_surface *surface = shsurf->surface; struct weston_surface *pes = shsurf->parent; + struct weston_view *pev = get_default_view(pes); reset_shell_surface_type(shsurf); @@ -1736,28 +1765,29 @@ set_surface_type(struct shell_surface *shsurf) case SHELL_SURFACE_TOPLEVEL: break; case SHELL_SURFACE_TRANSIENT: - weston_surface_set_position(surface, - pes->geometry.x + shsurf->transient.x, - pes->geometry.y + shsurf->transient.y); + if (pev) + weston_view_set_position(shsurf->view, + pev->geometry.x + shsurf->transient.x, + pev->geometry.y + shsurf->transient.y); break; case SHELL_SURFACE_MAXIMIZED: case SHELL_SURFACE_FULLSCREEN: - shsurf->saved_x = surface->geometry.x; - shsurf->saved_y = surface->geometry.y; + shsurf->saved_x = shsurf->view->geometry.x; + shsurf->saved_y = shsurf->view->geometry.y; shsurf->saved_position_valid = true; if (!wl_list_empty(&shsurf->rotation.transform.link)) { wl_list_remove(&shsurf->rotation.transform.link); wl_list_init(&shsurf->rotation.transform.link); - weston_surface_geometry_dirty(shsurf->surface); + weston_view_geometry_dirty(shsurf->view); shsurf->saved_rotation_valid = true; } break; case SHELL_SURFACE_XWAYLAND: - weston_surface_set_position(surface, shsurf->transient.x, - shsurf->transient.y); + weston_view_set_position(shsurf->view, shsurf->transient.x, + shsurf->transient.y); break; default: @@ -1815,15 +1845,15 @@ static int get_output_panel_height(struct desktop_shell *shell, struct weston_output *output) { - struct weston_surface *surface; + struct weston_view *view; int panel_height = 0; if (!output) return 0; - wl_list_for_each(surface, &shell->panel_layer.surface_list, layer_link) { - if (surface->output == output) { - panel_height = surface->geometry.height; + wl_list_for_each(view, &shell->panel_layer.view_list, layer_link) { + if (view->surface->output == output) { + panel_height = view->geometry.height; break; } } @@ -1864,29 +1894,37 @@ shell_surface_set_maximized(struct wl_client *client, static void black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height); -static struct weston_surface * +static struct weston_view * create_black_surface(struct weston_compositor *ec, struct weston_surface *fs_surface, float x, float y, int w, int h) { struct weston_surface *surface = NULL; + struct weston_view *view; surface = weston_surface_create(ec); if (surface == NULL) { weston_log("no memory\n"); return NULL; } + view = weston_view_create(surface); + if (surface == NULL) { + weston_log("no memory\n"); + weston_surface_destroy(surface); + return NULL; + } surface->configure = black_surface_configure; surface->configure_private = fs_surface; - weston_surface_configure(surface, x, y, w, h); weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); pixman_region32_fini(&surface->opaque); pixman_region32_init_rect(&surface->opaque, 0, 0, w, h); pixman_region32_fini(&surface->input); pixman_region32_init_rect(&surface->input, 0, 0, w, h); - return surface; + weston_view_configure(view, x, y, w, h); + + return view; } /* Create black surface and append it to the associated fullscreen surface. @@ -1903,33 +1941,35 @@ shell_configure_fullscreen(struct shell_surface *shsurf) if (shsurf->fullscreen.type != WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER) restore_output_mode(output); - if (!shsurf->fullscreen.black_surface) - shsurf->fullscreen.black_surface = + if (!shsurf->fullscreen.black_view) + shsurf->fullscreen.black_view = create_black_surface(surface->compositor, surface, output->x, output->y, output->width, output->height); - wl_list_remove(&shsurf->fullscreen.black_surface->layer_link); - wl_list_insert(&surface->layer_link, - &shsurf->fullscreen.black_surface->layer_link); - shsurf->fullscreen.black_surface->output = output; + wl_list_remove(&shsurf->fullscreen.black_view->layer_link); + wl_list_insert(&shsurf->view->layer_link, + &shsurf->fullscreen.black_view->layer_link); + shsurf->fullscreen.black_view->surface->output = output; + shsurf->fullscreen.black_view->output = output; - surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y, + surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y, &surf_width, &surf_height); switch (shsurf->fullscreen.type) { case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT: if (surface->buffer_ref.buffer) - center_on_output(surface, shsurf->fullscreen_output); + center_on_output(shsurf->view, shsurf->fullscreen_output); break; case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE: /* 1:1 mapping between surface and output dimensions */ if (output->width == surf_width && output->height == surf_height) { - weston_surface_set_position(surface, output->x - surf_x, - output->y - surf_y); + weston_view_set_position(shsurf->view, + output->x - surf_x, + output->y - surf_y); break; } @@ -1938,8 +1978,9 @@ shell_configure_fullscreen(struct shell_surface *shsurf) output_aspect = (float) output->width / (float) output->height; - surface_aspect = (float) surface->geometry.width / - (float) surface->geometry.height; + /* XXX: Use surf_width and surf_height here? */ + surface_aspect = (float) surface->width / + (float) surface->height; if (output_aspect < surface_aspect) scale = (float) output->width / (float) surf_width; @@ -1949,11 +1990,11 @@ shell_configure_fullscreen(struct shell_surface *shsurf) weston_matrix_scale(matrix, scale, scale, 1); wl_list_remove(&shsurf->fullscreen.transform.link); - wl_list_insert(&surface->geometry.transformation_list, + wl_list_insert(&shsurf->view->geometry.transformation_list, &shsurf->fullscreen.transform.link); x = output->x + (output->width - surf_width * scale) / 2 - surf_x; y = output->y + (output->height - surf_height * scale) / 2 - surf_y; - weston_surface_set_position(surface, x, y); + weston_view_set_position(shsurf->view, x, y); break; case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER: @@ -1965,23 +2006,23 @@ shell_configure_fullscreen(struct shell_surface *shsurf) if (weston_output_switch_mode(output, &mode, surface->buffer_scale, WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) { - weston_surface_set_position(surface, - output->x - surf_x, - output->y - surf_y); - weston_surface_configure(shsurf->fullscreen.black_surface, - output->x - surf_x, - output->y - surf_y, - output->width, - output->height); + weston_view_set_position(shsurf->view, + output->x - surf_x, + output->y - surf_y); + weston_view_configure(shsurf->fullscreen.black_view, + output->x - surf_x, + output->y - surf_y, + output->width, + output->height); break; } else { restore_output_mode(output); - center_on_output(surface, output); + center_on_output(shsurf->view, output); } } break; case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL: - center_on_output(surface, output); + center_on_output(shsurf->view, output); break; default: break; @@ -1993,26 +2034,25 @@ static void shell_stack_fullscreen(struct shell_surface *shsurf) { struct weston_output *output = shsurf->fullscreen_output; - struct weston_surface *surface = shsurf->surface; struct desktop_shell *shell = shell_surface_get_shell(shsurf); - wl_list_remove(&surface->layer_link); - wl_list_insert(&shell->fullscreen_layer.surface_list, - &surface->layer_link); - weston_surface_damage(surface); + wl_list_remove(&shsurf->view->layer_link); + wl_list_insert(&shell->fullscreen_layer.view_list, + &shsurf->view->layer_link); + weston_surface_damage(shsurf->surface); - if (!shsurf->fullscreen.black_surface) - shsurf->fullscreen.black_surface = - create_black_surface(surface->compositor, - surface, + if (!shsurf->fullscreen.black_view) + shsurf->fullscreen.black_view = + create_black_surface(shsurf->surface->compositor, + shsurf->surface, output->x, output->y, output->width, output->height); - wl_list_remove(&shsurf->fullscreen.black_surface->layer_link); - wl_list_insert(&surface->layer_link, - &shsurf->fullscreen.black_surface->layer_link); - weston_surface_damage(shsurf->fullscreen.black_surface); + wl_list_remove(&shsurf->fullscreen.black_view->layer_link); + wl_list_insert(&shsurf->view->layer_link, + &shsurf->fullscreen.black_view->layer_link); + weston_surface_damage(shsurf->fullscreen.black_view->surface); } static void @@ -2141,18 +2181,19 @@ static void popup_grab_focus(struct weston_pointer_grab *grab) { struct weston_pointer *pointer = grab->pointer; - struct weston_surface *surface; + struct weston_view *view; struct shell_seat *shseat = container_of(grab, struct shell_seat, popup_grab.grab); struct wl_client *client = shseat->popup_grab.client; wl_fixed_t sx, sy; - surface = weston_compositor_pick_surface(pointer->seat->compositor, - pointer->x, pointer->y, - &sx, &sy); + view = weston_compositor_pick_view(pointer->seat->compositor, + pointer->x, pointer->y, + &sx, &sy); - if (surface && wl_resource_get_client(surface->resource) == client) { - weston_pointer_set_focus(pointer, surface, sx, sy); + if (view && view->surface->resource && + wl_resource_get_client(view->surface->resource) == client) { + weston_pointer_set_focus(pointer, view, sx, sy); } else { weston_pointer_set_focus(pointer, NULL, wl_fixed_from_int(0), @@ -2168,9 +2209,9 @@ popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time) wl_fixed_t sx, sy; wl_resource_for_each(resource, &pointer->focus_resource_list) { - weston_surface_from_global_fixed(pointer->focus, - pointer->x, pointer->y, - &sx, &sy); + weston_view_from_global_fixed(pointer->focus, + pointer->x, pointer->y, + &sx, &sy); wl_pointer_send_motion(resource, time, sx, sy); } } @@ -2276,14 +2317,14 @@ static void shell_map_popup(struct shell_surface *shsurf) { struct shell_seat *shseat = shsurf->popup.shseat; - struct weston_surface *es = shsurf->surface; - struct weston_surface *parent = shsurf->parent; + struct weston_view *parent_view = get_default_view(shsurf->parent); - es->output = parent->output; + shsurf->surface->output = parent_view->output; + shsurf->view->output = parent_view->output; - weston_surface_set_transform_parent(es, parent); - weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y); - weston_surface_update_transform(es); + weston_view_set_transform_parent(shsurf->view, parent_view); + weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y); + weston_view_update_transform(shsurf->view); if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) { add_popup_grab(shsurf, shseat); @@ -2337,8 +2378,8 @@ destroy_shell_surface(struct shell_surface *shsurf) shell_surface_is_top_fullscreen(shsurf)) restore_output_mode (shsurf->fullscreen_output); - if (shsurf->fullscreen.black_surface) - weston_surface_destroy(shsurf->fullscreen.black_surface); + if (shsurf->fullscreen.black_view) + weston_surface_destroy(shsurf->fullscreen.black_view->surface); /* As destroy_resource() use wl_list_for_each_safe(), * we can always remove the listener. @@ -2348,6 +2389,8 @@ destroy_shell_surface(struct shell_surface *shsurf) ping_timer_destroy(shsurf); free(shsurf->title); + weston_view_destroy(shsurf->view); + wl_list_remove(&shsurf->link); free(shsurf); } @@ -2402,6 +2445,13 @@ create_shell_surface(void *shell, struct weston_surface *surface, return NULL; } + shsurf->view = weston_view_create(surface); + if (!shsurf->view) { + weston_log("no memory to allocate shell surface\n"); + free(shsurf); + return NULL; + } + surface->configure = shell_surface_configure; surface->configure_private = shsurf; @@ -2412,7 +2462,7 @@ create_shell_surface(void *shell, struct weston_surface *surface, shsurf->surface = surface; shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; shsurf->fullscreen.framerate = 0; - shsurf->fullscreen.black_surface = NULL; + shsurf->fullscreen.black_view = NULL; shsurf->ping_timer = NULL; wl_list_init(&shsurf->fullscreen.transform.link); @@ -2439,6 +2489,12 @@ create_shell_surface(void *shell, struct weston_surface *surface, return shsurf; } +static struct weston_view * +get_primary_view(void *shell, struct shell_surface *shsurf) +{ + return shsurf->view; +} + static void shell_get_shell_surface(struct wl_client *client, struct wl_resource *resource, @@ -2534,25 +2590,25 @@ terminate_screensaver(struct desktop_shell *shell) } static void -configure_static_surface(struct weston_surface *es, struct weston_layer *layer, int32_t width, int32_t height) +configure_static_view(struct weston_view *ev, struct weston_layer *layer, int32_t width, int32_t height) { - struct weston_surface *s, *next; + struct weston_view *v, *next; if (width == 0) return; - wl_list_for_each_safe(s, next, &layer->surface_list, layer_link) { - if (s->output == es->output && s != es) { - weston_surface_unmap(s); - s->configure = NULL; + wl_list_for_each_safe(v, next, &layer->view_list, layer_link) { + if (v->output == ev->output && v != ev) { + weston_view_unmap(v); + v->surface->configure = NULL; } } - weston_surface_configure(es, es->output->x, es->output->y, width, height); + weston_view_configure(ev, ev->output->x, ev->output->y, width, height); - if (wl_list_empty(&es->layer_link)) { - wl_list_insert(&layer->surface_list, &es->layer_link); - weston_compositor_schedule_repaint(es->compositor); + if (wl_list_empty(&ev->layer_link)) { + wl_list_insert(&layer->view_list, &ev->layer_link); + weston_compositor_schedule_repaint(ev->surface->compositor); } } @@ -2560,8 +2616,11 @@ static void background_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height) { struct desktop_shell *shell = es->configure_private; + struct weston_view *view; - configure_static_surface(es, &shell->background_layer, width, height); + view = container_of(es->views.next, struct weston_view, surface_link); + + configure_static_view(view, &shell->background_layer, width, height); } static void @@ -2573,6 +2632,7 @@ desktop_shell_set_background(struct wl_client *client, struct desktop_shell *shell = wl_resource_get_user_data(resource); struct weston_surface *surface = wl_resource_get_user_data(surface_resource); + struct weston_view *view, *next; if (surface->configure) { wl_resource_post_error(surface_resource, @@ -2581,9 +2641,14 @@ desktop_shell_set_background(struct wl_client *client, return; } + wl_list_for_each_safe(view, next, &surface->views, surface_link) + weston_view_destroy(view); + view = weston_view_create(surface); + surface->configure = background_configure; surface->configure_private = shell; surface->output = wl_resource_get_user_data(output_resource); + view->output = surface->output; desktop_shell_send_configure(resource, 0, surface_resource, surface->output->width, @@ -2594,8 +2659,11 @@ static void panel_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height) { struct desktop_shell *shell = es->configure_private; + struct weston_view *view; + + view = container_of(es->views.next, struct weston_view, surface_link); - configure_static_surface(es, &shell->panel_layer, width, height); + configure_static_view(view, &shell->panel_layer, width, height); } static void @@ -2607,6 +2675,7 @@ desktop_shell_set_panel(struct wl_client *client, struct desktop_shell *shell = wl_resource_get_user_data(resource); struct weston_surface *surface = wl_resource_get_user_data(surface_resource); + struct weston_view *view, *next; if (surface->configure) { wl_resource_post_error(surface_resource, @@ -2615,9 +2684,14 @@ desktop_shell_set_panel(struct wl_client *client, return; } + wl_list_for_each_safe(view, next, &surface->views, surface_link) + weston_view_destroy(view); + view = weston_view_create(surface); + surface->configure = panel_configure; surface->configure_private = shell; surface->output = wl_resource_get_user_data(output_resource); + view->output = surface->output; desktop_shell_send_configure(resource, 0, surface_resource, surface->output->width, @@ -2628,18 +2702,23 @@ static void lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height) { struct desktop_shell *shell = surface->configure_private; + struct weston_view *view; + + view = container_of(surface->views.next, struct weston_view, surface_link); if (width == 0) return; - surface->geometry.width = width; - surface->geometry.height = height; - center_on_output(surface, get_default_output(shell->compositor)); + surface->width = width; + surface->height = height; + view->geometry.width = width; + view->geometry.height = height; + center_on_output(view, get_default_output(shell->compositor)); if (!weston_surface_is_mapped(surface)) { - wl_list_insert(&shell->lock_layer.surface_list, - &surface->layer_link); - weston_surface_update_transform(surface); + wl_list_insert(&shell->lock_layer.view_list, + &view->layer_link); + weston_view_update_transform(view); shell_fade(shell, FADE_IN); } } @@ -2816,21 +2895,21 @@ resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *d shsurf->type == SHELL_SURFACE_MAXIMIZED) return; - weston_surface_from_global(surface, - wl_fixed_to_int(seat->pointer->grab_x), - wl_fixed_to_int(seat->pointer->grab_y), - &x, &y); + weston_view_from_global(shsurf->view, + wl_fixed_to_int(seat->pointer->grab_x), + wl_fixed_to_int(seat->pointer->grab_y), + &x, &y); - if (x < surface->geometry.width / 3) + if (x < shsurf->view->geometry.width / 3) edges |= WL_SHELL_SURFACE_RESIZE_LEFT; - else if (x < 2 * surface->geometry.width / 3) + else if (x < 2 * shsurf->view->geometry.width / 3) edges |= 0; else edges |= WL_SHELL_SURFACE_RESIZE_RIGHT; - if (y < surface->geometry.height / 3) + if (y < shsurf->view->geometry.height / 3) edges |= WL_SHELL_SURFACE_RESIZE_TOP; - else if (y < 2 * surface->geometry.height / 3) + else if (y < 2 * shsurf->view->geometry.height / 3) edges |= 0; else edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM; @@ -2857,14 +2936,14 @@ surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis, if (!shsurf) return; - surface->alpha -= wl_fixed_to_double(value) * step; + shsurf->view->alpha -= wl_fixed_to_double(value) * step; - if (surface->alpha > 1.0) - surface->alpha = 1.0; - if (surface->alpha < step) - surface->alpha = step; + if (shsurf->view->alpha > 1.0) + shsurf->view->alpha = 1.0; + if (shsurf->view->alpha < step) + shsurf->view->alpha = step; - weston_surface_geometry_dirty(surface); + weston_view_geometry_dirty(shsurf->view); weston_surface_damage(surface); } @@ -2906,7 +2985,7 @@ do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis, output->zoom.spring_z.target = output->zoom.level; - weston_output_update_zoom(output, output->zoom.type); + weston_output_update_zoom(output); } } } @@ -2941,23 +3020,20 @@ rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time) container_of(grab, struct rotate_grab, base.grab); struct weston_pointer *pointer = grab->pointer; struct shell_surface *shsurf = rotate->base.shsurf; - struct weston_surface *surface; float cx, cy, dx, dy, cposx, cposy, dposx, dposy, r; if (!shsurf) return; - surface = shsurf->surface; - - cx = 0.5f * surface->geometry.width; - cy = 0.5f * surface->geometry.height; + cx = 0.5f * shsurf->view->geometry.width; + cy = 0.5f * shsurf->view->geometry.height; dx = wl_fixed_to_double(pointer->x) - rotate->center.x; dy = wl_fixed_to_double(pointer->y) - rotate->center.y; r = sqrtf(dx * dx + dy * dy); wl_list_remove(&shsurf->rotation.transform.link); - weston_surface_geometry_dirty(shsurf->surface); + weston_view_geometry_dirty(shsurf->view); if (r > 20.0f) { struct weston_matrix *matrix = @@ -2973,7 +3049,7 @@ rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time) weston_matrix_translate(matrix, cx, cy, 0.0f); wl_list_insert( - &shsurf->surface->geometry.transformation_list, + &shsurf->view->geometry.transformation_list, &shsurf->rotation.transform.link); } else { wl_list_init(&shsurf->rotation.transform.link); @@ -2983,14 +3059,14 @@ rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time) /* We need to adjust the position of the surface * in case it was resized in a rotated state before */ - cposx = surface->geometry.x + cx; - cposy = surface->geometry.y + cy; + cposx = shsurf->view->geometry.x + cx; + cposy = shsurf->view->geometry.y + cy; dposx = rotate->center.x - cposx; dposy = rotate->center.y - cposy; if (dposx != 0.0f || dposy != 0.0f) { - weston_surface_set_position(surface, - surface->geometry.x + dposx, - surface->geometry.y + dposy); + weston_view_set_position(shsurf->view, + shsurf->view->geometry.x + dposx, + shsurf->view->geometry.y + dposy); } /* Repaint implies weston_surface_update_transform(), which @@ -3036,10 +3112,10 @@ surface_rotate(struct shell_surface *surface, struct weston_seat *seat) if (!rotate) return; - weston_surface_to_global_float(surface->surface, - surface->surface->geometry.width * 0.5f, - surface->surface->geometry.height * 0.5f, - &rotate->center.x, &rotate->center.y); + weston_view_to_global_float(surface->view, + surface->view->geometry.width * 0.5f, + surface->view->geometry.height * 0.5f, + &rotate->center.x, &rotate->center.y); dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x; dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y; @@ -3087,13 +3163,13 @@ static void lower_fullscreen_layer(struct desktop_shell *shell) { struct workspace *ws; - struct weston_surface *surface, *prev; + struct weston_view *view, *prev; ws = get_current_workspace(shell); - wl_list_for_each_reverse_safe(surface, prev, - &shell->fullscreen_layer.surface_list, + wl_list_for_each_reverse_safe(view, prev, + &shell->fullscreen_layer.view_list, layer_link) - weston_surface_restack(surface, &ws->layer.surface_list); + weston_view_restack(view, &ws->layer.view_list); } static void @@ -3101,6 +3177,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; @@ -3125,7 +3202,9 @@ activate(struct desktop_shell *shell, struct weston_surface *es, default: restore_all_output_modes(shell->compositor); ws = get_current_workspace(shell); - weston_surface_restack(main_surface, &ws->layer.surface_list); + main_view = get_default_view(main_surface); + if (main_view) + weston_view_restack(main_view, &ws->layer.view_list); break; } } @@ -3156,6 +3235,7 @@ activate_binding(struct weston_seat *seat, if (!focus) return; + focus = seat->pointer->focus->surface; if (is_black_surface(focus, &main_surface)) focus = main_surface; @@ -3241,7 +3321,7 @@ unlock(struct desktop_shell *shell) } static void -shell_fade_done(struct weston_surface_animation *animation, void *data) +shell_fade_done(struct weston_view_animation *animation, void *data) { struct desktop_shell *shell = data; @@ -3249,8 +3329,8 @@ shell_fade_done(struct weston_surface_animation *animation, void *data) switch (shell->fade.type) { case FADE_IN: - weston_surface_destroy(shell->fade.surface); - shell->fade.surface = NULL; + weston_surface_destroy(shell->fade.view->surface); + shell->fade.view = NULL; break; case FADE_OUT: lock(shell); @@ -3258,23 +3338,30 @@ shell_fade_done(struct weston_surface_animation *animation, void *data) } } -static struct weston_surface * +static struct weston_view * shell_fade_create_surface(struct desktop_shell *shell) { struct weston_compositor *compositor = shell->compositor; struct weston_surface *surface; + struct weston_view *view; surface = weston_surface_create(compositor); if (!surface) return NULL; - weston_surface_configure(surface, 0, 0, 8192, 8192); + view = weston_view_create(surface); + if (!view) { + weston_surface_destroy(surface); + return NULL; + } + + weston_view_configure(view, 0, 0, 8192, 8192); weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0); - wl_list_insert(&compositor->fade_layer.surface_list, - &surface->layer_link); + wl_list_insert(&compositor->fade_layer.view_list, + &view->layer_link); pixman_region32_init(&surface->input); - return surface; + return view; } static void @@ -3296,20 +3383,20 @@ shell_fade(struct desktop_shell *shell, enum fade_type type) shell->fade.type = type; - if (shell->fade.surface == NULL) { - shell->fade.surface = shell_fade_create_surface(shell); - if (!shell->fade.surface) + if (shell->fade.view == NULL) { + shell->fade.view = shell_fade_create_surface(shell); + if (!shell->fade.view) return; - shell->fade.surface->alpha = 1.0 - tint; - weston_surface_update_transform(shell->fade.surface); + shell->fade.view->alpha = 1.0 - tint; + weston_view_update_transform(shell->fade.view); } if (shell->fade.animation) weston_fade_update(shell->fade.animation, tint); else shell->fade.animation = - weston_fade_run(shell->fade.surface, + weston_fade_run(shell->fade.view, 1.0 - tint, tint, 300.0, shell_fade_done, shell); } @@ -3322,8 +3409,8 @@ do_shell_fade_startup(void *data) if (shell->startup_animation_type == ANIMATION_FADE) shell_fade(shell, FADE_IN); else if (shell->startup_animation_type == ANIMATION_NONE) { - weston_surface_destroy(shell->fade.surface); - shell->fade.surface = NULL; + weston_surface_destroy(shell->fade.view->surface); + shell->fade.view = NULL; } } @@ -3361,18 +3448,18 @@ shell_fade_init(struct desktop_shell *shell) struct wl_event_loop *loop; - if (shell->fade.surface != NULL) { + if (shell->fade.view != NULL) { weston_log("%s: warning: fade surface already exists\n", __func__); return; } - shell->fade.surface = shell_fade_create_surface(shell); - if (!shell->fade.surface) + shell->fade.view = shell_fade_create_surface(shell); + if (!shell->fade.view) return; - weston_surface_update_transform(shell->fade.surface); - weston_surface_damage(shell->fade.surface); + weston_view_update_transform(shell->fade.view); + weston_surface_damage(shell->fade.view->surface); loop = wl_display_get_event_loop(shell->compositor->wl_display); shell->fade.startup_timer = @@ -3405,8 +3492,7 @@ show_input_panels(struct wl_listener *listener, void *data) struct desktop_shell *shell = container_of(listener, struct desktop_shell, show_input_panel_listener); - struct input_panel_surface *surface, *next; - struct weston_surface *ws; + struct input_panel_surface *ipsurf, *next; shell->text_input.surface = (struct weston_surface*)data; @@ -3419,17 +3505,17 @@ show_input_panels(struct wl_listener *listener, void *data) wl_list_insert(&shell->panel_layer.link, &shell->input_panel_layer.link); - wl_list_for_each_safe(surface, next, + wl_list_for_each_safe(ipsurf, next, &shell->input_panel.surfaces, link) { - ws = surface->surface; - if (!ws->buffer_ref.buffer) + if (!ipsurf->surface->buffer_ref.buffer) continue; - wl_list_insert(&shell->input_panel_layer.surface_list, - &ws->layer_link); - weston_surface_geometry_dirty(ws); - weston_surface_update_transform(ws); - weston_surface_damage(ws); - weston_slide_run(ws, ws->geometry.height, 0, NULL, NULL); + 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->view->geometry.height, + 0, NULL, NULL); } } @@ -3439,7 +3525,7 @@ hide_input_panels(struct wl_listener *listener, void *data) struct desktop_shell *shell = container_of(listener, struct desktop_shell, hide_input_panel_listener); - struct weston_surface *surface, *next; + struct weston_view *view, *next; if (!shell->showing_input_panels) return; @@ -3449,9 +3535,9 @@ hide_input_panels(struct wl_listener *listener, void *data) if (!shell->locked) wl_list_remove(&shell->input_panel_layer.link); - wl_list_for_each_safe(surface, next, - &shell->input_panel_layer.surface_list, layer_link) - weston_surface_unmap(surface); + wl_list_for_each_safe(view, next, + &shell->input_panel_layer.view_list, layer_link) + weston_view_unmap(view); } static void @@ -3465,22 +3551,22 @@ update_input_panels(struct wl_listener *listener, void *data) } static void -center_on_output(struct weston_surface *surface, struct weston_output *output) +center_on_output(struct weston_view *view, struct weston_output *output) { int32_t surf_x, surf_y, width, height; float x, y; - surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y, &width, &height); + surface_subsurfaces_boundingbox(view->surface, &surf_x, &surf_y, &width, &height); x = output->x + (output->width - width) / 2 - surf_x / 2; y = output->y + (output->height - height) / 2 - surf_y / 2; - weston_surface_configure(surface, x, y, width, height); + weston_view_configure(view, x, y, width, height); } static void -weston_surface_set_initial_position (struct weston_surface *surface, - struct desktop_shell *shell) +weston_view_set_initial_position(struct weston_view *view, + struct desktop_shell *shell) { struct weston_compositor *compositor = shell->compositor; int ix = 0, iy = 0; @@ -3510,8 +3596,8 @@ weston_surface_set_initial_position (struct weston_surface *surface, } if (!target_output) { - weston_surface_set_position(surface, 10 + random() % 400, - 10 + random() % 400); + weston_view_set_position(view, 10 + random() % 400, + 10 + random() % 400); return; } @@ -3520,9 +3606,9 @@ weston_surface_set_initial_position (struct weston_surface *surface, * output. */ panel_height = get_output_panel_height(shell, target_output); - range_x = target_output->width - surface->geometry.width; + range_x = target_output->width - view->geometry.width; range_y = (target_output->height - panel_height) - - surface->geometry.height; + view->geometry.height; if (range_x > 0) dx = random() % range_x; @@ -3537,61 +3623,65 @@ weston_surface_set_initial_position (struct weston_surface *surface, x = target_output->x + dx; y = target_output->y + dy; - weston_surface_set_position (surface, x, y); + weston_view_set_position(view, x, y); } static void -map(struct desktop_shell *shell, struct weston_surface *surface, +map(struct desktop_shell *shell, struct shell_surface *shsurf, int32_t width, int32_t height, int32_t sx, int32_t sy) { struct weston_compositor *compositor = shell->compositor; - struct shell_surface *shsurf = get_shell_surface(surface); - enum shell_surface_type surface_type = shsurf->type; - struct weston_surface *parent; + struct weston_view *parent; struct weston_seat *seat; struct workspace *ws; int panel_height = 0; int32_t surf_x, surf_y; - surface->geometry.width = width; - surface->geometry.height = height; - weston_surface_geometry_dirty(surface); + shsurf->view->geometry.width = width; + shsurf->view->geometry.height = height; + weston_view_geometry_dirty(shsurf->view); /* initial positioning, see also configure() */ - switch (surface_type) { + switch (shsurf->type) { case SHELL_SURFACE_TOPLEVEL: - weston_surface_set_initial_position(surface, shell); + weston_view_set_initial_position(shsurf->view, shell); break; case SHELL_SURFACE_FULLSCREEN: - center_on_output(surface, shsurf->fullscreen_output); + center_on_output(shsurf->view, shsurf->fullscreen_output); shell_map_fullscreen(shsurf); break; case SHELL_SURFACE_MAXIMIZED: /* use surface configure to set the geometry */ - panel_height = get_output_panel_height(shell,surface->output); - surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y, - NULL, NULL); - weston_surface_set_position(surface, shsurf->output->x - surf_x, - shsurf->output->y + panel_height - surf_y); + panel_height = get_output_panel_height(shell, shsurf->output); + surface_subsurfaces_boundingbox(shsurf->surface, + &surf_x, &surf_y, NULL, NULL); + weston_view_set_position(shsurf->view, + shsurf->output->x - surf_x, + shsurf->output->y + panel_height - surf_y); break; case SHELL_SURFACE_POPUP: shell_map_popup(shsurf); break; case SHELL_SURFACE_NONE: - weston_surface_set_position(surface, - surface->geometry.x + sx, - surface->geometry.y + sy); + weston_view_set_position(shsurf->view, + shsurf->view->geometry.x + sx, + shsurf->view->geometry.y + sy); break; default: ; } /* surface stacking order, see also activate() */ - switch (surface_type) { + switch (shsurf->type) { case SHELL_SURFACE_POPUP: case SHELL_SURFACE_TRANSIENT: - parent = shsurf->parent; - wl_list_insert(parent->layer_link.prev, &surface->layer_link); + /* TODO: Handle a parent with multiple views */ + parent = get_default_view(shsurf->parent); + if (parent) { + wl_list_remove(&shsurf->view->layer_link); + wl_list_insert(parent->layer_link.prev, + &shsurf->view->layer_link); + } break; case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_NONE: @@ -3599,17 +3689,20 @@ map(struct desktop_shell *shell, struct weston_surface *surface, case SHELL_SURFACE_XWAYLAND: default: ws = get_current_workspace(shell); - wl_list_insert(&ws->layer.surface_list, &surface->layer_link); + wl_list_remove(&shsurf->view->layer_link); + wl_list_insert(&ws->layer.view_list, &shsurf->view->layer_link); break; } - if (surface_type != SHELL_SURFACE_NONE) { - weston_surface_update_transform(surface); - if (surface_type == SHELL_SURFACE_MAXIMIZED) - surface->output = shsurf->output; + if (shsurf->type != SHELL_SURFACE_NONE) { + weston_view_update_transform(shsurf->view); + if (shsurf->type == SHELL_SURFACE_MAXIMIZED) { + shsurf->surface->output = shsurf->output; + shsurf->view->output = shsurf->output; + } } - switch (surface_type) { + switch (shsurf->type) { /* XXX: xwayland's using the same fields for transient type */ case SHELL_SURFACE_XWAYLAND: case SHELL_SURFACE_TRANSIENT: @@ -3621,21 +3714,21 @@ map(struct desktop_shell *shell, struct weston_surface *surface, case SHELL_SURFACE_MAXIMIZED: if (!shell->locked) { wl_list_for_each(seat, &compositor->seat_list, link) - activate(shell, surface, seat); + activate(shell, shsurf->surface, seat); } break; default: break; } - if (surface_type == SHELL_SURFACE_TOPLEVEL) + if (shsurf->type == SHELL_SURFACE_TOPLEVEL) { switch (shell->win_animation_type) { case ANIMATION_FADE: - weston_fade_run(surface, 0.0, 1.0, 300.0, NULL, NULL); + weston_fade_run(shsurf->view, 0.0, 1.0, 300.0, NULL, NULL); break; case ANIMATION_ZOOM: - weston_zoom_run(surface, 0.5, 1.0, NULL, NULL); + weston_zoom_run(shsurf->view, 0.5, 1.0, NULL, NULL); break; default: break; @@ -3649,13 +3742,19 @@ configure(struct desktop_shell *shell, struct weston_surface *surface, { enum shell_surface_type surface_type = SHELL_SURFACE_NONE; struct shell_surface *shsurf; + struct weston_view *view; int32_t surf_x, surf_y; shsurf = get_shell_surface(surface); if (shsurf) surface_type = shsurf->type; - weston_surface_configure(surface, x, y, width, height); + /* TODO: + * This should probably be changed to be more shell_surface + * dependent + */ + wl_list_for_each(view, &surface->views, surface_link) + weston_view_configure(view, x, y, width, height); switch (surface_type) { case SHELL_SURFACE_FULLSCREEN: @@ -3666,9 +3765,9 @@ configure(struct desktop_shell *shell, struct weston_surface *surface, /* setting x, y and using configure to change that geometry */ surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y, NULL, NULL); - surface->geometry.x = surface->output->x - surf_x; - surface->geometry.y = surface->output->y + - get_output_panel_height(shell,surface->output) - surf_y; + shsurf->view->geometry.x = shsurf->output->x - surf_x; + shsurf->view->geometry.y = shsurf->output->y + + get_output_panel_height(shell,shsurf->output) - surf_y; break; case SHELL_SURFACE_TOPLEVEL: break; @@ -3678,7 +3777,8 @@ configure(struct desktop_shell *shell, struct weston_surface *surface, /* XXX: would a fullscreen surface need the same handling? */ if (surface->output) { - weston_surface_update_transform(surface); + wl_list_for_each(view, &surface->views, surface_link) + weston_view_update_transform(view); if (surface_type == SHELL_SURFACE_MAXIMIZED) surface->output = shsurf->output; @@ -3708,18 +3808,18 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32 } if (!weston_surface_is_mapped(es)) { - map(shell, es, width, height, sx, sy); + map(shell, shsurf, width, height, sx, sy); } else if (type_changed || sx != 0 || sy != 0 || - es->geometry.width != width || - es->geometry.height != height) { + shsurf->view->geometry.width != width || + shsurf->view->geometry.height != height) { float from_x, from_y; float to_x, to_y; - weston_surface_to_global_float(es, 0, 0, &from_x, &from_y); - weston_surface_to_global_float(es, sx, sy, &to_x, &to_y); + weston_view_to_global_float(shsurf->view, 0, 0, &from_x, &from_y); + weston_view_to_global_float(shsurf->view, sx, sy, &to_x, &to_y); configure(shell, es, - es->geometry.x + to_x - from_x, - es->geometry.y + to_y - from_y, + shsurf->view->geometry.x + to_x - from_x, + shsurf->view->geometry.y + to_y - from_y, width, height); } } @@ -3824,6 +3924,7 @@ static void screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height) { struct desktop_shell *shell = surface->configure_private; + struct weston_view *view; if (width == 0) return; @@ -3832,12 +3933,13 @@ screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy, in if (!shell->locked) return; - center_on_output(surface, surface->output); + view = container_of(surface->views.next, struct weston_view, surface_link); + center_on_output(view, surface->output); - if (wl_list_empty(&surface->layer_link)) { - wl_list_insert(shell->lock_layer.surface_list.prev, - &surface->layer_link); - weston_surface_update_transform(surface); + if (wl_list_empty(&view->layer_link)) { + wl_list_insert(shell->lock_layer.view_list.prev, + &view->layer_link); + weston_view_update_transform(view); wl_event_source_timer_update(shell->screensaver.timer, shell->screensaver.duration); shell_fade(shell, FADE_IN); @@ -3854,6 +3956,12 @@ screensaver_set_surface(struct wl_client *client, struct weston_surface *surface = wl_resource_get_user_data(surface_resource); struct weston_output *output = wl_resource_get_user_data(output_resource); + struct weston_view *view, *next; + + /* Make sure we only have one view */ + wl_list_for_each_safe(view, next, &surface->views, surface_link) + weston_view_destroy(view); + weston_view_create(surface); surface->configure = screensaver_configure; surface->configure_private = shell; @@ -3915,23 +4023,21 @@ input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, in fprintf(stderr, "%s panel: %d, output: %p\n", __FUNCTION__, ip_surface->panel, ip_surface->output); if (ip_surface->panel) { - x = shell->text_input.surface->geometry.x + shell->text_input.cursor_rectangle.x2; - y = shell->text_input.surface->geometry.y + shell->text_input.cursor_rectangle.y2; + x = get_default_view(shell->text_input.surface)->geometry.x + shell->text_input.cursor_rectangle.x2; + y = get_default_view(shell->text_input.surface)->geometry.y + shell->text_input.cursor_rectangle.y2; } else { x = ip_surface->output->x + (ip_surface->output->width - width) / 2; y = ip_surface->output->y + ip_surface->output->height - height; } - weston_surface_configure(surface, - x, y, - width, height); + weston_view_configure(ip_surface->view, x, y, width, height); if (show_surface) { - wl_list_insert(&shell->input_panel_layer.surface_list, - &surface->layer_link); - weston_surface_update_transform(surface); + 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(surface, surface->geometry.height, 0, NULL, NULL); + weston_slide_run(ip_surface->view, ip_surface->view->geometry.height, 0, NULL, NULL); } } @@ -3944,6 +4050,7 @@ destroy_input_panel_surface(struct input_panel_surface *input_panel_surface) wl_list_remove(&input_panel_surface->link); input_panel_surface->surface->configure = NULL; + weston_view_destroy(input_panel_surface->view); free(input_panel_surface); } @@ -3988,6 +4095,7 @@ create_input_panel_surface(struct desktop_shell *shell, input_panel_surface->shell = shell; input_panel_surface->surface = surface; + input_panel_surface->view = weston_view_create(surface); wl_signal_init(&input_panel_surface->destroy_signal); input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy; @@ -4124,33 +4232,33 @@ struct switcher { static void switcher_next(struct switcher *switcher) { - struct weston_surface *surface; + struct weston_view *view; struct weston_surface *first = NULL, *prev = NULL, *next = NULL; struct shell_surface *shsurf; struct workspace *ws = get_current_workspace(switcher->shell); - wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { - switch (get_shell_surface_type(surface)) { + wl_list_for_each(view, &ws->layer.view_list, layer_link) { + switch (get_shell_surface_type(view->surface)) { case SHELL_SURFACE_TOPLEVEL: case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_MAXIMIZED: if (first == NULL) - first = surface; + first = view->surface; if (prev == switcher->current) - next = surface; - prev = surface; - surface->alpha = 0.25; - weston_surface_geometry_dirty(surface); - weston_surface_damage(surface); + next = view->surface; + prev = view->surface; + view->alpha = 0.25; + weston_view_geometry_dirty(view); + weston_surface_damage(view->surface); break; default: break; } - if (is_black_surface(surface, NULL)) { - surface->alpha = 0.25; - weston_surface_geometry_dirty(surface); - weston_surface_damage(surface); + if (is_black_surface(view->surface, NULL)) { + view->alpha = 0.25; + weston_view_geometry_dirty(view); + weston_surface_damage(view->surface); } } @@ -4164,11 +4272,12 @@ switcher_next(struct switcher *switcher) wl_signal_add(&next->destroy_signal, &switcher->listener); switcher->current = next; - next->alpha = 1.0; + wl_list_for_each(view, &next->views, surface_link) + view->alpha = 1.0; shsurf = get_shell_surface(switcher->current); if (shsurf && shsurf->type ==SHELL_SURFACE_FULLSCREEN) - shsurf->fullscreen.black_surface->alpha = 1.0; + shsurf->fullscreen.black_view->alpha = 1.0; } static void @@ -4183,13 +4292,13 @@ switcher_handle_surface_destroy(struct wl_listener *listener, void *data) static void switcher_destroy(struct switcher *switcher) { - struct weston_surface *surface; + struct weston_view *view; struct weston_keyboard *keyboard = switcher->grab.keyboard; struct workspace *ws = get_current_workspace(switcher->shell); - wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { - surface->alpha = 1.0; - weston_surface_damage(surface); + wl_list_for_each(view, &ws->layer.view_list, layer_link) { + view->alpha = 1.0; + weston_surface_damage(view->surface); } if (switcher->current) @@ -4638,6 +4747,7 @@ module_init(struct weston_compositor *ec, ec->ping_handler = ping_handler; ec->shell_interface.shell = shell; ec->shell_interface.create_shell_surface = create_shell_surface; + ec->shell_interface.get_primary_view = get_primary_view; ec->shell_interface.set_toplevel = set_toplevel; ec->shell_interface.set_transient = set_transient; ec->shell_interface.set_fullscreen = set_fullscreen; diff --git a/src/spring-tool.c b/src/spring-tool.c index 935acc4b..41cc52ce 100644 --- a/src/spring-tool.c +++ b/src/spring-tool.c @@ -25,7 +25,7 @@ #include "compositor.h" WL_EXPORT void -weston_surface_geometry_dirty(struct weston_surface *surface) +weston_view_geometry_dirty(struct weston_view *view) { } @@ -36,7 +36,7 @@ weston_log(const char *fmt, ...) } WL_EXPORT void -weston_compositor_schedule_repaint(struct weston_compositor *compositor) +weston_view_schedule_repaint(struct weston_view *view) { } diff --git a/src/tablet-shell.c b/src/tablet-shell.c index b055ab23..5e926788 100644 --- a/src/tablet-shell.c +++ b/src/tablet-shell.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "compositor.h" #include "tablet-shell-server-protocol.h" @@ -124,27 +125,43 @@ tablet_shell_set_state(struct tablet_shell *shell, int state) shell->state = state; } +static struct weston_view * +get_surface_view(struct weston_surface *surface, int create) +{ + if (!surface) + return NULL; + + if (wl_list_empty(&surface->views)) { + if (create) + return weston_view_create(surface); + else + return NULL; + } + + return container_of(surface->views.next, struct weston_view, surface_link); +} + static void tablet_shell_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height) { struct tablet_shell *shell = get_shell(surface->compositor); + struct weston_view *view = get_surface_view(surface, 0); + assert(view); if (weston_surface_is_mapped(surface) || width == 0) return; - weston_surface_configure(surface, 0, 0, width, height); - if (surface == shell->lockscreen_surface) { - wl_list_insert(&shell->lockscreen_layer.surface_list, - &surface->layer_link); + wl_list_insert(&shell->lockscreen_layer.view_list, + &view->layer_link); } else if (surface == shell->switcher_surface) { /* */ } else if (surface == shell->home_surface) { if (shell->state == STATE_STARTING) { /* homescreen always visible, at the bottom */ - wl_list_insert(&shell->homescreen_layer.surface_list, - &surface->layer_link); + wl_list_insert(&shell->homescreen_layer.view_list, + &view->layer_link); tablet_shell_set_state(shell, STATE_LOCKED); shell->previous_state = STATE_HOME; @@ -155,12 +172,15 @@ tablet_shell_surface_configure(struct weston_surface *surface, shell->current_client->client == wl_resource_get_client(surface->resource)) { tablet_shell_set_state(shell, STATE_TASK); shell->current_client->surface = surface; - weston_zoom_run(surface, 0.3, 1.0, NULL, NULL); - wl_list_insert(&shell->application_layer.surface_list, - &surface->layer_link); + weston_zoom_run(view, 0.3, 1.0, NULL, NULL); + wl_list_insert(&shell->application_layer.view_list, + &view->layer_link); } - weston_surface_update_transform(surface); + if (view) { + weston_view_configure(view, 0, 0, width, height); + weston_view_update_transform(view); + } } static void @@ -181,10 +201,12 @@ tablet_shell_set_lockscreen(struct wl_client *client, { struct tablet_shell *shell = wl_resource_get_user_data(resource); struct weston_surface *es = wl_resource_get_user_data(surface_resource); + struct weston_view *view; - weston_surface_set_position(es, 0, 0); + view = weston_view_create(es); + weston_view_set_position(view, 0, 0); shell->lockscreen_surface = es; - shell->lockscreen_surface->configure = tablet_shell_surface_configure; + es->configure = tablet_shell_surface_configure; shell->lockscreen_listener.notify = handle_lockscreen_surface_destroy; wl_signal_add(&es->destroy_signal, &shell->lockscreen_listener); } @@ -208,14 +230,16 @@ tablet_shell_set_switcher(struct wl_client *client, { struct tablet_shell *shell = wl_resource_get_user_data(resource); struct weston_surface *es = wl_resource_get_user_data(surface_resource); + struct weston_view *view; /* FIXME: Switcher should be centered and the compositor * should do the tinting of the background. With the cache * layer idea, we should be able to hit the framerate on the * fade/zoom in. */ - shell->switcher_surface = es; - weston_surface_set_position(shell->switcher_surface, 0, 0); + view = weston_view_create(es); + weston_view_set_position(view, 0, 0); + shell->switcher_surface = es; shell->switcher_listener.notify = handle_switcher_surface_destroy; wl_signal_add(&es->destroy_signal, &shell->switcher_listener); } @@ -226,15 +250,18 @@ tablet_shell_set_homescreen(struct wl_client *client, struct wl_resource *surface_resource) { struct tablet_shell *shell = wl_resource_get_user_data(resource); + struct weston_surface *es = wl_resource_get_user_data(surface_resource); + struct weston_view *view; - shell->home_surface = wl_resource_get_user_data(surface_resource); - shell->home_surface->configure = tablet_shell_surface_configure; + view = weston_view_create(es); + weston_view_set_position(view, 0, 0); - weston_surface_set_position(shell->home_surface, 0, 0); + shell->home_surface = es; + es->configure = tablet_shell_surface_configure; } static void -minimize_zoom_done(struct weston_surface_animation *zoom, void *data) +minimize_zoom_done(struct weston_view_animation *zoom, void *data) { struct tablet_shell *shell = data; struct weston_compositor *compositor = shell->compositor; @@ -246,11 +273,12 @@ minimize_zoom_done(struct weston_surface_animation *zoom, void *data) static void tablet_shell_switch_to(struct tablet_shell *shell, - struct weston_surface *surface) + struct weston_surface *surface) { struct weston_compositor *compositor = shell->compositor; struct weston_seat *seat; struct weston_surface *current; + struct weston_view *view = get_surface_view(surface, 1); if (shell->state == STATE_SWITCHER) { wl_list_remove(&shell->switcher_listener.link); @@ -262,15 +290,15 @@ tablet_shell_switch_to(struct tablet_shell *shell, if (shell->current_client && shell->current_client->surface) { current = shell->current_client->surface; - weston_zoom_run(current, 1.0, 0.3, - minimize_zoom_done, shell); + weston_zoom_run(get_surface_view(current, 0), 1.0, 0.3, + minimize_zoom_done, shell); } } else { - fprintf(stderr, "switch to %p\n", surface); + fprintf(stderr, "switch to %p\n", view); wl_list_for_each(seat, &compositor->seat_list, link) - weston_surface_activate(surface, seat); + weston_surface_activate(view->surface, seat); tablet_shell_set_state(shell, STATE_TASK); - weston_zoom_run(surface, 0.3, 1.0, NULL, NULL); + weston_zoom_run(view, 0.3, 1.0, NULL, NULL); } } diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index a8892786..9c500e13 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -124,6 +124,7 @@ struct weston_wm_window { cairo_surface_t *cairo_surface; struct weston_surface *surface; struct shell_surface *shsurf; + struct weston_view *view; struct wl_listener surface_destroy_listener; struct wl_event_source *repaint_source; struct wl_event_source *configure_source; @@ -716,13 +717,13 @@ weston_wm_window_transform(struct wl_listener *listener, void *data) if (!window || !wm) return; - if (!weston_surface_is_mapped(surface)) + if (!window->view || !weston_view_is_mapped(window->view)) return; - if (window->x != surface->geometry.x || - window->y != surface->geometry.y) { - values[0] = surface->geometry.x; - values[1] = surface->geometry.y; + if (window->x != window->view->geometry.x || + window->y != window->view->geometry.y) { + values[0] = window->view->geometry.x; + values[1] = window->view->geometry.y; mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; xcb_configure_window(wm->conn, window->frame_id, mask, values); @@ -958,7 +959,8 @@ weston_wm_window_draw_decoration(void *data) window->width + 2, window->height + 2); } - weston_surface_geometry_dirty(window->surface); + if (window->view) + weston_view_geometry_dirty(window->view); } if (window->surface && !window->fullscreen) { @@ -986,7 +988,8 @@ weston_wm_window_schedule_repaint(struct weston_wm_window *window) pixman_region32_init_rect(&window->surface->pending.opaque, 0, 0, width, height); } - weston_surface_geometry_dirty(window->surface); + if (window->view) + weston_view_geometry_dirty(window->view); } return; } @@ -1177,8 +1180,8 @@ weston_wm_window_handle_moveresize(struct weston_wm_window *window, struct weston_shell_interface *shell_interface = &wm->server->compositor->shell_interface; - if (seat->pointer->button_count != 1 || - seat->pointer->focus != window->surface) + if (seat->pointer->button_count != 1 || !window->view + || seat->pointer->focus != window->view) return; detail = client_message->data.data32[2]; @@ -2169,10 +2172,15 @@ xserver_map_shell_surface(struct weston_wm *wm, if (!shell_interface->create_shell_surface) return; + if (!shell_interface->get_primary_view) + return; + window->shsurf = shell_interface->create_shell_surface(shell_interface->shell, window->surface, &shell_client); + window->view = shell_interface->get_primary_view(shell_interface->shell, + window->shsurf); if (window->name) shell_interface->set_title(window->shsurf, window->name); diff --git a/src/zoom.c b/src/zoom.c index 220b2b6e..962ed6d6 100644 --- a/src/zoom.c +++ b/src/zoom.c @@ -27,97 +27,6 @@ #include "compositor.h" #include "text-cursor-position-server-protocol.h" -struct text_cursor_position { - struct weston_compositor *ec; - struct wl_global *global; - struct wl_listener destroy_listener; -}; - -static void -text_cursor_position_notify(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *surface_resource, - wl_fixed_t x, wl_fixed_t y) -{ - struct weston_surface *surface = - wl_resource_get_user_data(surface_resource); - - weston_text_cursor_position_notify(surface, x, y); -} - -struct text_cursor_position_interface text_cursor_position_implementation = { - text_cursor_position_notify -}; - -static void -bind_text_cursor_position(struct wl_client *client, - void *data, uint32_t version, uint32_t id) -{ - struct wl_resource *resource; - - resource = wl_resource_create(client, - &text_cursor_position_interface, 1, id); - if (resource) - wl_resource_set_implementation(resource, - &text_cursor_position_implementation, - data, NULL); -} - -static void -text_cursor_position_notifier_destroy(struct wl_listener *listener, void *data) -{ - struct text_cursor_position *text_cursor_position = - container_of(listener, struct text_cursor_position, destroy_listener); - - wl_global_destroy(text_cursor_position->global); - free(text_cursor_position); -} - -void -text_cursor_position_notifier_create(struct weston_compositor *ec) -{ - struct text_cursor_position *text_cursor_position; - - text_cursor_position = malloc(sizeof *text_cursor_position); - if (text_cursor_position == NULL) - return; - - text_cursor_position->ec = ec; - - text_cursor_position->global = - wl_global_create(ec->wl_display, - &text_cursor_position_interface, 1, - text_cursor_position, - bind_text_cursor_position); - - text_cursor_position->destroy_listener.notify = - text_cursor_position_notifier_destroy; - wl_signal_add(&ec->destroy_signal, &text_cursor_position->destroy_listener); -} - -WL_EXPORT void -weston_text_cursor_position_notify(struct weston_surface *surface, - wl_fixed_t cur_pos_x, - wl_fixed_t cur_pos_y) -{ - struct weston_output *output; - wl_fixed_t global_x, global_y; - - weston_surface_to_global_fixed(surface, cur_pos_x, cur_pos_y, - &global_x, &global_y); - - wl_list_for_each(output, &surface->compositor->output_list, link) - if (output->zoom.active && - pixman_region32_contains_point(&output->region, - wl_fixed_to_int(global_x), - wl_fixed_to_int(global_y), - NULL)) { - output->zoom.text_cursor.x = global_x; - output->zoom.text_cursor.y = global_y; - weston_output_update_zoom(output, ZOOM_FOCUS_TEXT); - } -} - static void weston_zoom_frame_z(struct weston_animation *animation, struct weston_output *output, uint32_t msecs) @@ -176,12 +85,8 @@ weston_zoom_frame_xy(struct weston_animation *animation, if (weston_spring_done(&output->zoom.spring_xy)) { output->zoom.spring_xy.current = output->zoom.spring_xy.target; - output->zoom.current.x = - output->zoom.type == ZOOM_FOCUS_POINTER ? - seat->pointer->x : output->zoom.text_cursor.x; - output->zoom.current.y = - output->zoom.type == ZOOM_FOCUS_POINTER ? - seat->pointer->y : output->zoom.text_cursor.y; + output->zoom.current.x = seat->pointer->x; + output->zoom.current.y = seat->pointer->y; wl_list_remove(&animation->link); wl_list_init(&animation->link); } @@ -251,7 +156,6 @@ weston_zoom_apply_output_transform(struct weston_output *output, static void weston_output_update_zoom_transform(struct weston_output *output) { - uint32_t type = output->zoom.type; float global_x, global_y; wl_fixed_t x = output->zoom.current.x; wl_fixed_t y = output->zoom.current.y; @@ -265,8 +169,7 @@ weston_output_update_zoom_transform(struct weston_output *output) level == 0.0f) return; - if (type == ZOOM_FOCUS_POINTER && - wl_list_empty(&output->zoom.animation_xy.link)) + if (wl_list_empty(&output->zoom.animation_xy.link)) zoom_area_center_from_pointer(output, &x, &y); global_x = wl_fixed_to_double(x); @@ -297,39 +200,8 @@ weston_output_update_zoom_transform(struct weston_output *output) } static void -weston_zoom_transition(struct weston_output *output, uint32_t type, - wl_fixed_t x, wl_fixed_t y) +weston_zoom_transition(struct weston_output *output, wl_fixed_t x, wl_fixed_t y) { - if (output->zoom.type != type) { - /* Set from/to points and start animation */ - output->zoom.spring_xy.current = 0.0; - output->zoom.spring_xy.previous = 0.0; - output->zoom.spring_xy.target = 1.0; - - if (wl_list_empty(&output->zoom.animation_xy.link)) { - output->zoom.animation_xy.frame_counter = 0; - wl_list_insert(output->animation_list.prev, - &output->zoom.animation_xy.link); - - output->zoom.from.x = (type == ZOOM_FOCUS_TEXT) ? - x : output->zoom.text_cursor.x; - output->zoom.from.y = (type == ZOOM_FOCUS_TEXT) ? - y : output->zoom.text_cursor.y; - } else { - output->zoom.from.x = output->zoom.current.x; - output->zoom.from.y = output->zoom.current.y; - } - - output->zoom.to.x = (type == ZOOM_FOCUS_POINTER) ? - x : output->zoom.text_cursor.x; - output->zoom.to.y = (type == ZOOM_FOCUS_POINTER) ? - y : output->zoom.text_cursor.y; - output->zoom.current.x = output->zoom.from.x; - output->zoom.current.y = output->zoom.from.y; - - output->zoom.type = type; - } - if (output->zoom.level != output->zoom.spring_z.current) { output->zoom.spring_z.target = output->zoom.level; if (wl_list_empty(&output->zoom.animation_z.link)) { @@ -344,7 +216,7 @@ weston_zoom_transition(struct weston_output *output, uint32_t type, } WL_EXPORT void -weston_output_update_zoom(struct weston_output *output, uint32_t type) +weston_output_update_zoom(struct weston_output *output) { struct weston_seat *seat = weston_zoom_pick_seat(output->compositor); wl_fixed_t x = seat->pointer->x; @@ -352,27 +224,15 @@ weston_output_update_zoom(struct weston_output *output, uint32_t type) zoom_area_center_from_pointer(output, &x, &y); - if (type == ZOOM_FOCUS_POINTER) { - if (wl_list_empty(&output->zoom.animation_xy.link)) { - output->zoom.current.x = seat->pointer->x; - output->zoom.current.y = seat->pointer->y; - } else { - output->zoom.to.x = x; - output->zoom.to.y = y; - } - } - - if (type == ZOOM_FOCUS_TEXT) { - if (wl_list_empty(&output->zoom.animation_xy.link)) { - output->zoom.current.x = output->zoom.text_cursor.x; - output->zoom.current.y = output->zoom.text_cursor.y; - } else { - output->zoom.to.x = output->zoom.text_cursor.x; - output->zoom.to.y = output->zoom.text_cursor.y; - } + if (wl_list_empty(&output->zoom.animation_xy.link)) { + output->zoom.current.x = seat->pointer->x; + output->zoom.current.y = seat->pointer->y; + } else { + output->zoom.to.x = x; + output->zoom.to.y = y; } - weston_zoom_transition(output, type, x, y); + weston_zoom_transition(output, x, y); weston_output_update_zoom_transform(output); } @@ -385,7 +245,6 @@ weston_output_init_zoom(struct weston_output *output) output->zoom.level = 0.0; output->zoom.trans_x = 0.0; output->zoom.trans_y = 0.0; - output->zoom.type = ZOOM_FOCUS_POINTER; weston_spring_init(&output->zoom.spring_z, 250.0, 0.0, 0.0); output->zoom.spring_z.friction = 1000; output->zoom.animation_z.frame = weston_zoom_frame_z; diff --git a/tests/surface-global-test.c b/tests/surface-global-test.c index 04b64d6a..788e694d 100644 --- a/tests/surface-global-test.c +++ b/tests/surface-global-test.c @@ -29,39 +29,42 @@ surface_to_from_global(void *data) { struct weston_compositor *compositor = data; struct weston_surface *surface; + struct weston_view *view; float x, y; wl_fixed_t fx, fy; int32_t ix, iy; surface = weston_surface_create(compositor); assert(surface); - weston_surface_configure(surface, 5, 10, 50, 50); - weston_surface_update_transform(surface); + view = weston_view_create(surface); + assert(view); + weston_view_configure(view, 5, 10, 50, 50); + weston_view_update_transform(view); - weston_surface_to_global_float(surface, 33, 22, &x, &y); + weston_view_to_global_float(view, 33, 22, &x, &y); assert(x == 38 && y == 32); - weston_surface_to_global_float(surface, -8, -2, &x, &y); + weston_view_to_global_float(view, -8, -2, &x, &y); assert(x == -3 && y == 8); - weston_surface_to_global_fixed(surface, wl_fixed_from_int(12), + weston_view_to_global_fixed(view, wl_fixed_from_int(12), wl_fixed_from_int(5), &fx, &fy); assert(fx == wl_fixed_from_int(17) && fy == wl_fixed_from_int(15)); - weston_surface_from_global_float(surface, 38, 32, &x, &y); + weston_view_from_global_float(view, 38, 32, &x, &y); assert(x == 33 && y == 22); - weston_surface_from_global_float(surface, 42, 5, &x, &y); + weston_view_from_global_float(view, 42, 5, &x, &y); assert(x == 37 && y == -5); - weston_surface_from_global_fixed(surface, wl_fixed_from_int(21), + weston_view_from_global_fixed(view, wl_fixed_from_int(21), wl_fixed_from_int(100), &fx, &fy); assert(fx == wl_fixed_from_int(16) && fy == wl_fixed_from_int(90)); - weston_surface_from_global(surface, 0, 0, &ix, &iy); + weston_view_from_global(view, 0, 0, &ix, &iy); assert(ix == -5 && iy == -10); - weston_surface_from_global(surface, 5, 10, &ix, &iy); + weston_view_from_global(view, 5, 10, &ix, &iy); assert(ix == 0 && iy == 0); wl_display_terminate(compositor->wl_display); diff --git a/tests/surface-test.c b/tests/surface-test.c index e8af2ed7..4a8b2b29 100644 --- a/tests/surface-test.c +++ b/tests/surface-test.c @@ -31,20 +31,23 @@ surface_transform(void *data) { struct weston_compositor *compositor = data; struct weston_surface *surface; + struct weston_view *view; float x, y; surface = weston_surface_create(compositor); assert(surface); - weston_surface_configure(surface, 100, 100, 200, 200); - weston_surface_update_transform(surface); - weston_surface_to_global_float(surface, 20, 20, &x, &y); + view = weston_view_create(surface); + assert(view); + weston_view_configure(view, 100, 100, 200, 200); + weston_view_update_transform(view); + weston_view_to_global_float(view, 20, 20, &x, &y); fprintf(stderr, "20,20 maps to %f, %f\n", x, y); assert(x == 120 && y == 120); - weston_surface_set_position(surface, 150, 300); - weston_surface_update_transform(surface); - weston_surface_to_global_float(surface, 50, 40, &x, &y); + weston_view_set_position(view, 150, 300); + weston_view_update_transform(view); + weston_view_to_global_float(view, 50, 40, &x, &y); assert(x == 200 && y == 340); wl_display_terminate(compositor->wl_display); diff --git a/tests/weston-test.c b/tests/weston-test.c index a825d123..5f341d86 100644 --- a/tests/weston-test.c +++ b/tests/weston-test.c @@ -36,6 +36,7 @@ struct weston_test { struct weston_test_surface { struct weston_surface *surface; + struct weston_view *view; int32_t x, y; struct weston_test *test; }; @@ -79,15 +80,16 @@ test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, i struct weston_test_surface *test_surface = surface->configure_private; struct weston_test *test = test_surface->test; - if (wl_list_empty(&surface->layer_link)) - wl_list_insert(&test->layer.surface_list, - &surface->layer_link); + if (wl_list_empty(&test_surface->view->layer_link)) + wl_list_insert(&test->layer.view_list, + &test_surface->view->layer_link); - weston_surface_configure(surface, test_surface->x, test_surface->y, - width, height); + weston_view_configure(test_surface->view, + test_surface->x, test_surface->y, + width, height); - if (!weston_surface_is_mapped(surface)) - weston_surface_update_transform(surface); + if (!weston_view_is_mapped(test_surface->view)) + weston_view_update_transform(test_surface->view); } static void @@ -99,13 +101,23 @@ move_surface(struct wl_client *client, struct wl_resource *resource, wl_resource_get_user_data(surface_resource); struct weston_test_surface *test_surface; - surface->configure = test_surface_configure; - if (surface->configure_private == NULL) - surface->configure_private = malloc(sizeof *test_surface); test_surface = surface->configure_private; - if (test_surface == NULL) { - wl_resource_post_no_memory(resource); - return; + if (!test_surface) { + test_surface = malloc(sizeof *test_surface); + if (!test_surface) { + wl_resource_post_no_memory(resource); + return; + } + + test_surface->view = weston_view_create(surface); + if (!test_surface->view) { + wl_resource_post_no_memory(resource); + free(test_surface); + return; + } + + surface->configure_private = test_surface; + surface->configure = test_surface_configure; } test_surface->surface = surface;