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:
commit
f98d903b6d
@ -214,7 +214,8 @@ drm_output_prepare_scanout_surface(struct drm_output *output)
|
||||
}
|
||||
|
||||
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_compositor *compositor =
|
||||
@ -235,7 +236,7 @@ drm_output_repaint(struct weston_output *output_base)
|
||||
drm_output_prepare_scanout_surface(output);
|
||||
|
||||
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();
|
||||
|
||||
|
@ -329,7 +329,8 @@ static const struct wl_callback_listener frame_listener = {
|
||||
};
|
||||
|
||||
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_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)
|
||||
weston_surface_draw(surface, &output->base);
|
||||
weston_surface_draw(surface, &output->base, damage);
|
||||
|
||||
draw_border(output);
|
||||
|
||||
|
@ -186,7 +186,8 @@ x11_compositor_fini_egl(struct x11_compositor *compositor)
|
||||
}
|
||||
|
||||
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_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)
|
||||
weston_surface_draw(surface, &output->base);
|
||||
weston_surface_draw(surface, &output->base, damage);
|
||||
|
||||
eglSwapBuffers(compositor->base.display, output->egl_surface);
|
||||
|
||||
|
235
src/compositor.c
235
src/compositor.c
@ -211,6 +211,7 @@ weston_surface_create(struct weston_compositor *compositor)
|
||||
wl_list_init(&surface->surface.resource.destroy_listener_list);
|
||||
|
||||
wl_list_init(&surface->link);
|
||||
wl_list_init(&surface->layer_link);
|
||||
wl_list_init(&surface->buffer_link);
|
||||
|
||||
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->opaque);
|
||||
pixman_region32_init(&surface->clip);
|
||||
undef_region(&surface->input);
|
||||
pixman_region32_init(&surface->transform.opaque);
|
||||
wl_list_init(&surface->frame_callback_list);
|
||||
@ -281,17 +283,15 @@ surface_to_global_float(struct weston_surface *surface,
|
||||
WL_EXPORT void
|
||||
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)
|
||||
return;
|
||||
|
||||
if (surface->link.next == &surface->compositor->surface_list)
|
||||
return;
|
||||
|
||||
below = container_of(surface->link.next, struct weston_surface, link);
|
||||
pixman_region32_union(&below->damage, &below->damage,
|
||||
&surface->transform.boundingbox);
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_subtract(&damage, &surface->transform.boundingbox,
|
||||
&surface->clip);
|
||||
pixman_region32_union(&compositor->damage,
|
||||
&compositor->damage, &damage);
|
||||
pixman_region32_fini(&damage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -510,21 +510,6 @@ weston_surface_damage(struct weston_surface *surface)
|
||||
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
|
||||
weston_surface_configure(struct weston_surface *surface,
|
||||
GLfloat x, GLfloat y, int width, int height)
|
||||
@ -613,11 +598,18 @@ weston_compositor_repick(struct weston_compositor *compositor)
|
||||
static void
|
||||
weston_surface_unmap(struct weston_surface *surface)
|
||||
{
|
||||
struct wl_input_device *device = surface->compositor->input_device;
|
||||
|
||||
weston_surface_damage_below(surface);
|
||||
weston_surface_flush_damage(surface);
|
||||
surface->output = NULL;
|
||||
wl_list_remove(&surface->link);
|
||||
wl_list_remove(&surface->layer_link);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -647,6 +639,7 @@ destroy_surface(struct wl_resource *resource)
|
||||
pixman_region32_fini(&surface->transform.boundingbox);
|
||||
pixman_region32_fini(&surface->damage);
|
||||
pixman_region32_fini(&surface->opaque);
|
||||
pixman_region32_fini(&surface->clip);
|
||||
if (!region_is_undefined(&surface->input))
|
||||
pixman_region32_fini(&surface->input);
|
||||
|
||||
@ -762,7 +755,8 @@ texture_region(struct weston_surface *es, pixman_region32_t *region)
|
||||
}
|
||||
|
||||
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;
|
||||
GLfloat *v;
|
||||
@ -771,12 +765,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
|
||||
int n;
|
||||
|
||||
pixman_region32_init(&repaint);
|
||||
pixman_region32_intersect(&repaint, &es->transform.boundingbox,
|
||||
&output->region);
|
||||
pixman_region32_intersect(&repaint, &repaint, &es->damage);
|
||||
|
||||
/* Clear damage, assume outputs do not overlap. */
|
||||
pixman_region32_subtract(&es->damage, &es->damage, &output->region);
|
||||
pixman_region32_intersect(&repaint,
|
||||
&es->transform.boundingbox, damage);
|
||||
pixman_region32_subtract(&repaint, &repaint, &es->clip);
|
||||
|
||||
if (!pixman_region32_not_empty(&repaint))
|
||||
goto out;
|
||||
@ -826,37 +817,15 @@ out:
|
||||
pixman_region32_fini(&repaint);
|
||||
}
|
||||
|
||||
WL_EXPORT struct wl_list *
|
||||
weston_compositor_top(struct weston_compositor *compositor)
|
||||
{
|
||||
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)
|
||||
WL_EXPORT void
|
||||
weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
|
||||
{
|
||||
struct weston_compositor *compositor = surface->compositor;
|
||||
struct wl_list *list = weston_compositor_top(compositor);
|
||||
|
||||
wl_list_remove(&surface->link);
|
||||
wl_list_insert(list, &surface->link);
|
||||
wl_list_remove(&surface->layer_link);
|
||||
wl_list_insert(below, &surface->layer_link);
|
||||
weston_compositor_repick(compositor);
|
||||
weston_surface_damage_below(surface);
|
||||
weston_surface_damage(surface);
|
||||
}
|
||||
|
||||
@ -883,14 +852,9 @@ WL_EXPORT void
|
||||
weston_output_damage(struct weston_output *output)
|
||||
{
|
||||
struct weston_compositor *compositor = output->compositor;
|
||||
struct weston_surface *es;
|
||||
|
||||
if (wl_list_empty(&compositor->surface_list))
|
||||
return;
|
||||
|
||||
es = container_of(compositor->surface_list.next,
|
||||
struct weston_surface, link);
|
||||
pixman_region32_union(&es->damage, &es->damage, &output->region);
|
||||
pixman_region32_union(&compositor->damage,
|
||||
&compositor->damage, &output->region);
|
||||
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_surface *es;
|
||||
struct weston_layer *layer;
|
||||
struct weston_animation *animation, *next;
|
||||
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;
|
||||
|
||||
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;
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
pixman_region32_init(&new_damage);
|
||||
pixman_region32_init(&opaque);
|
||||
|
||||
wl_list_for_each(es, &ec->surface_list, link)
|
||||
/* Update surface transform now to avoid calling it ever
|
||||
* again from the repaint sub-functions. */
|
||||
weston_surface_update_transform(es);
|
||||
/* Rebuild the surface list and update surface transforms up front. */
|
||||
wl_list_init(&ec->surface_list);
|
||||
wl_list_for_each(layer, &ec->layer_list, link) {
|
||||
wl_list_for_each(es, &layer->surface_list, layer_link) {
|
||||
weston_surface_update_transform(es);
|
||||
wl_list_insert(ec->surface_list.prev, &es->link);
|
||||
}
|
||||
}
|
||||
|
||||
if (output->assign_planes)
|
||||
/*
|
||||
@ -965,33 +931,36 @@ weston_output_repaint(struct weston_output *output, int msecs)
|
||||
*/
|
||||
output->assign_planes(output);
|
||||
|
||||
pixman_region32_init(&new_damage);
|
||||
pixman_region32_init(&opaque);
|
||||
|
||||
wl_list_for_each(es, &ec->surface_list, link) {
|
||||
pixman_region32_subtract(&es->damage, &es->damage, &opaque);
|
||||
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_init(&total_damage);
|
||||
pixman_region32_union(&total_damage, &new_damage,
|
||||
&output->previous_damage);
|
||||
pixman_region32_intersect(&output->previous_damage,
|
||||
&new_damage, &output->region);
|
||||
pixman_region32_union(&ec->damage, &ec->damage, &new_damage);
|
||||
|
||||
pixman_region32_init(&output_damage);
|
||||
pixman_region32_union(&output_damage,
|
||||
&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(&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)
|
||||
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;
|
||||
|
||||
@ -1025,6 +994,13 @@ weston_output_finish_frame(struct weston_output *output, int msecs)
|
||||
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
|
||||
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);
|
||||
weston_surface_configure(surface, 0, 0, 8192, 8192);
|
||||
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);
|
||||
compositor->fade.surface = surface;
|
||||
pixman_region32_init(&surface->input);
|
||||
@ -1512,7 +1489,6 @@ WL_EXPORT void
|
||||
weston_surface_activate(struct weston_surface *surface,
|
||||
struct weston_input_device *device, uint32_t time)
|
||||
{
|
||||
weston_surface_raise(surface);
|
||||
wl_input_device_set_keyboard_focus(&device->input_device,
|
||||
&surface->surface, time);
|
||||
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) {
|
||||
wl_list_remove(&device->sprite->link);
|
||||
wl_list_remove(&device->sprite->layer_link);
|
||||
device->sprite->output = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device->sprite->output) {
|
||||
wl_list_insert(&compositor->surface_list,
|
||||
&device->sprite->link);
|
||||
wl_list_insert(&compositor->cursor_layer.surface_list,
|
||||
&device->sprite->layer_link);
|
||||
weston_surface_assign_output(device->sprite);
|
||||
}
|
||||
|
||||
@ -1856,12 +1833,25 @@ input_device_attach(struct wl_client *client,
|
||||
buffer->width, buffer->height);
|
||||
|
||||
weston_buffer_attach(buffer, &device->sprite->surface);
|
||||
weston_surface_damage(device->sprite);
|
||||
}
|
||||
|
||||
const static struct wl_input_device_interface input_device_interface = {
|
||||
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)
|
||||
{
|
||||
wl_list_remove(&resource->link);
|
||||
@ -1898,6 +1888,8 @@ weston_input_device_init(struct weston_input_device *device,
|
||||
device->modifier_state = 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);
|
||||
}
|
||||
|
||||
@ -1913,6 +1905,42 @@ weston_input_device_release(struct weston_input_device *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
|
||||
weston_input_update_drag_surface(struct wl_input_device *input_device,
|
||||
int dx, int dy)
|
||||
@ -1931,27 +1959,20 @@ weston_input_update_drag_surface(struct wl_input_device *input_device,
|
||||
surface_changed = 1;
|
||||
|
||||
if (!input_device->drag_surface || surface_changed) {
|
||||
undef_region(&device->drag_surface->input);
|
||||
device->drag_surface = NULL;
|
||||
device_release_drag_surface(device);
|
||||
if (!surface_changed)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device->drag_surface || surface_changed) {
|
||||
device->drag_surface = (struct weston_surface *)
|
||||
struct weston_surface *surface = (struct weston_surface *)
|
||||
input_device->drag_surface;
|
||||
|
||||
weston_surface_set_position(device->drag_surface,
|
||||
input_device->x, input_device->y);
|
||||
device_setup_new_drag_surface(device, surface);
|
||||
}
|
||||
|
||||
if (device->drag_surface->output == NULL &&
|
||||
device->drag_surface->buffer) {
|
||||
wl_list_insert(&device->sprite->link,
|
||||
&device->drag_surface->link);
|
||||
weston_surface_assign_output(device->drag_surface);
|
||||
empty_region(&device->drag_surface->input);
|
||||
}
|
||||
/* the client may not have attached a buffer to the drag surface
|
||||
* when we setup it up, so check if map is needed on every update */
|
||||
device_map_drag_surface(device);
|
||||
|
||||
/* the client may have attached a buffer with a different size to
|
||||
* 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);
|
||||
|
||||
wl_list_init(&ec->surface_list);
|
||||
wl_list_init(&ec->layer_list);
|
||||
wl_list_init(&ec->input_device_list);
|
||||
wl_list_init(&ec->output_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;
|
||||
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);
|
||||
|
||||
wl_data_device_manager_init(ec->wl_display);
|
||||
|
@ -91,7 +91,8 @@ struct weston_output {
|
||||
struct weston_mode *current;
|
||||
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 (*assign_planes)(struct weston_output *output);
|
||||
|
||||
@ -106,6 +107,7 @@ struct weston_input_device {
|
||||
struct weston_compositor *compositor;
|
||||
struct weston_surface *sprite;
|
||||
struct weston_surface *drag_surface;
|
||||
struct wl_listener drag_surface_destroy_listener;
|
||||
int32_t hotspot_x, hotspot_y;
|
||||
struct wl_list link;
|
||||
uint32_t modifier_state;
|
||||
@ -162,6 +164,11 @@ enum {
|
||||
|
||||
struct screenshooter;
|
||||
|
||||
struct weston_layer {
|
||||
struct wl_list surface_list;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct weston_compositor {
|
||||
struct wl_shm *shm;
|
||||
struct weston_xserver *wxs;
|
||||
@ -180,8 +187,12 @@ struct weston_compositor {
|
||||
/* There can be more than one, but not right now... */
|
||||
struct wl_input_device *input_device;
|
||||
|
||||
struct weston_layer fade_layer;
|
||||
struct weston_layer cursor_layer;
|
||||
|
||||
struct wl_list output_list;
|
||||
struct wl_list input_device_list;
|
||||
struct wl_list layer_list;
|
||||
struct wl_list surface_list;
|
||||
struct wl_list binding_list;
|
||||
struct wl_list animation_list;
|
||||
@ -198,8 +209,8 @@ struct weston_compositor {
|
||||
int idle_time; /* effective timeout, s */
|
||||
|
||||
/* Repaint state. */
|
||||
struct timespec previous_swap;
|
||||
struct wl_array vertices, indices;
|
||||
pixman_region32_t damage;
|
||||
|
||||
uint32_t focus;
|
||||
|
||||
@ -260,11 +271,13 @@ struct weston_surface {
|
||||
struct wl_surface surface;
|
||||
struct weston_compositor *compositor;
|
||||
GLuint texture;
|
||||
pixman_region32_t clip;
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_t opaque;
|
||||
pixman_region32_t input;
|
||||
int32_t pitch;
|
||||
struct wl_list link;
|
||||
struct wl_list layer_link;
|
||||
struct wl_list buffer_link;
|
||||
struct weston_shader *shader;
|
||||
GLfloat color[4];
|
||||
@ -341,7 +354,8 @@ void
|
||||
weston_surface_activate(struct weston_surface *surface,
|
||||
struct weston_input_device *device, uint32_t time);
|
||||
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
|
||||
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,
|
||||
int x, int y, int touch_type);
|
||||
|
||||
void
|
||||
weston_layer_init(struct weston_layer *layer, struct wl_list *below);
|
||||
|
||||
void
|
||||
weston_output_finish_frame(struct weston_output *output, int msecs);
|
||||
void
|
||||
@ -420,6 +437,9 @@ void
|
||||
weston_surface_configure(struct weston_surface *surface,
|
||||
GLfloat x, GLfloat y, int width, int height);
|
||||
|
||||
void
|
||||
weston_surface_restack(struct weston_surface *surface, struct wl_list *below);
|
||||
|
||||
void
|
||||
weston_surface_set_position(struct weston_surface *surface,
|
||||
GLfloat x, GLfloat y);
|
||||
|
234
src/shell.c
234
src/shell.c
@ -42,6 +42,12 @@ struct wl_shell {
|
||||
struct weston_compositor *compositor;
|
||||
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 weston_process process;
|
||||
struct wl_client *client;
|
||||
@ -56,7 +62,6 @@ struct wl_shell {
|
||||
|
||||
struct shell_surface *lock_surface;
|
||||
struct wl_listener lock_surface_listener;
|
||||
struct wl_list hidden_surface_list;
|
||||
|
||||
struct wl_list backgrounds;
|
||||
struct wl_list panels;
|
||||
@ -93,7 +98,6 @@ struct shell_surface {
|
||||
struct shell_surface *parent;
|
||||
|
||||
enum shell_surface_type type;
|
||||
enum shell_surface_type prev_type;
|
||||
int32_t saved_x, saved_y;
|
||||
bool saved_position_valid;
|
||||
|
||||
@ -379,6 +383,8 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
|
||||
shsurf->fullscreen.black_surface = NULL;
|
||||
shsurf->fullscreen_output = NULL;
|
||||
shsurf->surface->force_configure = 1;
|
||||
weston_surface_set_position(shsurf->surface,
|
||||
shsurf->saved_x, shsurf->saved_y);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -412,7 +418,6 @@ reset_shell_surface_type(struct shell_surface *surface)
|
||||
break;
|
||||
}
|
||||
|
||||
surface->prev_type = surface->type;
|
||||
surface->type = SHELL_SURFACE_NONE;
|
||||
return 0;
|
||||
}
|
||||
@ -545,11 +550,15 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
|
||||
center_on_output(surface, output);
|
||||
|
||||
if (!shsurf->fullscreen.black_surface)
|
||||
shsurf->fullscreen.black_surface = create_black_surface(surface->compositor,
|
||||
output->x, output->y,
|
||||
output->current->width, output->current->height);
|
||||
wl_list_remove(&shsurf->fullscreen.black_surface->link);
|
||||
wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
|
||||
shsurf->fullscreen.black_surface =
|
||||
create_black_surface(surface->compositor,
|
||||
output->x, output->y,
|
||||
output->current->width,
|
||||
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;
|
||||
|
||||
switch (shsurf->fullscreen.type) {
|
||||
@ -580,22 +589,17 @@ shell_stack_fullscreen(struct shell_surface *shsurf)
|
||||
{
|
||||
struct weston_surface *surface = shsurf->surface;
|
||||
struct wl_shell *shell = shell_surface_get_shell(shsurf);
|
||||
struct wl_list *list;
|
||||
|
||||
wl_list_remove(&surface->link);
|
||||
wl_list_remove(&shsurf->fullscreen.black_surface->link);
|
||||
wl_list_remove(&surface->layer_link);
|
||||
wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
|
||||
|
||||
if (shell->locked) {
|
||||
wl_list_insert(&shell->hidden_surface_list, &surface->link);
|
||||
wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
|
||||
} else {
|
||||
list = weston_compositor_top(surface->compositor);
|
||||
wl_list_insert(list, &surface->link);
|
||||
wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
|
||||
wl_list_insert(&shell->fullscreen_layer.surface_list,
|
||||
&surface->layer_link);
|
||||
wl_list_insert(&surface->layer_link,
|
||||
&shsurf->fullscreen.black_surface->layer_link);
|
||||
|
||||
weston_surface_damage(surface);
|
||||
weston_surface_damage(shsurf->fullscreen.black_surface);
|
||||
}
|
||||
weston_surface_damage(surface);
|
||||
weston_surface_damage(shsurf->fullscreen.black_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -623,17 +627,15 @@ shell_surface_set_fullscreen(struct wl_client *client,
|
||||
if (reset_shell_surface_type(shsurf))
|
||||
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.type = method;
|
||||
shsurf->fullscreen.framerate = framerate;
|
||||
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)
|
||||
shsurf->surface->force_configure = 1;
|
||||
|
||||
@ -860,7 +862,6 @@ shell_get_shell_surface(struct wl_client *client,
|
||||
weston_matrix_init(&shsurf->rotation.rotation);
|
||||
|
||||
shsurf->type = SHELL_SURFACE_NONE;
|
||||
shsurf->prev_type = SHELL_SURFACE_NONE;
|
||||
|
||||
wl_client_add_resource(client, &shsurf->resource);
|
||||
}
|
||||
@ -884,6 +885,11 @@ launch_screensaver(struct wl_shell *shell)
|
||||
if (!shell->screensaver.path)
|
||||
return;
|
||||
|
||||
if (shell->screensaver.process.pid != 0) {
|
||||
fprintf(stderr, "old screensaver still running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
weston_client_launch(shell->compositor,
|
||||
&shell->screensaver.process,
|
||||
shell->screensaver.path,
|
||||
@ -905,12 +911,12 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
|
||||
struct wl_list *list;
|
||||
|
||||
if (shell->lock_surface)
|
||||
list = &shell->lock_surface->surface->link;
|
||||
list = &shell->lock_surface->surface->layer_link;
|
||||
else
|
||||
list = &shell->compositor->surface_list;
|
||||
list = &shell->lock_layer.surface_list;
|
||||
|
||||
wl_list_remove(&surface->surface->link);
|
||||
wl_list_insert(list, &surface->surface->link);
|
||||
wl_list_remove(&surface->surface->layer_link);
|
||||
wl_list_insert(list, &surface->surface->layer_link);
|
||||
surface->surface->output = surface->output;
|
||||
weston_surface_damage(surface->surface);
|
||||
}
|
||||
@ -918,8 +924,8 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
|
||||
static void
|
||||
hide_screensaver(struct wl_shell *shell, struct shell_surface *surface)
|
||||
{
|
||||
wl_list_remove(&surface->surface->link);
|
||||
wl_list_init(&surface->surface->link);
|
||||
wl_list_remove(&surface->surface->layer_link);
|
||||
wl_list_init(&surface->surface->layer_link);
|
||||
surface->surface->output = NULL;
|
||||
}
|
||||
|
||||
@ -940,7 +946,7 @@ desktop_shell_set_background(struct wl_client *client,
|
||||
wl_list_for_each(priv, &shell->backgrounds, link) {
|
||||
if (priv->output == output_resource->data) {
|
||||
priv->surface->output = NULL;
|
||||
wl_list_remove(&priv->surface->link);
|
||||
wl_list_remove(&priv->surface->layer_link);
|
||||
wl_list_remove(&priv->link);
|
||||
break;
|
||||
}
|
||||
@ -978,7 +984,7 @@ desktop_shell_set_panel(struct wl_client *client,
|
||||
wl_list_for_each(priv, &shell->panels, link) {
|
||||
if (priv->output == output_resource->data) {
|
||||
priv->surface->output = NULL;
|
||||
wl_list_remove(&priv->surface->link);
|
||||
wl_list_remove(&priv->surface->layer_link);
|
||||
wl_list_remove(&priv->link);
|
||||
break;
|
||||
}
|
||||
@ -1038,8 +1044,6 @@ desktop_shell_set_lock_surface(struct wl_client *client,
|
||||
static void
|
||||
resume_desktop(struct wl_shell *shell)
|
||||
{
|
||||
struct weston_surface *surface;
|
||||
struct wl_list *list;
|
||||
struct shell_surface *tmp;
|
||||
|
||||
wl_list_for_each(tmp, &shell->screensaver.surfaces, link)
|
||||
@ -1047,21 +1051,12 @@ resume_desktop(struct wl_shell *shell)
|
||||
|
||||
terminate_screensaver(shell);
|
||||
|
||||
wl_list_for_each(surface, &shell->hidden_surface_list, link)
|
||||
weston_surface_assign_output(surface);
|
||||
|
||||
if (wl_list_empty(&shell->backgrounds)) {
|
||||
list = &shell->compositor->surface_list;
|
||||
} else {
|
||||
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);
|
||||
wl_list_remove(&shell->lock_layer.link);
|
||||
wl_list_insert(&shell->compositor->cursor_layer.link,
|
||||
&shell->fullscreen_layer.link);
|
||||
wl_list_insert(&shell->fullscreen_layer.link,
|
||||
&shell->panel_layer.link);
|
||||
wl_list_insert(&shell->panel_layer.link, &shell->toplevel_layer.link);
|
||||
|
||||
shell->locked = false;
|
||||
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 weston_compositor *compositor = shell->compositor;
|
||||
struct wl_list *list;
|
||||
|
||||
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)) {
|
||||
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:
|
||||
/* already put on top */
|
||||
case SHELL_SURFACE_LOCK:
|
||||
break;
|
||||
|
||||
case SHELL_SURFACE_SCREENSAVER:
|
||||
/* always below lock surface */
|
||||
if (shell->lock_surface) {
|
||||
wl_list_remove(&es->link);
|
||||
wl_list_insert(&shell->lock_surface->surface->link,
|
||||
&es->link);
|
||||
}
|
||||
if (shell->lock_surface)
|
||||
weston_surface_restack(es,
|
||||
&shell->lock_surface->surface->layer_link);
|
||||
break;
|
||||
case SHELL_SURFACE_FULLSCREEN:
|
||||
/* should on top of panels */
|
||||
break;
|
||||
default:
|
||||
if (!shell->locked) {
|
||||
list = weston_compositor_top(compositor);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
weston_surface_restack(es,
|
||||
&shell->toplevel_layer.surface_list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1451,9 +1433,6 @@ static void
|
||||
lock(struct weston_shell *base)
|
||||
{
|
||||
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 shell_surface *shsurf;
|
||||
struct weston_output *output;
|
||||
@ -1469,28 +1448,15 @@ lock(struct weston_shell *base)
|
||||
|
||||
shell->locked = true;
|
||||
|
||||
/* Move all surfaces from compositor's list to our hidden list,
|
||||
* except the background. This way nothing else can show or
|
||||
* receive input events while we are locked. */
|
||||
/* Hide all surfaces by removing the fullscreen, panel and
|
||||
* toplevel layers. This way nothing else can show or receive
|
||||
* input events while we are locked. */
|
||||
|
||||
if (!wl_list_empty(&shell->hidden_surface_list)) {
|
||||
fprintf(stderr,
|
||||
"%s: Assertion failed: hidden_surface_list is not empty.\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
wl_list_remove(&shell->panel_layer.link);
|
||||
wl_list_remove(&shell->toplevel_layer.link);
|
||||
wl_list_remove(&shell->fullscreen_layer.link);
|
||||
wl_list_insert(&shell->compositor->cursor_layer.link,
|
||||
&shell->lock_layer.link);
|
||||
|
||||
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 weston_compositor *compositor = shell->compositor;
|
||||
struct wl_list *list;
|
||||
struct shell_surface *shsurf;
|
||||
enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
|
||||
int do_configure;
|
||||
int panel_height = 0;
|
||||
|
||||
shsurf = get_shell_surface(surface);
|
||||
if (shsurf)
|
||||
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.height = height;
|
||||
surface->geometry.dirty = 1;
|
||||
@ -1618,19 +1574,19 @@ map(struct weston_shell *base, struct weston_surface *surface,
|
||||
switch (surface_type) {
|
||||
case SHELL_SURFACE_BACKGROUND:
|
||||
/* background always visible, at the bottom */
|
||||
wl_list_insert(compositor->surface_list.prev, &surface->link);
|
||||
do_configure = 1;
|
||||
wl_list_insert(&shell->background_layer.surface_list,
|
||||
&surface->layer_link);
|
||||
break;
|
||||
case SHELL_SURFACE_PANEL:
|
||||
/* 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;
|
||||
case SHELL_SURFACE_LOCK:
|
||||
/* 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);
|
||||
do_configure = 1;
|
||||
break;
|
||||
case SHELL_SURFACE_SCREENSAVER:
|
||||
/* If locked, show it. */
|
||||
@ -1641,32 +1597,20 @@ map(struct weston_shell *base, struct weston_surface *surface,
|
||||
if (!shell->lock_surface)
|
||||
compositor->state = WESTON_COMPOSITOR_IDLE;
|
||||
}
|
||||
do_configure = 0;
|
||||
break;
|
||||
case SHELL_SURFACE_FULLSCREEN:
|
||||
do_configure = 1;
|
||||
break;
|
||||
case SHELL_SURFACE_NONE:
|
||||
do_configure = 0;
|
||||
break;
|
||||
default:
|
||||
/* everything else just below the panel */
|
||||
if (!wl_list_empty(&shell->panels)) {
|
||||
struct shell_surface *panel =
|
||||
container_of(shell->panels.prev,
|
||||
struct shell_surface, link);
|
||||
wl_list_insert(&panel->surface->link, &surface->link);
|
||||
} else {
|
||||
wl_list_insert(list, &surface->link);
|
||||
}
|
||||
wl_list_insert(&shell->toplevel_layer.surface_list,
|
||||
&surface->layer_link);
|
||||
break;
|
||||
}
|
||||
|
||||
if (do_configure) {
|
||||
weston_surface_assign_output(surface);
|
||||
weston_compositor_repick(compositor);
|
||||
if (surface_type == SHELL_SURFACE_MAXIMIZED)
|
||||
surface->output = shsurf->output;
|
||||
}
|
||||
weston_surface_assign_output(surface);
|
||||
weston_compositor_repick(compositor);
|
||||
if (surface_type == SHELL_SURFACE_MAXIMIZED)
|
||||
surface->output = shsurf->output;
|
||||
|
||||
switch (surface_type) {
|
||||
case SHELL_SURFACE_TOPLEVEL:
|
||||
@ -1697,10 +1641,8 @@ configure(struct weston_shell *base, struct weston_surface *surface,
|
||||
struct shell_surface *shsurf;
|
||||
|
||||
shsurf = get_shell_surface(surface);
|
||||
if (shsurf) {
|
||||
if (shsurf)
|
||||
surface_type = shsurf->type;
|
||||
prev_surface_type = shsurf->prev_type;
|
||||
}
|
||||
|
||||
surface->geometry.x = x;
|
||||
surface->geometry.y = y;
|
||||
@ -1724,18 +1666,6 @@ configure(struct weston_shell *base, struct weston_surface *surface,
|
||||
get_output_panel_height(shell,surface->output);
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
@ -2071,11 +2001,17 @@ shell_init(struct weston_compositor *ec)
|
||||
shell->shell.configure = configure;
|
||||
shell->shell.destroy = shell_destroy;
|
||||
|
||||
wl_list_init(&shell->hidden_surface_list);
|
||||
wl_list_init(&shell->backgrounds);
|
||||
wl_list_init(&shell->panels);
|
||||
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);
|
||||
|
||||
if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
|
||||
|
Loading…
Reference in New Issue
Block a user