Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures: * The weston_surface structure storres everything required for a client-side or server-side surface. This includes buffers; callbacks; backend private data; input, damage, and opaque regions; and a few other bookkeeping bits. * The weston_view structure represents an entity in the scenegraph and storres all of the geometry information. This includes clip region, alpha, position, and the transformation list as well as all of the temporary information derived from the geometry state. Because a view, and not a surface, is a scenegraph element, the view is what is placed in layers and planes. There are a few things worth noting about the surface/view split: 1. This is *not* a modification to the protocol. It is, instead, a modification to Weston's internal scenegraph to allow a single surface to exist in multiple places at a time. Clients are completely unaware of how many views to a particular surface exist. 2. A view is considered a direct child of a surface and is destroyed when the surface is destroyed. Because of this, the view.surface pointer is always valid and non-null. 3. The compositor's surface_list is replaced with a view_list. Due to subsurfaces, building the view list is a little more complicated than it used to be and involves building a tree of views on the fly whenever subsurfaces are used. However, this means that backends can remain completely subsurface-agnostic. 4. Surfaces and views both keep track of which outputs they are on. 5. The weston_surface structure now has width and height fields. These are populated when a new buffer is attached before surface.configure is called. This is because there are many surface-based operations that really require the width and height and digging through the views didn't work well. Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
d4c1cd77c3
commit
a7af70436b
136
src/animation.c
136
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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
834
src/compositor.c
834
src/compositor.c
File diff suppressed because it is too large
Load Diff
213
src/compositor.h
213
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);
|
||||
|
||||
void
|
||||
weston_surface_configure(struct weston_surface *surface,
|
||||
float x, float y, int width, int height);
|
||||
struct weston_view *
|
||||
weston_view_create(struct weston_surface *surface);
|
||||
|
||||
void
|
||||
weston_surface_restack(struct weston_surface *surface, struct wl_list *below);
|
||||
weston_view_destroy(struct weston_view *view);
|
||||
|
||||
void
|
||||
weston_surface_set_position(struct weston_surface *surface,
|
||||
float x, float y);
|
||||
weston_view_configure(struct weston_view *view,
|
||||
float x, float y, int width, int height);
|
||||
|
||||
void
|
||||
weston_surface_set_transform_parent(struct weston_surface *surface,
|
||||
struct weston_surface *parent);
|
||||
weston_view_restack(struct weston_view *surface, struct wl_list *below);
|
||||
|
||||
void
|
||||
weston_view_set_position(struct weston_view *view,
|
||||
float x, float y);
|
||||
|
||||
void
|
||||
weston_view_set_transform_parent(struct weston_view *view,
|
||||
struct weston_view *parent);
|
||||
|
||||
int
|
||||
weston_view_is_mapped(struct weston_view *view);
|
||||
|
||||
void
|
||||
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,
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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. */
|
||||
|
@ -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))
|
||||
|
163
src/input.c
163
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 {
|
||||
|
@ -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
|
||||
|
@ -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,37 +962,6 @@ 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;
|
||||
DBG("new back %p, new front %p\n", surface->back, surface->front);
|
||||
}
|
||||
|
||||
static int
|
||||
is_surface_not_visible(struct weston_surface *surface)
|
||||
{
|
||||
/* 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);
|
||||
ret = !pixman_region32_not_empty(&unocc);
|
||||
pixman_region32_fini(&unocc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
rpir_surface_update(struct rpir_surface *surface, 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);
|
||||
@ -938,67 +969,80 @@ rpir_surface_update(struct rpir_surface *surface, struct rpir_output *output,
|
||||
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);
|
||||
tmp = surface->front;
|
||||
surface->front = surface->back;
|
||||
surface->back = tmp;
|
||||
}
|
||||
DBG("new back %p, new front %p\n", surface->back, surface->front);
|
||||
}
|
||||
|
||||
obscured = is_surface_not_visible(surface->surface);
|
||||
static int
|
||||
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, &view->transform.boundingbox,
|
||||
&view->clip);
|
||||
ret = !pixman_region32_not_empty(&unocc);
|
||||
pixman_region32_fini(&unocc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
rpir_view_update(struct rpir_view *view, struct rpir_output *output,
|
||||
DISPMANX_UPDATE_HANDLE_T update, int layer)
|
||||
{
|
||||
int ret;
|
||||
int obscured;
|
||||
|
||||
|
||||
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);
|
||||
|
802
src/shell.c
802
src/shell.c
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <linux/input.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
165
src/zoom.c
165
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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user