main neuswc / libswc / compositor.c
   1/* swc: libswc/compositor.c
   2 *
   3 * Copyright (c) 2013-2020 Michael Forney
   4 *
   5 * Based in part upon compositor.c from weston, which is:
   6 *
   7 *     Copyright © 2010-2011 Intel Corporation
   8 *     Copyright © 2008-2011 Kristian Høgsberg
   9 *     Copyright © 2012 Collabora, Ltd.
  10 *
  11 * Permission is hereby granted, free of charge, to any person obtaining a copy
  12 * of this software and associated documentation files (the "Software"), to deal
  13 * in the Software without restriction, including without limitation the rights
  14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15 * copies of the Software, and to permit persons to whom the Software is
  16 * furnished to do so, subject to the following conditions:
  17 *
  18 * The above copyright notice and this permission notice shall be included in
  19 * all copies or substantial portions of the Software.
  20 *
  21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  27 * SOFTWARE.
  28 */
  29
  30#include "compositor.h"
  31#include "data_device_manager.h"
  32#include "decor.h"
  33#include "drm.h"
  34#include "event.h"
  35#include "internal.h"
  36#include "launch.h"
  37#include "output.h"
  38#include "pointer.h"
  39#include "region.h"
  40#include "screen.h"
  41#include "seat.h"
  42#include "shm.h"
  43#include "subsurface.h"
  44#include "surface.h"
  45#include "swc.h"
  46#include "util.h"
  47#include "view.h"
  48#include "window.h"
  49
  50#include <assert.h>
  51#include <errno.h>
  52#include <limits.h>
  53#include <stdio.h>
  54#include <stdlib.h>
  55#include <wld/drm.h>
  56#include <wld/wld.h>
  57#include <xkbcommon/xkbcommon-keysyms.h>
  58
  59#define DEFAULT_BG 0xff000000u
  60
  61static inline int32_t
  62clamp_i32(int64_t v)
  63{
  64	if (v > INT32_MAX) {
  65		return INT32_MAX;
  66	}
  67	if (v < INT32_MIN) {
  68		return INT32_MIN;
  69	}
  70	return (int32_t)v;
  71}
  72
  73static inline uint32_t
  74span_u32(int32_t a, int32_t b)
  75{
  76	int64_t d = (int64_t)b - (int64_t)a;
  77
  78	if (d <= 0) {
  79		return 0;
  80	}
  81	if (d > UINT32_MAX) {
  82		return UINT32_MAX;
  83	}
  84	return (uint32_t)d;
  85}
  86
  87struct target {
  88	struct wld_surface *surface;
  89	struct wld_buffer *next_buffer, *current_buffer;
  90	struct view *view;
  91	struct view_handler view_handler;
  92	uint32_t mask;
  93
  94	struct wl_listener screen_destroy_listener;
  95};
  96
  97static bool
  98handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t x,
  99              wl_fixed_t y);
 100static bool
 101handle_button(struct pointer_handler *handler, uint32_t time,
 102              struct button *button, uint32_t state);
 103static void
 104perform_update(void *data);
 105
 106static struct pointer_handler pointer_handler = {
 107    .motion = handle_motion,
 108    .button = handle_button,
 109};
 110
 111static struct {
 112	struct wl_list views;
 113	pixman_region32_t damage, opaque;
 114	struct wl_listener swc_listener;
 115
 116	/* A mask of screens that have been repainted but are waiting on a page
 117	 * flip. */
 118	uint32_t pending_flips;
 119
 120	/* A mask of screens that are scheduled to be repainted on the next idle. */
 121	uint32_t scheduled_updates;
 122
 123	bool updating;
 124	struct wl_global *global;
 125	bool initialized;
 126
 127	/* zoom level (1.0 = normal, >1 = zoomed in, <1 = zoomed out) */
 128	float zoom;
 129	struct wld_buffer *zoom_buffer;
 130} compositor;
 131
 132static struct {
 133	bool active;
 134	int32_t x, y;
 135	uint32_t width, height;
 136	uint32_t color;
 137	uint32_t border_width;
 138} overlay;
 139
 140struct swc_compositor swc_compositor = {
 141    .pointer_handler = &pointer_handler,
 142};
 143
 144static void
 145handle_screen_destroy(struct wl_listener *listener, void *data)
 146{
 147	struct target *target =
 148	    wl_container_of(listener, target, screen_destroy_listener);
 149
 150	wld_destroy_surface(target->surface);
 151	free(target);
 152}
 153
 154static struct target *
 155target_get(struct screen *screen)
 156{
 157	struct wl_listener *listener =
 158	    wl_signal_get(&screen->destroy_signal, &handle_screen_destroy);
 159	struct target *target;
 160
 161	return listener ? wl_container_of(listener, target, screen_destroy_listener)
 162	                : NULL;
 163}
 164
 165static void
 166handle_screen_frame(struct view_handler *handler, uint32_t time)
 167{
 168	struct target *target = wl_container_of(handler, target, view_handler);
 169	struct compositor_view *view;
 170
 171	compositor.pending_flips &= ~target->mask;
 172
 173	wl_list_for_each(view, &compositor.views, link)
 174	{
 175		if (view->visible && view->base.screens & target->mask) {
 176			view_frame(&view->base, time);
 177		}
 178	}
 179
 180	if (target->current_buffer) {
 181		wld_surface_release(target->surface, target->current_buffer);
 182	}
 183
 184	target->current_buffer = target->next_buffer;
 185
 186	/* If we had scheduled updates that couldn't run because we were waiting on
 187	 * a page flip, run them now. If the compositor is currently updating, then
 188	 * the frame finished immediately, and we can be sure that there are no
 189	 * pending updates. */
 190	if (compositor.scheduled_updates && !compositor.updating) {
 191		perform_update(NULL);
 192	}
 193}
 194
 195static const struct view_handler_impl screen_view_handler = {
 196    .frame = handle_screen_frame,
 197};
 198
 199static int
 200target_swap_buffers(struct target *target)
 201{
 202	target->next_buffer = wld_surface_take(target->surface);
 203	return view_attach(target->view, target->next_buffer);
 204}
 205
 206static struct target *
 207target_new(struct screen *screen)
 208{
 209	struct target *target;
 210	struct swc_rectangle *geom = &screen->base.geometry;
 211
 212	if (!(target = malloc(sizeof(*target)))) {
 213		goto error0;
 214	}
 215
 216	target->surface =
 217	    wld_create_surface(swc.drm->context, geom->width, geom->height,
 218	                       WLD_FORMAT_XRGB8888, WLD_DRM_FLAG_SCANOUT);
 219
 220	if (!target->surface) {
 221		goto error1;
 222	}
 223
 224	target->view = &screen->planes.primary.view;
 225	target->view_handler.impl = &screen_view_handler;
 226	wl_list_insert(&target->view->handlers, &target->view_handler.link);
 227	target->current_buffer = NULL;
 228	target->mask = screen_mask(screen);
 229
 230	target->screen_destroy_listener.notify = &handle_screen_destroy;
 231	wl_signal_add(&screen->destroy_signal, &target->screen_destroy_listener);
 232
 233	return target;
 234
 235error1:
 236	free(target);
 237error0:
 238	return NULL;
 239}
 240
 241/* Rendering {{{ */
 242
 243static void
 244repaint_view(struct target *target, struct compositor_view *view,
 245             pixman_region32_t *damage)
 246{
 247	pixman_region32_t geom_region, buffer_region, border_region, view_damage,
 248	    buffer_damage, border_damage;
 249	const struct swc_rectangle *geom = &view->base.geometry,
 250	                           *target_geom = &target->view->geometry;
 251	int32_t buf_x, buf_y;
 252	uint32_t buf_w, buf_h;
 253	int64_t total_border;
 254
 255	if (!view->base.buffer) {
 256		return;
 257	}
 258
 259	buf_w = view->base.buffer->width;
 260	buf_h = view->base.buffer->height;
 261	buf_x = geom->x - view->buffer_offset_x;
 262	buf_y = geom->y - view->buffer_offset_y;
 263
 264	total_border =
 265	    (int64_t)view->border.outwidth + (int64_t)view->border.inwidth;
 266	pixman_region32_init_rect(&geom_region, geom->x, geom->y, geom->width,
 267	                          geom->height);
 268	if (view->window) {
 269		pixman_region32_init_rect(&buffer_region, geom->x, geom->y, geom->width,
 270		                          geom->height);
 271	} else {
 272		pixman_region32_init_rect(&buffer_region, buf_x, buf_y, buf_w, buf_h);
 273	}
 274	pixman_region32_init_rect(&border_region,
 275	                          geom->x - (int32_t)total_border,
 276	                          geom->y - (int32_t)total_border,
 277	                          geom->width + (uint32_t)(2 * total_border),
 278	                          geom->height + (uint32_t)(2 * total_border));
 279	pixman_region32_subtract(&border_region, &border_region, &geom_region);
 280	pixman_region32_init_with_extents(&view_damage, &view->extents);
 281	pixman_region32_init(&buffer_damage);
 282	pixman_region32_init(&border_damage);
 283
 284	pixman_region32_intersect(&view_damage, &view_damage, damage);
 285	pixman_region32_subtract(&view_damage, &view_damage, &view->clip);
 286	pixman_region32_intersect(&border_damage, &view_damage, &border_region);
 287	pixman_region32_intersect(&buffer_damage, &view_damage, &buffer_region);
 288
 289	if (pixman_region32_not_empty(&buffer_damage)) {
 290		pixman_region32_translate(&buffer_damage,
 291		                          -geom->x + view->buffer_offset_x,
 292		                          -geom->y + view->buffer_offset_y);
 293		wld_copy_region(swc.drm->renderer, view->buffer, buf_x - target_geom->x,
 294		                buf_y - target_geom->y, &buffer_damage);
 295	}
 296
 297	pixman_region32_fini(&view_damage);
 298	pixman_region32_fini(&buffer_damage);
 299
 300	pixman_region32_t in_rect;
 301	pixman_region32_init_rect(&in_rect,
 302	                          geom->x - view->border.inwidth,
 303	                          geom->y - view->border.inwidth,
 304	                          geom->width + (2 * view->border.inwidth),
 305	                          geom->height + (2 * view->border.inwidth));
 306
 307	pixman_region32_t out_border;
 308	pixman_region32_init(&out_border);
 309	pixman_region32_subtract(&out_border, &border_damage, &in_rect);
 310
 311	pixman_region32_t in_border;
 312	pixman_region32_init(&in_border);
 313	pixman_region32_subtract(&in_border, &in_rect, &geom_region);
 314	pixman_region32_intersect(&in_border, &in_border, &border_damage);
 315
 316	pixman_region32_fini(&geom_region);
 317	pixman_region32_fini(&buffer_region);
 318	pixman_region32_fini(&border_region);
 319
 320	/* Draw border */
 321	if (view->border.outwidth > 0 && pixman_region32_not_empty(&out_border)) {
 322		pixman_region32_translate(&out_border, -target_geom->x,
 323		                          -target_geom->y);
 324		wld_fill_region(swc.drm->renderer, view->border.outcolor, &out_border);
 325	}
 326
 327	if (view->border.inwidth > 0 && pixman_region32_not_empty(&in_border)) {
 328		pixman_region32_translate(&in_border, -target_geom->x, -target_geom->y);
 329		wld_fill_region(swc.drm->renderer, view->border.incolor, &in_border);
 330	}
 331
 332	pixman_region32_fini(&border_damage);
 333	pixman_region32_fini(&in_rect);
 334	pixman_region32_fini(&out_border);
 335	pixman_region32_fini(&in_border);
 336
 337	if ((view->decor.top || view->decor.right || view->decor.bottom ||
 338	     view->decor.left)) {
 339		decor_repaint(swc.drm->renderer, target_geom, view, damage);
 340	}
 341}
 342
 343static void
 344draw_overlays(struct wld_renderer *renderer, const struct swc_rectangle *target_geom)
 345{
 346	int32_t tx = (int32_t)target_geom->width;
 347	int32_t ty = (int32_t)target_geom->height;
 348
 349/* draw box as 4 rectangles with wld */
 350#define CLAMP_LOW(v, lo) ((v) < (lo) ? (lo) : (v))
 351#define CLAMP_HIGH(v, hi) ((v) > (hi) ? (hi) : (v))
 352#define DRAW_CLIPPED(rx, ry, rw, rh, clr)                                     \
 353	do {                                                                       \
 354		int32_t _x1 = CLAMP_LOW((rx), 0);                                      \
 355		int32_t _y1 = CLAMP_LOW((ry), 0);                                      \
 356		int32_t _x2 = CLAMP_HIGH((rx) + (int32_t)(rw), tx);                    \
 357		int32_t _y2 = CLAMP_HIGH((ry) + (int32_t)(rh), ty);                    \
 358		if (_x2 > _x1 && _y2 > _y1)                                            \
 359			wld_fill_rectangle(renderer, (clr), _x1, _y1,                      \
 360			                   (uint32_t)(_x2 - _x1), (uint32_t)(_y2 - _y1)); \
 361	} while (0)
 362
 363	if (overlay.active && overlay.border_width > 0) {
 364		int32_t x = overlay.x - target_geom->x;
 365		int32_t y = overlay.y - target_geom->y;
 366		uint32_t w = overlay.width, h = overlay.height,
 367		         bw = overlay.border_width;
 368
 369		if (w > 0 && h > 0) {
 370			if (bw > w) {
 371				bw = w;
 372			}
 373			if (bw > h) {
 374				bw = h;
 375			}
 376
 377			DRAW_CLIPPED(x, y, (int32_t)w, (int32_t)bw, overlay.color);
 378			DRAW_CLIPPED(x, y + (int32_t)h - (int32_t)bw, (int32_t)w,
 379			             (int32_t)bw, overlay.color);
 380			DRAW_CLIPPED(x, y, (int32_t)bw, (int32_t)h, overlay.color);
 381			DRAW_CLIPPED(x + (int32_t)w - (int32_t)bw, y, (int32_t)bw,
 382			             (int32_t)h, overlay.color);
 383		}
 384	}
 385
 386#undef DRAW_CLIPPED
 387#undef CLAMP_HIGH
 388#undef CLAMP_LOW
 389}
 390
 391static void
 392renderer_repaint(struct target *target, pixman_region32_t *damage,
 393                 pixman_region32_t *base_damage, struct wl_list *views,
 394                 struct screen *screen)
 395{
 396	struct compositor_view *view;
 397	const struct swc_rectangle *target_geom = &target->view->geometry;
 398
 399	DEBUG("Rendering to target { x: %d, y: %d, w: %u, h: %u }\n",
 400	      target->view->geometry.x, target->view->geometry.y,
 401	      target->view->geometry.width, target->view->geometry.height);
 402
 403	wld_set_target_surface(swc.drm->renderer, target->surface);
 404
 405	if (pixman_region32_not_empty(base_damage)) {
 406		pixman_region32_translate(base_damage, -target->view->geometry.x,
 407		                          -target->view->geometry.y);
 408		wld_fill_region(swc.drm->renderer, DEFAULT_BG,
 409		                base_damage);
 410	}
 411
 412	wl_list_for_each_reverse(view, views, link)
 413	{
 414		if (view->visible && view->base.screens & target->mask) {
 415			repaint_view(target, view, damage);
 416		}
 417	}
 418
 419	draw_overlays(swc.drm->renderer, target_geom);
 420
 421	wld_flush(swc.drm->renderer);
 422}
 423
 424static int
 425renderer_attach(struct compositor_view *view, struct wld_buffer *client_buffer)
 426{
 427	struct wld_buffer *buffer;
 428	bool was_proxy = view->buffer != view->base.buffer;
 429	bool needs_proxy =
 430	    client_buffer && !(wld_capabilities(swc.drm->renderer, client_buffer) &
 431	                       WLD_CAPABILITY_READ);
 432	bool resized = view->buffer && client_buffer &&
 433	               (view->buffer->width != client_buffer->width ||
 434	                view->buffer->height != client_buffer->height);
 435
 436	if (client_buffer) {
 437		/* Create a proxy buffer if necessary (for example a hardware buffer
 438		 * backing a SHM buffer). */
 439		if (needs_proxy) {
 440			if (!was_proxy || resized) {
 441				DEBUG("Creating a proxy buffer\n");
 442				buffer = wld_create_buffer(
 443				    swc.drm->context, client_buffer->width,
 444				    client_buffer->height, client_buffer->format, WLD_FLAG_MAP);
 445
 446				if (!buffer) {
 447					return -ENOMEM;
 448				}
 449			} else {
 450				/* Otherwise we can keep the original proxy buffer. */
 451				buffer = view->buffer;
 452			}
 453		} else {
 454			buffer = client_buffer;
 455		}
 456	} else {
 457		buffer = NULL;
 458	}
 459
 460	/* If we no longer need a proxy buffer, or the original buffer is of a
 461	 * different size, destroy the old proxy image. */
 462	if (view->buffer &&
 463	    ((!needs_proxy && was_proxy) || (needs_proxy && resized))) {
 464		wld_buffer_unreference(view->buffer);
 465	}
 466
 467	view->buffer = buffer;
 468
 469	return 0;
 470}
 471
 472static void
 473renderer_flush_view(struct compositor_view *view)
 474{
 475	if (view->buffer == view->base.buffer) {
 476		return;
 477	}
 478
 479	wld_set_target_buffer(swc.shm->renderer, view->buffer);
 480	wld_copy_region(swc.shm->renderer, view->base.buffer, 0, 0,
 481	                &view->surface->state.damage);
 482	wld_flush(swc.shm->renderer);
 483}
 484
 485/* }}} */
 486
 487/* Surface Views {{{ */
 488
 489/**
 490 * Adds the region below a view to the compositor's damaged region.
 491 */
 492static void
 493damage_below_view(struct compositor_view *view)
 494{
 495	pixman_region32_t damage_below;
 496
 497	pixman_region32_init_with_extents(&damage_below, &view->extents);
 498	pixman_region32_union(&compositor.damage, &compositor.damage,
 499	                      &damage_below);
 500	pixman_region32_fini(&damage_below);
 501}
 502
 503/**
 504 * Completely damages the surface and its border.
 505 */
 506static void
 507damage_view(struct compositor_view *view)
 508{
 509	damage_below_view(view);
 510	view->border.damaged_border1 = true;
 511	view->border.damaged_border2 = true;
 512}
 513
 514static void
 515update_extents(struct compositor_view *view)
 516{
 517	int64_t total_border =
 518	    (int64_t)view->border.outwidth + (int64_t)view->border.inwidth;
 519	int64_t geom_x = view->base.geometry.x;
 520	int64_t geom_y = view->base.geometry.y;
 521	int64_t geom_w = view->base.geometry.width;
 522	int64_t geom_h = view->base.geometry.height;
 523
 524	int64_t border_x1 = geom_x - total_border;
 525	int64_t border_y1 = geom_y - total_border;
 526	int64_t border_x2 = geom_x + geom_w + total_border;
 527	int64_t border_y2 = geom_y + geom_h + total_border;
 528	int64_t decor_x1 = geom_x - (int64_t)view->decor.left;
 529	int64_t decor_y1 = geom_y - (int64_t)view->decor.top;
 530	int64_t decor_x2 = geom_x + geom_w + (int64_t)view->decor.right;
 531	int64_t decor_y2 = geom_y + geom_h + (int64_t)view->decor.bottom;
 532
 533	int64_t buffer_x1 = geom_x - view->buffer_offset_x;
 534	int64_t buffer_y1 = geom_y - view->buffer_offset_y;
 535	int64_t buffer_x2 =
 536	    buffer_x1 +
 537	    (view->base.buffer ? view->base.buffer->width : (uint32_t)geom_w);
 538	int64_t buffer_y2 =
 539	    buffer_y1 +
 540	    (view->base.buffer ? view->base.buffer->height : (uint32_t)geom_h);
 541
 542	view->extents.x1 = clamp_i32(MIN(MIN(border_x1, decor_x1), buffer_x1));
 543	view->extents.y1 = clamp_i32(MIN(MIN(border_y1, decor_y1), buffer_y1));
 544	view->extents.x2 = clamp_i32(MAX(MAX(border_x2, decor_x2), buffer_x2));
 545	view->extents.y2 = clamp_i32(MAX(MAX(border_y2, decor_y2), buffer_y2));
 546
 547	if (view->extents.x2 < view->extents.x1) {
 548		view->extents.x2 = view->extents.x1;
 549	}
 550	if (view->extents.y2 < view->extents.y1) {
 551		view->extents.y2 = view->extents.y1;
 552	}
 553
 554	/* Damage border. */
 555	view->border.damaged_border1 = true;
 556	view->border.damaged_border2 = true;
 557	view->decor.damaged = true;
 558}
 559
 560static void
 561schedule_updates(uint32_t screens)
 562{
 563	if (compositor.scheduled_updates == 0) {
 564		wl_event_loop_add_idle(swc.event_loop, &perform_update, NULL);
 565	}
 566
 567	if (screens == -1) {
 568		struct screen *screen;
 569
 570		screens = 0;
 571		wl_list_for_each(screen, &swc.screens, link) screens |=
 572		    screen_mask(screen);
 573	}
 574
 575	/* when zoomed, force full screen damage since actual area differs from
 576	 * world coords */
 577	if (compositor.zoom != 1.0f) {
 578		struct screen *screen;
 579		wl_list_for_each(screen, &swc.screens, link)
 580		{
 581			pixman_region32_union_rect(
 582			    &compositor.damage, &compositor.damage, screen->base.geometry.x,
 583			    screen->base.geometry.y, screen->base.geometry.width,
 584			    screen->base.geometry.height);
 585			screens |= screen_mask(screen);
 586		}
 587	}
 588
 589	compositor.scheduled_updates |= screens;
 590}
 591
 592void
 593compositor_damage_all(void)
 594{
 595	struct screen *screen;
 596
 597	if (!compositor.initialized) {
 598		return;
 599	}
 600
 601	wl_list_for_each(screen, &swc.screens, link)
 602	{
 603		pixman_region32_union_rect(
 604		    &compositor.damage, &compositor.damage, screen->base.geometry.x,
 605		    screen->base.geometry.y, screen->base.geometry.width,
 606		    screen->base.geometry.height);
 607	}
 608
 609	schedule_updates(-1);
 610}
 611
 612static void
 613overlay_damage_region(int32_t x, int32_t y, uint32_t width, uint32_t height,
 614                      uint32_t border_width)
 615{
 616	(void)border_width;
 617	pixman_region32_union_rect(&compositor.damage, &compositor.damage, x, y,
 618	                           width, height);
 619}
 620
 621EXPORT void
 622swc_overlay_set_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
 623                    uint32_t color, uint32_t border_width)
 624{
 625	int32_t x = x1 < x2 ? x1 : x2;
 626	int32_t y = y1 < y2 ? y1 : y2;
 627	uint32_t width = (uint32_t)abs(x2 - x1);
 628	uint32_t height = (uint32_t)abs(y2 - y1);
 629
 630	if (border_width == 0) {
 631		border_width = 1;
 632	}
 633
 634	if (overlay.active) {
 635		overlay_damage_region(overlay.x, overlay.y, overlay.width,
 636		                      overlay.height, overlay.border_width);
 637	}
 638
 639	overlay.active = true;
 640	overlay.x = x;
 641	overlay.y = y;
 642	overlay.width = width;
 643	overlay.height = height;
 644	overlay.color = color;
 645	overlay.border_width = border_width;
 646
 647	overlay_damage_region(overlay.x, overlay.y, overlay.width, overlay.height,
 648	                      overlay.border_width);
 649	schedule_updates(-1);
 650}
 651
 652EXPORT void
 653swc_overlay_clear(void)
 654{
 655	if (!overlay.active) {
 656		return;
 657	}
 658
 659	overlay_damage_region(overlay.x, overlay.y, overlay.width, overlay.height,
 660	                      overlay.border_width);
 661	overlay.active = false;
 662	schedule_updates(-1);
 663}
 664
 665EXPORT void
 666swc_set_zoom(float level)
 667{
 668	if (level < 0.1f) {
 669		level = 0.1f;
 670	}
 671	if (level > 10.0f) {
 672		level = 10.0f;
 673	}
 674
 675	if (compositor.zoom != level) {
 676		compositor.zoom = level;
 677		if (level == 1.0f) {
 678			if (compositor.zoom_buffer) {
 679				wld_buffer_unreference(compositor.zoom_buffer);
 680				compositor.zoom_buffer = NULL;
 681			}
 682		}
 683		/* damage entire screen to force full repaint */
 684		schedule_updates(-1);
 685	}
 686}
 687
 688EXPORT float
 689swc_get_zoom(void)
 690{
 691	return compositor.zoom;
 692}
 693
 694static pixman_format_code_t
 695wld_to_pixman_format(enum wld_format format)
 696{
 697	switch (format) {
 698	case WLD_FORMAT_XRGB8888:
 699		return PIXMAN_x8r8g8b8;
 700	case WLD_FORMAT_ARGB8888:
 701		return PIXMAN_a8r8g8b8;
 702	default:
 703		return PIXMAN_x8r8g8b8;
 704	}
 705}
 706
 707static struct wld_buffer *
 708zoom_buffer_for_screen(struct screen *screen)
 709{
 710	uint32_t width = screen->base.geometry.width;
 711	uint32_t height = screen->base.geometry.height;
 712
 713	if (compositor.zoom_buffer &&
 714	    (compositor.zoom_buffer->width != width ||
 715	     compositor.zoom_buffer->height != height ||
 716	     compositor.zoom_buffer->format != WLD_FORMAT_ARGB8888)) {
 717		wld_buffer_unreference(compositor.zoom_buffer);
 718		compositor.zoom_buffer = NULL;
 719	}
 720
 721	if (!compositor.zoom_buffer) {
 722		compositor.zoom_buffer =
 723		    wld_create_buffer(swc.shm->context, width, height,
 724		                      WLD_FORMAT_ARGB8888, WLD_FLAG_MAP);
 725		if (!compositor.zoom_buffer) {
 726			return NULL;
 727		}
 728	}
 729
 730	wld_buffer_reference(compositor.zoom_buffer);
 731	return compositor.zoom_buffer;
 732}
 733
 734/* render zoomed view to shm      wallpaper unscaled, windows scaled */
 735static struct wld_buffer *
 736render_zoomed_to_shm(struct screen *screen, float zoom)
 737{
 738	uint32_t width = screen->base.geometry.width;
 739	uint32_t height = screen->base.geometry.height;
 740	int32_t screen_x = screen->base.geometry.x;
 741	int32_t screen_y = screen->base.geometry.y;
 742	int32_t cx = screen_x + width / 2;
 743	int32_t cy = screen_y + height / 2;
 744	struct compositor_view *view;
 745	struct wld_buffer *buffer = zoom_buffer_for_screen(screen);
 746	if (!buffer) {
 747		return NULL;
 748	}
 749
 750	if (!wld_set_target_buffer(swc.shm->renderer, buffer)) {
 751		wld_buffer_unreference(buffer);
 752		return NULL;
 753	}
 754
 755	pixman_region32_t full;
 756	pixman_region32_init_rect(&full, 0, 0, width, height);
 757	wld_fill_region(swc.shm->renderer, DEFAULT_BG, &full);
 758	pixman_region32_fini(&full);
 759	wld_flush(swc.shm->renderer);
 760
 761	if (!wld_map(buffer)) {
 762		wld_buffer_unreference(buffer);
 763		return NULL;
 764	}
 765
 766	pixman_image_t *dst_img = pixman_image_create_bits(
 767	    wld_to_pixman_format(buffer->format), buffer->width, buffer->height,
 768	    buffer->map, buffer->pitch);
 769
 770	if (!dst_img) {
 771		wld_unmap(buffer);
 772		wld_buffer_unreference(buffer);
 773		return NULL;
 774	}
 775
 776	/* render each view with scaling */
 777	wl_list_for_each_reverse(view, &compositor.views, link)
 778	{
 779		struct wld_buffer *src = view->buffer;
 780		const struct swc_rectangle *geom = &view->base.geometry;
 781
 782		if (!src) {
 783			continue;
 784		}
 785
 786		if (!(wld_capabilities(swc.shm->renderer, src) & WLD_CAPABILITY_READ)) {
 787			src = view->base.buffer;
 788		}
 789		if (!src) {
 790			continue;
 791		}
 792
 793		/* maths     zoom position and size */
 794		float zoomed_x, zoomed_y, zoomed_w, zoomed_h;
 795		float border_out, border_in, total_border;
 796
 797		if (view->always_top) {
 798			zoomed_x = geom->x - screen_x;
 799			zoomed_y = geom->y - screen_y;
 800			zoomed_w = geom->width;
 801			zoomed_h = geom->height;
 802
 803			border_out = view->border.outwidth;
 804			border_in = view->border.inwidth;
 805		} else {
 806			zoomed_x = (geom->x - cx) * zoom + width / 2.0f;
 807			zoomed_y = (geom->y - cy) * zoom + height / 2.0f;
 808			zoomed_w = geom->width * zoom;
 809			zoomed_h = geom->height * zoom;
 810
 811			border_out = view->border.outwidth * zoom;
 812			border_in = view->border.inwidth * zoom;
 813		}
 814
 815		total_border = border_out + border_in;
 816
 817		if (zoomed_x + zoomed_w + total_border < 0 ||
 818		    zoomed_x - total_border >= (int32_t)width ||
 819		    zoomed_y + zoomed_h + total_border < 0 ||
 820		    zoomed_y - total_border >= (int32_t)height) {
 821			continue;
 822		}
 823
 824		if (view->border.outwidth > 0 && border_out >= 1) {
 825			int32_t bx = (int32_t)(zoomed_x - total_border);
 826			int32_t by = (int32_t)(zoomed_y - total_border);
 827			int32_t bw = (int32_t)(zoomed_w + 2 * total_border);
 828			int32_t bh = (int32_t)(zoomed_h + 2 * total_border);
 829			int32_t bo = (int32_t)border_out;
 830
 831			pixman_color_t color = {
 832			    .red = ((view->border.outcolor >> 16) & 0xff) * 257,
 833			    .green = ((view->border.outcolor >> 8) & 0xff) * 257,
 834			    .blue = (view->border.outcolor & 0xff) * 257,
 835			    .alpha = 0xffff};
 836			pixman_image_t *fill = pixman_image_create_solid_fill(&color);
 837			if (fill) {
 838				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 839				                         0, 0, 0, bx, by, bw, bo);
 840				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 841				                         0, 0, 0, bx, by + bh - bo, bw, bo);
 842				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 843				                         0, 0, 0, bx, by + bo, bo, bh - 2 * bo);
 844				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 845				                         0, 0, 0, bx + bw - bo, by + bo, bo,
 846				                         bh - 2 * bo);
 847				pixman_image_unref(fill);
 848			}
 849		}
 850
 851		if (view->border.inwidth > 0 && border_in >= 1) {
 852			int32_t bx = (int32_t)(zoomed_x - border_in);
 853			int32_t by = (int32_t)(zoomed_y - border_in);
 854			int32_t bw = (int32_t)(zoomed_w + 2 * border_in);
 855			int32_t bh = (int32_t)(zoomed_h + 2 * border_in);
 856			int32_t bi = (int32_t)border_in;
 857
 858			pixman_color_t color = {
 859			    .red = ((view->border.incolor >> 16) & 0xff) * 257,
 860			    .green = ((view->border.incolor >> 8) & 0xff) * 257,
 861			    .blue = (view->border.incolor & 0xff) * 257,
 862			    .alpha = 0xffff};
 863			pixman_image_t *fill = pixman_image_create_solid_fill(&color);
 864			if (fill) {
 865				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 866				                         0, 0, 0, bx, by, bw, bi);
 867				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 868				                         0, 0, 0, bx, by + bh - bi, bw, bi);
 869				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 870				                         0, 0, 0, bx, by + bi, bi, bh - 2 * bi);
 871				pixman_image_composite32(PIXMAN_OP_OVER, fill, NULL, dst_img, 0,
 872				                         0, 0, 0, bx + bw - bi, by + bi, bi,
 873				                         bh - 2 * bi);
 874				pixman_image_unref(fill);
 875			}
 876		}
 877
 878		if (!wld_map(src)) {
 879			continue;
 880		}
 881
 882		pixman_image_t *src_img = pixman_image_create_bits(
 883		    wld_to_pixman_format(src->format), src->width, src->height,
 884		    src->map, src->pitch);
 885
 886		if (src_img) {
 887			if (!view->always_top) {
 888				pixman_transform_t transform;
 889				pixman_transform_init_identity(&transform);
 890				pixman_fixed_t scale = pixman_double_to_fixed(1.0 / zoom);
 891				pixman_transform_scale(&transform, NULL, scale, scale);
 892				pixman_image_set_transform(src_img, &transform);
 893				pixman_image_set_filter(src_img, PIXMAN_FILTER_BILINEAR, NULL,
 894				                        0);
 895			}
 896
 897			pixman_image_composite32(PIXMAN_OP_OVER, src_img, NULL, dst_img, 0,
 898			                         0, 0, 0, (int32_t)zoomed_x,
 899			                         (int32_t)zoomed_y, (int32_t)(zoomed_w + 1),
 900			                         (int32_t)(zoomed_h + 1));
 901
 902			pixman_image_unref(src_img);
 903		}
 904
 905		wld_unmap(src);
 906	}
 907
 908	pixman_image_unref(dst_img);
 909	wld_unmap(buffer);
 910
 911	return buffer;
 912}
 913
 914static bool
 915update(struct view *base)
 916{
 917	struct compositor_view *view = (void *)base;
 918
 919	if (!swc.active || !view->visible) {
 920		return false;
 921	}
 922
 923	schedule_updates(view->base.screens);
 924
 925	return true;
 926}
 927
 928static int
 929attach(struct view *base, struct wld_buffer *buffer)
 930{
 931	struct compositor_view *view = (void *)base;
 932	struct surface *surface = view->surface;
 933	pixman_box32_t old_extents;
 934	pixman_region32_t old, new, both;
 935	uint32_t new_width = buffer ? buffer->width : 0;
 936	uint32_t new_height = buffer ? buffer->height : 0;
 937	int ret;
 938
 939	if ((ret = renderer_attach(view, buffer)) < 0) {
 940		return ret;
 941	}
 942
 943	/* Schedule updates on the screens the view was previously
 944	 * visible on. */
 945	update(&view->base);
 946
 947	view->buffer_offset_x = 0;
 948	view->buffer_offset_y = 0;
 949	if (surface && surface->has_window_geometry && buffer) {
 950		if (surface->window_width > 0 && surface->window_height > 0) {
 951			new_width = (uint32_t)surface->window_width;
 952			new_height = (uint32_t)surface->window_height;
 953			view->buffer_offset_x = surface->window_x;
 954			view->buffer_offset_y = surface->window_y;
 955		}
 956	}
 957
 958	if (view_set_size(&view->base, new_width, new_height)) {
 959		/* The view was resized. */
 960		old_extents = view->extents;
 961		update_extents(view);
 962
 963		if (view->visible) {
 964			/* Damage the region that was newly uncovered or covered. */
 965			pixman_region32_init_with_extents(&old, &old_extents);
 966			pixman_region32_init_with_extents(&new, &view->extents);
 967			pixman_region32_init(&both);
 968			pixman_region32_intersect(&both, &old, &new);
 969			pixman_region32_union(&new, &old, &new);
 970			pixman_region32_subtract(&new, &new, &both);
 971			pixman_region32_union(&compositor.damage, &compositor.damage, &new);
 972			pixman_region32_fini(&old);
 973			pixman_region32_fini(&new);
 974			pixman_region32_fini(&both);
 975
 976			view_update_screens(&view->base);
 977			update(&view->base);
 978		}
 979	}
 980
 981	return 0;
 982}
 983
 984static bool
 985move(struct view *base, int32_t x, int32_t y)
 986{
 987	struct compositor_view *view = (void *)base;
 988
 989	if (view->visible) {
 990		damage_below_view(view);
 991		update(&view->base);
 992	}
 993
 994	if (view_set_position(&view->base, x, y)) {
 995		update_extents(view);
 996
 997		if (view->visible) {
 998			/* Assume worst-case no clipping until we draw the next frame (in
 999			 * case the surface gets moved again before that). */
1000			pixman_region32_init(&view->clip);
1001
1002			view_update_screens(&view->base);
1003			damage_below_view(view);
1004			update(&view->base);
1005		}
1006	}
1007
1008	return true;
1009}
1010
1011static const struct view_impl view_impl = {
1012    .update = update,
1013    .attach = attach,
1014    .move = move,
1015};
1016
1017static void
1018restack_view_for_layer(struct compositor_view *view, bool raise)
1019{
1020	struct compositor_view *other;
1021	struct wl_list *insert_after = &compositor.views;
1022	bool found_same = false;
1023
1024	wl_list_for_each(other, &compositor.views, link)
1025	{
1026		if (other == view) {
1027			continue;
1028		}
1029
1030		if (other->stack_layer > view->stack_layer) {
1031			insert_after = &other->link;
1032			continue;
1033		}
1034
1035		if (other->stack_layer == view->stack_layer) {
1036			found_same = true;
1037			if (raise) {
1038				insert_after = other->link.prev;
1039			} else {
1040				insert_after = &other->link;
1041			}
1042			break;
1043		}
1044
1045		insert_after = other->link.prev;
1046		break;
1047	}
1048
1049	if (!found_same && !raise && insert_after == &compositor.views) {
1050		insert_after = compositor.views.prev;
1051		if (insert_after == &view->link) {
1052			insert_after = insert_after->prev;
1053		}
1054	}
1055
1056	if (insert_after == &view->link) {
1057		insert_after = insert_after->prev;
1058	}
1059
1060	wl_list_remove(&view->link);
1061	wl_list_insert(insert_after, &view->link);
1062}
1063
1064static struct compositor_view *
1065view_at(int32_t x, int32_t y)
1066{
1067	struct compositor_view *view;
1068	struct swc_rectangle *geom;
1069	struct swc_rectangle buffer_geom;
1070
1071	wl_list_for_each(view, &compositor.views, link)
1072	{
1073		if (!view->visible) {
1074			continue;
1075		}
1076
1077		geom = &view->base.geometry;
1078		if (view->window) {
1079			if (!rectangle_contains_point(geom, x, y)) {
1080				continue;
1081			}
1082		} else if (view->base.buffer) {
1083			buffer_geom.x = geom->x - view->buffer_offset_x;
1084			buffer_geom.y = geom->y - view->buffer_offset_y;
1085			buffer_geom.width = view->base.buffer->width;
1086			buffer_geom.height = view->base.buffer->height;
1087			if (!rectangle_contains_point(&buffer_geom, x, y)) {
1088				continue;
1089			}
1090		} else if (!rectangle_contains_point(geom, x, y)) {
1091			continue;
1092		}
1093
1094		if (pixman_region32_contains_point(&view->surface->state.input,
1095		                                   x - geom->x + view->buffer_offset_x,
1096		                                   y - geom->y + view->buffer_offset_y,
1097		                                   NULL)) {
1098			return view;
1099		}
1100	}
1101
1102	return NULL;
1103}
1104
1105static struct compositor_view *
1106window_view(struct compositor_view *view)
1107{
1108	while (view && !view->window && view->parent && view->parent != view) {
1109		view = view->parent;
1110	}
1111	return (view && view->window) ? view : NULL;
1112}
1113
1114void
1115raise_window(struct compositor_view *view)
1116{
1117	struct compositor_view *other, *top_window;
1118	struct wl_list *insert_after;
1119	uint32_t screens;
1120
1121	view = window_view(view);
1122	if (!view || !view->visible) {
1123		return;
1124	}
1125
1126	top_window = NULL;
1127	insert_after = &compositor.views;
1128	wl_list_for_each(other, &compositor.views, link)
1129	{
1130		if (other == view) {
1131			continue;
1132		}
1133
1134		if (!other->visible) {
1135			continue;
1136		}
1137
1138		if (other->stack_layer > STACK_LAYER_NORMAL ||
1139		    other->always_top) {
1140			insert_after = &other->link;
1141			continue;
1142		}
1143
1144		if (other->stack_layer < STACK_LAYER_NORMAL) {
1145			break;
1146		}
1147
1148		if (other->window) {
1149			top_window = other;
1150			break;
1151		}
1152		insert_after = &other->link;
1153	}
1154
1155	if (view == top_window) {
1156		return;
1157	}
1158
1159	screens = view->base.screens;
1160
1161	wl_list_remove(&view->link);
1162	wl_list_insert(insert_after, &view->link);
1163
1164	view->border.damaged_border1 = true;
1165	pixman_region32_union_rect(&compositor.damage, &compositor.damage,
1166	                           view->extents.x1, view->extents.y1,
1167	                           span_u32(view->extents.x1, view->extents.x2),
1168	                           span_u32(view->extents.y1, view->extents.y2));
1169	schedule_updates(screens);
1170}
1171
1172void
1173raise_window_top(struct compositor_view *view)
1174{
1175	view->stack_layer = STACK_LAYER_OVERLAY;
1176	restack_view_for_layer(view, true);
1177	damage_view(view);
1178	schedule_updates(view->base.screens);
1179}
1180
1181void
1182compositor_view_set_stack_layer(struct compositor_view *view, uint32_t layer,
1183	                            bool raise)
1184{
1185	if (view->stack_layer == layer) {
1186		if (raise) {
1187			restack_view_for_layer(view, true);
1188			damage_view(view);
1189			schedule_updates(view->base.screens);
1190		}
1191		return;
1192	}
1193
1194	damage_view(view);
1195	view->stack_layer = layer;
1196	restack_view_for_layer(view, raise);
1197	damage_view(view);
1198	schedule_updates(view->base.screens);
1199}
1200
1201EXPORT struct swc_window *
1202swc_window_at(int32_t x, int32_t y)
1203{
1204	struct compositor_view *view = window_view(view_at(x, y));
1205
1206	return view ? &view->window->base : NULL;
1207}
1208
1209static struct compositor_view *
1210view_for_window(struct swc_window *base)
1211{
1212	struct window *window;
1213
1214	if (!base) {
1215		return NULL;
1216	}
1217
1218	window = (struct window *)base;
1219	return window->view;
1220}
1221
1222static struct compositor_view *
1223prev_window_view(struct compositor_view *view)
1224{
1225	struct wl_list *link;
1226	struct compositor_view *other;
1227
1228	for (link = view->link.prev; link != &compositor.views; link = link->prev) {
1229		other = wl_container_of(link, other, link);
1230
1231		if (other->visible && other->window) {
1232			return other;
1233		}
1234	}
1235
1236	return NULL;
1237}
1238
1239static struct compositor_view *
1240next_window_view(struct compositor_view *view)
1241{
1242	struct wl_list *link;
1243	struct compositor_view *other;
1244
1245	for (link = view->link.next; link != &compositor.views; link = link->next) {
1246		other = wl_container_of(link, other, link);
1247
1248		if (other->visible && other->window) {
1249			return other;
1250		}
1251	}
1252
1253	return NULL;
1254}
1255
1256static void
1257damage_views(struct compositor_view *a, struct compositor_view *b)
1258{
1259	uint32_t screens = a->base.screens | (b ? b->base.screens : 0);
1260
1261	a->border.damaged_border1 = true;
1262	a->border.damaged_border2 = true;
1263	pixman_region32_union_rect(&compositor.damage, &compositor.damage,
1264	                           a->extents.x1, a->extents.y1,
1265	                           span_u32(a->extents.x1, a->extents.x2),
1266	                           span_u32(a->extents.y1, a->extents.y2));
1267
1268	if (b) {
1269		b->border.damaged_border1 = true;
1270		b->border.damaged_border2 = true;
1271		pixman_region32_union_rect(&compositor.damage, &compositor.damage,
1272		                           b->extents.x1, b->extents.y1,
1273		                           span_u32(b->extents.x1, b->extents.x2),
1274		                           span_u32(b->extents.y1, b->extents.y2));
1275	}
1276
1277	schedule_updates(screens);
1278}
1279
1280EXPORT void
1281swc_window_stack(struct swc_window *window, int32_t direction)
1282{
1283	struct compositor_view *view = view_for_window(window);
1284	struct compositor_view *other = NULL;
1285
1286	if (!view || !view->visible || direction == 0) {
1287		return;
1288	}
1289
1290	if (direction < 0) {
1291		other = prev_window_view(view);
1292		if (!other) {
1293			return;
1294		}
1295		wl_list_remove(&view->link);
1296		wl_list_insert(other->link.prev, &view->link);
1297	} else {
1298		other = next_window_view(view);
1299		if (!other) {
1300			return;
1301		}
1302		wl_list_remove(&view->link);
1303		wl_list_insert(&other->link, &view->link);
1304	}
1305
1306	damage_views(view, other);
1307}
1308
1309struct compositor_view *
1310compositor_create_view(struct surface *surface)
1311{
1312	struct compositor_view *view;
1313
1314	view = malloc(sizeof(*view));
1315
1316	if (!view) {
1317		return NULL;
1318	}
1319
1320	view_initialize(&view->base, &view_impl);
1321	view->surface = surface;
1322	view->buffer = NULL;
1323	view->window = NULL;
1324	view->parent = NULL;
1325	view->buffer_offset_x = 0;
1326	view->buffer_offset_y = 0;
1327	view->visible = false;
1328	view->always_top = false;
1329	view->stack_layer = STACK_LAYER_NORMAL;
1330	view->extents.x1 = 0;
1331	view->extents.y1 = 0;
1332	view->extents.x2 = 0;
1333	view->extents.y2 = 0;
1334	view->border.outwidth = 0;
1335	view->border.outcolor = 0x000000;
1336	view->border.damaged_border1 = false;
1337	view->border.inwidth = 0;
1338	view->border.incolor = 0x000000;
1339	view->border.damaged_border2 = false;
1340	view->decor.color = 0x000000;
1341	view->decor.top = 0;
1342	view->decor.right = 0;
1343	view->decor.bottom = 0;
1344	view->decor.left = 0;
1345	decor_view_initialize(view);
1346	view->decor.damaged = false;
1347	pixman_region32_init(&view->clip);
1348	wl_signal_init(&view->destroy_signal);
1349	surface_set_view(surface, &view->base);
1350	wl_list_insert(&compositor.views, &view->link);
1351
1352	return view;
1353}
1354
1355void
1356compositor_view_destroy(struct compositor_view *view)
1357{
1358	wl_signal_emit(&view->destroy_signal, NULL);
1359	compositor_view_hide(view);
1360	surface_set_view(view->surface, NULL);
1361	view_finalize(&view->base);
1362	decor_view_finalize(view);
1363	pixman_region32_fini(&view->clip);
1364	wl_list_remove(&view->link);
1365	free(view);
1366}
1367
1368struct compositor_view *
1369compositor_view(struct view *view)
1370{
1371	return view->impl == &view_impl ? (struct compositor_view *)view : NULL;
1372}
1373
1374void
1375compositor_view_set_parent(struct compositor_view *view,
1376                           struct compositor_view *parent)
1377{
1378	view->parent = parent;
1379
1380	if (parent->visible) {
1381		compositor_view_show(view);
1382	} else {
1383		compositor_view_hide(view);
1384	}
1385}
1386
1387void
1388compositor_view_restack(struct compositor_view *view,
1389                        struct compositor_view *sibling, bool above)
1390{
1391	if (!view || !sibling || view == sibling) {
1392		return;
1393	}
1394
1395	if (above) {
1396		if (view->link.next == &sibling->link) {
1397			return;
1398		}
1399		wl_list_remove(&view->link);
1400		wl_list_insert(sibling->link.prev, &view->link);
1401	} else {
1402		if (view->link.prev == &sibling->link) {
1403			return;
1404		}
1405		wl_list_remove(&view->link);
1406		wl_list_insert(&sibling->link, &view->link);
1407	}
1408
1409	damage_views(view, sibling);
1410}
1411
1412void
1413compositor_view_show(struct compositor_view *view)
1414{
1415	struct compositor_view *other;
1416	struct subsurface *subsurface;
1417
1418	if (view->visible) {
1419		return;
1420	}
1421
1422	subsurface = view->surface ? view->surface->subsurface : NULL;
1423	if (subsurface) {
1424		if (!subsurface->added || !view->surface->state.buffer) {
1425			return;
1426		}
1427	}
1428
1429	view->visible = true;
1430	view_update_screens(&view->base);
1431
1432	if (view->window) {
1433		raise_window(view);
1434	}
1435
1436	/* Assume worst-case no clipping until we draw the next frame (in case the
1437	 * surface gets moved before that. */
1438	pixman_region32_clear(&view->clip);
1439	damage_view(view);
1440	update(&view->base);
1441
1442	wl_list_for_each(other, &compositor.views, link)
1443	{
1444		if (other->parent == view) {
1445			compositor_view_show(other);
1446		}
1447	}
1448}
1449
1450void
1451compositor_view_hide(struct compositor_view *view)
1452{
1453	struct compositor_view *other;
1454
1455	if (!view->visible) {
1456		return;
1457	}
1458
1459	/* Update all the screens the view was on. */
1460	update(&view->base);
1461	damage_below_view(view);
1462
1463	view_set_screens(&view->base, 0);
1464	view->visible = false;
1465
1466	wl_list_for_each(other, &compositor.views, link)
1467	{
1468		if (other->parent == view) {
1469			compositor_view_hide(other);
1470		}
1471	}
1472}
1473
1474void
1475compositor_view_set_border_width(struct compositor_view *view,
1476                                 uint32_t outwidth, uint32_t inwidth)
1477{
1478	if (view->border.outwidth == outwidth && view->border.inwidth == inwidth) {
1479		return;
1480	}
1481
1482	view->border.outwidth = outwidth;
1483	view->border.damaged_border1 = true;
1484
1485	view->border.inwidth = inwidth;
1486	view->border.damaged_border2 = true;
1487
1488	/* XXX: Damage above surface for transparent surfaces? */
1489
1490	update_extents(view);
1491	update(&view->base);
1492}
1493
1494void
1495compositor_view_set_border_color(struct compositor_view *view,
1496                                 uint32_t outcolor, uint32_t incolor)
1497{
1498	if (view->border.outcolor == outcolor && view->border.incolor == incolor) {
1499		return;
1500	}
1501
1502	view->border.outcolor = outcolor;
1503	view->border.damaged_border1 = true;
1504
1505	view->border.incolor = incolor;
1506	view->border.damaged_border2 = true;
1507
1508	/* XXX: Damage above surface for transparent surfaces? */
1509
1510	update(&view->base);
1511}
1512
1513void
1514compositor_view_set_decor(struct compositor_view *view,
1515                            const struct swc_decor *decor)
1516{
1517	decor_view_set(view, decor);
1518	update_extents(view);
1519	update(&view->base);
1520}
1521
1522void
1523compositor_view_damage_decor(struct compositor_view *view)
1524{
1525	if (!view->decor.top && !view->decor.right && !view->decor.bottom &&
1526	    !view->decor.left) {
1527		return;
1528	}
1529
1530	decor_view_damage(view);
1531	update(&view->base);
1532}
1533
1534/* }}} */
1535
1536static void
1537calculate_damage(void)
1538{
1539	struct compositor_view *view;
1540	struct swc_rectangle *geom;
1541	pixman_region32_t surface_opaque, *surface_damage;
1542
1543	pixman_region32_clear(&compositor.opaque);
1544	pixman_region32_init(&surface_opaque);
1545
1546	/* Go through views top-down to calculate clipping regions. */
1547	wl_list_for_each(view, &compositor.views, link)
1548	{
1549		if (!view->visible) {
1550			continue;
1551		}
1552
1553		geom = &view->base.geometry;
1554		pixman_region32_t view_region;
1555
1556		pixman_region32_init_rect(&view_region, geom->x, geom->y, geom->width,
1557		                          geom->height);
1558
1559		/* Clip the surface by the opaque region covering it. */
1560		pixman_region32_copy(&view->clip, &compositor.opaque);
1561
1562		/* Translate the opaque region to global coordinates. */
1563		pixman_region32_copy(&surface_opaque, &view->surface->state.opaque);
1564		pixman_region32_translate(&surface_opaque,
1565		                          geom->x - view->buffer_offset_x,
1566		                          geom->y - view->buffer_offset_y);
1567		pixman_region32_intersect(&surface_opaque, &surface_opaque,
1568		                          &view_region);
1569
1570		/* Add the surface's opaque region to the accumulated opaque region. */
1571		pixman_region32_union(&compositor.opaque, &compositor.opaque,
1572		                      &surface_opaque);
1573
1574		surface_damage = &view->surface->state.damage;
1575
1576		if (pixman_region32_not_empty(surface_damage)) {
1577			renderer_flush_view(view);
1578
1579			/* Translate surface damage to global coordinates. */
1580			pixman_region32_translate(surface_damage,
1581			                          geom->x - view->buffer_offset_x,
1582			                          geom->y - view->buffer_offset_y);
1583
1584			/* Add the surface damage to the compositor damage. */
1585			pixman_region32_union(&compositor.damage, &compositor.damage,
1586			                      surface_damage);
1587			pixman_region32_clear(surface_damage);
1588		}
1589
1590		/* redraw entire thingy if border or decor changed */
1591		if (view->border.damaged_border1 || view->border.damaged_border2 ||
1592		    view->decor.damaged) {
1593			pixman_region32_t border_region;
1594
1595			pixman_region32_init_with_extents(&border_region, &view->extents);
1596
1597			pixman_region32_subtract(&border_region, &border_region,
1598			                         &view_region);
1599
1600			pixman_region32_union(&compositor.damage, &compositor.damage,
1601			                      &border_region);
1602
1603			pixman_region32_fini(&border_region);
1604
1605			view->border.damaged_border1 = false;
1606			view->border.damaged_border2 = false;
1607			view->decor.damaged = false;
1608		}
1609
1610		pixman_region32_fini(&view_region);
1611	}
1612
1613	pixman_region32_fini(&surface_opaque);
1614}
1615
1616static void
1617update_screen(struct screen *screen)
1618{
1619	struct target *target;
1620	const struct swc_rectangle *geom = &screen->base.geometry;
1621	pixman_region32_t damage, *total_damage;
1622
1623	if (!(compositor.scheduled_updates & screen_mask(screen))) {
1624		return;
1625	}
1626
1627	if (!(target = target_get(screen))) {
1628		return;
1629	}
1630
1631	pixman_region32_init(&damage);
1632	pixman_region32_intersect_rect(&damage, &compositor.damage, geom->x,
1633	                               geom->y, geom->width, geom->height);
1634	pixman_region32_translate(&damage, -geom->x, -geom->y);
1635	total_damage = wld_surface_damage(target->surface, &damage);
1636
1637	/* Don't repaint the screen if it is waiting for a page flip. */
1638	if (compositor.pending_flips & screen_mask(screen)) {
1639		pixman_region32_fini(&damage);
1640		return;
1641	}
1642
1643	/* check if zoom */
1644	if (compositor.zoom != 1.0f) {
1645		pixman_region32_fini(&damage);
1646
1647		struct wld_buffer *zoomed =
1648		    render_zoomed_to_shm(screen, compositor.zoom);
1649		if (!zoomed) {
1650			return;
1651		}
1652
1653		pixman_region32_t full;
1654		pixman_region32_init_rect(&full, 0, 0, geom->width, geom->height);
1655		wld_set_target_surface(swc.drm->renderer, target->surface);
1656		wld_copy_region(swc.drm->renderer, zoomed, 0, 0, &full);
1657		wld_flush(swc.drm->renderer);
1658		pixman_region32_fini(&full);
1659
1660		wld_buffer_unreference(zoomed);
1661	} else {
1662		pixman_region32_t base_damage;
1663		pixman_region32_copy(&damage, total_damage);
1664		pixman_region32_translate(&damage, geom->x, geom->y);
1665		pixman_region32_init(&base_damage);
1666		pixman_region32_subtract(&base_damage, &damage, &compositor.opaque);
1667		renderer_repaint(target, &damage, &base_damage, &compositor.views,
1668		                 screen);
1669		pixman_region32_fini(&damage);
1670		pixman_region32_fini(&base_damage);
1671	}
1672
1673	switch (target_swap_buffers(target)) {
1674	case -EACCES:
1675		/* If we get an EACCES, it is because this session is being deactivated,
1676		 * but we haven't yet received the deactivate signal from swc-launch. */
1677		swc_deactivate();
1678		break;
1679	case 0:
1680		compositor.pending_flips |= screen_mask(screen);
1681		break;
1682	}
1683}
1684
1685static void
1686perform_update(void *data)
1687{
1688	struct screen *screen;
1689	uint32_t updates = compositor.scheduled_updates & ~compositor.pending_flips;
1690
1691	if (!swc.active || !updates) {
1692		return;
1693	}
1694
1695	DEBUG("Performing update\n");
1696
1697	compositor.updating = true;
1698	calculate_damage();
1699
1700	wl_list_for_each(screen, &swc.screens, link) update_screen(screen);
1701
1702	/* XXX: Should assert that all damage was covered by some output */
1703	pixman_region32_clear(&compositor.damage);
1704	compositor.scheduled_updates &= ~updates;
1705	compositor.updating = false;
1706}
1707
1708bool
1709handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx,
1710              wl_fixed_t fy)
1711{
1712	int32_t x = wl_fixed_to_int(fx), y = wl_fixed_to_int(fy);
1713
1714	/* If buttons are pressed, don't change pointer focus. */
1715	if (swc.seat->pointer->buttons.size > 0) {
1716		return false;
1717	}
1718
1719	struct compositor_view *view = view_at(x, y);
1720
1721	pointer_set_focus(swc.seat->pointer, view);
1722
1723	return false;
1724}
1725
1726static bool
1727handle_button(struct pointer_handler *handler, uint32_t time,
1728              struct button *button, uint32_t state)
1729{
1730	(void)handler;
1731	(void)time;
1732	(void)button;
1733
1734	if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
1735		return false;
1736	}
1737
1738	int32_t x = wl_fixed_to_int(swc.seat->pointer->x);
1739	int32_t y = wl_fixed_to_int(swc.seat->pointer->y);
1740	struct compositor_view *view = view_at(x, y);
1741
1742	pointer_set_focus(swc.seat->pointer, view);
1743	raise_window(view);
1744
1745	return false;
1746}
1747
1748static void
1749handle_terminate(void *data, uint32_t time, uint32_t value, uint32_t state)
1750{
1751	if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1752		wl_display_terminate(swc.display);
1753	}
1754}
1755
1756static void
1757handle_switch_vt(void *data, uint32_t time, uint32_t value, uint32_t state)
1758{
1759	uint8_t vt = value - XKB_KEY_XF86Switch_VT_1 + 1;
1760
1761	if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1762		launch_activate_vt(vt);
1763	}
1764}
1765
1766static void
1767handle_swc_event(struct wl_listener *listener, void *data)
1768{
1769	struct event *event = data;
1770
1771	switch (event->type) {
1772	case SWC_EVENT_ACTIVATED:
1773		schedule_updates(-1);
1774		break;
1775	case SWC_EVENT_DEACTIVATED:
1776		compositor.scheduled_updates = 0;
1777		break;
1778	}
1779}
1780
1781static void
1782create_surface(struct wl_client *client, struct wl_resource *resource,
1783               uint32_t id)
1784{
1785	struct surface *surface;
1786
1787	/* Initialize surface. */
1788	surface = surface_new(client, wl_resource_get_version(resource), id);
1789
1790	if (!surface) {
1791		wl_resource_post_no_memory(resource);
1792		return;
1793	}
1794
1795	wl_signal_emit(&swc_compositor.signal.new_surface, surface);
1796}
1797
1798static void
1799create_region(struct wl_client *client, struct wl_resource *resource,
1800              uint32_t id)
1801{
1802	if (!region_new(client, wl_resource_get_version(resource), id)) {
1803		wl_resource_post_no_memory(resource);
1804	}
1805}
1806
1807static const struct wl_compositor_interface compositor_impl = {
1808    .create_surface = create_surface,
1809    .create_region = create_region,
1810};
1811
1812static void
1813bind_compositor(struct wl_client *client, void *data, uint32_t version,
1814                uint32_t id)
1815{
1816	struct wl_resource *resource;
1817
1818	resource =
1819	    wl_resource_create(client, &wl_compositor_interface, version, id);
1820	if (!resource) {
1821		wl_client_post_no_memory(client);
1822		return;
1823	}
1824	wl_resource_set_implementation(resource, &compositor_impl, NULL, NULL);
1825}
1826
1827bool
1828compositor_initialize(void)
1829{
1830	struct screen *screen;
1831	uint32_t keysym;
1832
1833	compositor.global = wl_global_create(swc.display, &wl_compositor_interface,
1834	                                     4, NULL, &bind_compositor);
1835
1836	if (!compositor.global) {
1837		return false;
1838	}
1839
1840	compositor.scheduled_updates = 0;
1841	compositor.pending_flips = 0;
1842	compositor.updating = false;
1843	compositor.zoom = 1.0f;
1844	compositor.zoom_buffer = NULL;
1845	if (!decor_initialize()) {
1846		return false;
1847	}
1848	pixman_region32_init(&compositor.damage);
1849	pixman_region32_init(&compositor.opaque);
1850	wl_list_init(&compositor.views);
1851	wl_signal_init(&swc_compositor.signal.new_surface);
1852	compositor.swc_listener.notify = &handle_swc_event;
1853	wl_signal_add(&swc.event_signal, &compositor.swc_listener);
1854
1855	wl_list_for_each(screen, &swc.screens, link) target_new(screen);
1856	if (swc.active) {
1857		schedule_updates(-1);
1858	}
1859
1860	swc_add_binding(SWC_BINDING_KEY, SWC_MOD_CTRL | SWC_MOD_ALT,
1861	                XKB_KEY_BackSpace, &handle_terminate, NULL);
1862
1863	for (keysym = XKB_KEY_XF86Switch_VT_1; keysym <= XKB_KEY_XF86Switch_VT_12;
1864	     ++keysym) {
1865		swc_add_binding(SWC_BINDING_KEY, SWC_MOD_ANY, keysym, &handle_switch_vt,
1866		                NULL);
1867	}
1868
1869	compositor.initialized = true;
1870
1871	return true;
1872}
1873
1874void
1875compositor_finalize(void)
1876{
1877	compositor.initialized = false;
1878
1879	if (compositor.zoom_buffer) {
1880		wld_buffer_unreference(compositor.zoom_buffer);
1881		compositor.zoom_buffer = NULL;
1882	}
1883	decor_finalize();
1884	pixman_region32_fini(&compositor.damage);
1885	pixman_region32_fini(&compositor.opaque);
1886	wl_global_destroy(compositor.global);
1887}
1888
1889struct wld_buffer *
1890compositor_get_buffer(struct screen *screen)
1891{
1892	struct target *target = target_get(screen);
1893	if (!target) {
1894		return NULL;
1895	}
1896	return target->current_buffer;
1897}
1898
1899struct wld_buffer *
1900compositor_render_to_shm(struct screen *screen)
1901{
1902	if (compositor.zoom != 1.0f) {
1903		return render_zoomed_to_shm(screen, compositor.zoom);
1904	}
1905
1906	uint32_t width = screen->base.geometry.width;
1907	uint32_t height = screen->base.geometry.height;
1908	struct wld_buffer *buffer;
1909	struct compositor_view *view;
1910	pixman_region32_t region;
1911	pixman_region32_t damage;
1912	uint32_t caps;
1913
1914	/* create shm buf */
1915	buffer = wld_create_buffer(swc.shm->context, width, height,
1916	                           WLD_FORMAT_ARGB8888, WLD_FLAG_MAP);
1917	if (!buffer) {
1918		return NULL;
1919	}
1920
1921	caps = wld_capabilities(swc.shm->renderer, buffer);
1922	if (!(caps & WLD_CAPABILITY_WRITE) ||
1923	    !wld_set_target_buffer(swc.shm->renderer, buffer)) {
1924		wld_buffer_unreference(buffer);
1925		return NULL;
1926	}
1927
1928	/* set reigon */
1929	pixman_region32_init_rect(&region, 0, 0, width, height);
1930	pixman_region32_init_rect(&damage, screen->base.geometry.x,
1931	                          screen->base.geometry.y, width, height);
1932
1933	/* background */
1934	wld_fill_region(swc.shm->renderer, DEFAULT_BG, &region);
1935
1936	wl_list_for_each_reverse(view, &compositor.views, link)
1937	{
1938		struct wld_buffer *src = view->buffer;
1939
1940		if (!view->visible) {
1941			continue;
1942		}
1943
1944		if (src &&
1945		    !(wld_capabilities(swc.shm->renderer, src) & WLD_CAPABILITY_READ)) {
1946			src = view->base.buffer;
1947		}
1948
1949		if (src &&
1950		    (wld_capabilities(swc.shm->renderer, src) & WLD_CAPABILITY_READ)) {
1951			int32_t x = view->base.geometry.x - screen->base.geometry.x;
1952			int32_t y = view->base.geometry.y - screen->base.geometry.y;
1953
1954			wld_copy_rectangle(swc.shm->renderer, src, x, y, 0, 0,
1955			                   view->base.geometry.width,
1956			                   view->base.geometry.height);
1957		}
1958
1959		if ((view->border.outwidth > 0 || view->border.inwidth > 0) &&
1960		    view->base.buffer) {
1961			pixman_region32_t view_region, view_damage, border_damage;
1962			const struct swc_rectangle *geom = &view->base.geometry;
1963			const struct swc_rectangle *target_geom = &screen->base.geometry;
1964
1965			pixman_region32_init_rect(&view_region, geom->x, geom->y,
1966			                          geom->width, geom->height);
1967			pixman_region32_init_with_extents(&view_damage, &view->extents);
1968			pixman_region32_init(&border_damage);
1969
1970			pixman_region32_intersect(&view_damage, &view_damage, &damage);
1971			pixman_region32_subtract(&view_damage, &view_damage, &view->clip);
1972			pixman_region32_subtract(&border_damage, &view_damage,
1973			                         &view_region);
1974
1975			pixman_region32_t in_rect;
1976			pixman_region32_init_rect(&in_rect,
1977			                          geom->x - view->border.inwidth,
1978			                          geom->y - view->border.inwidth,
1979			                          geom->width + (2 * view->border.inwidth),
1980			                          geom->height +
1981			                              (2 * view->border.inwidth));
1982
1983			pixman_region32_t out_border;
1984			pixman_region32_init(&out_border);
1985			pixman_region32_subtract(&out_border, &border_damage, &in_rect);
1986
1987			pixman_region32_t in_border;
1988			pixman_region32_init(&in_border);
1989			pixman_region32_subtract(&in_border, &in_rect, &view_region);
1990			pixman_region32_intersect(&in_border, &in_border, &border_damage);
1991
1992			if (view->border.outwidth > 0 &&
1993			    pixman_region32_not_empty(&out_border)) {
1994				pixman_region32_translate(&out_border, -target_geom->x,
1995				                          -target_geom->y);
1996				wld_fill_region(swc.shm->renderer, view->border.outcolor,
1997				                &out_border);
1998			}
1999
2000			if (view->border.inwidth > 0 &&
2001			    pixman_region32_not_empty(&in_border)) {
2002				pixman_region32_translate(&in_border, -target_geom->x,
2003				                          -target_geom->y);
2004				wld_fill_region(swc.shm->renderer, view->border.incolor,
2005				                &in_border);
2006			}
2007
2008			pixman_region32_fini(&border_damage);
2009			pixman_region32_fini(&view_region);
2010			pixman_region32_fini(&view_damage);
2011			pixman_region32_fini(&in_rect);
2012			pixman_region32_fini(&out_border);
2013			pixman_region32_fini(&in_border);
2014		}
2015
2016		if (view->decor.top || view->decor.right || view->decor.bottom ||
2017		    view->decor.left) {
2018			const struct swc_rectangle *target_geom = &screen->base.geometry;
2019			decor_repaint(swc.shm->renderer, target_geom, view, &damage);
2020		}
2021	}
2022
2023	draw_overlays(swc.shm->renderer, &screen->base.geometry);
2024
2025	wld_flush(swc.shm->renderer);
2026	pixman_region32_fini(&region);
2027	pixman_region32_fini(&damage);
2028
2029	return buffer;
2030}