Merge branch 'layers'

I was integrating patches on the 'layers' branch and had a fixed version of
the fullscreen patch there.  My master branch had the fullscreen patch with
the resize bug, and when I pushed I meant to push the layers branch to master.

Conflicts:
	src/shell.c
This commit is contained in:
Kristian Høgsberg 2012-03-02 08:14:40 -05:00
commit f98d903b6d
6 changed files with 247 additions and 263 deletions

View File

@ -214,7 +214,8 @@ drm_output_prepare_scanout_surface(struct drm_output *output)
} }
static void static void
drm_output_repaint(struct weston_output *output_base) drm_output_repaint(struct weston_output *output_base,
pixman_region32_t *damage)
{ {
struct drm_output *output = (struct drm_output *) output_base; struct drm_output *output = (struct drm_output *) output_base;
struct drm_compositor *compositor = struct drm_compositor *compositor =
@ -235,7 +236,7 @@ drm_output_repaint(struct weston_output *output_base)
drm_output_prepare_scanout_surface(output); drm_output_prepare_scanout_surface(output);
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
weston_surface_draw(surface, &output->base); weston_surface_draw(surface, &output->base, damage);
glFlush(); glFlush();

View File

@ -329,7 +329,8 @@ static const struct wl_callback_listener frame_listener = {
}; };
static void static void
wayland_output_repaint(struct weston_output *output_base) wayland_output_repaint(struct weston_output *output_base,
pixman_region32_t *damage)
{ {
struct wayland_output *output = (struct wayland_output *) output_base; struct wayland_output *output = (struct wayland_output *) output_base;
struct wayland_compositor *compositor = struct wayland_compositor *compositor =
@ -344,7 +345,7 @@ wayland_output_repaint(struct weston_output *output_base)
} }
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
weston_surface_draw(surface, &output->base); weston_surface_draw(surface, &output->base, damage);
draw_border(output); draw_border(output);

View File

@ -186,7 +186,8 @@ x11_compositor_fini_egl(struct x11_compositor *compositor)
} }
static void static void
x11_output_repaint(struct weston_output *output_base) x11_output_repaint(struct weston_output *output_base,
pixman_region32_t *damage)
{ {
struct x11_output *output = (struct x11_output *)output_base; struct x11_output *output = (struct x11_output *)output_base;
struct x11_compositor *compositor = struct x11_compositor *compositor =
@ -200,7 +201,7 @@ x11_output_repaint(struct weston_output *output_base)
} }
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
weston_surface_draw(surface, &output->base); weston_surface_draw(surface, &output->base, damage);
eglSwapBuffers(compositor->base.display, output->egl_surface); eglSwapBuffers(compositor->base.display, output->egl_surface);

View File

@ -211,6 +211,7 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->surface.resource.destroy_listener_list); wl_list_init(&surface->surface.resource.destroy_listener_list);
wl_list_init(&surface->link); wl_list_init(&surface->link);
wl_list_init(&surface->layer_link);
wl_list_init(&surface->buffer_link); wl_list_init(&surface->buffer_link);
surface->surface.resource.client = NULL; surface->surface.resource.client = NULL;
@ -225,6 +226,7 @@ weston_surface_create(struct weston_compositor *compositor)
pixman_region32_init(&surface->damage); pixman_region32_init(&surface->damage);
pixman_region32_init(&surface->opaque); pixman_region32_init(&surface->opaque);
pixman_region32_init(&surface->clip);
undef_region(&surface->input); undef_region(&surface->input);
pixman_region32_init(&surface->transform.opaque); pixman_region32_init(&surface->transform.opaque);
wl_list_init(&surface->frame_callback_list); wl_list_init(&surface->frame_callback_list);
@ -281,17 +283,15 @@ surface_to_global_float(struct weston_surface *surface,
WL_EXPORT void WL_EXPORT void
weston_surface_damage_below(struct weston_surface *surface) weston_surface_damage_below(struct weston_surface *surface)
{ {
struct weston_surface *below; struct weston_compositor *compositor = surface->compositor;
pixman_region32_t damage;
if (surface->output == NULL) pixman_region32_init(&damage);
return; pixman_region32_subtract(&damage, &surface->transform.boundingbox,
&surface->clip);
if (surface->link.next == &surface->compositor->surface_list) pixman_region32_union(&compositor->damage,
return; &compositor->damage, &damage);
pixman_region32_fini(&damage);
below = container_of(surface->link.next, struct weston_surface, link);
pixman_region32_union(&below->damage, &below->damage,
&surface->transform.boundingbox);
} }
static void static void
@ -510,21 +510,6 @@ weston_surface_damage(struct weston_surface *surface)
weston_compositor_schedule_repaint(surface->compositor); weston_compositor_schedule_repaint(surface->compositor);
} }
static void
weston_surface_flush_damage(struct weston_surface *surface)
{
struct weston_surface *below;
if (surface->output &&
surface->link.next != &surface->compositor->surface_list) {
below = container_of(surface->link.next,
struct weston_surface, link);
pixman_region32_union(&below->damage,
&below->damage, &surface->damage);
}
}
WL_EXPORT void WL_EXPORT void
weston_surface_configure(struct weston_surface *surface, weston_surface_configure(struct weston_surface *surface,
GLfloat x, GLfloat y, int width, int height) GLfloat x, GLfloat y, int width, int height)
@ -613,11 +598,18 @@ weston_compositor_repick(struct weston_compositor *compositor)
static void static void
weston_surface_unmap(struct weston_surface *surface) weston_surface_unmap(struct weston_surface *surface)
{ {
struct wl_input_device *device = surface->compositor->input_device;
weston_surface_damage_below(surface); weston_surface_damage_below(surface);
weston_surface_flush_damage(surface);
surface->output = NULL; surface->output = NULL;
wl_list_remove(&surface->link); wl_list_remove(&surface->link);
wl_list_remove(&surface->layer_link);
weston_compositor_repick(surface->compositor); weston_compositor_repick(surface->compositor);
if (device->keyboard_focus == &surface->surface)
wl_input_device_set_keyboard_focus(device, NULL,
weston_compositor_get_time());
weston_compositor_schedule_repaint(surface->compositor); weston_compositor_schedule_repaint(surface->compositor);
} }
@ -647,6 +639,7 @@ destroy_surface(struct wl_resource *resource)
pixman_region32_fini(&surface->transform.boundingbox); pixman_region32_fini(&surface->transform.boundingbox);
pixman_region32_fini(&surface->damage); pixman_region32_fini(&surface->damage);
pixman_region32_fini(&surface->opaque); pixman_region32_fini(&surface->opaque);
pixman_region32_fini(&surface->clip);
if (!region_is_undefined(&surface->input)) if (!region_is_undefined(&surface->input))
pixman_region32_fini(&surface->input); pixman_region32_fini(&surface->input);
@ -762,7 +755,8 @@ texture_region(struct weston_surface *es, pixman_region32_t *region)
} }
WL_EXPORT void WL_EXPORT void
weston_surface_draw(struct weston_surface *es, struct weston_output *output) weston_surface_draw(struct weston_surface *es, struct weston_output *output,
pixman_region32_t *damage)
{ {
struct weston_compositor *ec = es->compositor; struct weston_compositor *ec = es->compositor;
GLfloat *v; GLfloat *v;
@ -771,12 +765,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
int n; int n;
pixman_region32_init(&repaint); pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint, &es->transform.boundingbox, pixman_region32_intersect(&repaint,
&output->region); &es->transform.boundingbox, damage);
pixman_region32_intersect(&repaint, &repaint, &es->damage); pixman_region32_subtract(&repaint, &repaint, &es->clip);
/* Clear damage, assume outputs do not overlap. */
pixman_region32_subtract(&es->damage, &es->damage, &output->region);
if (!pixman_region32_not_empty(&repaint)) if (!pixman_region32_not_empty(&repaint))
goto out; goto out;
@ -826,37 +817,15 @@ out:
pixman_region32_fini(&repaint); pixman_region32_fini(&repaint);
} }
WL_EXPORT struct wl_list * WL_EXPORT void
weston_compositor_top(struct weston_compositor *compositor) weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
{
struct weston_input_device *input_device;
struct wl_list *list;
input_device = (struct weston_input_device *) compositor->input_device;
/* Insert below pointer */
list = &compositor->surface_list;
if (compositor->fade.surface &&
list->next == &compositor->fade.surface->link)
list = list->next;
if (list->next == &input_device->sprite->link)
list = list->next;
if (input_device->drag_surface &&
list->next == &input_device->drag_surface->link)
list = list->next;
return list;
}
static void
weston_surface_raise(struct weston_surface *surface)
{ {
struct weston_compositor *compositor = surface->compositor; struct weston_compositor *compositor = surface->compositor;
struct wl_list *list = weston_compositor_top(compositor);
wl_list_remove(&surface->link); wl_list_remove(&surface->layer_link);
wl_list_insert(list, &surface->link); wl_list_insert(below, &surface->layer_link);
weston_compositor_repick(compositor); weston_compositor_repick(compositor);
weston_surface_damage_below(surface);
weston_surface_damage(surface); weston_surface_damage(surface);
} }
@ -883,14 +852,9 @@ WL_EXPORT void
weston_output_damage(struct weston_output *output) weston_output_damage(struct weston_output *output)
{ {
struct weston_compositor *compositor = output->compositor; struct weston_compositor *compositor = output->compositor;
struct weston_surface *es;
if (wl_list_empty(&compositor->surface_list)) pixman_region32_union(&compositor->damage,
return; &compositor->damage, &output->region);
es = container_of(compositor->surface_list.next,
struct weston_surface, link);
pixman_region32_union(&es->damage, &es->damage, &output->region);
weston_compositor_schedule_repaint(compositor); weston_compositor_schedule_repaint(compositor);
} }
@ -935,9 +899,10 @@ weston_output_repaint(struct weston_output *output, int msecs)
{ {
struct weston_compositor *ec = output->compositor; struct weston_compositor *ec = output->compositor;
struct weston_surface *es; struct weston_surface *es;
struct weston_layer *layer;
struct weston_animation *animation, *next; struct weston_animation *animation, *next;
struct weston_frame_callback *cb, *cnext; struct weston_frame_callback *cb, *cnext;
pixman_region32_t opaque, new_damage, total_damage; pixman_region32_t opaque, new_damage, output_damage;
int32_t width, height; int32_t width, height;
weston_compositor_update_drag_surfaces(ec); weston_compositor_update_drag_surfaces(ec);
@ -948,13 +913,14 @@ weston_output_repaint(struct weston_output *output, int msecs)
output->border.top + output->border.bottom; output->border.top + output->border.bottom;
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
pixman_region32_init(&new_damage); /* Rebuild the surface list and update surface transforms up front. */
pixman_region32_init(&opaque); wl_list_init(&ec->surface_list);
wl_list_for_each(layer, &ec->layer_list, link) {
wl_list_for_each(es, &ec->surface_list, link) wl_list_for_each(es, &layer->surface_list, layer_link) {
/* Update surface transform now to avoid calling it ever weston_surface_update_transform(es);
* again from the repaint sub-functions. */ wl_list_insert(ec->surface_list.prev, &es->link);
weston_surface_update_transform(es); }
}
if (output->assign_planes) if (output->assign_planes)
/* /*
@ -965,33 +931,36 @@ weston_output_repaint(struct weston_output *output, int msecs)
*/ */
output->assign_planes(output); output->assign_planes(output);
pixman_region32_init(&new_damage);
pixman_region32_init(&opaque);
wl_list_for_each(es, &ec->surface_list, link) { wl_list_for_each(es, &ec->surface_list, link) {
pixman_region32_subtract(&es->damage, &es->damage, &opaque); pixman_region32_subtract(&es->damage, &es->damage, &opaque);
pixman_region32_union(&new_damage, &new_damage, &es->damage); pixman_region32_union(&new_damage, &new_damage, &es->damage);
empty_region(&es->damage);
pixman_region32_copy(&es->clip, &opaque);
pixman_region32_union(&opaque, &opaque, &es->transform.opaque); pixman_region32_union(&opaque, &opaque, &es->transform.opaque);
} }
pixman_region32_init(&total_damage); pixman_region32_union(&ec->damage, &ec->damage, &new_damage);
pixman_region32_union(&total_damage, &new_damage,
&output->previous_damage); pixman_region32_init(&output_damage);
pixman_region32_intersect(&output->previous_damage, pixman_region32_union(&output_damage,
&new_damage, &output->region); &ec->damage, &output->previous_damage);
pixman_region32_copy(&output->previous_damage, &ec->damage);
pixman_region32_intersect(&output_damage,
&output_damage, &output->region);
pixman_region32_subtract(&ec->damage, &ec->damage, &output->region);
pixman_region32_fini(&opaque); pixman_region32_fini(&opaque);
pixman_region32_fini(&new_damage); pixman_region32_fini(&new_damage);
wl_list_for_each(es, &ec->surface_list, link) {
pixman_region32_copy(&es->damage, &total_damage);
pixman_region32_subtract(&total_damage,
&total_damage, &es->transform.opaque);
}
if (output->dirty) if (output->dirty)
weston_output_update_matrix(output); weston_output_update_matrix(output);
output->repaint(output); output->repaint(output, &output_damage);
pixman_region32_fini(&total_damage); pixman_region32_fini(&output_damage);
output->repaint_needed = 0; output->repaint_needed = 0;
@ -1025,6 +994,13 @@ weston_output_finish_frame(struct weston_output *output, int msecs)
output->repaint_scheduled = 0; output->repaint_scheduled = 0;
} }
WL_EXPORT void
weston_layer_init(struct weston_layer *layer, struct wl_list *below)
{
wl_list_init(&layer->surface_list);
wl_list_insert(below, &layer->link);
}
WL_EXPORT void WL_EXPORT void
weston_compositor_schedule_repaint(struct weston_compositor *compositor) weston_compositor_schedule_repaint(struct weston_compositor *compositor)
{ {
@ -1064,7 +1040,8 @@ weston_compositor_fade(struct weston_compositor *compositor, float tint)
surface = weston_surface_create(compositor); surface = weston_surface_create(compositor);
weston_surface_configure(surface, 0, 0, 8192, 8192); weston_surface_configure(surface, 0, 0, 8192, 8192);
weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0); weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0);
wl_list_insert(&compositor->surface_list, &surface->link); wl_list_insert(&compositor->fade_layer.surface_list,
&surface->layer_link);
weston_surface_assign_output(surface); weston_surface_assign_output(surface);
compositor->fade.surface = surface; compositor->fade.surface = surface;
pixman_region32_init(&surface->input); pixman_region32_init(&surface->input);
@ -1512,7 +1489,6 @@ WL_EXPORT void
weston_surface_activate(struct weston_surface *surface, weston_surface_activate(struct weston_surface *surface,
struct weston_input_device *device, uint32_t time) struct weston_input_device *device, uint32_t time)
{ {
weston_surface_raise(surface);
wl_input_device_set_keyboard_focus(&device->input_device, wl_input_device_set_keyboard_focus(&device->input_device,
&surface->surface, time); &surface->surface, time);
wl_data_device_set_keyboard_focus(&device->input_device); wl_data_device_set_keyboard_focus(&device->input_device);
@ -1837,13 +1813,14 @@ input_device_attach(struct wl_client *client,
if (!buffer_resource && device->sprite->output) { if (!buffer_resource && device->sprite->output) {
wl_list_remove(&device->sprite->link); wl_list_remove(&device->sprite->link);
wl_list_remove(&device->sprite->layer_link);
device->sprite->output = NULL; device->sprite->output = NULL;
return; return;
} }
if (!device->sprite->output) { if (!device->sprite->output) {
wl_list_insert(&compositor->surface_list, wl_list_insert(&compositor->cursor_layer.surface_list,
&device->sprite->link); &device->sprite->layer_link);
weston_surface_assign_output(device->sprite); weston_surface_assign_output(device->sprite);
} }
@ -1856,12 +1833,25 @@ input_device_attach(struct wl_client *client,
buffer->width, buffer->height); buffer->width, buffer->height);
weston_buffer_attach(buffer, &device->sprite->surface); weston_buffer_attach(buffer, &device->sprite->surface);
weston_surface_damage(device->sprite);
} }
const static struct wl_input_device_interface input_device_interface = { const static struct wl_input_device_interface input_device_interface = {
input_device_attach, input_device_attach,
}; };
static void
handle_drag_surface_destroy(struct wl_listener *listener,
struct wl_resource *resource, uint32_t time)
{
struct weston_input_device *device;
device = container_of(listener, struct weston_input_device,
drag_surface_destroy_listener);
device->drag_surface = NULL;
}
static void unbind_input_device(struct wl_resource *resource) static void unbind_input_device(struct wl_resource *resource)
{ {
wl_list_remove(&resource->link); wl_list_remove(&resource->link);
@ -1898,6 +1888,8 @@ weston_input_device_init(struct weston_input_device *device,
device->modifier_state = 0; device->modifier_state = 0;
device->num_tp = 0; device->num_tp = 0;
device->drag_surface_destroy_listener.func = handle_drag_surface_destroy;
wl_list_insert(ec->input_device_list.prev, &device->link); wl_list_insert(ec->input_device_list.prev, &device->link);
} }
@ -1913,6 +1905,42 @@ weston_input_device_release(struct weston_input_device *device)
wl_input_device_release(&device->input_device); wl_input_device_release(&device->input_device);
} }
static void
device_setup_new_drag_surface(struct weston_input_device *device,
struct weston_surface *surface)
{
struct wl_input_device *input_device = &device->input_device;
device->drag_surface = surface;
weston_surface_set_position(device->drag_surface,
input_device->x, input_device->y);
wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
&device->drag_surface_destroy_listener.link);
}
static void
device_release_drag_surface(struct weston_input_device *device)
{
undef_region(&device->drag_surface->input);
wl_list_remove(&device->drag_surface_destroy_listener.link);
device->drag_surface = NULL;
}
static void
device_map_drag_surface(struct weston_input_device *device)
{
if (device->drag_surface->output ||
!device->drag_surface->buffer)
return;
wl_list_insert(&device->sprite->layer_link,
&device->drag_surface->layer_link);
weston_surface_assign_output(device->drag_surface);
empty_region(&device->drag_surface->input);
}
static void static void
weston_input_update_drag_surface(struct wl_input_device *input_device, weston_input_update_drag_surface(struct wl_input_device *input_device,
int dx, int dy) int dx, int dy)
@ -1931,27 +1959,20 @@ weston_input_update_drag_surface(struct wl_input_device *input_device,
surface_changed = 1; surface_changed = 1;
if (!input_device->drag_surface || surface_changed) { if (!input_device->drag_surface || surface_changed) {
undef_region(&device->drag_surface->input); device_release_drag_surface(device);
device->drag_surface = NULL;
if (!surface_changed) if (!surface_changed)
return; return;
} }
if (!device->drag_surface || surface_changed) { if (!device->drag_surface || surface_changed) {
device->drag_surface = (struct weston_surface *) struct weston_surface *surface = (struct weston_surface *)
input_device->drag_surface; input_device->drag_surface;
device_setup_new_drag_surface(device, surface);
weston_surface_set_position(device->drag_surface,
input_device->x, input_device->y);
} }
if (device->drag_surface->output == NULL && /* the client may not have attached a buffer to the drag surface
device->drag_surface->buffer) { * when we setup it up, so check if map is needed on every update */
wl_list_insert(&device->sprite->link, device_map_drag_surface(device);
&device->drag_surface->link);
weston_surface_assign_output(device->drag_surface);
empty_region(&device->drag_surface->input);
}
/* the client may have attached a buffer with a different size to /* the client may have attached a buffer with a different size to
* the drag surface, causing the input region to be reset */ * the drag surface, causing the input region to be reset */
@ -2293,6 +2314,7 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
ec->bind_display(ec->display, ec->wl_display); ec->bind_display(ec->display, ec->wl_display);
wl_list_init(&ec->surface_list); wl_list_init(&ec->surface_list);
wl_list_init(&ec->layer_list);
wl_list_init(&ec->input_device_list); wl_list_init(&ec->input_device_list);
wl_list_init(&ec->output_list); wl_list_init(&ec->output_list);
wl_list_init(&ec->binding_list); wl_list_init(&ec->binding_list);
@ -2301,6 +2323,9 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
ec->fade.animation.frame = fade_frame; ec->fade.animation.frame = fade_frame;
wl_list_init(&ec->fade.animation.link); wl_list_init(&ec->fade.animation.link);
weston_layer_init(&ec->fade_layer, &ec->layer_list);
weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
ec->screenshooter = screenshooter_create(ec); ec->screenshooter = screenshooter_create(ec);
wl_data_device_manager_init(ec->wl_display); wl_data_device_manager_init(ec->wl_display);

View File

@ -91,7 +91,8 @@ struct weston_output {
struct weston_mode *current; struct weston_mode *current;
struct wl_list mode_list; struct wl_list mode_list;
void (*repaint)(struct weston_output *output); void (*repaint)(struct weston_output *output,
pixman_region32_t *damage);
void (*destroy)(struct weston_output *output); void (*destroy)(struct weston_output *output);
void (*assign_planes)(struct weston_output *output); void (*assign_planes)(struct weston_output *output);
@ -106,6 +107,7 @@ struct weston_input_device {
struct weston_compositor *compositor; struct weston_compositor *compositor;
struct weston_surface *sprite; struct weston_surface *sprite;
struct weston_surface *drag_surface; struct weston_surface *drag_surface;
struct wl_listener drag_surface_destroy_listener;
int32_t hotspot_x, hotspot_y; int32_t hotspot_x, hotspot_y;
struct wl_list link; struct wl_list link;
uint32_t modifier_state; uint32_t modifier_state;
@ -162,6 +164,11 @@ enum {
struct screenshooter; struct screenshooter;
struct weston_layer {
struct wl_list surface_list;
struct wl_list link;
};
struct weston_compositor { struct weston_compositor {
struct wl_shm *shm; struct wl_shm *shm;
struct weston_xserver *wxs; struct weston_xserver *wxs;
@ -180,8 +187,12 @@ struct weston_compositor {
/* There can be more than one, but not right now... */ /* There can be more than one, but not right now... */
struct wl_input_device *input_device; struct wl_input_device *input_device;
struct weston_layer fade_layer;
struct weston_layer cursor_layer;
struct wl_list output_list; struct wl_list output_list;
struct wl_list input_device_list; struct wl_list input_device_list;
struct wl_list layer_list;
struct wl_list surface_list; struct wl_list surface_list;
struct wl_list binding_list; struct wl_list binding_list;
struct wl_list animation_list; struct wl_list animation_list;
@ -198,8 +209,8 @@ struct weston_compositor {
int idle_time; /* effective timeout, s */ int idle_time; /* effective timeout, s */
/* Repaint state. */ /* Repaint state. */
struct timespec previous_swap;
struct wl_array vertices, indices; struct wl_array vertices, indices;
pixman_region32_t damage;
uint32_t focus; uint32_t focus;
@ -260,11 +271,13 @@ struct weston_surface {
struct wl_surface surface; struct wl_surface surface;
struct weston_compositor *compositor; struct weston_compositor *compositor;
GLuint texture; GLuint texture;
pixman_region32_t clip;
pixman_region32_t damage; pixman_region32_t damage;
pixman_region32_t opaque; pixman_region32_t opaque;
pixman_region32_t input; pixman_region32_t input;
int32_t pitch; int32_t pitch;
struct wl_list link; struct wl_list link;
struct wl_list layer_link;
struct wl_list buffer_link; struct wl_list buffer_link;
struct weston_shader *shader; struct weston_shader *shader;
GLfloat color[4]; GLfloat color[4];
@ -341,7 +354,8 @@ void
weston_surface_activate(struct weston_surface *surface, weston_surface_activate(struct weston_surface *surface,
struct weston_input_device *device, uint32_t time); struct weston_input_device *device, uint32_t time);
void void
weston_surface_draw(struct weston_surface *es, struct weston_output *output); weston_surface_draw(struct weston_surface *es,
struct weston_output *output, pixman_region32_t *damage);
void void
notify_motion(struct wl_input_device *device, notify_motion(struct wl_input_device *device,
@ -368,6 +382,9 @@ void
notify_touch(struct wl_input_device *device, uint32_t time, int touch_id, notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
int x, int y, int touch_type); int x, int y, int touch_type);
void
weston_layer_init(struct weston_layer *layer, struct wl_list *below);
void void
weston_output_finish_frame(struct weston_output *output, int msecs); weston_output_finish_frame(struct weston_output *output, int msecs);
void void
@ -420,6 +437,9 @@ void
weston_surface_configure(struct weston_surface *surface, weston_surface_configure(struct weston_surface *surface,
GLfloat x, GLfloat y, int width, int height); GLfloat x, GLfloat y, int width, int height);
void
weston_surface_restack(struct weston_surface *surface, struct wl_list *below);
void void
weston_surface_set_position(struct weston_surface *surface, weston_surface_set_position(struct weston_surface *surface,
GLfloat x, GLfloat y); GLfloat x, GLfloat y);

View File

@ -42,6 +42,12 @@ struct wl_shell {
struct weston_compositor *compositor; struct weston_compositor *compositor;
struct weston_shell shell; struct weston_shell shell;
struct weston_layer fullscreen_layer;
struct weston_layer panel_layer;
struct weston_layer toplevel_layer;
struct weston_layer background_layer;
struct weston_layer lock_layer;
struct { struct {
struct weston_process process; struct weston_process process;
struct wl_client *client; struct wl_client *client;
@ -56,7 +62,6 @@ struct wl_shell {
struct shell_surface *lock_surface; struct shell_surface *lock_surface;
struct wl_listener lock_surface_listener; struct wl_listener lock_surface_listener;
struct wl_list hidden_surface_list;
struct wl_list backgrounds; struct wl_list backgrounds;
struct wl_list panels; struct wl_list panels;
@ -93,7 +98,6 @@ struct shell_surface {
struct shell_surface *parent; struct shell_surface *parent;
enum shell_surface_type type; enum shell_surface_type type;
enum shell_surface_type prev_type;
int32_t saved_x, saved_y; int32_t saved_x, saved_y;
bool saved_position_valid; bool saved_position_valid;
@ -379,6 +383,8 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
shsurf->fullscreen.black_surface = NULL; shsurf->fullscreen.black_surface = NULL;
shsurf->fullscreen_output = NULL; shsurf->fullscreen_output = NULL;
shsurf->surface->force_configure = 1; shsurf->surface->force_configure = 1;
weston_surface_set_position(shsurf->surface,
shsurf->saved_x, shsurf->saved_y);
} }
static int static int
@ -412,7 +418,6 @@ reset_shell_surface_type(struct shell_surface *surface)
break; break;
} }
surface->prev_type = surface->type;
surface->type = SHELL_SURFACE_NONE; surface->type = SHELL_SURFACE_NONE;
return 0; return 0;
} }
@ -545,11 +550,15 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
center_on_output(surface, output); center_on_output(surface, output);
if (!shsurf->fullscreen.black_surface) if (!shsurf->fullscreen.black_surface)
shsurf->fullscreen.black_surface = create_black_surface(surface->compositor, shsurf->fullscreen.black_surface =
output->x, output->y, create_black_surface(surface->compositor,
output->current->width, output->current->height); output->x, output->y,
wl_list_remove(&shsurf->fullscreen.black_surface->link); output->current->width,
wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link); output->current->height);
wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
wl_list_insert(&surface->layer_link,
&shsurf->fullscreen.black_surface->layer_link);
shsurf->fullscreen.black_surface->output = output; shsurf->fullscreen.black_surface->output = output;
switch (shsurf->fullscreen.type) { switch (shsurf->fullscreen.type) {
@ -580,22 +589,17 @@ shell_stack_fullscreen(struct shell_surface *shsurf)
{ {
struct weston_surface *surface = shsurf->surface; struct weston_surface *surface = shsurf->surface;
struct wl_shell *shell = shell_surface_get_shell(shsurf); struct wl_shell *shell = shell_surface_get_shell(shsurf);
struct wl_list *list;
wl_list_remove(&surface->link); wl_list_remove(&surface->layer_link);
wl_list_remove(&shsurf->fullscreen.black_surface->link); wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
if (shell->locked) { wl_list_insert(&shell->fullscreen_layer.surface_list,
wl_list_insert(&shell->hidden_surface_list, &surface->link); &surface->layer_link);
wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link); wl_list_insert(&surface->layer_link,
} else { &shsurf->fullscreen.black_surface->layer_link);
list = weston_compositor_top(surface->compositor);
wl_list_insert(list, &surface->link);
wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
weston_surface_damage(surface); weston_surface_damage(surface);
weston_surface_damage(shsurf->fullscreen.black_surface); weston_surface_damage(shsurf->fullscreen.black_surface);
}
} }
static void static void
@ -623,17 +627,15 @@ shell_surface_set_fullscreen(struct wl_client *client,
if (reset_shell_surface_type(shsurf)) if (reset_shell_surface_type(shsurf))
return; return;
if (shsurf->prev_type != SHELL_SURFACE_FULLSCREEN) {
shsurf->saved_x = es->geometry.x;
shsurf->saved_y = es->geometry.y;
shsurf->saved_position_valid = true;
}
shsurf->fullscreen_output = shsurf->output; shsurf->fullscreen_output = shsurf->output;
shsurf->fullscreen.type = method; shsurf->fullscreen.type = method;
shsurf->fullscreen.framerate = framerate; shsurf->fullscreen.framerate = framerate;
shsurf->type = SHELL_SURFACE_FULLSCREEN; shsurf->type = SHELL_SURFACE_FULLSCREEN;
shsurf->saved_x = es->geometry.x;
shsurf->saved_y = es->geometry.y;
shsurf->saved_position_valid = true;
if (es->output) if (es->output)
shsurf->surface->force_configure = 1; shsurf->surface->force_configure = 1;
@ -860,7 +862,6 @@ shell_get_shell_surface(struct wl_client *client,
weston_matrix_init(&shsurf->rotation.rotation); weston_matrix_init(&shsurf->rotation.rotation);
shsurf->type = SHELL_SURFACE_NONE; shsurf->type = SHELL_SURFACE_NONE;
shsurf->prev_type = SHELL_SURFACE_NONE;
wl_client_add_resource(client, &shsurf->resource); wl_client_add_resource(client, &shsurf->resource);
} }
@ -884,6 +885,11 @@ launch_screensaver(struct wl_shell *shell)
if (!shell->screensaver.path) if (!shell->screensaver.path)
return; return;
if (shell->screensaver.process.pid != 0) {
fprintf(stderr, "old screensaver still running\n");
return;
}
weston_client_launch(shell->compositor, weston_client_launch(shell->compositor,
&shell->screensaver.process, &shell->screensaver.process,
shell->screensaver.path, shell->screensaver.path,
@ -905,12 +911,12 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
struct wl_list *list; struct wl_list *list;
if (shell->lock_surface) if (shell->lock_surface)
list = &shell->lock_surface->surface->link; list = &shell->lock_surface->surface->layer_link;
else else
list = &shell->compositor->surface_list; list = &shell->lock_layer.surface_list;
wl_list_remove(&surface->surface->link); wl_list_remove(&surface->surface->layer_link);
wl_list_insert(list, &surface->surface->link); wl_list_insert(list, &surface->surface->layer_link);
surface->surface->output = surface->output; surface->surface->output = surface->output;
weston_surface_damage(surface->surface); weston_surface_damage(surface->surface);
} }
@ -918,8 +924,8 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
static void static void
hide_screensaver(struct wl_shell *shell, struct shell_surface *surface) hide_screensaver(struct wl_shell *shell, struct shell_surface *surface)
{ {
wl_list_remove(&surface->surface->link); wl_list_remove(&surface->surface->layer_link);
wl_list_init(&surface->surface->link); wl_list_init(&surface->surface->layer_link);
surface->surface->output = NULL; surface->surface->output = NULL;
} }
@ -940,7 +946,7 @@ desktop_shell_set_background(struct wl_client *client,
wl_list_for_each(priv, &shell->backgrounds, link) { wl_list_for_each(priv, &shell->backgrounds, link) {
if (priv->output == output_resource->data) { if (priv->output == output_resource->data) {
priv->surface->output = NULL; priv->surface->output = NULL;
wl_list_remove(&priv->surface->link); wl_list_remove(&priv->surface->layer_link);
wl_list_remove(&priv->link); wl_list_remove(&priv->link);
break; break;
} }
@ -978,7 +984,7 @@ desktop_shell_set_panel(struct wl_client *client,
wl_list_for_each(priv, &shell->panels, link) { wl_list_for_each(priv, &shell->panels, link) {
if (priv->output == output_resource->data) { if (priv->output == output_resource->data) {
priv->surface->output = NULL; priv->surface->output = NULL;
wl_list_remove(&priv->surface->link); wl_list_remove(&priv->surface->layer_link);
wl_list_remove(&priv->link); wl_list_remove(&priv->link);
break; break;
} }
@ -1038,8 +1044,6 @@ desktop_shell_set_lock_surface(struct wl_client *client,
static void static void
resume_desktop(struct wl_shell *shell) resume_desktop(struct wl_shell *shell)
{ {
struct weston_surface *surface;
struct wl_list *list;
struct shell_surface *tmp; struct shell_surface *tmp;
wl_list_for_each(tmp, &shell->screensaver.surfaces, link) wl_list_for_each(tmp, &shell->screensaver.surfaces, link)
@ -1047,21 +1051,12 @@ resume_desktop(struct wl_shell *shell)
terminate_screensaver(shell); terminate_screensaver(shell);
wl_list_for_each(surface, &shell->hidden_surface_list, link) wl_list_remove(&shell->lock_layer.link);
weston_surface_assign_output(surface); wl_list_insert(&shell->compositor->cursor_layer.link,
&shell->fullscreen_layer.link);
if (wl_list_empty(&shell->backgrounds)) { wl_list_insert(&shell->fullscreen_layer.link,
list = &shell->compositor->surface_list; &shell->panel_layer.link);
} else { wl_list_insert(&shell->panel_layer.link, &shell->toplevel_layer.link);
struct shell_surface *background;
background = container_of(shell->backgrounds.prev,
struct shell_surface, link);
list = background->surface->link.prev;
}
if (!wl_list_empty(&shell->hidden_surface_list))
wl_list_insert_list(list, &shell->hidden_surface_list);
wl_list_init(&shell->hidden_surface_list);
shell->locked = false; shell->locked = false;
weston_compositor_repick(shell->compositor); weston_compositor_repick(shell->compositor);
@ -1383,7 +1378,6 @@ activate(struct weston_shell *base, struct weston_surface *es,
{ {
struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wl_shell *shell = container_of(base, struct wl_shell, shell);
struct weston_compositor *compositor = shell->compositor; struct weston_compositor *compositor = shell->compositor;
struct wl_list *list;
weston_surface_activate(es, device, time); weston_surface_activate(es, device, time);
@ -1392,35 +1386,23 @@ activate(struct weston_shell *base, struct weston_surface *es,
switch (get_shell_surface_type(es)) { switch (get_shell_surface_type(es)) {
case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_BACKGROUND:
/* put background back to bottom */
wl_list_remove(&es->link);
wl_list_insert(compositor->surface_list.prev, &es->link);
break;
case SHELL_SURFACE_PANEL: case SHELL_SURFACE_PANEL:
/* already put on top */ case SHELL_SURFACE_LOCK:
break; break;
case SHELL_SURFACE_SCREENSAVER: case SHELL_SURFACE_SCREENSAVER:
/* always below lock surface */ /* always below lock surface */
if (shell->lock_surface) { if (shell->lock_surface)
wl_list_remove(&es->link); weston_surface_restack(es,
wl_list_insert(&shell->lock_surface->surface->link, &shell->lock_surface->surface->layer_link);
&es->link);
}
break; break;
case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_FULLSCREEN:
/* should on top of panels */ /* should on top of panels */
break; break;
default: default:
if (!shell->locked) { weston_surface_restack(es,
list = weston_compositor_top(compositor); &shell->toplevel_layer.surface_list);
break;
/* bring panel back to top */
struct shell_surface *panel;
wl_list_for_each(panel, &shell->panels, link) {
wl_list_remove(&panel->surface->link);
wl_list_insert(list, &panel->surface->link);
}
}
} }
} }
@ -1451,9 +1433,6 @@ static void
lock(struct weston_shell *base) lock(struct weston_shell *base)
{ {
struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wl_shell *shell = container_of(base, struct wl_shell, shell);
struct wl_list *surface_list = &shell->compositor->surface_list;
struct weston_surface *cur;
struct weston_surface *tmp;
struct weston_input_device *device; struct weston_input_device *device;
struct shell_surface *shsurf; struct shell_surface *shsurf;
struct weston_output *output; struct weston_output *output;
@ -1469,28 +1448,15 @@ lock(struct weston_shell *base)
shell->locked = true; shell->locked = true;
/* Move all surfaces from compositor's list to our hidden list, /* Hide all surfaces by removing the fullscreen, panel and
* except the background. This way nothing else can show or * toplevel layers. This way nothing else can show or receive
* receive input events while we are locked. */ * input events while we are locked. */
if (!wl_list_empty(&shell->hidden_surface_list)) { wl_list_remove(&shell->panel_layer.link);
fprintf(stderr, wl_list_remove(&shell->toplevel_layer.link);
"%s: Assertion failed: hidden_surface_list is not empty.\n", wl_list_remove(&shell->fullscreen_layer.link);
__func__); wl_list_insert(&shell->compositor->cursor_layer.link,
} &shell->lock_layer.link);
wl_list_for_each_safe(cur, tmp, surface_list, link) {
/* skip input device sprites, cur->surface is uninitialised */
if (cur->surface.resource.client == NULL)
continue;
if (get_shell_surface_type(cur) == SHELL_SURFACE_BACKGROUND)
continue;
cur->output = NULL;
wl_list_remove(&cur->link);
wl_list_insert(shell->hidden_surface_list.prev, &cur->link);
}
launch_screensaver(shell); launch_screensaver(shell);
@ -1558,24 +1524,14 @@ map(struct weston_shell *base, struct weston_surface *surface,
{ {
struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wl_shell *shell = container_of(base, struct wl_shell, shell);
struct weston_compositor *compositor = shell->compositor; struct weston_compositor *compositor = shell->compositor;
struct wl_list *list;
struct shell_surface *shsurf; struct shell_surface *shsurf;
enum shell_surface_type surface_type = SHELL_SURFACE_NONE; enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
int do_configure;
int panel_height = 0; int panel_height = 0;
shsurf = get_shell_surface(surface); shsurf = get_shell_surface(surface);
if (shsurf) if (shsurf)
surface_type = shsurf->type; surface_type = shsurf->type;
if (shell->locked) {
list = &shell->hidden_surface_list;
do_configure = 0;
} else {
list = weston_compositor_top(compositor);
do_configure = 1;
}
surface->geometry.width = width; surface->geometry.width = width;
surface->geometry.height = height; surface->geometry.height = height;
surface->geometry.dirty = 1; surface->geometry.dirty = 1;
@ -1618,19 +1574,19 @@ map(struct weston_shell *base, struct weston_surface *surface,
switch (surface_type) { switch (surface_type) {
case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_BACKGROUND:
/* background always visible, at the bottom */ /* background always visible, at the bottom */
wl_list_insert(compositor->surface_list.prev, &surface->link); wl_list_insert(&shell->background_layer.surface_list,
do_configure = 1; &surface->layer_link);
break; break;
case SHELL_SURFACE_PANEL: case SHELL_SURFACE_PANEL:
/* panel always on top, hidden while locked */ /* panel always on top, hidden while locked */
wl_list_insert(list, &surface->link); wl_list_insert(&shell->panel_layer.surface_list,
&surface->layer_link);
break; break;
case SHELL_SURFACE_LOCK: case SHELL_SURFACE_LOCK:
/* lock surface always visible, on top */ /* lock surface always visible, on top */
wl_list_insert(&compositor->surface_list, &surface->link); wl_list_insert(&shell->lock_layer.surface_list,
&surface->layer_link);
weston_compositor_wake(compositor); weston_compositor_wake(compositor);
do_configure = 1;
break; break;
case SHELL_SURFACE_SCREENSAVER: case SHELL_SURFACE_SCREENSAVER:
/* If locked, show it. */ /* If locked, show it. */
@ -1641,32 +1597,20 @@ map(struct weston_shell *base, struct weston_surface *surface,
if (!shell->lock_surface) if (!shell->lock_surface)
compositor->state = WESTON_COMPOSITOR_IDLE; compositor->state = WESTON_COMPOSITOR_IDLE;
} }
do_configure = 0;
break; break;
case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_FULLSCREEN:
do_configure = 1;
break;
case SHELL_SURFACE_NONE: case SHELL_SURFACE_NONE:
do_configure = 0;
break; break;
default: default:
/* everything else just below the panel */ wl_list_insert(&shell->toplevel_layer.surface_list,
if (!wl_list_empty(&shell->panels)) { &surface->layer_link);
struct shell_surface *panel = break;
container_of(shell->panels.prev,
struct shell_surface, link);
wl_list_insert(&panel->surface->link, &surface->link);
} else {
wl_list_insert(list, &surface->link);
}
} }
if (do_configure) { weston_surface_assign_output(surface);
weston_surface_assign_output(surface); weston_compositor_repick(compositor);
weston_compositor_repick(compositor); if (surface_type == SHELL_SURFACE_MAXIMIZED)
if (surface_type == SHELL_SURFACE_MAXIMIZED) surface->output = shsurf->output;
surface->output = shsurf->output;
}
switch (surface_type) { switch (surface_type) {
case SHELL_SURFACE_TOPLEVEL: case SHELL_SURFACE_TOPLEVEL:
@ -1697,10 +1641,8 @@ configure(struct weston_shell *base, struct weston_surface *surface,
struct shell_surface *shsurf; struct shell_surface *shsurf;
shsurf = get_shell_surface(surface); shsurf = get_shell_surface(surface);
if (shsurf) { if (shsurf)
surface_type = shsurf->type; surface_type = shsurf->type;
prev_surface_type = shsurf->prev_type;
}
surface->geometry.x = x; surface->geometry.x = x;
surface->geometry.y = y; surface->geometry.y = y;
@ -1724,18 +1666,6 @@ configure(struct weston_shell *base, struct weston_surface *surface,
get_output_panel_height(shell,surface->output); get_output_panel_height(shell,surface->output);
break; break;
case SHELL_SURFACE_TOPLEVEL: case SHELL_SURFACE_TOPLEVEL:
if (prev_surface_type != SHELL_SURFACE_TOPLEVEL) {
if (shsurf->saved_position_valid &&
shsurf->saved_x != surface->geometry.x &&
shsurf->saved_y != surface->geometry.y) {
weston_surface_set_position(surface,
shsurf->saved_x,
shsurf->saved_y);
} else if (!shsurf->saved_position_valid) {
weston_surface_set_position(surface, 10 + random() % 400,
10 + random() % 400);
}
}
break; break;
default: default:
break; break;
@ -2071,11 +2001,17 @@ shell_init(struct weston_compositor *ec)
shell->shell.configure = configure; shell->shell.configure = configure;
shell->shell.destroy = shell_destroy; shell->shell.destroy = shell_destroy;
wl_list_init(&shell->hidden_surface_list);
wl_list_init(&shell->backgrounds); wl_list_init(&shell->backgrounds);
wl_list_init(&shell->panels); wl_list_init(&shell->panels);
wl_list_init(&shell->screensaver.surfaces); wl_list_init(&shell->screensaver.surfaces);
weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
weston_layer_init(&shell->toplevel_layer, &shell->panel_layer.link);
weston_layer_init(&shell->background_layer,
&shell->toplevel_layer.link);
wl_list_init(&shell->lock_layer.surface_list);
shell_configuration(shell); shell_configuration(shell);
if (wl_display_add_global(ec->wl_display, &wl_shell_interface, if (wl_display_add_global(ec->wl_display, &wl_shell_interface,