summaryrefslogtreecommitdiff
path: root/src/compositor
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/README70
-rw-r--r--src/compositor/clutter-utils.c188
-rw-r--r--src/compositor/clutter-utils.h40
-rw-r--r--src/compositor/cogl-utils.c114
-rw-r--r--src/compositor/cogl-utils.h39
-rw-r--r--src/compositor/compositor-private.h101
-rw-r--r--src/compositor/compositor.c1581
-rw-r--r--src/compositor/meta-background-actor-private.h10
-rw-r--r--src/compositor/meta-background-actor.c218
-rw-r--r--src/compositor/meta-background-content-private.h16
-rw-r--r--src/compositor/meta-background-content.c1312
-rw-r--r--src/compositor/meta-background-group.c66
-rw-r--r--src/compositor/meta-background-image.c370
-rw-r--r--src/compositor/meta-background-private.h14
-rw-r--r--src/compositor/meta-background.c1018
-rw-r--r--src/compositor/meta-compositor-native.c151
-rw-r--r--src/compositor/meta-compositor-native.h33
-rw-r--r--src/compositor/meta-compositor-server.c100
-rw-r--r--src/compositor/meta-compositor-server.h38
-rw-r--r--src/compositor/meta-compositor-x11.c530
-rw-r--r--src/compositor/meta-compositor-x11.h39
-rw-r--r--src/compositor/meta-cullable.c245
-rw-r--r--src/compositor/meta-cullable.h61
-rw-r--r--src/compositor/meta-dnd-actor-private.h48
-rw-r--r--src/compositor/meta-dnd-actor.c242
-rw-r--r--src/compositor/meta-dnd.c336
-rw-r--r--src/compositor/meta-feedback-actor-private.h70
-rw-r--r--src/compositor/meta-feedback-actor.c285
-rw-r--r--src/compositor/meta-later-private.h28
-rw-r--r--src/compositor/meta-later.c352
-rw-r--r--src/compositor/meta-module.c193
-rw-r--r--src/compositor/meta-module.h55
-rw-r--r--src/compositor/meta-plugin-manager.c419
-rw-r--r--src/compositor/meta-plugin-manager.h105
-rw-r--r--src/compositor/meta-plugin.c223
-rw-r--r--src/compositor/meta-shadow-factory.c1066
-rw-r--r--src/compositor/meta-shaped-texture-private.h76
-rw-r--r--src/compositor/meta-shaped-texture.c1676
-rw-r--r--src/compositor/meta-surface-actor-wayland.c198
-rw-r--r--src/compositor/meta-surface-actor-wayland.h63
-rw-r--r--src/compositor/meta-surface-actor-x11.c422
-rw-r--r--src/compositor/meta-surface-actor-x11.h62
-rw-r--r--src/compositor/meta-surface-actor.c698
-rw-r--r--src/compositor/meta-surface-actor.h72
-rw-r--r--src/compositor/meta-sync-ring.c592
-rw-r--r--src/compositor/meta-sync-ring.h13
-rw-r--r--src/compositor/meta-texture-tower.c484
-rw-r--r--src/compositor/meta-texture-tower.h68
-rw-r--r--src/compositor/meta-window-actor-private.h102
-rw-r--r--src/compositor/meta-window-actor-wayland.c171
-rw-r--r--src/compositor/meta-window-actor-wayland.h37
-rw-r--r--src/compositor/meta-window-actor-x11.c1693
-rw-r--r--src/compositor/meta-window-actor-x11.h47
-rw-r--r--src/compositor/meta-window-actor.c1559
-rw-r--r--src/compositor/meta-window-group-private.h23
-rw-r--r--src/compositor/meta-window-group.c222
-rw-r--r--src/compositor/meta-window-shape.c259
-rw-r--r--src/compositor/plugins/default.c923
-rw-r--r--src/compositor/plugins/meson.build20
-rw-r--r--src/compositor/region-utils.c458
-rw-r--r--src/compositor/region-utils.h119
61 files changed, 0 insertions, 19833 deletions
diff --git a/src/compositor/README b/src/compositor/README
deleted file mode 100644
index 93edf8dc9..000000000
--- a/src/compositor/README
+++ /dev/null
@@ -1,70 +0,0 @@
-Intro
-=====
-
-In general, the compositor splits the window from the contents of
-the window from the shape of the window. In other words, a window
-has contents, and the contents of the window have a shape. This is
-represented by the actor hierarchy:
-
- +--------------------------------------+
- | MetaWindowActor |
- | +----------------------------------+ |
- | | MetaSurfaceActor | |
- | | +------------------------------+ | |
- | | | MetaShapedTexture | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | +------------------------------+ | |
- | +----------------------------------+ |
- +--------------------------------------+
-
-Surfaces may also contain subsurfaces. The MetaWindowActor and
-MetaSurfaceActor subclasses that will be created depend on the client
-type, and the display server type.
-
-## Subsurfaces
-
-Additionally, there is also the case of subsurfaces: surfaces that
-are child of other surfaces. That is also represented in the actor
-hierarchy by having one or many MetaSurfaceActors (the subsurfaces)
-added as children of a parent MetaSurfaceActor. There are no limits
-to how many subsurfaces a surface may have. With subsurfaces, the
-actor hierarchy looks like this:
-
- MetaWindowActor
- ↳ MetaSurfaceActor (surface)
- ↳ MetaShapedTexture
- ↳ MetaSurfaceActor (subsurface)
- ↳ MetaShapedTexture
- ↳ MetaSurfaceActor (sub-subsurface)
- ↳ MetaShapedTexture
- ↳ MetaSurfaceActor (subsurface)
- ↳ MetaShapedTexture
-
-In this example, the main surface has 2 subsurfaces. One of these
-subsurfaces contains a subsurface as well.
-
-All MetaWindowActors contain at least one MetaSurfaceActor, and all
-MetaSurfaceActors contain a MetaShapedTexture.
-
-## Client and compositor
-
-MetaWindowActor and its subclasses represent the client window's
-type. A X11 client will have a MetaWindowActorX11 representing it,
-and a Wayland client will have a MetaWindowActorWayland.
-
-On the compositor side, the surface where the contents of the window
-are drawn into are represented by MetaSurfaceActor subclasses. On a
-Wayland session, windows are backed by a MetaSurfaceActorWayland
-surface, whereas on X11 sessions, by MetaSurfaceActorX11.
-
-XWayland windows are X11 client windows (MetaWindowActorX11) backed
-by Wayland surfaces (MetaWindowActorWayland).
-
-
-Env Vars
-========
-
-MUTTER_DISABLE_MIPMAPS - set to disable use of mipmaped windows. \ No newline at end of file
diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c
deleted file mode 100644
index 86d788562..000000000
--- a/src/compositor/clutter-utils.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Cogl
- *
- * Copyright 2010 Red Hat, Inc.
- * Copyright 2010 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "compositor/clutter-utils.h"
-
-#include <math.h>
-
-/* This file uses pixel-aligned region computation to determine what
- * can be clipped out. This only really works if everything is aligned
- * to the pixel grid - not scaled or rotated and at integer offsets.
- *
- * (This could be relaxed - if we turned off filtering for unscaled
- * windows then windows would be, by definition aligned to the pixel
- * grid. And for rectangular windows without a shape, the outline that
- * we draw for an unrotated window is always a rectangle because we
- * don't use antialasing for the window boundary - with or without
- * filtering, with or without a scale. But figuring out exactly
- * what pixels will be drawn by the graphics system in these cases
- * gets tricky, so we just go for the easiest part - no scale,
- * and at integer offsets.)
- *
- * The way we check for pixel-aligned is by looking at the
- * transformation into screen space of the allocation box of an actor
- * and and checking if the corners are "close enough" to integral
- * pixel values.
- */
-
-/* The definition of "close enough" to integral pixel values is
- * equality when we convert to 24.8 fixed-point.
- */
-static inline int
-round_to_fixed (float x)
-{
- return roundf (x * 256);
-}
-
-/* Help macros to scale from OpenGL <-1,1> coordinates system to
- * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
- */
-#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
-#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
-
-/* This helper function checks if (according to our fixed point precision)
- * the vertices @verts form a box of width @widthf and height @heightf
- * located at integral coordinates. These coordinates are returned
- * in @x_origin and @y_origin.
- */
-gboolean
-meta_actor_vertices_are_untransformed (graphene_point3d_t *verts,
- float widthf,
- float heightf,
- int *x_origin,
- int *y_origin)
-{
- int width, height;
- int v0x, v0y, v1x, v1y, v2x, v2y, v3x, v3y;
- int x, y;
-
- width = round_to_fixed (widthf);
- height = round_to_fixed (heightf);
-
- v0x = round_to_fixed (verts[0].x); v0y = round_to_fixed (verts[0].y);
- v1x = round_to_fixed (verts[1].x); v1y = round_to_fixed (verts[1].y);
- v2x = round_to_fixed (verts[2].x); v2y = round_to_fixed (verts[2].y);
- v3x = round_to_fixed (verts[3].x); v3y = round_to_fixed (verts[3].y);
-
- /* Using shifting for converting fixed => int, gets things right for
- * negative values. / 256. wouldn't do the same
- */
- x = v0x >> 8;
- y = v0y >> 8;
-
- /* At integral coordinates? */
- if (x * 256 != v0x || y * 256 != v0y)
- return FALSE;
-
- /* Not scaled? */
- if (v1x - v0x != width || v2y - v0y != height)
- return FALSE;
-
- /* Not rotated/skewed? */
- if (v0x != v2x || v0y != v1y ||
- v3x != v1x || v3y != v2y)
- return FALSE;
-
- if (x_origin)
- *x_origin = x;
- if (y_origin)
- *y_origin = y;
-
- return TRUE;
-}
-
-/**
- * meta_actor_painting_untransformed:
- * @paint_width: the width of the painted area
- * @paint_height: the height of the painted area
- * @sample_width: the width of the sampled area of the texture
- * @sample_height: the height of the sampled area of the texture
- * @x_origin: if the transform is only an integer translation
- * then the X coordinate of the location of the origin under the transformation
- * from drawing space to screen pixel space is returned here.
- * @y_origin: if the transform is only an integer translation
- * then the X coordinate of the location of the origin under the transformation
- * from drawing space to screen pixel space is returned here.
- *
- * Determines if the current painting transform is an integer translation.
- * This can differ from the result of meta_actor_is_untransformed() when
- * painting an actor if we're inside a inside a clone paint. @paint_width
- * and @paint_height are used to determine the vertices of the rectangle
- * we check to see if the painted area is "close enough" to the integer
- * transform.
- */
-gboolean
-meta_actor_painting_untransformed (CoglFramebuffer *fb,
- int paint_width,
- int paint_height,
- int sample_width,
- int sample_height,
- int *x_origin,
- int *y_origin)
-{
- graphene_matrix_t modelview, projection, modelview_projection;
- graphene_point3d_t vertices[4];
- float viewport[4];
- int i;
-
- cogl_framebuffer_get_modelview_matrix (fb, &modelview);
- cogl_framebuffer_get_projection_matrix (fb, &projection);
-
- graphene_matrix_multiply (&modelview,
- &projection,
- &modelview_projection);
-
- vertices[0].x = 0;
- vertices[0].y = 0;
- vertices[0].z = 0;
- vertices[1].x = paint_width;
- vertices[1].y = 0;
- vertices[1].z = 0;
- vertices[2].x = 0;
- vertices[2].y = paint_height;
- vertices[2].z = 0;
- vertices[3].x = paint_width;
- vertices[3].y = paint_height;
- vertices[3].z = 0;
-
- cogl_framebuffer_get_viewport4fv (fb, viewport);
-
- for (i = 0; i < 4; i++)
- {
- float w = 1;
- cogl_graphene_matrix_project_point (&modelview_projection,
- &vertices[i].x,
- &vertices[i].y,
- &vertices[i].z,
- &w);
- vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w,
- viewport[2], viewport[0]);
- vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w,
- viewport[3], viewport[1]);
- }
-
- return meta_actor_vertices_are_untransformed (vertices,
- sample_width, sample_height,
- x_origin, y_origin);
-}
-
diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h
deleted file mode 100644
index 8ed0e2a4d..000000000
--- a/src/compositor/clutter-utils.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Clutter
- *
- * Copyright 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_CLUTTER_UTILS_H__
-#define __META_CLUTTER_UTILS_H__
-
-#include "clutter/clutter.h"
-
-gboolean meta_actor_vertices_are_untransformed (graphene_point3d_t *verts,
- float widthf,
- float heightf,
- int *x_origin,
- int *y_origin);
-
-gboolean meta_actor_painting_untransformed (CoglFramebuffer *fb,
- int paint_width,
- int paint_height,
- int sample_widthf,
- int sample_heightf,
- int *x_origin,
- int *y_origin);
-
-#endif /* __META_CLUTTER_UTILS_H__ */
diff --git a/src/compositor/cogl-utils.c b/src/compositor/cogl-utils.c
deleted file mode 100644
index 0a39755a5..000000000
--- a/src/compositor/cogl-utils.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Cogl
- *
- * Copyright 2010 Red Hat, Inc.
- * Copyright 2010 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "clutter/clutter.h"
-#include "compositor/cogl-utils.h"
-
-/* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */
-
-/**
- * meta_create_texture_pipeline:
- * @src_texture: (nullable): texture to use initially for the layer
- *
- * Creates a pipeline with a single layer. Using a common template
- * makes it easier for Cogl to share a shader for different uses in
- * Mutter.
- *
- * Return value: (transfer full): a newly created #CoglPipeline
- */
-CoglPipeline *
-meta_create_texture_pipeline (CoglTexture *src_texture)
-{
- static CoglPipeline *texture_pipeline_template = NULL;
- CoglPipeline *pipeline;
-
- /* The only state used in the pipeline that would affect the shader
- generation is the texture type on the layer. Therefore we create
- a template pipeline which sets this state and all texture
- pipelines are created as a copy of this. That way Cogl can find
- the shader state for the pipeline more quickly by looking at the
- pipeline ancestry instead of resorting to the shader cache. */
- if (G_UNLIKELY (texture_pipeline_template == NULL))
- {
- CoglContext *ctx =
- clutter_backend_get_cogl_context (clutter_get_default_backend ());
-
- texture_pipeline_template = cogl_pipeline_new (ctx);
- cogl_pipeline_set_layer_null_texture (texture_pipeline_template, 0);
- }
-
- pipeline = cogl_pipeline_copy (texture_pipeline_template);
-
- if (src_texture != NULL)
- cogl_pipeline_set_layer_texture (pipeline, 0, src_texture);
-
- return pipeline;
-}
-
-/**
- * meta_create_texture:
- * @width: width of the texture to create
- * @height: height of the texture to create
- * @components; components to store in the texture (color or alpha)
- * @flags: flags that affect the allocation behavior
- *
- * Creates a texture of the given size with the specified components
- * for use as a frame buffer object.
- *
- * If %META_TEXTURE_ALLOW_SLICING is present in @flags, and the texture
- * is larger than the texture size limits of the system, then the texture
- * will be created as a sliced texture. This also will cause problems
- * with using the texture with GLSL, and is more likely to be an issue
- * since all GL implementations have texture size limits, and they can
- * be as small as 2048x2048 on reasonably current systems.
- */
-CoglTexture *
-meta_create_texture (int width,
- int height,
- CoglTextureComponents components,
- MetaTextureFlags flags)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
- CoglContext *ctx = clutter_backend_get_cogl_context (backend);
- CoglTexture *texture;
-
- texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height));
- cogl_texture_set_components (texture, components);
-
- if ((flags & META_TEXTURE_ALLOW_SLICING) != 0)
- {
- /* To find out if we need to slice the texture, we have to go ahead and force storage
- * to be allocated
- */
- GError *catch_error = NULL;
- if (!cogl_texture_allocate (texture, &catch_error))
- {
- g_error_free (catch_error);
- cogl_object_unref (texture);
- texture = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx, width, height, COGL_TEXTURE_MAX_WASTE));
- cogl_texture_set_components (texture, components);
- }
- }
-
- return texture;
-}
diff --git a/src/compositor/cogl-utils.h b/src/compositor/cogl-utils.h
deleted file mode 100644
index ae7e85176..000000000
--- a/src/compositor/cogl-utils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Cogl
- *
- * Copyright 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_COGL_UTILS_H__
-#define __META_COGL_UTILS_H__
-
-#include "cogl/cogl.h"
-
-CoglPipeline * meta_create_texture_pipeline (CoglTexture *texture);
-
-typedef enum
-{
- META_TEXTURE_FLAGS_NONE = 0,
- META_TEXTURE_ALLOW_SLICING = 1 << 1
-} MetaTextureFlags;
-
-CoglTexture *meta_create_texture (int width,
- int height,
- CoglTextureComponents components,
- MetaTextureFlags flags);
-
-#endif /* __META_COGL_UTILS_H__ */
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
deleted file mode 100644
index 580618e48..000000000
--- a/src/compositor/compositor-private.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_COMPOSITOR_PRIVATE_H
-#define META_COMPOSITOR_PRIVATE_H
-
-#include <X11/extensions/Xfixes.h>
-
-#include "clutter/clutter-mutter.h"
-#include "clutter/clutter.h"
-#include "compositor/meta-plugin-manager.h"
-#include "compositor/meta-window-actor-private.h"
-#include "meta/compositor.h"
-#include "meta/display.h"
-
-/* Wait 2ms after vblank before starting to draw next frame */
-#define META_SYNC_DELAY 2
-
-typedef struct _MetaLaters MetaLaters;
-
-struct _MetaCompositorClass
-{
- GObjectClass parent_class;
-
- gboolean (* manage) (MetaCompositor *compositor,
- GError **error);
- void (* unmanage) (MetaCompositor *compositor);
- void (* before_paint) (MetaCompositor *compositor,
- ClutterStageView *stage_view);
- void (* after_paint) (MetaCompositor *compositor,
- ClutterStageView *stage_view);
- void (* remove_window) (MetaCompositor *compositor,
- MetaWindow *window);
- int64_t (* monotonic_to_high_res_xserver_time) (MetaCompositor *compositor,
- int64_t time_us);
- void (* grab_begin) (MetaCompositor *compositor);
- void (* grab_end) (MetaCompositor *compositor);
-};
-
-gboolean meta_compositor_do_manage (MetaCompositor *compositor,
- GError **error);
-
-void meta_compositor_remove_window_actor (MetaCompositor *compositor,
- MetaWindowActor *window_actor);
-
-void meta_switch_workspace_completed (MetaCompositor *compositor);
-
-gboolean meta_begin_modal_for_plugin (MetaCompositor *compositor,
- MetaPlugin *plugin,
- MetaModalOptions options,
- guint32 timestamp);
-void meta_end_modal_for_plugin (MetaCompositor *compositor,
- MetaPlugin *plugin,
- guint32 timestamp);
-
-MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
-
-int64_t meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
- int64_t monotonic_time_us);
-
-void meta_compositor_flash_window (MetaCompositor *compositor,
- MetaWindow *window);
-
-MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor,
- MetaWindow *window);
-
-MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
- MetaWindow *window);
-
-void meta_compositor_locate_pointer (MetaCompositor *compositor);
-
-void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
-
-gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor);
-
-MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);
-
-MetaWindowActor * meta_compositor_get_top_window_actor (MetaCompositor *compositor);
-
-ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
-
-gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
-
-MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
-
-/*
- * This function takes a 64 bit time stamp from the monotonic clock, and clamps
- * it to the scope of the X server clock, without losing the granularity.
- */
-static inline int64_t
-meta_translate_to_high_res_xserver_time (int64_t time_us)
-{
- int64_t us;
- int64_t ms;
-
- us = time_us % 1000;
- ms = time_us / 1000;
-
- return ms2us (ms & 0xffffffff) + us;
-}
-
-#endif /* META_COMPOSITOR_PRIVATE_H */
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
deleted file mode 100644
index 9cdd39c15..000000000
--- a/src/compositor/compositor.c
+++ /dev/null
@@ -1,1581 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:compositor
- * @Title: MetaCompositor
- * @Short_Description: Compositor API
- *
- * At a high-level, a window is not-visible or visible. When a
- * window is added (with meta_compositor_add_window()) it is not visible.
- * meta_compositor_show_window() indicates a transition from not-visible to
- * visible. Some of the reasons for this:
- *
- * - Window newly created
- * - Window is unminimized
- * - Window is moved to the current desktop
- * - Window was made sticky
- *
- * meta_compositor_hide_window() indicates that the window has transitioned from
- * visible to not-visible. Some reasons include:
- *
- * - Window was destroyed
- * - Window is minimized
- * - Window is moved to a different desktop
- * - Window no longer sticky.
- *
- * Note that combinations are possible - a window might have first
- * been minimized and then moved to a different desktop. The 'effect' parameter
- * to meta_compositor_show_window() and meta_compositor_hide_window() is a hint
- * as to the appropriate effect to show the user and should not
- * be considered to be indicative of a state change.
- *
- * When the active workspace is changed, meta_compositor_switch_workspace() is
- * called first, then meta_compositor_show_window() and
- * meta_compositor_hide_window() are called individually for each window
- * affected, with an effect of META_COMP_EFFECT_NONE.
- * If hiding windows will affect the switch workspace animation, the
- * compositor needs to delay hiding the windows until the switch
- * workspace animation completes.
- *
- * # Containers #
- *
- * There's two containers in the stage that are used to place window actors, here
- * are listed in the order in which they are painted:
- *
- * - window group, accessible with meta_get_window_group_for_display()
- * - top window group, accessible with meta_get_top_window_group_for_display()
- *
- * Mutter will place actors representing windows in the window group, except for
- * override-redirect windows (ie. popups and menus) which will be placed in the
- * top window group.
- */
-
-#include "config.h"
-
-#include "compositor/compositor-private.h"
-
-#include <X11/extensions/Xcomposite.h>
-
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-event-x11.h"
-#include "backends/x11/meta-stage-x11.h"
-#include "clutter/clutter-mutter.h"
-#include "cogl/cogl.h"
-#include "compositor/meta-later-private.h"
-#include "compositor/meta-window-actor-x11.h"
-#include "compositor/meta-window-actor-private.h"
-#include "compositor/meta-window-group-private.h"
-#include "core/frame.h"
-#include "core/util-private.h"
-#include "core/window-private.h"
-#include "meta/compositor-mutter.h"
-#include "meta/main.h"
-#include "meta/meta-backend.h"
-#include "meta/meta-background-actor.h"
-#include "meta/meta-background-group.h"
-#include "meta/meta-context.h"
-#include "meta/meta-shadow-factory.h"
-#include "meta/meta-x11-errors.h"
-#include "meta/prefs.h"
-#include "meta/window.h"
-#include "x11/meta-x11-display-private.h"
-
-#ifdef HAVE_WAYLAND
-#include "compositor/meta-window-actor-wayland.h"
-#include "wayland/meta-wayland-private.h"
-#endif
-
-enum
-{
- PROP_0,
-
- PROP_DISPLAY,
- PROP_BACKEND,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS] = { NULL, };
-
-typedef struct _MetaCompositorPrivate
-{
- GObject parent;
-
- MetaDisplay *display;
- MetaBackend *backend;
-
- gulong stage_presented_id;
- gulong before_paint_handler_id;
- gulong after_paint_handler_id;
-
- int64_t server_time_query_time;
- int64_t server_time_offset;
-
- gboolean server_time_is_monotonic_time;
-
- ClutterActor *window_group;
- ClutterActor *top_window_group;
- ClutterActor *feedback_group;
-
- GList *windows;
-
- CoglContext *context;
-
- MetaWindowActor *top_window_actor;
- gulong top_window_actor_destroy_id;
-
- int disable_unredirect_count;
-
- int switch_workspace_in_progress;
-
- MetaPluginManager *plugin_mgr;
-
- MetaLaters *laters;
-} MetaCompositorPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor,
- G_TYPE_OBJECT)
-
-static void
-on_presented (ClutterStage *stage,
- ClutterStageView *stage_view,
- ClutterFrameInfo *frame_info,
- MetaCompositor *compositor);
-
-static void
-on_top_window_actor_destroyed (MetaWindowActor *window_actor,
- MetaCompositor *compositor);
-
-static gboolean
-is_modal (MetaDisplay *display)
-{
- return display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB;
-}
-
-static void sync_actor_stacking (MetaCompositor *compositor);
-
-static void
-meta_finish_workspace_switch (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- GList *l;
-
- /* Finish hiding and showing actors for the new workspace */
- for (l = priv->windows; l; l = l->next)
- meta_window_actor_sync_visibility (l->data);
-
- /* Fix up stacking order. */
- sync_actor_stacking (compositor);
-}
-
-void
-meta_switch_workspace_completed (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- /* FIXME -- must redo stacking order */
- priv->switch_workspace_in_progress--;
- if (priv->switch_workspace_in_progress < 0)
- {
- g_warning ("Error in workspace_switch accounting!");
- priv->switch_workspace_in_progress = 0;
- }
-
- if (!priv->switch_workspace_in_progress)
- meta_finish_workspace_switch (compositor);
-}
-
-void
-meta_compositor_destroy (MetaCompositor *compositor)
-{
- g_object_run_dispose (G_OBJECT (compositor));
- g_object_unref (compositor);
-}
-
-/* compat helper */
-static MetaCompositor *
-get_compositor_for_display (MetaDisplay *display)
-{
- return display->compositor;
-}
-
-/**
- * meta_get_stage_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The #ClutterStage for the display
- */
-ClutterActor *
-meta_get_stage_for_display (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- g_return_val_if_fail (display, NULL);
-
- compositor = get_compositor_for_display (display);
- g_return_val_if_fail (compositor, NULL);
- priv = meta_compositor_get_instance_private (compositor);
-
- return meta_backend_get_stage (priv->backend);
-}
-
-/**
- * meta_get_window_group_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The window group corresponding to @display
- */
-ClutterActor *
-meta_get_window_group_for_display (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- g_return_val_if_fail (display, NULL);
-
- compositor = get_compositor_for_display (display);
- g_return_val_if_fail (compositor, NULL);
- priv = meta_compositor_get_instance_private (compositor);
-
- return priv->window_group;
-}
-
-/**
- * meta_get_top_window_group_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The top window group corresponding to @display
- */
-ClutterActor *
-meta_get_top_window_group_for_display (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- g_return_val_if_fail (display, NULL);
-
- compositor = get_compositor_for_display (display);
- g_return_val_if_fail (compositor, NULL);
- priv = meta_compositor_get_instance_private (compositor);
-
- return priv->top_window_group;
-}
-
-/**
- * meta_get_feedback_group_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The feedback group corresponding to @display
- */
-ClutterActor *
-meta_get_feedback_group_for_display (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- g_return_val_if_fail (display, NULL);
-
- compositor = get_compositor_for_display (display);
- g_return_val_if_fail (compositor, NULL);
- priv = meta_compositor_get_instance_private (compositor);
-
- return priv->feedback_group;
-}
-
-/**
- * meta_get_window_actors:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none) (element-type Clutter.Actor): The set of #MetaWindowActor on @display
- */
-GList *
-meta_get_window_actors (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- g_return_val_if_fail (display, NULL);
-
- compositor = get_compositor_for_display (display);
- g_return_val_if_fail (compositor, NULL);
- priv = meta_compositor_get_instance_private (compositor);
-
- return priv->windows;
-}
-
-void
-meta_focus_stage_window (MetaDisplay *display,
- guint32 timestamp)
-{
- ClutterStage *stage;
- Window window;
-
- stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
- if (!stage)
- return;
-
- window = meta_x11_get_stage_window (stage);
-
- if (window == None)
- return;
-
- meta_x11_display_set_input_focus_xwindow (display->x11_display,
- window,
- timestamp);
-}
-
-gboolean
-meta_stage_is_focused (MetaDisplay *display)
-{
- ClutterStage *stage;
- Window window;
-
- if (meta_is_wayland_compositor ())
- return TRUE;
-
- stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
- if (!stage)
- return FALSE;
-
- window = meta_x11_get_stage_window (stage);
-
- if (window == None)
- return FALSE;
-
- return (display->x11_display->focus_xwindow == window);
-}
-
-static gboolean
-grab_devices (MetaModalOptions options,
- guint32 timestamp)
-{
- MetaBackend *backend = META_BACKEND (meta_get_backend ());
- gboolean pointer_grabbed = FALSE;
- gboolean keyboard_grabbed = FALSE;
-
- if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
- {
- if (!meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
- goto fail;
-
- pointer_grabbed = TRUE;
- }
-
- if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
- {
- if (!meta_backend_grab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp))
- goto fail;
-
- keyboard_grabbed = TRUE;
- }
-
- return TRUE;
-
- fail:
- if (pointer_grabbed)
- meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
- if (keyboard_grabbed)
- meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
-
- return FALSE;
-}
-
-static void
-meta_compositor_grab_begin (MetaCompositor *compositor)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->grab_begin (compositor);
-}
-
-static void
-meta_compositor_grab_end (MetaCompositor *compositor)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor);
-}
-
-gboolean
-meta_begin_modal_for_plugin (MetaCompositor *compositor,
- MetaPlugin *plugin,
- MetaModalOptions options,
- guint32 timestamp)
-{
- /* To some extent this duplicates code in meta_display_begin_grab_op(), but there
- * are significant differences in how we handle grabs that make it difficult to
- * merge the two.
- */
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaDisplay *display = priv->display;
-
-#ifdef HAVE_WAYLAND
- if (display->grab_op == META_GRAB_OP_WAYLAND_POPUP)
- {
- MetaWaylandSeat *seat = meta_wayland_compositor_get_default ()->seat;
- meta_wayland_pointer_end_popup_grab (seat->pointer);
- }
-#endif
-
- if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE)
- return FALSE;
-
- if (display->x11_display)
- {
- /* XXX: why is this needed? */
- XIUngrabDevice (display->x11_display->xdisplay,
- META_VIRTUAL_CORE_POINTER_ID,
- timestamp);
- XSync (display->x11_display->xdisplay, False);
- }
-
- if (!grab_devices (options, timestamp))
- return FALSE;
-
- display->grab_op = META_GRAB_OP_COMPOSITOR;
- display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB;
- display->grab_window = NULL;
- display->grab_have_pointer = TRUE;
- display->grab_have_keyboard = TRUE;
-
- g_signal_emit_by_name (display, "grab-op-begin",
- display->grab_window, display->grab_op);
-
- meta_compositor_grab_begin (compositor);
-
- return TRUE;
-}
-
-void
-meta_end_modal_for_plugin (MetaCompositor *compositor,
- MetaPlugin *plugin,
- guint32 timestamp)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaDisplay *display = priv->display;
- MetaBackend *backend = meta_get_backend ();
- MetaWindow *grab_window = display->grab_window;
- MetaGrabOp grab_op = display->grab_op;
-
- g_return_if_fail (is_modal (display));
-
- display->grab_op = META_GRAB_OP_NONE;
- display->event_route = META_EVENT_ROUTE_NORMAL;
- display->grab_window = NULL;
- display->grab_have_pointer = FALSE;
- display->grab_have_keyboard = FALSE;
-
- meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
- meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
-
- meta_compositor_grab_end (compositor);
-
- g_signal_emit_by_name (display, "grab-op-end",
- grab_window, grab_op);
-}
-
-static void
-redirect_windows (MetaX11Display *x11_display)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaContext *context = meta_backend_get_context (backend);
- Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
- Window xroot = meta_x11_display_get_xroot (x11_display);
- int screen_number = meta_x11_display_get_screen_number (x11_display);
- guint n_retries;
- guint max_retries;
-
- if (meta_context_is_replacing (context))
- max_retries = 5;
- else
- max_retries = 1;
-
- n_retries = 0;
-
- /* Some compositors (like old versions of Mutter) might not properly unredirect
- * subwindows before destroying the WM selection window; so we wait a while
- * for such a compositor to exit before giving up.
- */
- while (TRUE)
- {
- meta_x11_error_trap_push (x11_display);
- XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
- XSync (xdisplay, FALSE);
-
- if (!meta_x11_error_trap_pop_with_return (x11_display))
- break;
-
- if (n_retries == max_retries)
- {
- /* This probably means that a non-WM compositor like xcompmgr is running;
- * we have no way to get it to exit */
- meta_fatal (_("Another compositing manager is already running on screen %i on display “%s”."),
- screen_number, x11_display->name);
- }
-
- n_retries++;
- g_usleep (G_USEC_PER_SEC);
- }
-}
-
-void
-meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaDisplay *display = priv->display;
-
- if (display->x11_display)
- redirect_windows (display->x11_display);
-}
-
-gboolean
-meta_compositor_do_manage (MetaCompositor *compositor,
- GError **error)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaDisplay *display = priv->display;
- MetaBackend *backend = priv->backend;
- ClutterActor *stage = meta_backend_get_stage (backend);
-
- priv->stage_presented_id =
- g_signal_connect (stage, "presented",
- G_CALLBACK (on_presented),
- compositor);
-
- priv->window_group = meta_window_group_new (display);
- priv->top_window_group = meta_window_group_new (display);
- priv->feedback_group = meta_window_group_new (display);
-
- clutter_actor_add_child (stage, priv->window_group);
- clutter_actor_add_child (stage, priv->top_window_group);
- clutter_actor_add_child (stage, priv->feedback_group);
-
- if (!META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor, error))
- return FALSE;
-
- priv->plugin_mgr = meta_plugin_manager_new (compositor);
-
- return TRUE;
-}
-
-void
-meta_compositor_manage (MetaCompositor *compositor)
-{
- GError *error = NULL;
-
- if (!meta_compositor_do_manage (compositor, &error))
- g_error ("Compositor failed to manage display: %s", error->message);
-}
-
-void
-meta_compositor_unmanage (MetaCompositor *compositor)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->unmanage (compositor);
-}
-
-void
-meta_compositor_add_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *window_actor;
- ClutterActor *window_group;
- GType window_actor_type = G_TYPE_INVALID;
-
- switch (window->client_type)
- {
- case META_WINDOW_CLIENT_TYPE_X11:
- window_actor_type = META_TYPE_WINDOW_ACTOR_X11;
- break;
-
-#ifdef HAVE_WAYLAND
- case META_WINDOW_CLIENT_TYPE_WAYLAND:
- window_actor_type = META_TYPE_WINDOW_ACTOR_WAYLAND;
- break;
-#endif
-
- default:
- g_return_if_reached ();
- }
-
- window_actor = g_object_new (window_actor_type,
- "meta-window", window,
- "show-on-set-parent", FALSE,
- NULL);
-
- if (window->layer == META_LAYER_OVERRIDE_REDIRECT)
- window_group = priv->top_window_group;
- else
- window_group = priv->window_group;
-
- clutter_actor_add_child (window_group, CLUTTER_ACTOR (window_actor));
-
- /* Initial position in the stack is arbitrary; stacking will be synced
- * before we first paint.
- */
- priv->windows = g_list_append (priv->windows, window_actor);
- sync_actor_stacking (compositor);
-}
-
-static void
-meta_compositor_real_remove_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_queue_destroy (window_actor);
-}
-
-void
-meta_compositor_remove_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->remove_window (compositor, window);
-}
-
-void
-meta_compositor_remove_window_actor (MetaCompositor *compositor,
- MetaWindowActor *window_actor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- priv->windows = g_list_remove (priv->windows, window_actor);
-}
-
-void
-meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_sync_updates_frozen (window_actor);
-}
-
-void
-meta_compositor_queue_frame_drawn (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean no_delay_frame)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_queue_frame_drawn (window_actor, no_delay_frame);
-}
-
-void
-meta_compositor_window_shape_changed (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor;
-
- window_actor = meta_window_actor_from_window (window);
- if (!window_actor)
- return;
-
- meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor));
-}
-
-void
-meta_compositor_window_opacity_changed (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor;
-
- window_actor = meta_window_actor_from_window (window);
- if (!window_actor)
- return;
-
- meta_window_actor_update_opacity (window_actor);
-}
-
-gboolean
-meta_compositor_filter_keybinding (MetaCompositor *compositor,
- MetaKeyBinding *binding)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return meta_plugin_manager_filter_keybinding (priv->plugin_mgr, binding);
-}
-
-void
-meta_compositor_show_window (MetaCompositor *compositor,
- MetaWindow *window,
- MetaCompEffect effect)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_show (window_actor, effect);
-}
-
-void
-meta_compositor_hide_window (MetaCompositor *compositor,
- MetaWindow *window,
- MetaCompEffect effect)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_hide (window_actor, effect);
- meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker);
-}
-
-void
-meta_compositor_size_change_window (MetaCompositor *compositor,
- MetaWindow *window,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_size_change (window_actor, which_change, old_frame_rect, old_buffer_rect);
-}
-
-void
-meta_compositor_switch_workspace (MetaCompositor *compositor,
- MetaWorkspace *from,
- MetaWorkspace *to,
- MetaMotionDirection direction)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- gint to_indx, from_indx;
-
- to_indx = meta_workspace_index (to);
- from_indx = meta_workspace_index (from);
-
- priv->switch_workspace_in_progress++;
-
- if (!meta_plugin_manager_switch_workspace (priv->plugin_mgr,
- from_indx,
- to_indx,
- direction))
- {
- priv->switch_workspace_in_progress--;
-
- /* We have to explicitly call this to fix up stacking order of the
- * actors; this is because the abs stacking position of actors does not
- * necessarily change during the window hiding/unhiding, only their
- * relative position toward the destkop window.
- */
- meta_finish_workspace_switch (compositor);
- }
-}
-
-static void
-sync_actor_stacking (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- GList *children;
- GList *expected_window_node;
- GList *tmp;
- GList *old;
- GList *backgrounds;
- gboolean has_windows;
- gboolean reordered;
-
- /* NB: The first entries in the lists are stacked the lowest */
-
- /* Restacking will trigger full screen redraws, so it's worth a
- * little effort to make sure we actually need to restack before
- * we go ahead and do it */
-
- children = clutter_actor_get_children (priv->window_group);
- has_windows = FALSE;
- reordered = FALSE;
-
- /* We allow for actors in the window group other than the actors we
- * know about, but it's up to a plugin to try and keep them stacked correctly
- * (we really need extra API to make that reliable.)
- */
-
- /* First we collect a list of all backgrounds, and check if they're at the
- * bottom. Then we check if the window actors are in the correct sequence */
- backgrounds = NULL;
- expected_window_node = priv->windows;
- for (old = children; old != NULL; old = old->next)
- {
- ClutterActor *actor = old->data;
-
- if (META_IS_BACKGROUND_GROUP (actor) ||
- META_IS_BACKGROUND_ACTOR (actor))
- {
- backgrounds = g_list_prepend (backgrounds, actor);
-
- if (has_windows)
- reordered = TRUE;
- }
- else if (META_IS_WINDOW_ACTOR (actor) && !reordered)
- {
- has_windows = TRUE;
-
- if (expected_window_node != NULL && actor == expected_window_node->data)
- expected_window_node = expected_window_node->next;
- else
- reordered = TRUE;
- }
- }
-
- g_list_free (children);
-
- if (!reordered)
- {
- g_list_free (backgrounds);
- return;
- }
-
- /* reorder the actors by lowering them in turn to the bottom of the stack.
- * windows first, then background.
- *
- * We reorder the actors even if they're not parented to the window group,
- * to allow stacking to work with intermediate actors (eg during effects)
- */
- for (tmp = g_list_last (priv->windows); tmp != NULL; tmp = tmp->prev)
- {
- ClutterActor *actor = tmp->data, *parent;
-
- parent = clutter_actor_get_parent (actor);
- clutter_actor_set_child_below_sibling (parent, actor, NULL);
- }
-
- /* we prepended the backgrounds above so the last actor in the list
- * should get lowered to the bottom last.
- */
- for (tmp = backgrounds; tmp != NULL; tmp = tmp->next)
- {
- ClutterActor *actor = tmp->data, *parent;
-
- parent = clutter_actor_get_parent (actor);
- clutter_actor_set_child_below_sibling (parent, actor, NULL);
- }
- g_list_free (backgrounds);
-}
-
-/*
- * Find the top most window that is visible on the screen. The intention of
- * this is to avoid offscreen windows that isn't actually part of the visible
- * desktop (such as the UI frames override redirect window).
- */
-static MetaWindowActor *
-get_top_visible_window_actor (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- GList *l;
-
- for (l = g_list_last (priv->windows); l; l = l->prev)
- {
- MetaWindowActor *window_actor = l->data;
- MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
- MetaRectangle buffer_rect;
- MetaRectangle display_rect = { 0 };
-
- if (!window->visible_to_compositor)
- continue;
-
- meta_window_get_buffer_rect (window, &buffer_rect);
- meta_display_get_size (priv->display,
- &display_rect.width, &display_rect.height);
-
- if (meta_rectangle_overlap (&display_rect, &buffer_rect))
- return window_actor;
- }
-
- return NULL;
-}
-
-static void
-on_top_window_actor_destroyed (MetaWindowActor *window_actor,
- MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- priv->top_window_actor = NULL;
- priv->top_window_actor_destroy_id = 0;
- priv->windows = g_list_remove (priv->windows, window_actor);
-
- meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker);
-}
-
-void
-meta_compositor_sync_stack (MetaCompositor *compositor,
- GList *stack)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *top_window_actor;
- GList *old_stack;
-
- /* This is painful because hidden windows that we are in the process
- * of animating out of existence. They'll be at the bottom of the
- * stack of X windows, but we want to leave them in their old position
- * until the animation effect finishes.
- */
-
- /* Sources: first window is the highest */
- stack = g_list_copy (stack); /* The new stack of MetaWindow */
- old_stack = g_list_reverse (priv->windows); /* The old stack of MetaWindowActor */
- priv->windows = NULL;
-
- while (TRUE)
- {
- MetaWindowActor *old_actor = NULL, *stack_actor = NULL, *actor;
- MetaWindow *old_window = NULL, *stack_window = NULL, *window;
-
- /* Find the remaining top actor in our existing stack (ignoring
- * windows that have been hidden and are no longer animating) */
- while (old_stack)
- {
- old_actor = old_stack->data;
- old_window = meta_window_actor_get_meta_window (old_actor);
-
- if ((old_window->hidden || old_window->unmanaging) &&
- !meta_window_actor_effect_in_progress (old_actor))
- {
- old_stack = g_list_delete_link (old_stack, old_stack);
- old_actor = NULL;
- }
- else
- break;
- }
-
- /* And the remaining top actor in the new stack */
- while (stack)
- {
- stack_window = stack->data;
- stack_actor = meta_window_actor_from_window (stack_window);
- if (!stack_actor)
- {
- meta_verbose ("Failed to find corresponding MetaWindowActor "
- "for window %s", meta_window_get_description (stack_window));
- stack = g_list_delete_link (stack, stack);
- }
- else
- break;
- }
-
- if (!old_actor && !stack_actor) /* Nothing more to stack */
- break;
-
- /* We usually prefer the window in the new stack, but if if we
- * found a hidden window in the process of being animated out
- * of existence in the old stack we use that instead. We've
- * filtered out non-animating hidden windows above.
- */
- if (old_actor &&
- (!stack_actor || old_window->hidden || old_window->unmanaging))
- {
- actor = old_actor;
- window = old_window;
- }
- else
- {
- actor = stack_actor;
- window = stack_window;
- }
-
- /* OK, we know what actor we want next. Add it to our window
- * list, and remove it from both source lists. (It will
- * be at the front of at least one, hopefully it will be
- * near the front of the other.)
- */
- priv->windows = g_list_prepend (priv->windows, actor);
-
- stack = g_list_remove (stack, window);
- old_stack = g_list_remove (old_stack, actor);
- }
-
- sync_actor_stacking (compositor);
-
- top_window_actor = get_top_visible_window_actor (compositor);
-
- if (priv->top_window_actor == top_window_actor)
- return;
-
- g_clear_signal_handler (&priv->top_window_actor_destroy_id,
- priv->top_window_actor);
-
- priv->top_window_actor = top_window_actor;
-
- if (priv->top_window_actor)
- priv->top_window_actor_destroy_id =
- g_signal_connect (priv->top_window_actor, "destroy",
- G_CALLBACK (on_top_window_actor_destroyed),
- compositor);
-}
-
-void
-meta_compositor_sync_window_geometry (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean did_placement)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
- MetaWindowActorChanges changes;
-
- changes = meta_window_actor_sync_actor_geometry (window_actor, did_placement);
-
- if (changes & META_WINDOW_ACTOR_CHANGE_SIZE)
- meta_plugin_manager_event_size_changed (priv->plugin_mgr, window_actor);
-}
-
-static void
-on_presented (ClutterStage *stage,
- ClutterStageView *stage_view,
- ClutterFrameInfo *frame_info,
- MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- int64_t presentation_time = frame_info->presentation_time;
- GList *l;
-
- for (l = priv->windows; l; l = l->next)
- {
- ClutterActor *actor = l->data;
- GList *actor_stage_views;
-
- actor_stage_views = clutter_actor_peek_stage_views (actor);
- if (g_list_find (actor_stage_views, stage_view))
- {
- meta_window_actor_frame_complete (META_WINDOW_ACTOR (actor),
- frame_info,
- presentation_time);
- }
- }
-}
-
-static void
-meta_compositor_real_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- GList *l;
-
- for (l = priv->windows; l; l = l->next)
- meta_window_actor_before_paint (l->data, stage_view);
-}
-
-static void
-meta_compositor_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
- "Compositor (before-paint)");
- META_COMPOSITOR_GET_CLASS (compositor)->before_paint (compositor, stage_view);
-}
-
-static void
-meta_compositor_real_after_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- ClutterActor *stage_actor = meta_backend_get_stage (priv->backend);
- CoglGraphicsResetStatus status;
- GList *l;
-
- status = cogl_get_graphics_reset_status (priv->context);
- switch (status)
- {
- case COGL_GRAPHICS_RESET_STATUS_NO_ERROR:
- break;
-
- case COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET:
- g_signal_emit_by_name (priv->display, "gl-video-memory-purged");
- g_signal_emit_by_name (stage_actor, "gl-video-memory-purged");
- clutter_actor_queue_redraw (stage_actor);
- break;
-
- default:
- /* The ARB_robustness spec says that, on error, the application
- should destroy the old context and create a new one. Since we
- don't have the necessary plumbing to do this we'll simply
- restart the process. Obviously we can't do this when we are
- a wayland compositor but in that case we shouldn't get here
- since we don't enable robustness in that case. */
- g_assert (!meta_is_wayland_compositor ());
- meta_restart (NULL);
- break;
- }
-
- for (l = priv->windows; l; l = l->next)
- {
- ClutterActor *actor = l->data;
- GList *actor_stage_views;
-
- actor_stage_views = clutter_actor_peek_stage_views (actor);
- if (g_list_find (actor_stage_views, stage_view))
- meta_window_actor_after_paint (META_WINDOW_ACTOR (actor), stage_view);
- }
-}
-
-static void
-meta_compositor_after_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- COGL_TRACE_BEGIN_SCOPED (MetaCompositorPostPaint,
- "Compositor (after-paint)");
- META_COMPOSITOR_GET_CLASS (compositor)->after_paint (compositor, stage_view);
-}
-
-static void
-on_before_paint (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- meta_compositor_before_paint (compositor, stage_view);
-}
-
-static void
-on_after_paint (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- meta_compositor_after_paint (compositor, stage_view);
-}
-
-static void
-meta_compositor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- switch (prop_id)
- {
- case PROP_DISPLAY:
- priv->display = g_value_get_object (value);
- break;
- case PROP_BACKEND:
- priv->backend = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_compositor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- switch (prop_id)
- {
- case PROP_DISPLAY:
- g_value_set_object (value, priv->display);
- break;
- case PROP_BACKEND:
- g_value_set_object (value, priv->backend);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_compositor_init (MetaCompositor *compositor)
-{
-}
-
-static void
-meta_compositor_constructed (GObject *object)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- ClutterBackend *clutter_backend =
- meta_backend_get_clutter_backend (priv->backend);
- ClutterActor *stage = meta_backend_get_stage (priv->backend);
-
- priv->context = clutter_backend->cogl_context;
-
- priv->before_paint_handler_id =
- g_signal_connect (stage,
- "before-paint",
- G_CALLBACK (on_before_paint),
- compositor);
- priv->after_paint_handler_id =
- g_signal_connect_after (stage,
- "after-paint",
- G_CALLBACK (on_after_paint),
- compositor);
-
- priv->laters = meta_laters_new (compositor);
-
- G_OBJECT_CLASS (meta_compositor_parent_class)->constructed (object);
-}
-
-static void
-meta_compositor_dispose (GObject *object)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- ClutterActor *stage = meta_backend_get_stage (priv->backend);
-
- g_clear_pointer (&priv->laters, meta_laters_free);
-
- g_clear_signal_handler (&priv->stage_presented_id, stage);
- g_clear_signal_handler (&priv->before_paint_handler_id, stage);
- g_clear_signal_handler (&priv->after_paint_handler_id, stage);
-
- g_clear_signal_handler (&priv->top_window_actor_destroy_id,
- priv->top_window_actor);
-
- g_clear_pointer (&priv->window_group, clutter_actor_destroy);
- g_clear_pointer (&priv->top_window_group, clutter_actor_destroy);
- g_clear_pointer (&priv->feedback_group, clutter_actor_destroy);
- g_clear_pointer (&priv->windows, g_list_free);
-
- G_OBJECT_CLASS (meta_compositor_parent_class)->dispose (object);
-}
-
-static void
-meta_compositor_class_init (MetaCompositorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = meta_compositor_set_property;
- object_class->get_property = meta_compositor_get_property;
- object_class->constructed = meta_compositor_constructed;
- object_class->dispose = meta_compositor_dispose;
-
- klass->remove_window = meta_compositor_real_remove_window;
- klass->before_paint = meta_compositor_real_before_paint;
- klass->after_paint = meta_compositor_real_after_paint;
-
- obj_props[PROP_DISPLAY] =
- g_param_spec_object ("display",
- "display",
- "MetaDisplay",
- META_TYPE_DISPLAY,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_BACKEND] =
- g_param_spec_object ("backend",
- "backend",
- "MetaBackend",
- META_TYPE_BACKEND,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-}
-
-/**
- * meta_disable_unredirect_for_display:
- * @display: a #MetaDisplay
- *
- * Disables unredirection, can be useful in situations where having
- * unredirected windows is undesirable like when recording a video.
- *
- */
-void
-meta_disable_unredirect_for_display (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- if (display->closing)
- return;
-
- compositor = get_compositor_for_display (display);
- priv = meta_compositor_get_instance_private (compositor);
-
- priv->disable_unredirect_count++;
-}
-
-/**
- * meta_enable_unredirect_for_display:
- * @display: a #MetaDisplay
- *
- * Enables unredirection which reduces the overhead for apps like games.
- *
- */
-void
-meta_enable_unredirect_for_display (MetaDisplay *display)
-{
- MetaCompositor *compositor;
- MetaCompositorPrivate *priv;
-
- if (display->closing)
- return;
-
- compositor = get_compositor_for_display (display);
- priv = meta_compositor_get_instance_private (compositor);
-
- if (priv->disable_unredirect_count == 0)
- g_warning ("Called enable_unredirect_for_display while unredirection is enabled.");
- if (priv->disable_unredirect_count > 0)
- priv->disable_unredirect_count--;
-}
-
-gboolean
-meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->disable_unredirect_count > 0;
-}
-
-#define FLASH_TIME_MS 50
-
-static void
-flash_out_completed (ClutterTimeline *timeline,
- gboolean is_finished,
- gpointer user_data)
-{
- ClutterActor *flash = CLUTTER_ACTOR (user_data);
- clutter_actor_destroy (flash);
-}
-
-void
-meta_compositor_flash_display (MetaCompositor *compositor,
- MetaDisplay *display)
-{
- ClutterActor *stage;
- ClutterActor *flash;
- ClutterTransition *transition;
- gfloat width, height;
-
- stage = meta_get_stage_for_display (display);
- clutter_actor_get_size (stage, &width, &height);
-
- flash = clutter_actor_new ();
- clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black);
- clutter_actor_set_size (flash, width, height);
- clutter_actor_set_opacity (flash, 0);
- clutter_actor_add_child (stage, flash);
-
- clutter_actor_save_easing_state (flash);
- clutter_actor_set_easing_mode (flash, CLUTTER_EASE_IN_QUAD);
- clutter_actor_set_easing_duration (flash, FLASH_TIME_MS);
- clutter_actor_set_opacity (flash, 192);
-
- transition = clutter_actor_get_transition (flash, "opacity");
- clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE);
- clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2);
-
- g_signal_connect (transition, "stopped",
- G_CALLBACK (flash_out_completed), flash);
-
- clutter_actor_restore_easing_state (flash);
-}
-
-static void
-window_flash_out_completed (ClutterTimeline *timeline,
- gboolean is_finished,
- gpointer user_data)
-{
- ClutterActor *flash = CLUTTER_ACTOR (user_data);
- clutter_actor_destroy (flash);
-}
-
-void
-meta_compositor_flash_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- ClutterActor *window_actor =
- CLUTTER_ACTOR (meta_window_actor_from_window (window));
- ClutterActor *flash;
- ClutterTransition *transition;
-
- flash = clutter_actor_new ();
- clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black);
- clutter_actor_set_size (flash, window->rect.width, window->rect.height);
- clutter_actor_set_position (flash,
- window->custom_frame_extents.left,
- window->custom_frame_extents.top);
- clutter_actor_set_opacity (flash, 0);
- clutter_actor_add_child (window_actor, flash);
-
- clutter_actor_save_easing_state (flash);
- clutter_actor_set_easing_mode (flash, CLUTTER_EASE_IN_QUAD);
- clutter_actor_set_easing_duration (flash, FLASH_TIME_MS);
- clutter_actor_set_opacity (flash, 192);
-
- transition = clutter_actor_get_transition (flash, "opacity");
- clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE);
- clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2);
-
- g_signal_connect (transition, "stopped",
- G_CALLBACK (window_flash_out_completed), flash);
-
- clutter_actor_restore_easing_state (flash);
-}
-
-/**
- * meta_compositor_monotonic_to_high_res_xserver_time:
- * @display: a #MetaDisplay
- * @monotonic_time: time in the units of g_get_monotonic_time()
- *
- * _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages represent time
- * as a "high resolution server time" - this is the server time interpolated
- * to microsecond resolution. The advantage of this time representation
- * is that if X server is running on the same computer as a client, and
- * the Xserver uses 'clock_gettime(CLOCK_MONOTONIC, ...)' for the server
- * time, the client can detect this, and all such clients will share a
- * a time representation with high accuracy. If there is not a common
- * time source, then the time synchronization will be less accurate.
- */
-int64_t
-meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
- int64_t monotonic_time_us)
-{
- MetaCompositorClass *klass = META_COMPOSITOR_GET_CLASS (compositor);
-
- return klass->monotonic_to_high_res_xserver_time (compositor, monotonic_time_us);
-}
-
-void
-meta_compositor_show_tile_preview (MetaCompositor *compositor,
- MetaWindow *window,
- MetaRectangle *tile_rect,
- int tile_monitor_number)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- meta_plugin_manager_show_tile_preview (priv->plugin_mgr,
- window, tile_rect, tile_monitor_number);
-}
-
-void
-meta_compositor_hide_tile_preview (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- meta_plugin_manager_hide_tile_preview (priv->plugin_mgr);
-}
-
-void
-meta_compositor_show_window_menu (MetaCompositor *compositor,
- MetaWindow *window,
- MetaWindowMenuType menu,
- int x,
- int y)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- meta_plugin_manager_show_window_menu (priv->plugin_mgr, window, menu, x, y);
-}
-
-void
-meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
- MetaWindow *window,
- MetaWindowMenuType menu,
- MetaRectangle *rect)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- meta_plugin_manager_show_window_menu_for_rect (priv->plugin_mgr, window, menu, rect);
-}
-
-MetaCloseDialog *
-meta_compositor_create_close_dialog (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return meta_plugin_manager_create_close_dialog (priv->plugin_mgr,
- window);
-}
-
-MetaInhibitShortcutsDialog *
-meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return meta_plugin_manager_create_inhibit_shortcuts_dialog (priv->plugin_mgr,
- window);
-}
-
-void
-meta_compositor_locate_pointer (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- meta_plugin_manager_locate_pointer (priv->plugin_mgr);
-}
-
-MetaPluginManager *
-meta_compositor_get_plugin_manager (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->plugin_mgr;
-}
-
-MetaDisplay *
-meta_compositor_get_display (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->display;
-}
-
-ClutterStage *
-meta_compositor_get_stage (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return CLUTTER_STAGE (meta_backend_get_stage (priv->backend));
-}
-
-MetaWindowActor *
-meta_compositor_get_top_window_actor (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->top_window_actor;
-}
-
-gboolean
-meta_compositor_is_switching_workspace (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->switch_workspace_in_progress > 0;
-}
-
-MetaLaters *
-meta_compositor_get_laters (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->laters;
-}
diff --git a/src/compositor/meta-background-actor-private.h b/src/compositor/meta-background-actor-private.h
deleted file mode 100644
index bdf8c4744..000000000
--- a/src/compositor/meta-background-actor-private.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_BACKGROUND_ACTOR_PRIVATE_H
-#define META_BACKGROUND_ACTOR_PRIVATE_H
-
-#include "meta/meta-background-actor.h"
-
-cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self);
-
-#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c
deleted file mode 100644
index 105f94259..000000000
--- a/src/compositor/meta-background-actor.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright 2009 Sander Dijkhuis
- * Copyright 2014 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Portions adapted from gnome-shell/src/shell-global.c
- */
-
-#include "config.h"
-
-#include "compositor/meta-background-actor-private.h"
-#include "compositor/meta-background-content-private.h"
-
-#include "compositor/meta-cullable.h"
-
-enum
-{
- PROP_META_DISPLAY = 1,
- PROP_MONITOR,
-};
-
-struct _MetaBackgroundActor
-{
- ClutterActor parent;
-
- MetaDisplay *display;
- int monitor;
-
- MetaBackgroundContent *content;
-};
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
-
-static void
-maybe_create_content (MetaBackgroundActor *self)
-{
- g_autoptr (ClutterContent) content = NULL;
-
- if (self->content || !self->display || self->monitor == -1)
- return;
-
- content = meta_background_content_new (self->display, self->monitor);
- self->content = META_BACKGROUND_CONTENT (content);
- clutter_actor_set_content (CLUTTER_ACTOR (self), content);
-}
-
-static void
-meta_background_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- self->display = g_value_get_object (value);
- maybe_create_content (self);
- break;
- case PROP_MONITOR:
- self->monitor = g_value_get_int (value);
- maybe_create_content (self);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- g_value_set_object (value, self->display);
- break;
- case PROP_MONITOR:
- g_value_set_int (value, self->monitor);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_actor_class_init (MetaBackgroundActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- object_class->set_property = meta_background_actor_set_property;
- object_class->get_property = meta_background_actor_get_property;
-
- param_spec = g_param_spec_object ("meta-display",
- "MetaDisplay",
- "MetaDisplay",
- META_TYPE_DISPLAY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_META_DISPLAY,
- param_spec);
-
- param_spec = g_param_spec_int ("monitor",
- "monitor",
- "monitor",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_MONITOR,
- param_spec);
-}
-
-static void
-meta_background_actor_init (MetaBackgroundActor *self)
-{
- self->monitor = -1;
-
- clutter_actor_set_request_mode (CLUTTER_ACTOR (self),
- CLUTTER_REQUEST_CONTENT_SIZE);
-}
-
-/**
- * meta_background_actor_new:
- * @monitor: Index of the monitor for which to draw the background
- *
- * Creates a new actor to draw the background for the given monitor.
- *
- * Return value: the newly created background actor
- */
-ClutterActor *
-meta_background_actor_new (MetaDisplay *display,
- int monitor)
-{
- MetaBackgroundActor *self;
-
- self = g_object_new (META_TYPE_BACKGROUND_ACTOR,
- "meta-display", display,
- "monitor", monitor,
- NULL);
-
- return CLUTTER_ACTOR (self);
-}
-
-static void
-meta_background_actor_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
-
- if (!self->content)
- return;
-
- meta_background_content_cull_out (self->content,
- unobscured_region,
- clip_region);
-}
-
-static void
-meta_background_actor_reset_culling (MetaCullable *cullable)
-{
- MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
-
- if (!self->content)
- return;
-
- meta_background_content_reset_culling (self->content);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_background_actor_cull_out;
- iface->reset_culling = meta_background_actor_reset_culling;
-}
-
-/**
- * meta_background_actor_get_clip_region:
- * @self: a #MetaBackgroundActor
- *
- * Return value (transfer none): a #cairo_region_t that represents the part of
- * the background not obscured by other #MetaBackgroundActor or
- * #MetaWindowActor objects.
- */
-cairo_region_t *
-meta_background_actor_get_clip_region (MetaBackgroundActor *self)
-{
- if (!self->content)
- return NULL;
-
- return meta_background_content_get_clip_region (self->content);
-}
diff --git a/src/compositor/meta-background-content-private.h b/src/compositor/meta-background-content-private.h
deleted file mode 100644
index 284cddb3a..000000000
--- a/src/compositor/meta-background-content-private.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_BACKGROUND_CONTENT_PRIVATE_H
-#define META_BACKGROUND_CONTENT_PRIVATE_H
-
-#include "meta/meta-background-content.h"
-
-cairo_region_t *meta_background_content_get_clip_region (MetaBackgroundContent *self);
-
-void meta_background_content_cull_out (MetaBackgroundContent *self,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region);
-
-void meta_background_content_reset_culling (MetaBackgroundContent *self);
-
-#endif /* META_BACKGROUND_CONTENT_PRIVATE_H */
diff --git a/src/compositor/meta-background-content.c b/src/compositor/meta-background-content.c
deleted file mode 100644
index 86f777752..000000000
--- a/src/compositor/meta-background-content.c
+++ /dev/null
@@ -1,1312 +0,0 @@
-/*
- * Copyright 2009 Sander Dijkhuis
- * Copyright 2014 Red Hat, Inc.
- * Copyright 2020 Endless Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Portions adapted from gnome-shell/src/shell-global.c
- */
-
-
-/**
- * SECTION:meta-background-content
- * @title: MetaBackgroundContent
- * @short_description: ClutterContent for painting the root window background
- *
- */
-
-/*
- * The overall model drawing model of this content is that we have one
- * texture, or two interpolated textures, possibly with alpha or
- * margins that let the underlying background show through, blended
- * over a solid color or a gradient. The result of that combination
- * can then be affected by a "vignette" that darkens the background
- * away from a central point (or as a no-GLSL fallback, simply darkens
- * the background) and by overall opacity.
- *
- * As of GNOME 3.14, GNOME is only using a fraction of this when the
- * user sets the background through the control center - what can be
- * set is:
- *
- * A single image without a border
- * An animation of images without a border that blend together,
- * with the blend changing every 4-5 minutes
- * A solid color with a repeated noise texture blended over it
- *
- * This all is pretty easy to do in a fragment shader, except when:
- *
- * A) We don't have GLSL - in this case, the operation of
- * interpolating the two textures and blending the result over the
- * background can't be expressed with Cogl's fixed-function layer
- * combining (which is confined to what GL's texture environment
- * combining can do) So we can only handle the above directly if
- * there are no margins or alpha.
- *
- * B) The image textures are sliced. Texture size limits on older
- * hardware (pre-965 intel hardware, r300, etc.) is often 2048,
- * and it would be common to use a texture larger than this for a
- * background and expect it to be scaled down. Cogl can compensate
- * for this by breaking the texture up into multiple textures, but
- * can't multitexture with sliced textures. So we can only handle
- * the above if there's a single texture.
- *
- * However, even when we *can* represent everything in a single pass,
- * it's not necessarily efficient. If we want to draw a 1024x768
- * background, it's pretty inefficient to bilinearly texture from
- * two 2560x1440 images and mix that. So the drawing model we take
- * here is that MetaBackground generates a single texture (which
- * might be a 1x1 texture for a solid color, or a 1x2 texture for a
- * gradient, or a repeated texture for wallpaper, or a pre-rendered
- * texture the size of the screen), and we draw with that, possibly
- * adding the vignette and opacity.
- */
-
-#include "config.h"
-
-#include "compositor/meta-background-content-private.h"
-
-#include "backends/meta-backend-private.h"
-#include "clutter/clutter.h"
-#include "compositor/clutter-utils.h"
-#include "compositor/cogl-utils.h"
-#include "compositor/meta-background-private.h"
-#include "compositor/meta-cullable.h"
-#include "meta/display.h"
-
-typedef enum
-{
- CHANGED_BACKGROUND = 1 << 0,
- CHANGED_EFFECTS = 1 << 2,
- CHANGED_VIGNETTE_PARAMETERS = 1 << 3,
- CHANGED_GRADIENT_PARAMETERS = 1 << 4,
- CHANGED_ROUNDED_CLIP_PARAMETERS = 1 << 5,
- CHANGED_ALL = 0xFFFF
-} ChangedFlags;
-
-#define GRADIENT_VERTEX_SHADER_DECLARATIONS \
-"uniform vec2 scale;\n" \
-"varying vec2 position;\n" \
-
-#define GRADIENT_VERTEX_SHADER_CODE \
-"position = cogl_tex_coord0_in.xy * scale;\n" \
-
-#define GRADIENT_FRAGMENT_SHADER_DECLARATIONS \
-"uniform float gradient_height_perc;\n" \
-"uniform float gradient_max_darkness;\n" \
-"varying vec2 position;\n" \
-
-#define GRADIENT_FRAGMENT_SHADER_CODE \
-"float min_brightness = 1.0 - gradient_max_darkness;\n" \
-"float gradient_y_pos = min(position.y, gradient_height_perc) / gradient_height_perc;\n" \
-"float pixel_brightness = (1.0 - min_brightness) * gradient_y_pos + min_brightness;\n" \
-"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
-
-#define VIGNETTE_VERTEX_SHADER_DECLARATIONS \
-"uniform vec2 scale;\n" \
-"uniform vec2 offset;\n" \
-"varying vec2 position;\n" \
-
-#define VIGNETTE_VERTEX_SHADER_CODE \
-"position = cogl_tex_coord0_in.xy * scale + offset;\n" \
-
-#define VIGNETTE_SQRT_2 "1.4142"
-
-#define VIGNETTE_FRAGMENT_SHADER_DECLARATIONS \
-"uniform float vignette_sharpness;\n" \
-"varying vec2 position;\n" \
-"float rand(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453123); }\n" \
-
-#define VIGNETTE_FRAGMENT_SHADER_CODE \
-"float t = " VIGNETTE_SQRT_2 " * length(position);\n" \
-"t = min(t, 1.0);\n" \
-"float pixel_brightness = 1.0 - t * vignette_sharpness;\n" \
-"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
-"cogl_color_out.rgb += (rand(position) - 0.5) / 255.0;\n" \
-
-/* The ellipsis_dist(), ellipsis_coverage() and rounded_rect_coverage() are
- * copied from GSK, see gsk_ellipsis_dist(), gsk_ellipsis_coverage(), and
- * gsk_rounded_rect_coverage() here:
- * https://gitlab.gnome.org/GNOME/gtk/-/blob/4.3.1/gsk/gl/resources/preamble.fs.glsl
- */
-#define ROUNDED_CLIP_FRAGMENT_SHADER_DECLARATIONS \
-"uniform vec4 bounds; // x, y: top left; w, v: bottom right \n"\
-"uniform vec4 corner_centers_1; // x, y: top left; w, v: top right \n"\
-"uniform vec4 corner_centers_2; // x, y: bottom right; w, v: bottom left \n"\
-"uniform vec2 pixel_step; \n"\
-" \n"\
-"float \n"\
-"ellipsis_dist (vec2 p, vec2 radius) \n"\
-"{ \n"\
-" if (radius == vec2(0, 0)) \n"\
-" return 0.0; \n"\
-" \n"\
-" vec2 p0 = p / radius; \n"\
-" vec2 p1 = (2.0 * p0) / radius; \n"\
-" \n"\
-" return (dot(p0, p0) - 1.0) / length (p1); \n"\
-"} \n"\
-" \n"\
-"float \n"\
-"ellipsis_coverage (vec2 point, vec2 center, vec2 radius) \n"\
-"{ \n"\
-" float d = ellipsis_dist ((point - center), radius); \n"\
-" return clamp (0.5 - d, 0.0, 1.0); \n"\
-"} \n"\
-" \n"\
-"float \n"\
-"rounded_rect_coverage (vec4 bounds, \n"\
-" vec4 corner_centers_1, \n"\
-" vec4 corner_centers_2, \n"\
-" vec2 p) \n"\
-"{ \n"\
-" if (p.x < bounds.x || p.y < bounds.y || \n"\
-" p.x >= bounds.z || p.y >= bounds.w) \n"\
-" return 0.0; \n"\
-" \n"\
-" vec2 ref_tl = corner_centers_1.xy; \n"\
-" vec2 ref_tr = corner_centers_1.zw; \n"\
-" vec2 ref_br = corner_centers_2.xy; \n"\
-" vec2 ref_bl = corner_centers_2.zw; \n"\
-" \n"\
-" if (p.x >= ref_tl.x && p.x >= ref_bl.x && \n"\
-" p.x <= ref_tr.x && p.x <= ref_br.x) \n"\
-" return 1.0; \n"\
-" \n"\
-" if (p.y >= ref_tl.y && p.y >= ref_tr.y && \n"\
-" p.y <= ref_bl.y && p.y <= ref_br.y) \n"\
-" return 1.0; \n"\
-" \n"\
-" vec2 rad_tl = corner_centers_1.xy - bounds.xy; \n"\
-" vec2 rad_tr = corner_centers_1.zw - bounds.zy; \n"\
-" vec2 rad_br = corner_centers_2.xy - bounds.zw; \n"\
-" vec2 rad_bl = corner_centers_2.zw - bounds.xw; \n"\
-" \n"\
-" float d_tl = ellipsis_coverage(p, ref_tl, rad_tl); \n"\
-" float d_tr = ellipsis_coverage(p, ref_tr, rad_tr); \n"\
-" float d_br = ellipsis_coverage(p, ref_br, rad_br); \n"\
-" float d_bl = ellipsis_coverage(p, ref_bl, rad_bl); \n"\
-" \n"\
-" vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl); \n"\
-" \n"\
-" bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y, \n"\
-" p.x > ref_tr.x && p.y < ref_tr.y, \n"\
-" p.x > ref_br.x && p.y > ref_br.y, \n"\
-" p.x < ref_bl.x && p.y > ref_bl.y); \n"\
-" \n"\
-" return 1.0 - dot(vec4(is_out), corner_coverages); \n"\
-"} \n"
-
-#define ROUNDED_CLIP_FRAGMENT_SHADER_CODE \
-"vec2 texture_coord; \n"\
-" \n"\
-"texture_coord = cogl_tex_coord0_in.xy / pixel_step; \n"\
-" \n"\
-"cogl_color_out *= rounded_rect_coverage (bounds, \n"\
-" corner_centers_1, \n"\
-" corner_centers_2, \n"\
-" texture_coord); \n"
-
-typedef struct _MetaBackgroundLayer MetaBackgroundLayer;
-
-typedef enum
-{
- PIPELINE_VIGNETTE = (1 << 0),
- PIPELINE_BLEND = (1 << 1),
- PIPELINE_GRADIENT = (1 << 2),
- PIPELINE_ROUNDED_CLIP = (1 << 3),
-
- PIPELINE_ALL = (PIPELINE_VIGNETTE |
- PIPELINE_BLEND |
- PIPELINE_GRADIENT |
- PIPELINE_ROUNDED_CLIP)
-} PipelineFlags;
-
-struct _MetaBackgroundContent
-{
- GObject parent;
-
- MetaDisplay *display;
- int monitor;
-
- MetaBackground *background;
-
- gboolean gradient;
- double gradient_max_darkness;
- int gradient_height;
-
- gboolean vignette;
- double vignette_brightness;
- double vignette_sharpness;
-
- gboolean has_rounded_clip;
- float rounded_clip_radius;
- gboolean rounded_clip_bounds_set;
- graphene_rect_t rounded_clip_bounds;
-
- ChangedFlags changed;
- CoglPipeline *pipeline;
- PipelineFlags pipeline_flags;
- cairo_rectangle_int_t texture_area;
- int texture_width, texture_height;
-
- cairo_region_t *clip_region;
- cairo_region_t *unobscured_region;
-};
-
-static void clutter_content_iface_init (ClutterContentInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaBackgroundContent,
- meta_background_content,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
- clutter_content_iface_init));
-
-enum
-{
- PROP_0,
- PROP_META_DISPLAY,
- PROP_MONITOR,
- PROP_BACKGROUND,
- PROP_GRADIENT,
- PROP_GRADIENT_HEIGHT,
- PROP_GRADIENT_MAX_DARKNESS,
- PROP_VIGNETTE,
- PROP_VIGNETTE_SHARPNESS,
- PROP_VIGNETTE_BRIGHTNESS,
- PROP_ROUNDED_CLIP_RADIUS,
- N_PROPS,
-};
-
-static GParamSpec *properties[N_PROPS] = { NULL, };
-
-static void
-set_clip_region (MetaBackgroundContent *self,
- cairo_region_t *clip_region)
-{
- g_clear_pointer (&self->clip_region, cairo_region_destroy);
- if (clip_region)
- {
- if (cairo_region_is_empty (clip_region))
- self->clip_region = cairo_region_reference (clip_region);
- else
- self->clip_region = cairo_region_copy (clip_region);
- }
-}
-
-static void
-set_unobscured_region (MetaBackgroundContent *self,
- cairo_region_t *unobscured_region)
-{
- g_clear_pointer (&self->unobscured_region, cairo_region_destroy);
- if (unobscured_region)
- {
- if (cairo_region_is_empty (unobscured_region))
- self->unobscured_region = cairo_region_reference (unobscured_region);
- else
- self->unobscured_region = cairo_region_copy (unobscured_region);
- }
-}
-
-static void
-invalidate_pipeline (MetaBackgroundContent *self,
- ChangedFlags changed)
-{
- self->changed |= changed;
-}
-
-static void
-on_background_changed (MetaBackground *background,
- MetaBackgroundContent *self)
-{
- invalidate_pipeline (self, CHANGED_BACKGROUND);
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-static CoglPipeline *
-make_pipeline (PipelineFlags pipeline_flags)
-{
- static CoglPipeline *templates[PIPELINE_ALL + 1];
- CoglPipeline **templatep;
-
- g_assert (pipeline_flags < G_N_ELEMENTS (templates));
-
- templatep = &templates[pipeline_flags];
- if (*templatep == NULL)
- {
- /* Cogl automatically caches pipelines with no eviction policy,
- * so we need to prevent identical pipelines from getting cached
- * separately, by reusing the same shader snippets.
- */
- *templatep = COGL_PIPELINE (meta_create_texture_pipeline (NULL));
-
- if ((pipeline_flags & PIPELINE_VIGNETTE) != 0)
- {
- static CoglSnippet *vignette_vertex_snippet;
- static CoglSnippet *vignette_fragment_snippet;
-
- if (!vignette_vertex_snippet)
- vignette_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
- VIGNETTE_VERTEX_SHADER_DECLARATIONS,
- VIGNETTE_VERTEX_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, vignette_vertex_snippet);
-
- if (!vignette_fragment_snippet)
- vignette_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
- VIGNETTE_FRAGMENT_SHADER_DECLARATIONS,
- VIGNETTE_FRAGMENT_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, vignette_fragment_snippet);
- }
-
- if ((pipeline_flags & PIPELINE_GRADIENT) != 0)
- {
- static CoglSnippet *gradient_vertex_snippet;
- static CoglSnippet *gradient_fragment_snippet;
-
- if (!gradient_vertex_snippet)
- gradient_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
- GRADIENT_VERTEX_SHADER_DECLARATIONS,
- GRADIENT_VERTEX_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, gradient_vertex_snippet);
-
- if (!gradient_fragment_snippet)
- gradient_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
- GRADIENT_FRAGMENT_SHADER_DECLARATIONS,
- GRADIENT_FRAGMENT_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, gradient_fragment_snippet);
- }
-
- if ((pipeline_flags & PIPELINE_ROUNDED_CLIP) != 0)
- {
- static CoglSnippet *rounded_clip_fragment_snippet;
-
- if (!rounded_clip_fragment_snippet)
- {
- rounded_clip_fragment_snippet =
- cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
- ROUNDED_CLIP_FRAGMENT_SHADER_DECLARATIONS,
- ROUNDED_CLIP_FRAGMENT_SHADER_CODE);
- }
-
- cogl_pipeline_add_snippet (*templatep, rounded_clip_fragment_snippet);
- }
-
-
- if ((pipeline_flags & PIPELINE_BLEND) == 0)
- cogl_pipeline_set_blend (*templatep, "RGBA = ADD (SRC_COLOR, 0)", NULL);
- }
-
- return cogl_pipeline_copy (*templatep);
-}
-
-static void
-setup_pipeline (MetaBackgroundContent *self,
- ClutterActor *actor,
- ClutterPaintContext *paint_context,
- cairo_rectangle_int_t *actor_pixel_rect)
-{
- PipelineFlags pipeline_flags = 0;
- guint8 opacity;
- float color_component;
- CoglFramebuffer *fb;
- CoglPipelineFilter min_filter, mag_filter;
-
- opacity = clutter_actor_get_paint_opacity (actor);
- if (opacity < 255)
- pipeline_flags |= PIPELINE_BLEND;
- if (self->vignette && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- pipeline_flags |= PIPELINE_VIGNETTE;
- if (self->gradient && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- pipeline_flags |= PIPELINE_GRADIENT;
- if (self->has_rounded_clip && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- pipeline_flags |= PIPELINE_ROUNDED_CLIP | PIPELINE_BLEND;
-
- if (pipeline_flags != self->pipeline_flags)
- g_clear_pointer (&self->pipeline, cogl_object_unref);
-
- if (self->pipeline == NULL)
- {
- self->pipeline_flags = pipeline_flags;
- self->pipeline = make_pipeline (pipeline_flags);
- self->changed = CHANGED_ALL;
- }
-
- if (self->changed & CHANGED_BACKGROUND)
- {
- CoglPipelineWrapMode wrap_mode;
- CoglTexture *texture = meta_background_get_texture (self->background,
- self->monitor,
- &self->texture_area,
- &wrap_mode);
-
- if (texture)
- {
- self->texture_width = cogl_texture_get_width (texture);
- self->texture_height = cogl_texture_get_height (texture);
- }
- else
- {
- self->texture_width = 0;
- self->texture_height = 0;
- }
-
- cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
- cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode);
-
- self->changed &= ~CHANGED_BACKGROUND;
- }
-
- if (self->changed & CHANGED_VIGNETTE_PARAMETERS)
- {
- cogl_pipeline_set_uniform_1f (self->pipeline,
- cogl_pipeline_get_uniform_location (self->pipeline,
- "vignette_sharpness"),
- self->vignette_sharpness);
-
- self->changed &= ~CHANGED_VIGNETTE_PARAMETERS;
- }
-
- if (self->changed & CHANGED_GRADIENT_PARAMETERS)
- {
- MetaRectangle monitor_geometry;
- float gradient_height_perc;
-
- meta_display_get_monitor_geometry (self->display,
- self->monitor, &monitor_geometry);
- gradient_height_perc = MAX (0.0001, self->gradient_height / (float)monitor_geometry.height);
- cogl_pipeline_set_uniform_1f (self->pipeline,
- cogl_pipeline_get_uniform_location (self->pipeline,
- "gradient_height_perc"),
- gradient_height_perc);
- cogl_pipeline_set_uniform_1f (self->pipeline,
- cogl_pipeline_get_uniform_location (self->pipeline,
- "gradient_max_darkness"),
- self->gradient_max_darkness);
-
- self->changed &= ~CHANGED_GRADIENT_PARAMETERS;
- }
-
- if (self->changed & CHANGED_ROUNDED_CLIP_PARAMETERS)
- {
- float monitor_scale;
- float bounds_x1, bounds_x2, bounds_y1, bounds_y2;
- float clip_radius;
-
- monitor_scale = meta_is_stage_views_scaled ()
- ? meta_display_get_monitor_scale (self->display, self->monitor)
- : 1.0;
-
- if (self->rounded_clip_bounds_set)
- {
- bounds_x1 = self->rounded_clip_bounds.origin.x;
- bounds_x2 = self->rounded_clip_bounds.origin.x + self->rounded_clip_bounds.size.width;
- bounds_y1 = self->rounded_clip_bounds.origin.y;
- bounds_y2 = self->rounded_clip_bounds.origin.y + self->rounded_clip_bounds.size.height;
-
- bounds_x1 *= monitor_scale;
- bounds_x2 *= monitor_scale;
- bounds_y1 *= monitor_scale;
- bounds_y2 *= monitor_scale;
- }
- else
- {
- bounds_x1 = 0.0;
- bounds_x2 = self->texture_width;
- bounds_y1 = 0.0;
- bounds_y2 = self->texture_height;
- }
-
- clip_radius = self->rounded_clip_radius * monitor_scale;
-
- float bounds[] = {
- bounds_x1,
- bounds_y1,
- bounds_x2,
- bounds_y2,
- };
-
- float corner_centers_1[] = {
- bounds_x1 + clip_radius,
- bounds_y1 + clip_radius,
- bounds_x2 - clip_radius,
- bounds_y1 + clip_radius,
- };
-
- float corner_centers_2[] = {
- bounds_x2 - clip_radius,
- bounds_y2 - clip_radius,
- bounds_x1 + clip_radius,
- bounds_y2 - clip_radius,
- };
-
- int bounds_uniform_location;
- int corner_centers_1_uniform_location;
- int corner_centers_2_uniform_location;
-
- bounds_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline, "bounds");
- corner_centers_1_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline, "corner_centers_1");
- corner_centers_2_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline, "corner_centers_2");
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- bounds_uniform_location,
- 4, 1,
- bounds);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- corner_centers_1_uniform_location,
- 4, 1,
- corner_centers_1);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- corner_centers_2_uniform_location,
- 4, 1,
- corner_centers_2);
-
- self->changed &= ~CHANGED_ROUNDED_CLIP_PARAMETERS;
- }
-
- if (self->vignette)
- {
- color_component = self->vignette_brightness * opacity / 255.;
-
- if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- {
- /* Darken everything to match the average brightness that would
- * be there if we were drawing the vignette, which is
- * (1 - (pi/12.) * vignette_sharpness) [exercise for the reader :]
- */
- color_component *= (1 - 0.74 * self->vignette_sharpness);
- }
- }
- else
- {
- color_component = opacity / 255.;
- }
-
- cogl_pipeline_set_color4f (self->pipeline,
- color_component,
- color_component,
- color_component,
- opacity / 255.);
-
- fb = clutter_paint_context_get_framebuffer (paint_context);
- if (meta_actor_painting_untransformed (fb,
- actor_pixel_rect->width,
- actor_pixel_rect->height,
- self->texture_width,
- self->texture_height,
- NULL, NULL))
- {
- min_filter = COGL_PIPELINE_FILTER_NEAREST;
- mag_filter = COGL_PIPELINE_FILTER_NEAREST;
- }
- else
- {
- min_filter = COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST;
- mag_filter = COGL_PIPELINE_FILTER_LINEAR;
- }
-
- cogl_pipeline_set_layer_filters (self->pipeline, 0, min_filter, mag_filter);
-}
-
-static void
-set_glsl_parameters (MetaBackgroundContent *self,
- cairo_rectangle_int_t *actor_pixel_rect)
-{
- float monitor_scale;
- float scale[2];
- float offset[2];
- int pixel_step_uniform_location;
-
- monitor_scale = meta_is_stage_views_scaled ()
- ? meta_display_get_monitor_scale (self->display, self->monitor)
- : 1.0;
-
- float pixel_step[] = {
- 1.f / (self->texture_area.width * monitor_scale),
- 1.f / (self->texture_area.height * monitor_scale),
- };
-
- pixel_step_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline,
- "pixel_step");
-
- /* Compute a scale and offset for transforming texture coordinates to the
- * coordinate system from [-0.5 to 0.5] across the area of the actor
- */
- scale[0] = self->texture_area.width / (float)actor_pixel_rect->width;
- scale[1] = self->texture_area.height / (float)actor_pixel_rect->height;
- offset[0] = self->texture_area.x / (float)actor_pixel_rect->width - 0.5;
- offset[1] = self->texture_area.y / (float)actor_pixel_rect->height - 0.5;
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- cogl_pipeline_get_uniform_location (self->pipeline,
- "scale"),
- 2, 1, scale);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- cogl_pipeline_get_uniform_location (self->pipeline,
- "offset"),
- 2, 1, offset);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- pixel_step_uniform_location,
- 2, 1,
- pixel_step);
-}
-
-static void
-paint_clipped_rectangle (MetaBackgroundContent *self,
- ClutterPaintNode *node,
- ClutterActorBox *actor_box,
- cairo_rectangle_int_t *rect)
-{
- g_autoptr (ClutterPaintNode) pipeline_node = NULL;
- float h_scale, v_scale;
- float x1, y1, x2, y2;
- float tx1, ty1, tx2, ty2;
-
- h_scale = self->texture_area.width / clutter_actor_box_get_width (actor_box);
- v_scale = self->texture_area.height / clutter_actor_box_get_height (actor_box);
-
- x1 = rect->x;
- y1 = rect->y;
- x2 = rect->x + rect->width;
- y2 = rect->y + rect->height;
-
- tx1 = (x1 * h_scale - self->texture_area.x) / (float)self->texture_area.width;
- ty1 = (y1 * v_scale - self->texture_area.y) / (float)self->texture_area.height;
- tx2 = (x2 * h_scale - self->texture_area.x) / (float)self->texture_area.width;
- ty2 = (y2 * v_scale - self->texture_area.y) / (float)self->texture_area.height;
-
- pipeline_node = clutter_pipeline_node_new (self->pipeline);
- clutter_paint_node_set_name (pipeline_node, "MetaBackgroundContent (Slice)");
- clutter_paint_node_add_texture_rectangle (pipeline_node,
- &(ClutterActorBox) {
- .x1 = x1,
- .y1 = y1,
- .x2 = x2,
- .y2 = y2,
- },
- tx1, ty1,
- tx2, ty2);
-
- clutter_paint_node_add_child (node, pipeline_node);
-}
-
-static void
-meta_background_content_paint_content (ClutterContent *content,
- ClutterActor *actor,
- ClutterPaintNode *node,
- ClutterPaintContext *paint_context)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (content);
- ClutterActorBox actor_box;
- cairo_rectangle_int_t rect_within_actor;
- cairo_rectangle_int_t rect_within_stage;
- cairo_region_t *region;
- int i, n_rects;
- float transformed_x, transformed_y, transformed_width, transformed_height;
- gboolean untransformed;
-
- if ((self->clip_region && cairo_region_is_empty (self->clip_region)))
- return;
-
- clutter_actor_get_content_box (actor, &actor_box);
- rect_within_actor.x = actor_box.x1;
- rect_within_actor.y = actor_box.y1;
- rect_within_actor.width = actor_box.x2 - actor_box.x1;
- rect_within_actor.height = actor_box.y2 - actor_box.y1;
-
- if (clutter_actor_is_in_clone_paint (actor))
- {
- untransformed = FALSE;
- }
- else
- {
- clutter_actor_get_transformed_position (actor,
- &transformed_x,
- &transformed_y);
- rect_within_stage.x = floorf (transformed_x);
- rect_within_stage.y = floorf (transformed_y);
-
- clutter_actor_get_transformed_size (actor,
- &transformed_width,
- &transformed_height);
- rect_within_stage.width = ceilf (transformed_width);
- rect_within_stage.height = ceilf (transformed_height);
-
- untransformed =
- rect_within_actor.x == rect_within_stage.x &&
- rect_within_actor.y == rect_within_stage.y &&
- rect_within_actor.width == rect_within_stage.width &&
- rect_within_actor.height == rect_within_stage.height;
- }
-
- if (untransformed) /* actor and stage space are the same */
- {
- if (self->clip_region)
- {
- region = cairo_region_copy (self->clip_region);
- cairo_region_intersect_rectangle (region, &rect_within_stage);
- }
- else
- {
- const cairo_region_t *redraw_clip;
-
- redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
- if (redraw_clip)
- {
- region = cairo_region_copy (redraw_clip);
- cairo_region_intersect_rectangle (region, &rect_within_stage);
- }
- else
- {
- region = cairo_region_create_rectangle (&rect_within_stage);
- }
- }
- }
- else /* actor and stage space are different but we need actor space */
- {
- if (self->clip_region)
- {
- region = cairo_region_copy (self->clip_region);
- cairo_region_intersect_rectangle (region, &rect_within_actor);
- }
- else
- {
- region = cairo_region_create_rectangle (&rect_within_actor);
- }
- }
-
- if (self->unobscured_region)
- cairo_region_intersect (region, self->unobscured_region);
-
- /* region is now in actor space */
- if (cairo_region_is_empty (region))
- {
- cairo_region_destroy (region);
- return;
- }
-
- setup_pipeline (self, actor, paint_context, &rect_within_actor);
- set_glsl_parameters (self, &rect_within_actor);
-
- /* Limit to how many separate rectangles we'll draw; beyond this just
- * fall back and draw the whole thing */
-#define MAX_RECTS 64
-
- n_rects = cairo_region_num_rectangles (region);
- if (n_rects <= MAX_RECTS)
- {
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (region, i, &rect);
- paint_clipped_rectangle (self, node, &actor_box, &rect);
- }
- }
- else
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_extents (region, &rect);
- paint_clipped_rectangle (self, node, &actor_box, &rect);
- }
-
- cairo_region_destroy (region);
-}
-
-static gboolean
-meta_background_content_get_preferred_size (ClutterContent *content,
- float *width,
- float *height)
-
-{
- MetaBackgroundContent *background_content = META_BACKGROUND_CONTENT (content);
- MetaRectangle monitor_geometry;
-
- meta_display_get_monitor_geometry (background_content->display,
- background_content->monitor,
- &monitor_geometry);
-
- if (width)
- *width = monitor_geometry.width;
-
- if (height)
- *height = monitor_geometry.height;
-
- return TRUE;
-}
-
-static void
-clutter_content_iface_init (ClutterContentInterface *iface)
-{
- iface->paint_content = meta_background_content_paint_content;
- iface->get_preferred_size = meta_background_content_get_preferred_size;
-}
-
-static void
-set_monitor (MetaBackgroundContent *self,
- int monitor)
-{
- MetaRectangle old_monitor_geometry;
- MetaRectangle new_monitor_geometry;
- MetaDisplay *display = self->display;
-
- if(self->monitor == monitor)
- return;
-
- meta_display_get_monitor_geometry (display, self->monitor, &old_monitor_geometry);
- meta_display_get_monitor_geometry (display, monitor, &new_monitor_geometry);
- if(old_monitor_geometry.height != new_monitor_geometry.height)
- invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS);
-
- self->monitor = monitor;
-}
-
-static void
-meta_background_content_dispose (GObject *object)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
-
- set_clip_region (self, NULL);
- set_unobscured_region (self, NULL);
- meta_background_content_set_background (self, NULL);
-
- g_clear_pointer (&self->pipeline, cogl_object_unref);
-
- G_OBJECT_CLASS (meta_background_content_parent_class)->dispose (object);
-}
-
-static void
-meta_background_content_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- self->display = g_value_get_object (value);
- break;
- case PROP_MONITOR:
- set_monitor (self, g_value_get_int (value));
- break;
- case PROP_BACKGROUND:
- meta_background_content_set_background (self, g_value_get_object (value));
- break;
- case PROP_GRADIENT:
- meta_background_content_set_gradient (self,
- g_value_get_boolean (value),
- self->gradient_height,
- self->gradient_max_darkness);
- break;
- case PROP_GRADIENT_HEIGHT:
- meta_background_content_set_gradient (self,
- self->gradient,
- g_value_get_int (value),
- self->gradient_max_darkness);
- break;
- case PROP_GRADIENT_MAX_DARKNESS:
- meta_background_content_set_gradient (self,
- self->gradient,
- self->gradient_height,
- g_value_get_double (value));
- break;
- case PROP_VIGNETTE:
- meta_background_content_set_vignette (self,
- g_value_get_boolean (value),
- self->vignette_brightness,
- self->vignette_sharpness);
- break;
- case PROP_VIGNETTE_SHARPNESS:
- meta_background_content_set_vignette (self,
- self->vignette,
- self->vignette_brightness,
- g_value_get_double (value));
- break;
- case PROP_VIGNETTE_BRIGHTNESS:
- meta_background_content_set_vignette (self,
- self->vignette,
- g_value_get_double (value),
- self->vignette_sharpness);
- break;
- case PROP_ROUNDED_CLIP_RADIUS:
- meta_background_content_set_rounded_clip_radius (self,
- g_value_get_float (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_content_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- g_value_set_object (value, self->display);
- break;
- case PROP_MONITOR:
- g_value_set_int (value, self->monitor);
- break;
- case PROP_BACKGROUND:
- g_value_set_object (value, self->background);
- break;
- case PROP_GRADIENT:
- g_value_set_boolean (value, self->gradient);
- break;
- case PROP_GRADIENT_HEIGHT:
- g_value_set_int (value, self->gradient_height);
- break;
- case PROP_GRADIENT_MAX_DARKNESS:
- g_value_set_double (value, self->gradient_max_darkness);
- break;
- case PROP_VIGNETTE:
- g_value_set_boolean (value, self->vignette);
- break;
- case PROP_VIGNETTE_BRIGHTNESS:
- g_value_set_double (value, self->vignette_brightness);
- break;
- case PROP_VIGNETTE_SHARPNESS:
- g_value_set_double (value, self->vignette_sharpness);
- break;
- case PROP_ROUNDED_CLIP_RADIUS:
- g_value_set_float (value, self->rounded_clip_radius);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_content_class_init (MetaBackgroundContentClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = meta_background_content_dispose;
- object_class->set_property = meta_background_content_set_property;
- object_class->get_property = meta_background_content_get_property;
-
- properties[PROP_META_DISPLAY] =
- g_param_spec_object ("meta-display",
- "MetaDisplay",
- "MetaDisplay",
- META_TYPE_DISPLAY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- properties[PROP_MONITOR] =
- g_param_spec_int ("monitor",
- "monitor",
- "monitor",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- properties[PROP_BACKGROUND] =
- g_param_spec_object ("background",
- "Background",
- "MetaBackground object holding background parameters",
- META_TYPE_BACKGROUND,
- G_PARAM_READWRITE);
-
- properties[PROP_GRADIENT] =
- g_param_spec_boolean ("gradient",
- "Gradient",
- "Whether gradient effect is enabled",
- FALSE,
- G_PARAM_READWRITE);
-
- properties[PROP_GRADIENT_HEIGHT] =
- g_param_spec_int ("gradient-height",
- "Gradient Height",
- "Height of gradient effect",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE);
-
- properties[PROP_GRADIENT_MAX_DARKNESS] =
- g_param_spec_double ("gradient-max-darkness",
- "Gradient Max Darkness",
- "How dark is the gradient initially",
- 0.0, 1.0, 0.0,
- G_PARAM_READWRITE);
-
- properties[PROP_VIGNETTE] =
- g_param_spec_boolean ("vignette",
- "Vignette",
- "Whether vignette effect is enabled",
- FALSE,
- G_PARAM_READWRITE);
-
- properties[PROP_VIGNETTE_BRIGHTNESS] =
- g_param_spec_double ("brightness",
- "Vignette Brightness",
- "Brightness of vignette effect",
- 0.0, 1.0, 1.0,
- G_PARAM_READWRITE);
-
- properties[PROP_VIGNETTE_SHARPNESS] =
- g_param_spec_double ("vignette-sharpness",
- "Vignette Sharpness",
- "Sharpness of vignette effect",
- 0.0, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE);
-
- properties[PROP_ROUNDED_CLIP_RADIUS] =
- g_param_spec_float ("rounded-clip-radius",
- "Rounded clip radius",
- "Rounded clip radius",
- 0.0, G_MAXFLOAT, 0.0,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS |
- G_PARAM_EXPLICIT_NOTIFY);
-
- g_object_class_install_properties (object_class, N_PROPS, properties);
-}
-
-static void
-meta_background_content_init (MetaBackgroundContent *self)
-{
- self->gradient = FALSE;
- self->gradient_height = 0;
- self->gradient_max_darkness = 0.0;
-
- self->vignette = FALSE;
- self->vignette_brightness = 1.0;
- self->vignette_sharpness = 0.0;
-
- self->has_rounded_clip = FALSE;
- self->rounded_clip_radius = 0.0;
-}
-
-/**
- * meta_background_content_new:
- * @monitor: Index of the monitor for which to draw the background
- *
- * Creates a new actor to draw the background for the given monitor.
- *
- * Return value: (transfer full): the newly created background actor
- */
-ClutterContent *
-meta_background_content_new (MetaDisplay *display,
- int monitor)
-{
- return g_object_new (META_TYPE_BACKGROUND_CONTENT,
- "meta-display", display,
- "monitor", monitor,
- NULL);
-}
-
-void
-meta_background_content_set_background (MetaBackgroundContent *self,
- MetaBackground *background)
-{
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
- g_return_if_fail (background == NULL || META_IS_BACKGROUND (background));
-
- if (background == self->background)
- return;
-
- if (self->background)
- {
- g_signal_handlers_disconnect_by_func (self->background,
- (gpointer)on_background_changed,
- self);
- g_clear_object (&self->background);
- }
-
- if (background)
- {
- self->background = g_object_ref (background);
- g_signal_connect (self->background, "changed",
- G_CALLBACK (on_background_changed), self);
- }
-
- invalidate_pipeline (self, CHANGED_BACKGROUND);
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-void
-meta_background_content_set_gradient (MetaBackgroundContent *self,
- gboolean enabled,
- int height,
- double max_darkness)
-{
- gboolean changed = FALSE;
-
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
- g_return_if_fail (height >= 0);
- g_return_if_fail (max_darkness >= 0. && max_darkness <= 1.);
-
- enabled = enabled != FALSE && height != 0;
-
- if (enabled != self->gradient)
- {
- self->gradient = enabled;
- invalidate_pipeline (self, CHANGED_EFFECTS);
- changed = TRUE;
- }
-
- if (height != self->gradient_height || max_darkness != self->gradient_max_darkness)
- {
- self->gradient_height = height;
- self->gradient_max_darkness = max_darkness;
- invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS);
- changed = TRUE;
- }
-
- if (changed)
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-void
-meta_background_content_set_vignette (MetaBackgroundContent *self,
- gboolean enabled,
- double brightness,
- double sharpness)
-{
- gboolean changed = FALSE;
-
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
- g_return_if_fail (brightness >= 0. && brightness <= 1.);
- g_return_if_fail (sharpness >= 0.);
-
- enabled = enabled != FALSE;
-
- if (enabled != self->vignette)
- {
- self->vignette = enabled;
- invalidate_pipeline (self, CHANGED_EFFECTS);
- changed = TRUE;
- }
-
- if (brightness != self->vignette_brightness || sharpness != self->vignette_sharpness)
- {
- self->vignette_brightness = brightness;
- self->vignette_sharpness = sharpness;
- invalidate_pipeline (self, CHANGED_VIGNETTE_PARAMETERS);
- changed = TRUE;
- }
-
- if (changed)
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-void
-meta_background_content_set_rounded_clip_radius (MetaBackgroundContent *self,
- float radius)
-{
- gboolean enabled;
- gboolean changed = FALSE;
-
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
- g_return_if_fail (radius >= 0.0);
-
- enabled = radius > 0.0;
-
- if (enabled != self->has_rounded_clip)
- {
- self->has_rounded_clip = enabled;
- invalidate_pipeline (self, CHANGED_EFFECTS);
- changed = TRUE;
- }
-
- if (!G_APPROX_VALUE (radius, self->rounded_clip_radius, FLT_EPSILON))
- {
- self->rounded_clip_radius = radius;
- invalidate_pipeline (self, CHANGED_ROUNDED_CLIP_PARAMETERS);
- changed = TRUE;
- }
-
- if (changed)
- {
- clutter_content_invalidate (CLUTTER_CONTENT (self));
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ROUNDED_CLIP_RADIUS]);
- }
-}
-
-/**
- * meta_background_content_set_rounded_clip_bounds:
- * @self: The #MetaBackgroundContent
- * @bounds: (allow-none): The new bounding clip rectangle, or %NULL
- *
- * Sets the bounding clip rectangle of the #MetaBackgroundContent that's used
- * when a rounded clip set via meta_background_content_set_rounded_clip_radius()
- * is in effect, set it to %NULL to use no bounding clip, rounding the edges
- * of the full texture.
- */
-void
-meta_background_content_set_rounded_clip_bounds (MetaBackgroundContent *self,
- const graphene_rect_t *bounds)
-{
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
-
- if (bounds == NULL)
- {
- if (!self->rounded_clip_bounds_set)
- return;
-
- self->rounded_clip_bounds_set = FALSE;
- }
- else
- {
- if (self->rounded_clip_bounds_set &&
- graphene_rect_equal (&self->rounded_clip_bounds, bounds))
- return;
-
- self->rounded_clip_bounds_set = TRUE;
- graphene_rect_init_from_rect (&self->rounded_clip_bounds, bounds);
- }
-
- invalidate_pipeline (self, CHANGED_ROUNDED_CLIP_PARAMETERS);
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-cairo_region_t *
-meta_background_content_get_clip_region (MetaBackgroundContent *self)
-{
- return self->clip_region;
-}
-
-void
-meta_background_content_cull_out (MetaBackgroundContent *self,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- set_unobscured_region (self, unobscured_region);
- set_clip_region (self, clip_region);
-}
-
-void
-meta_background_content_reset_culling (MetaBackgroundContent *self)
-{
- set_unobscured_region (self, NULL);
- set_clip_region (self, NULL);
-}
diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c
deleted file mode 100644
index e30b8af4c..000000000
--- a/src/compositor/meta-background-group.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:meta-background-group
- * @title: MetaBackgroundGroup
- * @short_description: Container for background actors
- *
- * This class is a subclass of ClutterActor with special handling for
- * MetaBackgroundActor/MetaBackgroundGroup when painting children.
- * It makes sure to only draw the parts of the backgrounds not
- * occluded by opaque windows.
- *
- * See #MetaWindowGroup for more information behind the motivation,
- * and details on implementation.
- */
-
-#include "config.h"
-
-#include "compositor/meta-cullable.h"
-#include "meta/meta-background-group.h"
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
-
-static void
-meta_background_group_class_init (MetaBackgroundGroupClass *klass)
-{
-}
-
-static void
-meta_background_group_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
-}
-
-static void
-meta_background_group_reset_culling (MetaCullable *cullable)
-{
- meta_cullable_reset_culling_children (cullable);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_background_group_cull_out;
- iface->reset_culling = meta_background_group_reset_culling;
-}
-
-static void
-meta_background_group_init (MetaBackgroundGroup *self)
-{
-}
-
-ClutterActor *
-meta_background_group_new (void)
-{
- MetaBackgroundGroup *background_group;
-
- background_group = g_object_new (META_TYPE_BACKGROUND_GROUP, NULL);
-
- return CLUTTER_ACTOR (background_group);
-}
diff --git a/src/compositor/meta-background-image.c b/src/compositor/meta-background-image.c
deleted file mode 100644
index ed9425bb3..000000000
--- a/src/compositor/meta-background-image.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright 2014 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:meta-background-image
- * @title: MetaBackgroundImage
- * @short_description: objects holding images loaded from files, used for backgrounds
- */
-
-#include "config.h"
-
-#include "meta/meta-background-image.h"
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gio/gio.h>
-
-#include "clutter/clutter.h"
-#include "compositor/cogl-utils.h"
-
-enum
-{
- LOADED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/**
- * MetaBackgroundImageCache:
- *
- * #MetaBackgroundImageCache caches loading of textures for backgrounds; there's actually
- * nothing background specific about it, other than it is tuned to work well for
- * large images as typically are used for backgrounds.
- */
-struct _MetaBackgroundImageCache
-{
- GObject parent_instance;
-
- GHashTable *images;
-};
-
-/**
- * MetaBackgroundImage:
- *
- * #MetaBackgroundImage is an object that represents a loaded or loading background image.
- */
-struct _MetaBackgroundImage
-{
- GObject parent_instance;
- GFile *file;
- MetaBackgroundImageCache *cache;
- gboolean in_cache;
- gboolean loaded;
- CoglTexture *texture;
-};
-
-G_DEFINE_TYPE (MetaBackgroundImageCache, meta_background_image_cache, G_TYPE_OBJECT);
-
-static void
-meta_background_image_cache_init (MetaBackgroundImageCache *cache)
-{
- cache->images = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
-}
-
-static void
-meta_background_image_cache_finalize (GObject *object)
-{
- MetaBackgroundImageCache *cache = META_BACKGROUND_IMAGE_CACHE (object);
- GHashTableIter iter;
- gpointer key, value;
-
- g_hash_table_iter_init (&iter, cache->images);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- MetaBackgroundImage *image = value;
- image->in_cache = FALSE;
- }
-
- g_hash_table_destroy (cache->images);
-
- G_OBJECT_CLASS (meta_background_image_cache_parent_class)->finalize (object);
-}
-
-static void
-meta_background_image_cache_class_init (MetaBackgroundImageCacheClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_background_image_cache_finalize;
-}
-
-/**
- * meta_background_image_cache_get_default:
- *
- * Return value: (transfer none): the global singleton background cache
- */
-MetaBackgroundImageCache *
-meta_background_image_cache_get_default (void)
-{
- static MetaBackgroundImageCache *cache;
-
- if (cache == NULL)
- cache = g_object_new (META_TYPE_BACKGROUND_IMAGE_CACHE, NULL);
-
- return cache;
-}
-
-static void
-load_file (GTask *task,
- MetaBackgroundImage *image,
- gpointer task_data,
- GCancellable *cancellable)
-{
- GError *error = NULL;
- GdkPixbuf *pixbuf;
- GFileInputStream *stream;
-
- stream = g_file_read (image->file, NULL, &error);
- if (stream == NULL)
- {
- g_task_return_error (task, error);
- return;
- }
-
- pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream), NULL, &error);
- g_object_unref (stream);
-
- if (pixbuf == NULL)
- {
- g_task_return_error (task, error);
- return;
- }
-
- g_task_return_pointer (task, pixbuf, (GDestroyNotify) g_object_unref);
-}
-
-static void
-file_loaded (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- MetaBackgroundImage *image = META_BACKGROUND_IMAGE (source_object);
- GError *error = NULL;
- GError *catch_error = NULL;
- GTask *task;
- CoglTexture *texture;
- GdkPixbuf *pixbuf, *rotated;
- int width, height, row_stride;
- guchar *pixels;
- gboolean has_alpha;
-
- task = G_TASK (result);
- pixbuf = g_task_propagate_pointer (task, &error);
-
- if (pixbuf == NULL)
- {
- char *uri = g_file_get_uri (image->file);
- g_warning ("Failed to load background '%s': %s",
- uri, error->message);
- g_clear_error (&error);
- g_free (uri);
- goto out;
- }
-
- rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
- if (rotated != NULL)
- {
- g_object_unref (pixbuf);
- pixbuf = rotated;
- }
-
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- row_stride = gdk_pixbuf_get_rowstride (pixbuf);
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
-
- texture = meta_create_texture (width, height,
- has_alpha ? COGL_TEXTURE_COMPONENTS_RGBA : COGL_TEXTURE_COMPONENTS_RGB,
- META_TEXTURE_ALLOW_SLICING);
-
- if (!cogl_texture_set_data (texture,
- has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
- row_stride,
- pixels, 0,
- &catch_error))
- {
- g_warning ("Failed to create texture for background");
- g_error_free (catch_error);
- cogl_object_unref (texture);
- }
-
- image->texture = texture;
-
-out:
- if (pixbuf != NULL)
- g_object_unref (pixbuf);
-
- image->loaded = TRUE;
- g_signal_emit (image, signals[LOADED], 0);
-}
-
-/**
- * meta_background_image_cache_load:
- * @cache: a #MetaBackgroundImageCache
- * @file: #GFile to load
- *
- * Loads an image to use as a background, or returns a reference to an
- * image that is already in the process of loading or loaded. In either
- * case, what is returned is a #MetaBackgroundImage which can be dereferenced
- * to get a #CoglTexture. If meta_background_image_is_loaded() returns %TRUE,
- * the background is loaded, otherwise the MetaBackgroundImage::loaded
- * signal will be emitted exactly once. The 'loaded' state means that the
- * loading process finished, whether it succeeded or failed.
- *
- * Return value: (transfer full): a #MetaBackgroundImage to dereference to get the loaded texture
- */
-MetaBackgroundImage *
-meta_background_image_cache_load (MetaBackgroundImageCache *cache,
- GFile *file)
-{
- MetaBackgroundImage *image;
- GTask *task;
-
- g_return_val_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache), NULL);
- g_return_val_if_fail (file != NULL, NULL);
-
- image = g_hash_table_lookup (cache->images, file);
- if (image != NULL)
- return g_object_ref (image);
-
- image = g_object_new (META_TYPE_BACKGROUND_IMAGE, NULL);
- image->cache = cache;
- image->in_cache = TRUE;
- image->file = g_object_ref (file);
- g_hash_table_insert (cache->images, image->file, image);
-
- task = g_task_new (image, NULL, file_loaded, NULL);
-
- g_task_run_in_thread (task, (GTaskThreadFunc) load_file);
- g_object_unref (task);
-
- return image;
-}
-
-/**
- * meta_background_image_cache_purge:
- * @cache: a #MetaBackgroundImageCache
- * @file: file to remove from the cache
- *
- * Remove an entry from the cache; this would be used if monitoring
- * showed that the file changed.
- */
-void
-meta_background_image_cache_purge (MetaBackgroundImageCache *cache,
- GFile *file)
-{
- MetaBackgroundImage *image;
-
- g_return_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache));
- g_return_if_fail (file != NULL);
-
- image = g_hash_table_lookup (cache->images, file);
- if (image == NULL)
- return;
-
- g_hash_table_remove (cache->images, image->file);
- image->in_cache = FALSE;
-}
-
-G_DEFINE_TYPE (MetaBackgroundImage, meta_background_image, G_TYPE_OBJECT);
-
-static void
-meta_background_image_init (MetaBackgroundImage *image)
-{
-}
-
-static void
-meta_background_image_finalize (GObject *object)
-{
- MetaBackgroundImage *image = META_BACKGROUND_IMAGE (object);
-
- if (image->in_cache)
- g_hash_table_remove (image->cache->images, image->file);
-
- if (image->texture)
- cogl_object_unref (image->texture);
- if (image->file)
- g_object_unref (image->file);
-
- G_OBJECT_CLASS (meta_background_image_parent_class)->finalize (object);
-}
-
-static void
-meta_background_image_class_init (MetaBackgroundImageClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_background_image_finalize;
-
- signals[LOADED] =
- g_signal_new ("loaded",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-/**
- * meta_background_image_is_loaded:
- * @image: a #MetaBackgroundImage
- *
- * Return value: %TRUE if loading has already completed, %FALSE otherwise
- */
-gboolean
-meta_background_image_is_loaded (MetaBackgroundImage *image)
-{
- g_return_val_if_fail (META_IS_BACKGROUND_IMAGE (image), FALSE);
-
- return image->loaded;
-}
-
-/**
- * meta_background_image_get_success:
- * @image: a #MetaBackgroundImage
- *
- * This function is a convenience function for checking for success,
- * without having to call meta_background_image_get_texture() and
- * handle the return of a Cogl type.
- *
- * Return value: %TRUE if loading completed successfully, otherwise %FALSE
- */
-gboolean
-meta_background_image_get_success (MetaBackgroundImage *image)
-{
- g_return_val_if_fail (META_IS_BACKGROUND_IMAGE (image), FALSE);
-
- return image->texture != NULL;
-}
-
-/**
- * meta_background_image_get_texture:
- * @image: a #MetaBackgroundImage
- *
- * Return value: (transfer none): a #CoglTexture if loading succeeded; if
- * loading failed or has not yet finished, %NULL.
- */
-CoglTexture *
-meta_background_image_get_texture (MetaBackgroundImage *image)
-{
- g_return_val_if_fail (META_IS_BACKGROUND_IMAGE (image), NULL);
-
- return image->texture;
-}
diff --git a/src/compositor/meta-background-private.h b/src/compositor/meta-background-private.h
deleted file mode 100644
index 871487da4..000000000
--- a/src/compositor/meta-background-private.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_BACKGROUND_PRIVATE_H
-#define META_BACKGROUND_PRIVATE_H
-
-#include "cogl/cogl.h"
-#include "meta/meta-background.h"
-
-CoglTexture *meta_background_get_texture (MetaBackground *self,
- int monitor_index,
- cairo_rectangle_int_t *texture_area,
- CoglPipelineWrapMode *wrap_mode);
-
-#endif /* META_BACKGROUND_PRIVATE_H */
diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
deleted file mode 100644
index c0d8d335d..000000000
--- a/src/compositor/meta-background.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2013 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "compositor/meta-background-private.h"
-
-#include <string.h>
-
-#include "backends/meta-backend-private.h"
-#include "compositor/cogl-utils.h"
-#include "meta/display.h"
-#include "meta/meta-background-image.h"
-#include "meta/meta-background.h"
-#include "meta/meta-monitor-manager.h"
-#include "meta/util.h"
-
-enum
-{
- CHANGED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-typedef struct _MetaBackgroundMonitor MetaBackgroundMonitor;
-
-struct _MetaBackgroundMonitor
-{
- gboolean dirty;
- CoglTexture *texture;
- CoglFramebuffer *fbo;
-};
-
-struct _MetaBackground
-{
- GObject parent;
-
- MetaDisplay *display;
- MetaBackgroundMonitor *monitors;
- int n_monitors;
-
- GDesktopBackgroundStyle style;
- GDesktopBackgroundShading shading_direction;
- ClutterColor color;
- ClutterColor second_color;
-
- GFile *file1;
- MetaBackgroundImage *background_image1;
- GFile *file2;
- MetaBackgroundImage *background_image2;
-
- CoglTexture *color_texture;
- CoglTexture *wallpaper_texture;
-
- float blend_factor;
-
- guint wallpaper_allocation_failed : 1;
-};
-
-enum
-{
- PROP_META_DISPLAY = 1,
- PROP_MONITOR,
-};
-
-G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT)
-
-static gboolean texture_has_alpha (CoglTexture *texture);
-
-static GSList *all_backgrounds = NULL;
-
-static void
-free_fbos (MetaBackground *self)
-{
- int i;
-
- for (i = 0; i < self->n_monitors; i++)
- {
- MetaBackgroundMonitor *monitor = &self->monitors[i];
-
- g_clear_object (&monitor->fbo);
- cogl_clear_object (&monitor->texture);
- }
-}
-
-static void
-free_color_texture (MetaBackground *self)
-{
- cogl_clear_object (&self->color_texture);
-}
-
-static void
-free_wallpaper_texture (MetaBackground *self)
-{
- cogl_clear_object (&self->wallpaper_texture);
-
- self->wallpaper_allocation_failed = FALSE;
-}
-
-static void
-invalidate_monitor_backgrounds (MetaBackground *self)
-{
- free_fbos (self);
- g_clear_pointer (&self->monitors, g_free);
- self->n_monitors = 0;
-
- if (self->display)
- {
- int i;
-
- self->n_monitors = meta_display_get_n_monitors (self->display);
- self->monitors = g_new0 (MetaBackgroundMonitor, self->n_monitors);
-
- for (i = 0; i < self->n_monitors; i++)
- self->monitors[i].dirty = TRUE;
- }
-}
-
-static void
-on_monitors_changed (MetaBackground *self)
-{
- invalidate_monitor_backgrounds (self);
-}
-
-static void
-set_display (MetaBackground *self,
- MetaDisplay *display)
-{
- g_set_object (&self->display, display);
-
- invalidate_monitor_backgrounds (self);
-}
-
-static void
-meta_background_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- set_display (META_BACKGROUND (object), g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaBackground *self = META_BACKGROUND (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- g_value_set_object (value, self->display);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-need_prerender (MetaBackground *self)
-{
- CoglTexture *texture1 = self->background_image1 ? meta_background_image_get_texture (self->background_image1) : NULL;
- CoglTexture *texture2 = self->background_image2 ? meta_background_image_get_texture (self->background_image2) : NULL;
-
- if (texture1 == NULL && texture2 == NULL)
- return FALSE;
-
- if (texture2 == NULL && self->style == G_DESKTOP_BACKGROUND_STYLE_WALLPAPER)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-mark_changed (MetaBackground *self)
-{
- int i;
-
- if (!need_prerender (self))
- free_fbos (self);
-
- for (i = 0; i < self->n_monitors; i++)
- self->monitors[i].dirty = TRUE;
-
- g_signal_emit (self, signals[CHANGED], 0);
-}
-
-static void
-on_background_loaded (MetaBackgroundImage *image,
- MetaBackground *self)
-{
- mark_changed (self);
-}
-
-static gboolean
-file_equal0 (GFile *file1,
- GFile *file2)
-{
- if (file1 == file2)
- return TRUE;
-
- if ((file1 == NULL) || (file2 == NULL))
- return FALSE;
-
- return g_file_equal (file1, file2);
-}
-
-static void
-set_file (MetaBackground *self,
- GFile **filep,
- MetaBackgroundImage **imagep,
- GFile *file,
- gboolean force_reload)
-{
- if (force_reload || !file_equal0 (*filep, file))
- {
- if (*imagep)
- {
- g_signal_handlers_disconnect_by_func (*imagep,
- (gpointer)on_background_loaded,
- self);
- g_clear_object (imagep);
- }
-
- g_set_object (filep, file);
-
- if (file)
- {
- MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
-
- *imagep = meta_background_image_cache_load (cache, file);
- g_signal_connect (*imagep, "loaded",
- G_CALLBACK (on_background_loaded), self);
- }
- }
-}
-
-static void
-on_gl_video_memory_purged (MetaBackground *self)
-{
- MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
-
- /* The GPU memory that just got invalidated is the texture inside
- * self->background_image1,2 and/or its mipmaps. However, to save memory the
- * original pixbuf isn't kept in RAM so we can't do a simple re-upload. The
- * only copy of the image was the one in texture memory that got invalidated.
- * So we need to do a full reload from disk.
- */
- if (self->file1)
- {
- meta_background_image_cache_purge (cache, self->file1);
- set_file (self, &self->file1, &self->background_image1, self->file1, TRUE);
- }
-
- if (self->file2)
- {
- meta_background_image_cache_purge (cache, self->file2);
- set_file (self, &self->file2, &self->background_image2, self->file2, TRUE);
- }
-
- mark_changed (self);
-}
-
-static void
-meta_background_dispose (GObject *object)
-{
- MetaBackground *self = META_BACKGROUND (object);
-
- free_color_texture (self);
- free_wallpaper_texture (self);
-
- set_file (self, &self->file1, &self->background_image1, NULL, FALSE);
- set_file (self, &self->file2, &self->background_image2, NULL, FALSE);
-
- set_display (self, NULL);
-
- G_OBJECT_CLASS (meta_background_parent_class)->dispose (object);
-}
-
-static void
-meta_background_finalize (GObject *object)
-{
- all_backgrounds = g_slist_remove (all_backgrounds, object);
-
- G_OBJECT_CLASS (meta_background_parent_class)->finalize (object);
-}
-
-static void
-meta_background_constructed (GObject *object)
-{
- MetaBackground *self = META_BACKGROUND (object);
- MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
-
- G_OBJECT_CLASS (meta_background_parent_class)->constructed (object);
-
- g_signal_connect_object (self->display, "gl-video-memory-purged",
- G_CALLBACK (on_gl_video_memory_purged), object, G_CONNECT_SWAPPED);
-
- g_signal_connect_object (monitor_manager, "monitors-changed",
- G_CALLBACK (on_monitors_changed), self,
- G_CONNECT_SWAPPED);
-}
-
-static void
-meta_background_class_init (MetaBackgroundClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- object_class->dispose = meta_background_dispose;
- object_class->finalize = meta_background_finalize;
- object_class->constructed = meta_background_constructed;
- object_class->set_property = meta_background_set_property;
- object_class->get_property = meta_background_get_property;
-
- signals[CHANGED] =
- g_signal_new ("changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- param_spec = g_param_spec_object ("meta-display",
- "MetaDisplay",
- "MetaDisplay",
- META_TYPE_DISPLAY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_META_DISPLAY,
- param_spec);
-
-}
-
-static void
-meta_background_init (MetaBackground *self)
-{
- all_backgrounds = g_slist_prepend (all_backgrounds, self);
-}
-
-static void
-set_texture_area_from_monitor_area (cairo_rectangle_int_t *monitor_area,
- cairo_rectangle_int_t *texture_area)
-{
- texture_area->x = 0;
- texture_area->y = 0;
- texture_area->width = monitor_area->width;
- texture_area->height = monitor_area->height;
-}
-
-static void
-get_texture_area (MetaBackground *self,
- cairo_rectangle_int_t *monitor_rect,
- float monitor_scale,
- CoglTexture *texture,
- cairo_rectangle_int_t *texture_area)
-{
- cairo_rectangle_int_t image_area;
- int screen_width, screen_height;
- float texture_width, texture_height;
- float monitor_x_scale, monitor_y_scale;
-
- texture_width = cogl_texture_get_width (texture);
- texture_height = cogl_texture_get_height (texture);
-
- switch (self->style)
- {
- case G_DESKTOP_BACKGROUND_STYLE_STRETCHED:
- default:
- /* paint region is whole actor, and the texture
- * is scaled disproportionately to fit the actor
- */
- set_texture_area_from_monitor_area (monitor_rect, texture_area);
- break;
- case G_DESKTOP_BACKGROUND_STYLE_WALLPAPER:
- meta_display_get_size (self->display, &screen_width, &screen_height);
-
- /* Start off by centering a tile in the middle of the
- * total screen area taking care of the monitor scaling.
- */
- image_area.x = (screen_width - texture_width) / 2.0;
- image_area.y = (screen_height - texture_height) / 2.0;
- image_area.width = texture_width;
- image_area.height = texture_height;
-
- /* Translate into the coordinate system of the particular monitor */
- image_area.x -= monitor_rect->x;
- image_area.y -= monitor_rect->y;
-
- *texture_area = image_area;
- break;
- case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
- /* paint region is the original image size centered in the actor,
- * and the texture is scaled to the original image size */
- image_area.width = texture_width;
- image_area.height = texture_height;
- image_area.x = monitor_rect->width / 2 - image_area.width / 2;
- image_area.y = monitor_rect->height / 2 - image_area.height / 2;
-
- *texture_area = image_area;
- break;
- case G_DESKTOP_BACKGROUND_STYLE_SCALED:
- case G_DESKTOP_BACKGROUND_STYLE_ZOOM:
- /* paint region is the actor size in one dimension, and centered and
- * scaled by proportional amount in the other dimension.
- *
- * SCALED forces the centered dimension to fit on screen.
- * ZOOM forces the centered dimension to grow off screen
- */
- monitor_x_scale = monitor_rect->width / texture_width;
- monitor_y_scale = monitor_rect->height / texture_height;
-
- if ((self->style == G_DESKTOP_BACKGROUND_STYLE_SCALED &&
- (monitor_x_scale < monitor_y_scale)) ||
- (self->style == G_DESKTOP_BACKGROUND_STYLE_ZOOM &&
- (monitor_x_scale > monitor_y_scale)))
- {
- /* Fill image to exactly fit actor horizontally */
- image_area.width = monitor_rect->width;
- image_area.height = texture_height * monitor_x_scale;
-
- /* Position image centered vertically in actor */
- image_area.x = 0;
- image_area.y = monitor_rect->height / 2 - image_area.height / 2;
- }
- else
- {
- /* Scale image to exactly fit actor vertically */
- image_area.width = texture_width * monitor_y_scale;
- image_area.height = monitor_rect->height;
-
- /* Position image centered horizontally in actor */
- image_area.x = monitor_rect->width / 2 - image_area.width / 2;
- image_area.y = 0;
- }
-
- *texture_area = image_area;
- break;
-
- case G_DESKTOP_BACKGROUND_STYLE_SPANNED:
- {
- /* paint region is the union of all monitors, with the origin
- * of the region set to align with monitor associated with the background.
- */
- meta_display_get_size (self->display, &screen_width, &screen_height);
-
- /* unclipped texture area is whole screen, scaled depending on monitor */
- image_area.width = screen_width * monitor_scale;
- image_area.height = screen_height * monitor_scale;
-
- /* But make (0,0) line up with the appropriate monitor */
- image_area.x = -monitor_rect->x;
- image_area.y = -monitor_rect->y;
-
- *texture_area = image_area;
- break;
- }
- }
-}
-
-static gboolean
-draw_texture (MetaBackground *self,
- CoglFramebuffer *framebuffer,
- CoglPipeline *pipeline,
- CoglTexture *texture,
- cairo_rectangle_int_t *monitor_area,
- float monitor_scale)
-{
- cairo_rectangle_int_t texture_area;
- gboolean bare_region_visible;
-
- get_texture_area (self, monitor_area, monitor_scale, texture, &texture_area);
-
- switch (self->style)
- {
- case G_DESKTOP_BACKGROUND_STYLE_STRETCHED:
- case G_DESKTOP_BACKGROUND_STYLE_WALLPAPER:
- case G_DESKTOP_BACKGROUND_STYLE_ZOOM:
- case G_DESKTOP_BACKGROUND_STYLE_SPANNED:
- /* Draw the entire monitor */
- cogl_framebuffer_draw_textured_rectangle (framebuffer,
- pipeline,
- 0,
- 0,
- monitor_area->width,
- monitor_area->height,
- - texture_area.x / (float)texture_area.width,
- - texture_area.y / (float)texture_area.height,
- (monitor_area->width - texture_area.x) / (float)texture_area.width,
- (monitor_area->height - texture_area.y) / (float)texture_area.height);
-
- bare_region_visible = texture_has_alpha (texture);
-
- /* Draw just the texture */
- break;
- case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
- case G_DESKTOP_BACKGROUND_STYLE_SCALED:
- cogl_framebuffer_draw_textured_rectangle (framebuffer,
- pipeline,
- texture_area.x, texture_area.y,
- texture_area.x + texture_area.width,
- texture_area.y + texture_area.height,
- 0, 0, 1.0, 1.0);
- bare_region_visible = texture_has_alpha (texture) || memcmp (&texture_area, monitor_area, sizeof (cairo_rectangle_int_t)) != 0;
- break;
- case G_DESKTOP_BACKGROUND_STYLE_NONE:
- bare_region_visible = TRUE;
- break;
- default:
- g_return_val_if_reached(FALSE);
- }
-
- return bare_region_visible;
-}
-
-static void
-ensure_color_texture (MetaBackground *self)
-{
- if (self->color_texture == NULL)
- {
- ClutterBackend *backend = clutter_get_default_backend ();
- CoglContext *ctx = clutter_backend_get_cogl_context (backend);
- GError *error = NULL;
- uint8_t pixels[6];
- int width, height;
-
- if (self->shading_direction == G_DESKTOP_BACKGROUND_SHADING_SOLID)
- {
- width = 1;
- height = 1;
-
- pixels[0] = self->color.red;
- pixels[1] = self->color.green;
- pixels[2] = self->color.blue;
- }
- else
- {
- switch (self->shading_direction)
- {
- case G_DESKTOP_BACKGROUND_SHADING_VERTICAL:
- width = 1;
- height = 2;
- break;
- case G_DESKTOP_BACKGROUND_SHADING_HORIZONTAL:
- width = 2;
- height = 1;
- break;
- default:
- g_return_if_reached ();
- }
-
- pixels[0] = self->color.red;
- pixels[1] = self->color.green;
- pixels[2] = self->color.blue;
- pixels[3] = self->second_color.red;
- pixels[4] = self->second_color.green;
- pixels[5] = self->second_color.blue;
- }
-
- self->color_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
- COGL_PIXEL_FORMAT_RGB_888,
- width * 3,
- pixels,
- &error));
-
- if (error != NULL)
- {
- meta_warning ("Failed to allocate color texture: %s", error->message);
- g_error_free (error);
- }
- }
-}
-
-typedef enum
-{
- PIPELINE_REPLACE,
- PIPELINE_ADD,
- PIPELINE_OVER_REVERSE,
-} PipelineType;
-
-static CoglPipeline *
-create_pipeline (PipelineType type)
-{
- const char * const blend_strings[3] = {
- [PIPELINE_REPLACE] = "RGBA = ADD (SRC_COLOR, 0)",
- [PIPELINE_ADD] = "RGBA = ADD (SRC_COLOR, DST_COLOR)",
- [PIPELINE_OVER_REVERSE] = "RGBA = ADD (SRC_COLOR * (1 - DST_COLOR[A]), DST_COLOR)",
- };
- static CoglPipeline *templates[3];
-
- if (templates[type] == NULL)
- {
- templates[type] = meta_create_texture_pipeline (NULL);
- cogl_pipeline_set_blend (templates[type], blend_strings[type], NULL);
- }
-
- cogl_pipeline_set_layer_filters (templates[type],
- 0,
- COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR,
- COGL_PIPELINE_FILTER_LINEAR);
-
- return cogl_pipeline_copy (templates[type]);
-}
-
-static gboolean
-texture_has_alpha (CoglTexture *texture)
-{
- if (!texture)
- return FALSE;
-
- switch (cogl_texture_get_components (texture))
- {
- case COGL_TEXTURE_COMPONENTS_A:
- case COGL_TEXTURE_COMPONENTS_RGBA:
- return TRUE;
- case COGL_TEXTURE_COMPONENTS_RG:
- case COGL_TEXTURE_COMPONENTS_RGB:
- case COGL_TEXTURE_COMPONENTS_DEPTH:
- return FALSE;
- default:
- g_assert_not_reached ();
- return FALSE;
- }
-}
-
-static gboolean
-ensure_wallpaper_texture (MetaBackground *self,
- CoglTexture *texture)
-{
- if (self->wallpaper_texture == NULL && !self->wallpaper_allocation_failed)
- {
- int width = cogl_texture_get_width (texture);
- int height = cogl_texture_get_height (texture);
- CoglOffscreen *offscreen;
- CoglFramebuffer *fbo;
- GError *catch_error = NULL;
- CoglPipeline *pipeline;
-
- self->wallpaper_texture = meta_create_texture (width, height,
- COGL_TEXTURE_COMPONENTS_RGBA,
- META_TEXTURE_FLAGS_NONE);
- offscreen = cogl_offscreen_new_with_texture (self->wallpaper_texture);
- fbo = COGL_FRAMEBUFFER (offscreen);
-
- if (!cogl_framebuffer_allocate (fbo, &catch_error))
- {
- /* This probably means that the size of the wallpapered texture is larger
- * than the maximum texture size; we treat it as permanent until the
- * background is changed again.
- */
- g_error_free (catch_error);
-
- cogl_clear_object (&self->wallpaper_texture);
- g_object_unref (fbo);
-
- self->wallpaper_allocation_failed = TRUE;
- return FALSE;
- }
-
- cogl_framebuffer_orthographic (fbo, 0, 0,
- width, height, -1., 1.);
-
- pipeline = create_pipeline (PIPELINE_REPLACE);
- cogl_pipeline_set_layer_texture (pipeline, 0, texture);
- cogl_framebuffer_draw_textured_rectangle (fbo, pipeline, 0, 0, width, height,
- 0., 0., 1., 1.);
- cogl_object_unref (pipeline);
-
- if (texture_has_alpha (texture))
- {
- ensure_color_texture (self);
-
- pipeline = create_pipeline (PIPELINE_OVER_REVERSE);
- cogl_pipeline_set_layer_texture (pipeline, 0, self->color_texture);
- cogl_framebuffer_draw_rectangle (fbo, pipeline, 0, 0, width, height);
- cogl_object_unref (pipeline);
- }
-
- g_object_unref (fbo);
- }
-
- return self->wallpaper_texture != NULL;
-}
-
-static CoglPipelineWrapMode
-get_wrap_mode (GDesktopBackgroundStyle style)
-{
- switch (style)
- {
- case G_DESKTOP_BACKGROUND_STYLE_WALLPAPER:
- return COGL_PIPELINE_WRAP_MODE_REPEAT;
- case G_DESKTOP_BACKGROUND_STYLE_NONE:
- case G_DESKTOP_BACKGROUND_STYLE_STRETCHED:
- case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
- case G_DESKTOP_BACKGROUND_STYLE_SCALED:
- case G_DESKTOP_BACKGROUND_STYLE_ZOOM:
- case G_DESKTOP_BACKGROUND_STYLE_SPANNED:
- default:
- return COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE;
- }
-}
-
-static int
-get_best_mipmap_level (CoglTexture *texture,
- int visible_width,
- int visible_height)
-{
- int mipmap_width = cogl_texture_get_width (texture);
- int mipmap_height = cogl_texture_get_height (texture);
- int halves = 0;
-
- while (mipmap_width >= visible_width && mipmap_height >= visible_height)
- {
- halves++;
- mipmap_width /= 2;
- mipmap_height /= 2;
- }
-
- return MAX (0, halves - 1);
-}
-
-CoglTexture *
-meta_background_get_texture (MetaBackground *self,
- int monitor_index,
- cairo_rectangle_int_t *texture_area,
- CoglPipelineWrapMode *wrap_mode)
-{
- MetaBackgroundMonitor *monitor;
- MetaRectangle geometry;
- cairo_rectangle_int_t monitor_area;
- CoglTexture *texture1, *texture2;
- float monitor_scale;
-
- g_return_val_if_fail (META_IS_BACKGROUND (self), NULL);
- g_return_val_if_fail (monitor_index >= 0 && monitor_index < self->n_monitors, NULL);
-
- monitor = &self->monitors[monitor_index];
-
- meta_display_get_monitor_geometry (self->display, monitor_index, &geometry);
- monitor_scale = meta_display_get_monitor_scale (self->display, monitor_index);
- monitor_area.x = geometry.x;
- monitor_area.y = geometry.y;
- monitor_area.width = geometry.width;
- monitor_area.height = geometry.height;
-
- texture1 = self->background_image1 ? meta_background_image_get_texture (self->background_image1) : NULL;
- texture2 = self->background_image2 ? meta_background_image_get_texture (self->background_image2) : NULL;
-
- if (texture1 == NULL && texture2 == NULL)
- {
- ensure_color_texture (self);
- if (texture_area)
- set_texture_area_from_monitor_area (&monitor_area, texture_area);
- if (wrap_mode)
- *wrap_mode = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE;
- return self->color_texture;
- }
-
- if (texture2 == NULL && self->style == G_DESKTOP_BACKGROUND_STYLE_WALLPAPER &&
- self->shading_direction == G_DESKTOP_BACKGROUND_SHADING_SOLID &&
- ensure_wallpaper_texture (self, texture1))
- {
- if (texture_area)
- get_texture_area (self, &monitor_area, monitor_scale,
- self->wallpaper_texture, texture_area);
- if (wrap_mode)
- *wrap_mode = COGL_PIPELINE_WRAP_MODE_REPEAT;
- return self->wallpaper_texture;
- }
-
- if (monitor->dirty)
- {
- GError *catch_error = NULL;
- gboolean bare_region_visible = FALSE;
- int texture_width, texture_height;
-
- if (meta_is_stage_views_scaled ())
- {
- texture_width = monitor_area.width * monitor_scale;
- texture_height = monitor_area.height * monitor_scale;
- }
- else
- {
- texture_width = monitor_area.width;
- texture_height = monitor_area.height;
- }
-
- if (monitor->texture == NULL)
- {
- CoglOffscreen *offscreen;
-
- monitor->texture = meta_create_texture (texture_width,
- texture_height,
- COGL_TEXTURE_COMPONENTS_RGB,
- META_TEXTURE_FLAGS_NONE);
- offscreen = cogl_offscreen_new_with_texture (monitor->texture);
- monitor->fbo = COGL_FRAMEBUFFER (offscreen);
- }
-
- if (self->style != G_DESKTOP_BACKGROUND_STYLE_WALLPAPER)
- {
- monitor_area.x *= monitor_scale;
- monitor_area.y *= monitor_scale;
- monitor_area.width *= monitor_scale;
- monitor_area.height *= monitor_scale;
- }
-
- if (!cogl_framebuffer_allocate (monitor->fbo, &catch_error))
- {
- /* Texture or framebuffer allocation failed; it's unclear why this happened;
- * we'll try again the next time this is called. (MetaBackgroundActor
- * caches the result, so user might be left without a background.)
- */
- cogl_clear_object (&monitor->texture);
- g_clear_object (&monitor->fbo);
-
- g_error_free (catch_error);
- return NULL;
- }
-
- cogl_framebuffer_orthographic (monitor->fbo, 0, 0,
- monitor_area.width, monitor_area.height, -1., 1.);
-
- if (texture2 != NULL && self->blend_factor != 0.0)
- {
- CoglPipeline *pipeline = create_pipeline (PIPELINE_REPLACE);
- int mipmap_level;
-
- mipmap_level = get_best_mipmap_level (texture2,
- texture_width,
- texture_height);
-
- cogl_pipeline_set_color4f (pipeline,
- self->blend_factor, self->blend_factor, self->blend_factor, self->blend_factor);
- cogl_pipeline_set_layer_texture (pipeline, 0, texture2);
- cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style));
- cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level);
-
- bare_region_visible = draw_texture (self,
- monitor->fbo, pipeline,
- texture2, &monitor_area,
- monitor_scale);
-
- cogl_object_unref (pipeline);
- }
- else
- {
- cogl_framebuffer_clear4f (monitor->fbo,
- COGL_BUFFER_BIT_COLOR,
- 0.0, 0.0, 0.0, 0.0);
- }
-
- if (texture1 != NULL && self->blend_factor != 1.0)
- {
- CoglPipeline *pipeline = create_pipeline (PIPELINE_ADD);
- int mipmap_level;
-
- mipmap_level = get_best_mipmap_level (texture1,
- texture_width,
- texture_height);
-
- cogl_pipeline_set_color4f (pipeline,
- (1 - self->blend_factor),
- (1 - self->blend_factor),
- (1 - self->blend_factor),
- (1 - self->blend_factor));
- cogl_pipeline_set_layer_texture (pipeline, 0, texture1);
- cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style));
- cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level);
-
- bare_region_visible = bare_region_visible || draw_texture (self,
- monitor->fbo, pipeline,
- texture1, &monitor_area,
- monitor_scale);
-
- cogl_object_unref (pipeline);
- }
-
- if (bare_region_visible)
- {
- CoglPipeline *pipeline = create_pipeline (PIPELINE_OVER_REVERSE);
-
- ensure_color_texture (self);
- cogl_pipeline_set_layer_texture (pipeline, 0, self->color_texture);
- cogl_framebuffer_draw_rectangle (monitor->fbo,
- pipeline,
- 0, 0,
- monitor_area.width, monitor_area.height);
- cogl_object_unref (pipeline);
- }
-
- monitor->dirty = FALSE;
- }
-
- if (texture_area)
- set_texture_area_from_monitor_area (&geometry, texture_area);
-
- if (wrap_mode)
- *wrap_mode = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE;
- return monitor->texture;
-}
-
-MetaBackground *
-meta_background_new (MetaDisplay *display)
-{
- return g_object_new (META_TYPE_BACKGROUND,
- "meta-display", display,
- NULL);
-}
-
-void
-meta_background_set_color (MetaBackground *self,
- ClutterColor *color)
-{
- ClutterColor dummy = { 0 };
-
- g_return_if_fail (META_IS_BACKGROUND (self));
- g_return_if_fail (color != NULL);
-
- meta_background_set_gradient (self,
- G_DESKTOP_BACKGROUND_SHADING_SOLID,
- color, &dummy);
-}
-
-void
-meta_background_set_gradient (MetaBackground *self,
- GDesktopBackgroundShading shading_direction,
- ClutterColor *color,
- ClutterColor *second_color)
-{
- g_return_if_fail (META_IS_BACKGROUND (self));
- g_return_if_fail (color != NULL);
- g_return_if_fail (second_color != NULL);
-
- self->shading_direction = shading_direction;
- self->color = *color;
- self->second_color = *second_color;
-
- free_color_texture (self);
- free_wallpaper_texture (self);
- mark_changed (self);
-}
-
-/**
- * meta_background_set_file:
- * @self: a #MetaBackground
- * @file: (nullable): a #GFile representing the background file
- * @style: the background style to apply
- *
- * Set the background to @file
- */
-void
-meta_background_set_file (MetaBackground *self,
- GFile *file,
- GDesktopBackgroundStyle style)
-{
- g_return_if_fail (META_IS_BACKGROUND (self));
-
- meta_background_set_blend (self, file, NULL, 0.0, style);
-}
-
-void
-meta_background_set_blend (MetaBackground *self,
- GFile *file1,
- GFile *file2,
- double blend_factor,
- GDesktopBackgroundStyle style)
-{
- g_return_if_fail (META_IS_BACKGROUND (self));
- g_return_if_fail (blend_factor >= 0.0 && blend_factor <= 1.0);
-
- set_file (self, &self->file1, &self->background_image1, file1, FALSE);
- set_file (self, &self->file2, &self->background_image2, file2, FALSE);
-
- self->blend_factor = blend_factor;
- self->style = style;
-
- free_wallpaper_texture (self);
- mark_changed (self);
-}
-
-void
-meta_background_refresh_all (void)
-{
- GSList *l;
-
- for (l = all_backgrounds; l; l = l->next)
- mark_changed (l->data);
-}
diff --git a/src/compositor/meta-compositor-native.c b/src/compositor/meta-compositor-native.c
deleted file mode 100644
index 00f66b70d..000000000
--- a/src/compositor/meta-compositor-native.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2019 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include "compositor/meta-compositor-native.h"
-
-#include "backends/meta-logical-monitor.h"
-#include "compositor/meta-surface-actor-wayland.h"
-
-struct _MetaCompositorNative
-{
- MetaCompositorServer parent;
-};
-
-G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
- META_TYPE_COMPOSITOR_SERVER)
-
-static MetaRendererView *
-get_window_view (MetaRenderer *renderer,
- MetaWindow *window)
-{
- GList *l;
- MetaRendererView *view_found = NULL;
-
- for (l = meta_renderer_get_views (renderer); l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- MetaRectangle view_layout;
-
- clutter_stage_view_get_layout (stage_view, &view_layout);
-
- if (meta_rectangle_equal (&window->buffer_rect,
- &view_layout))
- {
- if (view_found)
- return NULL;
- view_found = META_RENDERER_VIEW (stage_view);
- }
- }
-
- return view_found;
-}
-
-static void
-maybe_assign_primary_plane (MetaCompositor *compositor)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaWindowActor *window_actor;
- MetaWindow *window;
- MetaRendererView *view;
- CoglFramebuffer *framebuffer;
- CoglOnscreen *onscreen;
- MetaSurfaceActor *surface_actor;
- MetaSurfaceActorWayland *surface_actor_wayland;
- g_autoptr (CoglScanout) scanout = NULL;
-
- if (meta_compositor_is_unredirect_inhibited (compositor))
- return;
-
- window_actor = meta_compositor_get_top_window_actor (compositor);
- if (!window_actor)
- return;
-
- if (meta_window_actor_effect_in_progress (window_actor))
- return;
-
- if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
- return;
-
- if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
- return;
-
- window = meta_window_actor_get_meta_window (window_actor);
- if (!window)
- return;
-
- view = get_window_view (renderer, window);
- if (!view)
- return;
-
- framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
- if (!COGL_IS_ONSCREEN (framebuffer))
- return;
-
- surface_actor = meta_window_actor_get_surface (window_actor);
- if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
- return;
-
- surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor);
- onscreen = COGL_ONSCREEN (framebuffer);
- scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
- onscreen);
- if (!scanout)
- return;
-
- clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
-}
-
-static void
-meta_compositor_native_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorClass *parent_class;
-
- maybe_assign_primary_plane (compositor);
-
- parent_class = META_COMPOSITOR_CLASS (meta_compositor_native_parent_class);
- parent_class->before_paint (compositor, stage_view);
-}
-
-MetaCompositorNative *
-meta_compositor_native_new (MetaDisplay *display,
- MetaBackend *backend)
-{
- return g_object_new (META_TYPE_COMPOSITOR_NATIVE,
- "display", display,
- "backend", backend,
- NULL);
-}
-
-static void
-meta_compositor_native_init (MetaCompositorNative *compositor_native)
-{
-}
-
-static void
-meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
-{
- MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
-
- compositor_class->before_paint = meta_compositor_native_before_paint;
-}
diff --git a/src/compositor/meta-compositor-native.h b/src/compositor/meta-compositor-native.h
deleted file mode 100644
index 2b1c65208..000000000
--- a/src/compositor/meta-compositor-native.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2019 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#ifndef META_COMPOSITOR_NATIVE_H
-#define META_COMPOSITOR_NATIVE_H
-
-#include "compositor/meta-compositor-server.h"
-
-#define META_TYPE_COMPOSITOR_NATIVE (meta_compositor_native_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCompositorNative, meta_compositor_native,
- META, COMPOSITOR_NATIVE, MetaCompositor)
-
-MetaCompositorNative * meta_compositor_native_new (MetaDisplay *display,
- MetaBackend *backend);
-
-#endif /* META_COMPOSITOR_NATIVE_H */
diff --git a/src/compositor/meta-compositor-server.c b/src/compositor/meta-compositor-server.c
deleted file mode 100644
index 179dc83ef..000000000
--- a/src/compositor/meta-compositor-server.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2019 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include "backends/meta-dnd-private.h"
-#include "compositor/meta-compositor-server.h"
-#include "core/display-private.h"
-
-G_DEFINE_TYPE (MetaCompositorServer, meta_compositor_server, META_TYPE_COMPOSITOR)
-
-static gboolean
-meta_compositor_server_manage (MetaCompositor *compositor,
- GError **error)
-{
- return TRUE;
-}
-
-static void
-meta_compositor_server_unmanage (MetaCompositor *compositor)
-{
-}
-
-static int64_t
-meta_compositor_server_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
- int64_t monotonic_time_us)
-{
- return meta_translate_to_high_res_xserver_time (monotonic_time_us);
-}
-
-static void
-meta_compositor_server_grab_begin (MetaCompositor *compositor)
-{
- MetaDisplay *display;
-
- display = meta_compositor_get_display (compositor);
- meta_display_sync_wayland_input_focus (display);
- meta_display_cancel_touch (display);
-
-#ifdef HAVE_WAYLAND
- meta_dnd_wayland_handle_begin_modal (compositor);
-#endif
-}
-
-static void
-meta_compositor_server_grab_end (MetaCompositor *compositor)
-{
- MetaDisplay *display;
-
- display = meta_compositor_get_display (compositor);
-#ifdef HAVE_WAYLAND
- meta_dnd_wayland_handle_end_modal (compositor);
-#endif
- meta_display_sync_wayland_input_focus (display);
-}
-
-MetaCompositorServer *
-meta_compositor_server_new (MetaDisplay *display,
- MetaBackend *backend)
-{
- return g_object_new (META_TYPE_COMPOSITOR_SERVER,
- "display", display,
- "backend", backend,
- NULL);
-}
-
-static void
-meta_compositor_server_init (MetaCompositorServer *compositor_server)
-{
-}
-
-static void
-meta_compositor_server_class_init (MetaCompositorServerClass *klass)
-{
- MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
-
- compositor_class->manage = meta_compositor_server_manage;
- compositor_class->unmanage = meta_compositor_server_unmanage;
- compositor_class->monotonic_to_high_res_xserver_time =
- meta_compositor_server_monotonic_to_high_res_xserver_time;
- compositor_class->grab_begin = meta_compositor_server_grab_begin;
- compositor_class->grab_end = meta_compositor_server_grab_end;
-}
diff --git a/src/compositor/meta-compositor-server.h b/src/compositor/meta-compositor-server.h
deleted file mode 100644
index 2bf8d5ec3..000000000
--- a/src/compositor/meta-compositor-server.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#ifndef META_COMPOSITOR_SERVER_H
-#define META_COMPOSITOR_SERVER_H
-
-#include "compositor/compositor-private.h"
-
-#define META_TYPE_COMPOSITOR_SERVER (meta_compositor_server_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaCompositorServer, meta_compositor_server,
- META, COMPOSITOR_SERVER, MetaCompositor)
-
-struct _MetaCompositorServerClass
-{
- MetaCompositorClass parent_class;
-};
-
-MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display,
- MetaBackend *backend);
-
-#endif /* META_COMPOSITOR_SERVER_H */
diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c
deleted file mode 100644
index a16604640..000000000
--- a/src/compositor/meta-compositor-x11.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright (C) 2019 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include "compositor/meta-compositor-x11.h"
-
-#include <X11/extensions/shape.h>
-#include <X11/extensions/Xcomposite.h>
-
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "backends/x11/meta-event-x11.h"
-#include "compositor/meta-sync-ring.h"
-#include "compositor/meta-window-actor-x11.h"
-#include "core/display-private.h"
-#include "x11/meta-x11-display-private.h"
-
-struct _MetaCompositorX11
-{
- MetaCompositor parent;
-
- Window output;
-
- gulong before_update_handler_id;
- gulong after_update_handler_id;
-
- gboolean frame_has_updated_xsurfaces;
- gboolean have_x11_sync_object;
-
- MetaWindow *unredirected_window;
-
- gboolean xserver_uses_monotonic_clock;
- int64_t xserver_time_query_time_us;
- int64_t xserver_time_offset_us;
-};
-
-G_DEFINE_TYPE (MetaCompositorX11, meta_compositor_x11, META_TYPE_COMPOSITOR)
-
-static void
-process_damage (MetaCompositorX11 *compositor_x11,
- XDamageNotifyEvent *damage_xevent,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
- MetaWindowActorX11 *window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
-
- meta_window_actor_x11_process_damage (window_actor_x11, damage_xevent);
-
- compositor_x11->frame_has_updated_xsurfaces = TRUE;
-}
-
-void
-meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11,
- XEvent *xevent,
- MetaWindow *window)
-{
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- MetaDisplay *display = meta_compositor_get_display (compositor);
- MetaX11Display *x11_display = display->x11_display;
- int damage_event_base;
-
- damage_event_base = meta_x11_display_get_damage_event_base (x11_display);
- if (xevent->type == damage_event_base + XDamageNotify)
- {
- /*
- * Core code doesn't handle damage events, so we need to extract the
- * MetaWindow ourselves.
- */
- if (!window)
- {
- Window xwindow;
-
- xwindow = ((XDamageNotifyEvent *) xevent)->drawable;
- window = meta_x11_display_lookup_x_window (x11_display, xwindow);
- }
-
- if (window)
- process_damage (compositor_x11, (XDamageNotifyEvent *) xevent, window);
- }
-
- if (compositor_x11->have_x11_sync_object)
- meta_sync_ring_handle_event (xevent);
-
- /*
- * Clutter needs to know about MapNotify events otherwise it will think the
- * stage is invisible
- */
- if (xevent->type == MapNotify)
- meta_x11_handle_event (xevent);
-}
-
-static void
-determine_server_clock_source (MetaCompositorX11 *compositor_x11)
-{
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- MetaDisplay *display = meta_compositor_get_display (compositor);
- MetaX11Display *x11_display = display->x11_display;
- uint32_t server_time_ms;
- int64_t server_time_us;
- int64_t translated_monotonic_now_us;
-
- server_time_ms = meta_x11_display_get_current_time_roundtrip (x11_display);
- server_time_us = ms2us (server_time_ms);
- translated_monotonic_now_us =
- meta_translate_to_high_res_xserver_time (g_get_monotonic_time ());
-
- /* If the server time offset is within a second of the monotonic time, we
- * assume that they are identical. This seems like a big margin, but we want
- * to be as robust as possible even if the system is under load and our
- * processing of the server response is delayed.
- */
- if (ABS (server_time_us - translated_monotonic_now_us) < s2us (1))
- compositor_x11->xserver_uses_monotonic_clock = TRUE;
- else
- compositor_x11->xserver_uses_monotonic_clock = FALSE;
-}
-
-static gboolean
-meta_compositor_x11_manage (MetaCompositor *compositor,
- GError **error)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
- MetaDisplay *display = meta_compositor_get_display (compositor);
- MetaX11Display *x11_display = display->x11_display;
- Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
- int composite_version;
- MetaBackend *backend = meta_get_backend ();
- Window xwindow;
-
- if (!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ||
- !META_X11_DISPLAY_HAS_DAMAGE (x11_display))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Missing required extension %s",
- !META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ?
- "composite" : "damage");
- return FALSE;
- }
-
- composite_version = ((x11_display->composite_major_version * 10) +
- x11_display->composite_minor_version);
- if (composite_version < 3)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "COMPOSITE extension 3.0 required (found %d.%d)",
- x11_display->composite_major_version,
- x11_display->composite_minor_version);
- return FALSE;
- }
-
- determine_server_clock_source (compositor_x11);
-
- meta_x11_display_set_cm_selection (display->x11_display);
-
- compositor_x11->output = display->x11_display->composite_overlay_window;
-
- xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
-
- XReparentWindow (xdisplay, xwindow, compositor_x11->output, 0, 0);
-
- meta_x11_display_clear_stage_input_region (display->x11_display);
-
- /*
- * Make sure there isn't any left-over output shape on the overlay window by
- * setting the whole screen to be an output region.
- *
- * Note: there doesn't seem to be any real chance of that because the X
- * server will destroy the overlay window when the last client using it
- * exits.
- */
- XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
- ShapeBounding, 0, 0, None);
-
- /*
- * Map overlay window before redirecting windows offscreen so we catch their
- * contents until we show the stage.
- */
- XMapWindow (xdisplay, compositor_x11->output);
-
- compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay);
-
- meta_compositor_redirect_x11_windows (META_COMPOSITOR (compositor));
-
- return TRUE;
-}
-
-static void
-meta_compositor_x11_unmanage (MetaCompositor *compositor)
-{
- MetaDisplay *display = meta_compositor_get_display (compositor);
- MetaX11Display *x11_display = display->x11_display;
- Display *xdisplay = x11_display->xdisplay;
- Window xroot = x11_display->xroot;
-
- /*
- * This is the most important part of cleanup - we have to do this before
- * giving up the window manager selection or the next window manager won't be
- * able to redirect subwindows
- */
- XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
-}
-
-/*
- * Sets an bounding shape on the COW so that the given window
- * is exposed. If window is %NULL it clears the shape again.
- *
- * Used so we can unredirect windows, by shaping away the part
- * of the COW, letting the raw window be seen through below.
- */
-static void
-shape_cow_for_window (MetaCompositorX11 *compositor_x11,
- MetaWindow *window)
-{
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- MetaDisplay *display = meta_compositor_get_display (compositor);
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- if (!window)
- {
- XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
- ShapeBounding, 0, 0, None);
- }
- else
- {
- XserverRegion output_region;
- XRectangle screen_rect, window_bounds;
- int width, height;
- MetaRectangle rect;
-
- meta_window_get_frame_rect (window, &rect);
-
- window_bounds.x = rect.x;
- window_bounds.y = rect.y;
- window_bounds.width = rect.width;
- window_bounds.height = rect.height;
-
- meta_display_get_size (display, &width, &height);
- screen_rect.x = 0;
- screen_rect.y = 0;
- screen_rect.width = width;
- screen_rect.height = height;
-
- output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1);
-
- XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region);
- XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
- ShapeBounding, 0, 0, output_region);
- XFixesDestroyRegion (xdisplay, output_region);
- }
-}
-
-static void
-set_unredirected_window (MetaCompositorX11 *compositor_x11,
- MetaWindow *window)
-{
- MetaWindow *prev_unredirected_window = compositor_x11->unredirected_window;
-
- if (prev_unredirected_window == window)
- return;
-
- if (prev_unredirected_window)
- {
- MetaWindowActor *window_actor;
- MetaWindowActorX11 *window_actor_x11;
-
- window_actor = meta_window_actor_from_window (prev_unredirected_window);
- window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
- meta_window_actor_x11_set_unredirected (window_actor_x11, FALSE);
- }
-
- shape_cow_for_window (compositor_x11, window);
- compositor_x11->unredirected_window = window;
-
- if (window)
- {
- MetaWindowActor *window_actor;
- MetaWindowActorX11 *window_actor_x11;
-
- window_actor = meta_window_actor_from_window (window);
- window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
- meta_window_actor_x11_set_unredirected (window_actor_x11, TRUE);
- }
-}
-
-static void
-maybe_unredirect_top_window (MetaCompositorX11 *compositor_x11)
-{
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- MetaWindow *window_to_unredirect = NULL;
- MetaWindowActor *window_actor;
- MetaWindowActorX11 *window_actor_x11;
-
- if (meta_compositor_is_unredirect_inhibited (compositor))
- goto out;
-
- window_actor = meta_compositor_get_top_window_actor (compositor);
- if (!window_actor)
- goto out;
-
- window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
- if (!meta_window_actor_x11_should_unredirect (window_actor_x11))
- goto out;
-
- window_to_unredirect = meta_window_actor_get_meta_window (window_actor);
-
-out:
- set_unredirected_window (compositor_x11, window_to_unredirect);
-}
-
-static void
-on_before_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
-
- if (compositor_x11->frame_has_updated_xsurfaces)
- {
- MetaDisplay *display = meta_compositor_get_display (compositor);
-
- /*
- * We need to make sure that any X drawing that happens before the
- * XDamageSubtract() for each window above is visible to subsequent GL
- * rendering; the standardized way to do this is GL_EXT_X11_sync_object.
- * Since this isn't implemented yet in mesa, we also have a path that
- * relies on the implementation of the open source drivers.
- *
- * Anything else, we just hope for the best.
- *
- * Xorg and open source driver specifics:
- *
- * The X server makes sure to flush drawing to the kernel before sending
- * out damage events, but since we use DamageReportBoundingBox there may
- * be drawing between the last damage event and the XDamageSubtract()
- * that needs to be flushed as well.
- *
- * Xorg always makes sure that drawing is flushed to the kernel before
- * writing events or responses to the client, so any round trip request
- * at this point is sufficient to flush the GLX buffers.
- */
- if (compositor_x11->have_x11_sync_object)
- compositor_x11->have_x11_sync_object = meta_sync_ring_insert_wait ();
- else
- XSync (display->x11_display->xdisplay, False);
- }
-}
-
-static void
-on_after_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
-
- if (compositor_x11->frame_has_updated_xsurfaces)
- {
- if (compositor_x11->have_x11_sync_object)
- compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame ();
-
- compositor_x11->frame_has_updated_xsurfaces = FALSE;
- }
-}
-
-static void
-meta_compositor_x11_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
- MetaCompositorClass *parent_class;
-
- maybe_unredirect_top_window (compositor_x11);
-
- parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
- parent_class->before_paint (compositor, stage_view);
-}
-
-static void
-meta_compositor_x11_remove_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
- MetaCompositorClass *parent_class;
-
- if (compositor_x11->unredirected_window == window)
- set_unredirected_window (compositor_x11, NULL);
-
- parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
- parent_class->remove_window (compositor, window);
-}
-
-static int64_t
-meta_compositor_x11_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
- int64_t monotonic_time_us)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
- int64_t now_us;
-
- if (compositor_x11->xserver_uses_monotonic_clock)
- return meta_translate_to_high_res_xserver_time (monotonic_time_us);
-
- now_us = g_get_monotonic_time ();
-
- if (compositor_x11->xserver_time_query_time_us == 0 ||
- now_us > (compositor_x11->xserver_time_query_time_us + s2us (10)))
- {
- MetaDisplay *display = meta_compositor_get_display (compositor);
- MetaX11Display *x11_display = display->x11_display;
- uint32_t xserver_time_ms;
- int64_t xserver_time_us;
-
- compositor_x11->xserver_time_query_time_us = now_us;
-
- xserver_time_ms =
- meta_x11_display_get_current_time_roundtrip (x11_display);
- xserver_time_us = ms2us (xserver_time_ms);
- compositor_x11->xserver_time_offset_us = xserver_time_us - now_us;
- }
-
- return monotonic_time_us + compositor_x11->xserver_time_offset_us;
-}
-
-static void
-meta_compositor_x11_grab_begin (MetaCompositor *compositor)
-{
- MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ());
-
- meta_backend_x11_sync_pointer (backend_x11);
-}
-
-static void
-meta_compositor_x11_grab_end (MetaCompositor *compositor)
-{
- MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ());
-
- meta_backend_x11_sync_pointer (backend_x11);
-}
-
-Window
-meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11)
-{
- return compositor_x11->output;
-}
-
-MetaCompositorX11 *
-meta_compositor_x11_new (MetaDisplay *display,
- MetaBackend *backend)
-{
- return g_object_new (META_TYPE_COMPOSITOR_X11,
- "display", display,
- "backend", backend,
- NULL);
-}
-
-static void
-meta_compositor_x11_constructed (GObject *object)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (object);
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- ClutterStage *stage = meta_compositor_get_stage (compositor);
-
- compositor_x11->before_update_handler_id =
- g_signal_connect (stage, "before-update",
- G_CALLBACK (on_before_update), compositor);
- compositor_x11->after_update_handler_id =
- g_signal_connect (stage, "after-update",
- G_CALLBACK (on_after_update), compositor);
-
- G_OBJECT_CLASS (meta_compositor_x11_parent_class)->constructed (object);
-}
-
-static void
-meta_compositor_x11_dispose (GObject *object)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (object);
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- ClutterStage *stage = meta_compositor_get_stage (compositor);
-
- if (compositor_x11->have_x11_sync_object)
- {
- meta_sync_ring_destroy ();
- compositor_x11->have_x11_sync_object = FALSE;
- }
-
- g_clear_signal_handler (&compositor_x11->before_update_handler_id, stage);
- g_clear_signal_handler (&compositor_x11->after_update_handler_id, stage);
-
- G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object);
-}
-
-static void
-meta_compositor_x11_init (MetaCompositorX11 *compositor_x11)
-{
-}
-
-static void
-meta_compositor_x11_class_init (MetaCompositorX11Class *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
-
- object_class->constructed = meta_compositor_x11_constructed;
- object_class->dispose = meta_compositor_x11_dispose;
-
- compositor_class->manage = meta_compositor_x11_manage;
- compositor_class->unmanage = meta_compositor_x11_unmanage;
- compositor_class->before_paint = meta_compositor_x11_before_paint;
- compositor_class->remove_window = meta_compositor_x11_remove_window;
- compositor_class->monotonic_to_high_res_xserver_time =
- meta_compositor_x11_monotonic_to_high_res_xserver_time;
- compositor_class->grab_begin = meta_compositor_x11_grab_begin;
- compositor_class->grab_end = meta_compositor_x11_grab_end;
-}
diff --git a/src/compositor/meta-compositor-x11.h b/src/compositor/meta-compositor-x11.h
deleted file mode 100644
index 42554feb3..000000000
--- a/src/compositor/meta-compositor-x11.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#ifndef META_COMPOSITOR_X11_H
-#define META_COMPOSITOR_X11_H
-
-#include "compositor/compositor-private.h"
-
-#define META_TYPE_COMPOSITOR_X11 (meta_compositor_x11_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCompositorX11, meta_compositor_x11,
- META, COMPOSITOR_X11, MetaCompositor)
-
-MetaCompositorX11 * meta_compositor_x11_new (MetaDisplay *display,
- MetaBackend *backend);
-
-void meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11,
- XEvent *xevent,
- MetaWindow *window);
-
-Window meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11);
-
-#endif /* META_COMPOSITOR_X11_H */
diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c
deleted file mode 100644
index 6f38c5e47..000000000
--- a/src/compositor/meta-cullable.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright (C) 2013 Red Hat
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Owen Taylor <otaylor@redhat.com>
- * Ray Strode <rstrode@redhat.com>
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include "config.h"
-
-#include "compositor/clutter-utils.h"
-#include "compositor/meta-cullable.h"
-
-G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR);
-
-static gboolean
-has_active_effects (ClutterActor *actor)
-{
- g_autoptr (GList) effects = NULL;
- GList *l;
-
- effects = clutter_actor_get_effects (actor);
- for (l = effects; l != NULL; l = l->next)
- {
- if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (l->data)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * SECTION:meta-cullable
- * @title: MetaCullable
- * @short_description: CPU culling operations for efficient drawing
- *
- * When we are painting a stack of 5-10 large actors, the standard
- * bottom-to-top method of drawing every actor results in a tremendous
- * amount of overdraw. If these actors are painting textures like
- * windows, it can easily max out the available memory bandwidth on a
- * low-end graphics chipset. It's even worse if window textures are
- * being accessed over the AGP bus.
- *
- * #MetaCullable is our solution. The basic technique applied here is to
- * do a pre-pass before painting where we walk each actor from top to bottom
- * and ask each actor to "cull itself out". We pass in a region it can copy
- * to clip its drawing to, and the actor can subtract its fully opaque pixels
- * so that actors underneath know not to draw there as well.
- */
-
-/**
- * meta_cullable_cull_out_children:
- * @cullable: The #MetaCullable
- * @unobscured_region: The unobscured region, as passed into cull_out()
- * @clip_region: The clip region, as passed into cull_out()
- *
- * This is a helper method for actors that want to recurse over their
- * child actors, and cull them out.
- *
- * See #MetaCullable and meta_cullable_cull_out() for more details.
- */
-void
-meta_cullable_cull_out_children (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- ClutterActor *actor = CLUTTER_ACTOR (cullable);
- ClutterActor *child;
- ClutterActorIter iter;
-
- clutter_actor_iter_init (&iter, actor);
- while (clutter_actor_iter_prev (&iter, &child))
- {
- float x, y;
- gboolean needs_culling;
-
- if (!META_IS_CULLABLE (child))
- continue;
-
- needs_culling = (unobscured_region != NULL && clip_region != NULL);
-
- if (needs_culling && !CLUTTER_ACTOR_IS_VISIBLE (child))
- needs_culling = FALSE;
-
- /* If an actor has effects applied, then that can change the area
- * it paints and the opacity, so we no longer can figure out what
- * portion of the actor is obscured and what portion of the screen
- * it obscures, so we skip the actor.
- *
- * This has a secondary beneficial effect: if a ClutterOffscreenEffect
- * is applied to an actor, then our clipped redraws interfere with the
- * caching of the FBO - even if we only need to draw a small portion
- * of the window right now, ClutterOffscreenEffect may use other portions
- * of the FBO later. So, skipping actors with effects applied also
- * prevents these bugs.
- *
- * Theoretically, we should check clutter_actor_get_offscreen_redirect()
- * as well for the same reason, but omitted for simplicity in the
- * hopes that no-one will do that.
- */
- if (needs_culling && has_active_effects (child))
- needs_culling = FALSE;
-
- if (needs_culling && !meta_cullable_is_untransformed (META_CULLABLE (child)))
- needs_culling = FALSE;
-
- if (needs_culling)
- {
- clutter_actor_get_position (child, &x, &y);
-
- /* Temporarily move to the coordinate system of the actor */
- cairo_region_translate (unobscured_region, - x, - y);
- cairo_region_translate (clip_region, - x, - y);
-
- meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region);
-
- cairo_region_translate (unobscured_region, x, y);
- cairo_region_translate (clip_region, x, y);
- }
- else
- {
- meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL);
- }
- }
-}
-
-/**
- * meta_cullable_reset_culling_children:
- * @cullable: The #MetaCullable
- *
- * This is a helper method for actors that want to recurse over their
- * child actors, and cull them out.
- *
- * See #MetaCullable and meta_cullable_reset_culling() for more details.
- */
-void
-meta_cullable_reset_culling_children (MetaCullable *cullable)
-{
- ClutterActor *actor = CLUTTER_ACTOR (cullable);
- ClutterActor *child;
- ClutterActorIter iter;
-
- clutter_actor_iter_init (&iter, actor);
- while (clutter_actor_iter_next (&iter, &child))
- {
- if (!META_IS_CULLABLE (child))
- continue;
-
- meta_cullable_reset_culling (META_CULLABLE (child));
- }
-}
-
-static gboolean
-meta_cullable_default_is_untransformed (MetaCullable *cullable)
-{
- float width, height;
- graphene_point3d_t verts[4];
-
- clutter_actor_get_size (CLUTTER_ACTOR (cullable), &width, &height);
- clutter_actor_get_abs_allocation_vertices (CLUTTER_ACTOR (cullable), verts);
-
- return meta_actor_vertices_are_untransformed (verts, width, height,
- NULL, NULL);
-}
-
-static void
-meta_cullable_default_init (MetaCullableInterface *iface)
-{
- iface->is_untransformed = meta_cullable_default_is_untransformed;
-}
-
-/**
- * meta_cullable_cull_out:
- * @cullable: The #MetaCullable
- * @unobscured_region: The unobscured region, in @cullable's space.
- * @clip_region: The clip region, in @cullable's space.
- *
- * When #MetaWindowGroup is painted, we walk over its direct cullable
- * children from top to bottom and ask themselves to "cull out". Cullables
- * can use @unobscured_region and @clip_region to clip their drawing. Actors
- * interested in eliminating overdraw should copy the @clip_region and only
- * paint those parts, as everything else has been obscured by actors above it.
- *
- * Actors that may have fully opaque parts should also subtract out a region
- * that is fully opaque from @unobscured_region and @clip_region.
- *
- * @unobscured_region and @clip_region are extremely similar. The difference
- * is that @clip_region starts off with the stage's clip, if Clutter detects
- * that we're doing a clipped redraw. @unobscured_region, however, starts off
- * with the full stage size, so actors that may want to record what parts of
- * their window are unobscured for e.g. scheduling repaints can do so.
- *
- * Actors that have children can also use the meta_cullable_cull_out_children()
- * helper method to do a simple cull across all their children.
- */
-void
-meta_cullable_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region);
-}
-
-/**
- * meta_cullable_is_untransformed:
- * @cullable: The #MetaCullable
- *
- * Check if a cullable is "untransformed" - which actually means transformed by
- * at most a integer-translation.
- */
-gboolean
-meta_cullable_is_untransformed (MetaCullable *cullable)
-{
- return META_CULLABLE_GET_IFACE (cullable)->is_untransformed (cullable);
-}
-
-/**
- * meta_cullable_reset_culling:
- * @cullable: The #MetaCullable
- *
- * Actors that copied data in their cull_out() implementation can now
- * reset their data, as the paint is now over. Additional paints may be
- * done by #ClutterClone or similar, and they should not be affected by
- * the culling operation.
- */
-void
-meta_cullable_reset_culling (MetaCullable *cullable)
-{
- META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable);
-}
diff --git a/src/compositor/meta-cullable.h b/src/compositor/meta-cullable.h
deleted file mode 100644
index 471681da3..000000000
--- a/src/compositor/meta-cullable.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2013 Red Hat
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Owen Taylor <otaylor@redhat.com>
- * Ray Strode <rstrode@redhat.com>
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#ifndef __META_CULLABLE_H__
-#define __META_CULLABLE_H__
-
-#include "clutter/clutter.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_CULLABLE (meta_cullable_get_type ())
-G_DECLARE_INTERFACE (MetaCullable, meta_cullable, META, CULLABLE, ClutterActor)
-
-struct _MetaCullableInterface
-{
- GTypeInterface g_iface;
-
- void (* cull_out) (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region);
- gboolean (* is_untransformed) (MetaCullable *cullable);
- void (* reset_culling) (MetaCullable *cullable);
-};
-
-void meta_cullable_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region);
-gboolean meta_cullable_is_untransformed (MetaCullable *cullable);
-void meta_cullable_reset_culling (MetaCullable *cullable);
-
-/* Utility methods for implementations */
-void meta_cullable_cull_out_children (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region);
-void meta_cullable_reset_culling_children (MetaCullable *cullable);
-
-G_END_DECLS
-
-#endif /* __META_CULLABLE_H__ */
-
diff --git a/src/compositor/meta-dnd-actor-private.h b/src/compositor/meta-dnd-actor-private.h
deleted file mode 100644
index 20be369eb..000000000
--- a/src/compositor/meta-dnd-actor-private.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * meta-dnd-actor-private.h: Actor for painting the DnD surface
- *
- * Copyright 2014 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Carlos Garnacho <carlosg@gnome.org>
- */
-
-#ifndef META_DND_ACTOR_PRIVATE_H
-#define META_DND_ACTOR_PRIVATE_H
-
-#include "compositor/meta-feedback-actor-private.h"
-
-/**
- * MetaDnDActor:
- *
- * This class handles the rendering of the DnD surface
- */
-
-#define META_TYPE_DND_ACTOR (meta_dnd_actor_get_type ())
-G_DECLARE_FINAL_TYPE (MetaDnDActor,
- meta_dnd_actor,
- META, DND_ACTOR,
- MetaFeedbackActor)
-
-
-ClutterActor *meta_dnd_actor_new (ClutterActor *drag_origin,
- int start_x,
- int start_y);
-
-void meta_dnd_actor_drag_finish (MetaDnDActor *self,
- gboolean success);
-
-#endif /* META_DND_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-dnd-actor.c b/src/compositor/meta-dnd-actor.c
deleted file mode 100644
index 80bffdeb7..000000000
--- a/src/compositor/meta-dnd-actor.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright 2014 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Carlos Garnacho <carlosg@gnome.org>
- */
-
-/**
- * SECTION:meta-dnd-actor
- * @title: MetaDnDActor
- * @short_description: Actor for painting the drag and drop surface
- *
- */
-
-#include "config.h"
-
-#include "compositor/meta-dnd-actor-private.h"
-#include "compositor/meta-window-actor-private.h"
-
-#include "clutter/clutter.h"
-
-#define DRAG_FAILED_DURATION 500
-
-enum
-{
- PROP_DRAG_ORIGIN = 1,
- PROP_DRAG_START_X,
- PROP_DRAG_START_Y
-};
-
-struct _MetaDnDActor
-{
- MetaFeedbackActor parent;
-
- ClutterActor *drag_origin;
- int drag_start_x;
- int drag_start_y;
-};
-
-G_DEFINE_TYPE (MetaDnDActor, meta_dnd_actor, META_TYPE_FEEDBACK_ACTOR)
-
-static void
-meta_dnd_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaDnDActor *self = META_DND_ACTOR (object);
-
- switch (prop_id)
- {
- case PROP_DRAG_ORIGIN:
- self->drag_origin = g_value_get_object (value);
- break;
- case PROP_DRAG_START_X:
- self->drag_start_x = g_value_get_int (value);
- break;
- case PROP_DRAG_START_Y:
- self->drag_start_y = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_dnd_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaDnDActor *self = META_DND_ACTOR (object);
-
- switch (prop_id)
- {
- case PROP_DRAG_ORIGIN:
- g_value_set_object (value, self->drag_origin);
- break;
- case PROP_DRAG_START_X:
- g_value_set_int (value, self->drag_start_x);
- break;
- case PROP_DRAG_START_Y:
- g_value_set_int (value, self->drag_start_y);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_dnd_actor_class_init (MetaDnDActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- object_class->set_property = meta_dnd_actor_set_property;
- object_class->get_property = meta_dnd_actor_get_property;
-
- pspec = g_param_spec_object ("drag-origin",
- "Drag origin",
- "The origin of the DnD operation",
- CLUTTER_TYPE_ACTOR,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_DRAG_ORIGIN,
- pspec);
-
- pspec = g_param_spec_int ("drag-start-x",
- "Drag start X",
- "The X axis of the drag start point",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_DRAG_START_X,
- pspec);
-
- pspec = g_param_spec_int ("drag-start-y",
- "Drag start Y",
- "The Y axis of the drag start point",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_DRAG_START_Y,
- pspec);
-}
-
-static void
-meta_dnd_actor_init (MetaDnDActor *self)
-{
-}
-
-/**
- * meta_dnd_actor_new:
- *
- * Creates a new actor to draw the current drag and drop surface.
- *
- * Return value: the newly created background actor
- */
-ClutterActor *
-meta_dnd_actor_new (ClutterActor *drag_origin,
- int drag_start_x,
- int drag_start_y)
-{
- MetaDnDActor *self;
-
- self = g_object_new (META_TYPE_DND_ACTOR,
- "drag-origin", drag_origin,
- "drag-start-x", drag_start_x,
- "drag-start-y", drag_start_y,
- NULL);
-
- return CLUTTER_ACTOR (self);
-}
-
-static void
-drag_failed_complete (ClutterTimeline *timeline,
- gboolean is_finished,
- gpointer user_data)
-{
- ClutterActor *self = user_data;
-
- clutter_actor_remove_all_children (self);
- clutter_actor_destroy (self);
-}
-
-void
-meta_dnd_actor_drag_finish (MetaDnDActor *self,
- gboolean success)
-{
- ClutterActor *actor;
-
- g_return_if_fail (META_IS_DND_ACTOR (self));
-
- actor = CLUTTER_ACTOR (self);
-
- if (success)
- {
- clutter_actor_remove_all_children (CLUTTER_ACTOR (self));
- clutter_actor_destroy (CLUTTER_ACTOR (self));
- }
- else
- {
- ClutterTransition *transition;
-
- clutter_actor_save_easing_state (actor);
- clutter_actor_set_easing_mode (actor, CLUTTER_EASE_OUT_CUBIC);
- clutter_actor_set_easing_duration (actor, DRAG_FAILED_DURATION);
- clutter_actor_set_opacity (actor, 0);
-
- if (CLUTTER_ACTOR_IS_VISIBLE (self->drag_origin))
- {
- MetaWindowActor *origin_actor;
- float anchor_x, anchor_y;
- graphene_point_t dest;
- int origin_geometry_scale;
- int feedback_geometry_scale;
-
- clutter_actor_get_transformed_position (self->drag_origin,
- &dest.x, &dest.y);
-
- origin_actor = meta_window_actor_from_actor (self->drag_origin);
- g_return_if_fail (origin_actor);
- origin_geometry_scale =
- meta_window_actor_get_geometry_scale (origin_actor);
-
- meta_feedback_actor_get_anchor (META_FEEDBACK_ACTOR (self),
- &anchor_x, &anchor_y);
- feedback_geometry_scale =
- meta_feedback_actor_get_geometry_scale (META_FEEDBACK_ACTOR (self));
-
- dest.x += ((self->drag_start_x * origin_geometry_scale) -
- (anchor_x * feedback_geometry_scale));
- dest.y += ((self->drag_start_y * origin_geometry_scale) -
- (anchor_y * feedback_geometry_scale));
- clutter_actor_set_position (actor, dest.x, dest.y);
- }
-
- transition = clutter_actor_get_transition (actor, "opacity");
- g_signal_connect (transition, "stopped",
- G_CALLBACK (drag_failed_complete), self);
-
- clutter_actor_restore_easing_state (actor);
- }
-}
diff --git a/src/compositor/meta-dnd.c b/src/compositor/meta-dnd.c
deleted file mode 100644
index 8461690a2..000000000
--- a/src/compositor/meta-dnd.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright (C) 2016 Hyungwon Hwang
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "config.h"
-
-#include <gdk/gdkx.h>
-
-#include "meta/meta-backend.h"
-#include "compositor/compositor-private.h"
-#include "core/display-private.h"
-#include "backends/meta-dnd-private.h"
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "backends/x11/meta-stage-x11.h"
-#include "meta/meta-dnd.h"
-#include "x11/meta-x11-display-private.h"
-
-struct _MetaDndClass
-{
- GObjectClass parent_class;
-};
-
-#ifdef HAVE_WAYLAND
-#include "wayland/meta-wayland-private.h"
-#include "wayland/meta-wayland-data-device.h"
-#endif
-
-typedef struct _MetaDndPrivate MetaDndPrivate;
-
-struct _MetaDndPrivate
-{
-#ifdef HAVE_WAYLAND
- gulong handler_id[3];
-
- MetaCompositor *compositor;
- MetaWaylandCompositor *wl_compositor;
-#else
- /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
- gchar dummy;
-#endif
-};
-
-struct _MetaDnd
-{
- GObject parent;
-
- MetaDndPrivate *priv;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaDnd, meta_dnd, G_TYPE_OBJECT);
-
-enum
-{
- ENTER,
- POSITION_CHANGE,
- LEAVE,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static void
-meta_dnd_class_init (MetaDndClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- signals[ENTER] =
- g_signal_new ("dnd-enter",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- signals[POSITION_CHANGE] =
- g_signal_new ("dnd-position-change",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
-
- signals[LEAVE] =
- g_signal_new ("dnd-leave",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-static void
-meta_dnd_init (MetaDnd *dnd)
-{
-}
-
-void
-meta_dnd_init_xdnd (MetaX11Display *x11_display)
-{
- MetaBackend *backend = meta_get_backend ();
- Display *xdisplay = x11_display->xdisplay;
- Window xwindow, overlay_xwindow;
- long xdnd_version = 5;
-
- overlay_xwindow = x11_display->composite_overlay_window;
- xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
-
- XChangeProperty (xdisplay, xwindow,
- XInternAtom (xdisplay, "XdndAware", TRUE), XA_ATOM,
- 32, PropModeReplace,
- (const unsigned char *) &xdnd_version, 1);
-
- XChangeProperty (xdisplay, overlay_xwindow,
- XInternAtom (xdisplay, "XdndProxy", TRUE), XA_WINDOW,
- 32, PropModeReplace, (const unsigned char *) &xwindow, 1);
-
- /*
- * XdndProxy is additionally set on the proxy window as verification that the
- * XdndProxy property on the target window isn't a left-over
- */
- XChangeProperty (xdisplay, xwindow,
- XInternAtom (xdisplay, "XdndProxy", TRUE), XA_WINDOW,
- 32, PropModeReplace, (const unsigned char *) &xwindow, 1);
-}
-
-static void
-meta_dnd_notify_dnd_enter (MetaDnd *dnd)
-{
- g_signal_emit (dnd, signals[ENTER], 0);
-}
-
-static void
-meta_dnd_notify_dnd_position_change (MetaDnd *dnd,
- int x,
- int y)
-{
- g_signal_emit (dnd, signals[POSITION_CHANGE], 0, x, y);
-}
-
-static void
-meta_dnd_notify_dnd_leave (MetaDnd *dnd)
-{
- g_signal_emit (dnd, signals[LEAVE], 0);
-}
-
-/*
- * Process Xdnd events
- *
- * We pass the position and leave events to the plugin via a signal
- * where the actual drag & drop handling happens.
- *
- * http://www.freedesktop.org/wiki/Specifications/XDND
- */
-gboolean
-meta_dnd_handle_xdnd_event (MetaBackend *backend,
- MetaCompositorX11 *compositor_x11,
- Display *xdisplay,
- XEvent *xev)
-{
- MetaDnd *dnd = meta_backend_get_dnd (backend);
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- Window output_window;
- ClutterStage *stage;
-
- if (xev->xany.type != ClientMessage)
- return FALSE;
-
- output_window = meta_compositor_x11_get_output_xwindow (compositor_x11);
- stage = meta_compositor_get_stage (compositor);
- if (xev->xany.window != output_window &&
- xev->xany.window != meta_x11_get_stage_window (stage))
- return FALSE;
-
- if (xev->xclient.message_type == XInternAtom (xdisplay, "XdndPosition", TRUE))
- {
- XEvent xevent;
- Window src = xev->xclient.data.l[0];
-
- memset (&xevent, 0, sizeof(xevent));
- xevent.xany.type = ClientMessage;
- xevent.xany.display = xdisplay;
- xevent.xclient.window = src;
- xevent.xclient.message_type = XInternAtom (xdisplay, "XdndStatus", TRUE);
- xevent.xclient.format = 32;
- xevent.xclient.data.l[0] = output_window;
- /* flags: bit 0: will we accept the drop? bit 1: do we want more position messages */
- xevent.xclient.data.l[1] = 2;
- xevent.xclient.data.l[4] = None;
-
- XSendEvent (xdisplay, src, False, 0, &xevent);
-
- meta_dnd_notify_dnd_position_change (dnd,
- (int)(xev->xclient.data.l[2] >> 16),
- (int)(xev->xclient.data.l[2] & 0xFFFF));
-
- return TRUE;
- }
- else if (xev->xclient.message_type == XInternAtom (xdisplay, "XdndLeave", TRUE))
- {
- meta_dnd_notify_dnd_leave (dnd);
-
- return TRUE;
- }
- else if (xev->xclient.message_type == XInternAtom (xdisplay, "XdndEnter", TRUE))
- {
- meta_dnd_notify_dnd_enter (dnd);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-#ifdef HAVE_WAYLAND
-static void
-meta_dnd_wayland_on_motion_event (ClutterActor *actor,
- ClutterEvent *event,
- MetaDnd *dnd)
-{
- MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
- MetaWaylandDragGrab *current_grab;
- gfloat event_x, event_y;
-
- g_return_if_fail (event != NULL);
-
- clutter_event_get_coords (event, &event_x, &event_y);
- meta_dnd_notify_dnd_position_change (dnd, (int)event_x, (int)event_y);
-
- current_grab = meta_wayland_data_device_get_current_grab (&priv->wl_compositor->seat->data_device);
- if (current_grab)
- meta_wayland_drag_grab_update_feedback_actor (current_grab, event);
-}
-
-static void
-meta_dnd_wayland_end_notify (ClutterActor *actor,
- ClutterEvent *event,
- MetaDnd *dnd)
-{
- MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
-
- meta_wayland_data_device_end_drag (&priv->wl_compositor->seat->data_device);
- meta_dnd_wayland_handle_end_modal (priv->compositor);
-}
-
-static void
-meta_dnd_wayland_on_button_released (ClutterActor *actor,
- ClutterEvent *event,
- MetaDnd *dnd)
-{
- meta_dnd_wayland_end_notify (actor, event, dnd);
-}
-
-static void
-meta_dnd_wayland_on_key_pressed (ClutterActor *actor,
- ClutterEvent *event,
- MetaDnd *dnd)
-{
- guint key = clutter_event_get_key_symbol (event);
-
- if (key != CLUTTER_KEY_Escape)
- return;
-
- meta_dnd_wayland_end_notify (actor, event, dnd);
-}
-
-void
-meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor)
-{
- MetaWaylandCompositor *wl_compositor = meta_wayland_compositor_get_default ();
- MetaDnd *dnd = meta_backend_get_dnd (meta_get_backend ());
- MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
-
- if (priv->handler_id[0] == 0 &&
- meta_wayland_data_device_get_current_grab (&wl_compositor->seat->data_device) != NULL)
- {
- ClutterStage *stage = meta_compositor_get_stage (compositor);
-
- priv->compositor = compositor;
- priv->wl_compositor = wl_compositor;
-
- priv->handler_id[0] = g_signal_connect (stage,
- "motion-event",
- G_CALLBACK (meta_dnd_wayland_on_motion_event),
- dnd);
-
- priv->handler_id[1] = g_signal_connect (stage,
- "button-release-event",
- G_CALLBACK (meta_dnd_wayland_on_button_released),
- dnd);
-
- priv->handler_id[2] = g_signal_connect (stage,
- "key-press-event",
- G_CALLBACK (meta_dnd_wayland_on_key_pressed),
- dnd);
-
- meta_dnd_notify_dnd_enter (dnd);
- }
-}
-
-void
-meta_dnd_wayland_handle_end_modal (MetaCompositor *compositor)
-{
- MetaDnd *dnd = meta_backend_get_dnd (meta_get_backend ());
- MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
- ClutterStage *stage = meta_compositor_get_stage (compositor);
- unsigned int i;
-
- if (!priv->compositor)
- return;
-
- for (i = 0; i < G_N_ELEMENTS (priv->handler_id); i++)
- g_clear_signal_handler (&priv->handler_id[i], stage);
-
- priv->compositor = NULL;
- priv->wl_compositor = NULL;
-
- meta_dnd_notify_dnd_leave (dnd);
-}
-#endif
diff --git a/src/compositor/meta-feedback-actor-private.h b/src/compositor/meta-feedback-actor-private.h
deleted file mode 100644
index 86cacb360..000000000
--- a/src/compositor/meta-feedback-actor-private.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * meta-feedback-actor-private.h: Actor for painting user interaction feedback
- *
- * Copyright 2014 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Carlos Garnacho <carlosg@gnome.org>
- */
-
-#ifndef META_FEEDBACK_ACTOR_PRIVATE_H
-#define META_FEEDBACK_ACTOR_PRIVATE_H
-
-#include "clutter/clutter.h"
-
-/**
- * MetaFeedbackActor:
- *
- * This class handles the rendering of user interaction feedback
- */
-
-#define META_TYPE_FEEDBACK_ACTOR (meta_feedback_actor_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaFeedbackActor,
- meta_feedback_actor,
- META, FEEDBACK_ACTOR,
- ClutterActor)
-
-
-struct _MetaFeedbackActorClass
-{
- /*< private >*/
- ClutterActorClass parent_class;
-};
-
-
-ClutterActor *meta_feedback_actor_new (float anchor_x,
- float anchor_y);
-
-void meta_feedback_actor_set_anchor (MetaFeedbackActor *actor,
- float anchor_x,
- float anchor_y);
-void meta_feedback_actor_get_anchor (MetaFeedbackActor *actor,
- float *anchor_x,
- float *anchor_y);
-
-void meta_feedback_actor_set_position (MetaFeedbackActor *self,
- float x,
- float y);
-
-void meta_feedback_actor_update (MetaFeedbackActor *self,
- const ClutterEvent *event);
-
-void meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self,
- int geometry_scale);
-
-int meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self);
-
-#endif /* META_FEEDBACK_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-feedback-actor.c b/src/compositor/meta-feedback-actor.c
deleted file mode 100644
index 4b4bed78a..000000000
--- a/src/compositor/meta-feedback-actor.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright 2014 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Carlos Garnacho <carlosg@gnome.org>
- */
-
-/**
- * SECTION:meta-feedback-actor
- * @title: MetaFeedbackActor
- * @short_description: Actor for painting user interaction feedback
- */
-
-#include "config.h"
-
-#include "compositor/compositor-private.h"
-#include "compositor/meta-feedback-actor-private.h"
-#include "core/display-private.h"
-
-enum
-{
- PROP_ANCHOR_X = 1,
- PROP_ANCHOR_Y
-};
-
-typedef struct _MetaFeedbackActorPrivate MetaFeedbackActorPrivate;
-
-struct _MetaFeedbackActorPrivate
-{
- float anchor_x;
- float anchor_y;
- float pos_x;
- float pos_y;
-
- int geometry_scale;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaFeedbackActor, meta_feedback_actor, CLUTTER_TYPE_ACTOR)
-
-static void
-meta_feedback_actor_constructed (GObject *object)
-{
- MetaDisplay *display;
- ClutterActor *feedback_group;
-
- display = meta_get_display ();
- feedback_group = meta_get_feedback_group_for_display (display);
- clutter_actor_add_child (feedback_group, CLUTTER_ACTOR (object));
-}
-
-static void
-meta_feedback_actor_update_position (MetaFeedbackActor *self)
-{
- MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
-
- clutter_actor_set_position (CLUTTER_ACTOR (self),
- priv->pos_x -
- (priv->anchor_x * priv->geometry_scale),
- priv->pos_y -
- (priv->anchor_y * priv->geometry_scale));
-}
-
-static void
-meta_feedback_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaFeedbackActor *self = META_FEEDBACK_ACTOR (object);
- MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
-
- switch (prop_id)
- {
- case PROP_ANCHOR_X:
- priv->anchor_x = g_value_get_int (value);
- meta_feedback_actor_update_position (self);
- break;
- case PROP_ANCHOR_Y:
- priv->anchor_y = g_value_get_int (value);
- meta_feedback_actor_update_position (self);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_feedback_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaFeedbackActor *self = META_FEEDBACK_ACTOR (object);
- MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
-
- switch (prop_id)
- {
- case PROP_ANCHOR_X:
- g_value_set_float (value, priv->anchor_x);
- break;
- case PROP_ANCHOR_Y:
- g_value_set_float (value, priv->anchor_y);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_feedback_actor_class_init (MetaFeedbackActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- object_class->constructed = meta_feedback_actor_constructed;
- object_class->set_property = meta_feedback_actor_set_property;
- object_class->get_property = meta_feedback_actor_get_property;
-
- pspec = g_param_spec_float ("anchor-x",
- "Anchor X",
- "The X axis of the anchor point",
- 0, G_MAXFLOAT, 0,
- G_PARAM_READWRITE);
-
- g_object_class_install_property (object_class,
- PROP_ANCHOR_X,
- pspec);
-
- pspec = g_param_spec_float ("anchor-y",
- "Anchor Y",
- "The Y axis of the anchor point",
- 0, G_MAXFLOAT, 0,
- G_PARAM_READWRITE);
-
- g_object_class_install_property (object_class,
- PROP_ANCHOR_Y,
- pspec);
-}
-
-static void
-meta_feedback_actor_init (MetaFeedbackActor *self)
-{
- clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE);
-}
-
-/**
- * meta_feedback_actor_new:
- *
- * Creates a new actor to draw the current drag and drop surface.
- *
- * Return value: the newly created background actor
- */
-ClutterActor *
-meta_feedback_actor_new (float anchor_x,
- float anchor_y)
-{
- MetaFeedbackActor *self;
-
- self = g_object_new (META_TYPE_FEEDBACK_ACTOR,
- "anchor-x", anchor_x,
- "anchor-y", anchor_y,
- NULL);
-
- return CLUTTER_ACTOR (self);
-}
-
-void
-meta_feedback_actor_set_anchor (MetaFeedbackActor *self,
- float anchor_x,
- float anchor_y)
-{
- MetaFeedbackActorPrivate *priv;
-
- g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
-
- priv = meta_feedback_actor_get_instance_private (self);
-
- if (priv->anchor_x == anchor_x && priv->anchor_y == anchor_y)
- return;
-
- if (priv->anchor_x != anchor_x)
- {
- priv->anchor_x = anchor_x;
- g_object_notify (G_OBJECT (self), "anchor-x");
- }
-
- if (priv->anchor_y != anchor_y)
- {
- priv->anchor_y = anchor_y;
- g_object_notify (G_OBJECT (self), "anchor-y");
- }
-
- meta_feedback_actor_update_position (self);
-}
-
-void
-meta_feedback_actor_get_anchor (MetaFeedbackActor *self,
- float *anchor_x,
- float *anchor_y)
-{
- MetaFeedbackActorPrivate *priv;
-
- g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
-
- priv = meta_feedback_actor_get_instance_private (self);
-
- if (anchor_x)
- *anchor_x = priv->anchor_x;
- if (anchor_y)
- *anchor_y = priv->anchor_y;
-}
-
-void
-meta_feedback_actor_set_position (MetaFeedbackActor *self,
- float x,
- float y)
-{
- MetaFeedbackActorPrivate *priv;
-
- g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
-
- priv = meta_feedback_actor_get_instance_private (self);
- priv->pos_x = x;
- priv->pos_y = y;
-
- meta_feedback_actor_update_position (self);
-}
-
-void
-meta_feedback_actor_update (MetaFeedbackActor *self,
- const ClutterEvent *event)
-{
- graphene_point_t point;
-
- g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
- g_return_if_fail (event != NULL);
-
- clutter_event_get_position (event, &point);
- meta_feedback_actor_set_position (self, point.x, point.y);
-}
-
-void
-meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self,
- int geometry_scale)
-{
- MetaFeedbackActorPrivate *priv =
- meta_feedback_actor_get_instance_private (self);
- graphene_matrix_t child_transform;
-
- if (priv->geometry_scale == geometry_scale)
- return;
-
- priv->geometry_scale = geometry_scale;
-
- graphene_matrix_init_scale (&child_transform,
- geometry_scale,
- geometry_scale,
- 1);
- clutter_actor_set_child_transform (CLUTTER_ACTOR (self),
- &child_transform);
-}
-
-int
-meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self)
-{
- MetaFeedbackActorPrivate *priv =
- meta_feedback_actor_get_instance_private (self);
-
- return priv->geometry_scale;
-}
diff --git a/src/compositor/meta-later-private.h b/src/compositor/meta-later-private.h
deleted file mode 100644
index c8d0f80a8..000000000
--- a/src/compositor/meta-later-private.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2020 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_LATER_PRIVATE_H
-#define META_LATER_PRIVATE_H
-
-typedef struct _MetaLaters MetaLaters;
-typedef struct _MetaCompositor MetaCompositor;
-
-MetaLaters * meta_laters_new (MetaCompositor *compositor);
-
-void meta_laters_free (MetaLaters *laters);
-
-#endif /* META_LATER_PRIVATE_H */
diff --git a/src/compositor/meta-later.c b/src/compositor/meta-later.c
deleted file mode 100644
index 43da6d8e6..000000000
--- a/src/compositor/meta-later.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- * Copyright (C) 2020 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "compositor/meta-later-private.h"
-
-#include "cogl/cogl.h"
-#include "compositor/compositor-private.h"
-#include "core/display-private.h"
-#include "meta/meta-later.h"
-
-typedef struct _MetaLater
-{
- unsigned int id;
- unsigned int ref_count;
- MetaLaterType when;
-
- GSourceFunc func;
- gpointer user_data;
- GDestroyNotify destroy_notify;
-
- guint source_id;
- gboolean run_once;
-} MetaLater;
-
-#define META_LATER_N_TYPES (META_LATER_IDLE + 1)
-
-struct _MetaLaters
-{
- MetaCompositor *compositor;
-
- unsigned int last_later_id;
-
- GSList *laters[META_LATER_N_TYPES];
-
- gulong before_update_handler_id;
-};
-
-static MetaLater *
-meta_later_ref (MetaLater *later)
-{
- later->ref_count++;
- return later;
-}
-
-static void
-meta_later_unref (MetaLater *later)
-{
- if (--later->ref_count == 0)
- {
- if (later->destroy_notify)
- {
- later->destroy_notify (later->user_data);
- later->destroy_notify = NULL;
- }
-
- g_free (later);
- }
-}
-
-static void
-meta_later_destroy (MetaLater *later)
-{
- g_clear_handle_id (&later->source_id, g_source_remove);
- later->func = NULL;
- meta_later_unref (later);
-}
-
-#ifdef COGL_HAS_TRACING
-static const char *
-later_type_to_string (MetaLaterType when)
-{
- switch (when)
- {
- case META_LATER_RESIZE:
- return "Later (resize)";
- case META_LATER_CALC_SHOWING:
- return "Later (calc-showing)";
- case META_LATER_CHECK_FULLSCREEN:
- return "Later (check-fullscreen)";
- case META_LATER_SYNC_STACK:
- return "Later (sync-stack)";
- case META_LATER_BEFORE_REDRAW:
- return "Later (before-redraw)";
- case META_LATER_IDLE:
- return "Later (idle)";
- }
-
- return "unknown";
-}
-#endif
-
-static gboolean
-meta_later_invoke (MetaLater *later)
-{
- COGL_TRACE_BEGIN_SCOPED (later, later_type_to_string (later->when));
- return later->func (later->user_data);
-}
-
-static gboolean
-remove_later_from_list (unsigned int later_id,
- GSList **laters_list)
-{
- GSList *l;
-
- for (l = *laters_list; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (later->id == later_id)
- {
- *laters_list = g_slist_delete_link (*laters_list, l);
- meta_later_destroy (later);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-run_repaint_laters (GSList **laters_list)
-{
- g_autoptr (GSList) laters_copy = NULL;
- GSList *l;
-
- for (l = *laters_list; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (!later->source_id ||
- (later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
- laters_copy = g_slist_prepend (laters_copy, meta_later_ref (later));
- }
- laters_copy = g_slist_reverse (laters_copy);
-
- for (l = laters_copy; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (!later->func)
- remove_later_from_list (later->id, laters_list);
- else if (!meta_later_invoke (later))
- remove_later_from_list (later->id, laters_list);
-
- meta_later_unref (later);
- }
-}
-
-static void
-on_before_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaLaters *laters)
-{
- unsigned int i;
- GSList *l;
- gboolean needs_schedule_update = FALSE;
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- run_repaint_laters (&laters->laters[i]);
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- {
- for (l = laters->laters[i]; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (!later->source_id)
- needs_schedule_update = TRUE;
- }
- }
-
- if (needs_schedule_update)
- clutter_stage_schedule_update (stage);
-}
-
-static gboolean
-invoke_later_idle (gpointer data)
-{
- MetaLater *later = data;
-
- if (!later->func (later->user_data))
- {
- meta_later_remove (later->id);
- return FALSE;
- }
- else
- {
- later->run_once = TRUE;
- return TRUE;
- }
-}
-
-static unsigned int
-meta_laters_add (MetaLaters *laters,
- MetaLaterType when,
- GSourceFunc func,
- gpointer user_data,
- GDestroyNotify notify)
-{
- ClutterStage *stage = meta_compositor_get_stage (laters->compositor);
- MetaLater *later = g_new0 (MetaLater, 1);
-
- later->id = ++laters->last_later_id;
- later->ref_count = 1;
- later->when = when;
- later->func = func;
- later->user_data = user_data;
- later->destroy_notify = notify;
-
- laters->laters[when] = g_slist_prepend (laters->laters[when], later);
-
- switch (when)
- {
- case META_LATER_RESIZE:
- later->source_id = g_idle_add_full (META_PRIORITY_RESIZE,
- invoke_later_idle,
- later, NULL);
- g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
- clutter_stage_schedule_update (stage);
- break;
- case META_LATER_CALC_SHOWING:
- case META_LATER_CHECK_FULLSCREEN:
- case META_LATER_SYNC_STACK:
- case META_LATER_BEFORE_REDRAW:
- clutter_stage_schedule_update (stage);
- break;
- case META_LATER_IDLE:
- later->source_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- invoke_later_idle,
- later, NULL);
- g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
- break;
- }
-
- return later->id;
-}
-
-/**
- * meta_later_add:
- * @when: enumeration value determining the phase at which to run the callback
- * @func: callback to run later
- * @data: data to pass to the callback
- * @notify: function to call to destroy @data when it is no longer in use, or %NULL
- *
- * Sets up a callback to be called at some later time. @when determines the
- * particular later occasion at which it is called. This is much like g_idle_add(),
- * except that the functions interact properly with clutter event handling.
- * If a "later" function is added from a clutter event handler, and is supposed
- * to be run before the stage is redrawn, it will be run before that redraw
- * of the stage, not the next one.
- *
- * Return value: an integer ID (guaranteed to be non-zero) that can be used
- * to cancel the callback and prevent it from being run.
- */
-unsigned int
-meta_later_add (MetaLaterType when,
- GSourceFunc func,
- gpointer data,
- GDestroyNotify notify)
-{
- MetaDisplay *display = meta_get_display ();
- MetaCompositor *compositor;
-
- g_return_val_if_fail (display, 0);
- g_return_val_if_fail (display->compositor, 0);
-
- compositor = display->compositor;
- return meta_laters_add (meta_compositor_get_laters (compositor),
- when, func, data, notify);
-}
-
-static void
-meta_laters_remove (MetaLaters *laters,
- unsigned int later_id)
-{
- unsigned int i;
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- {
- if (remove_later_from_list (later_id, &laters->laters[i]))
- return;
- }
-}
-
-/**
- * meta_later_remove:
- * @later_id: the integer ID returned from meta_later_add()
- *
- * Removes a callback added with meta_later_add()
- */
-void
-meta_later_remove (unsigned int later_id)
-{
- MetaDisplay *display = meta_get_display ();
- MetaCompositor *compositor;
-
- g_return_if_fail (display);
-
- compositor = display->compositor;
- if (!compositor)
- return;
-
- meta_laters_remove (meta_compositor_get_laters (compositor), later_id);
-}
-
-MetaLaters *
-meta_laters_new (MetaCompositor *compositor)
-{
- ClutterStage *stage = meta_compositor_get_stage (compositor);
- MetaLaters *laters;
-
- laters = g_new0 (MetaLaters, 1);
- laters->compositor = compositor;
-
- laters->before_update_handler_id =
- g_signal_connect (stage, "before-update",
- G_CALLBACK (on_before_update),
- laters);
-
- return laters;
-}
-
-void
-meta_laters_free (MetaLaters *laters)
-{
- ClutterStage *stage = meta_compositor_get_stage (laters->compositor);
- unsigned int i;
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- g_slist_free_full (laters->laters[i], (GDestroyNotify) meta_later_unref);
-
- g_clear_signal_handler (&laters->before_update_handler_id, stage);
- g_free (laters);
-}
diff --git a/src/compositor/meta-module.c b/src/compositor/meta-module.c
deleted file mode 100644
index a8ed15bae..000000000
--- a/src/compositor/meta-module.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "compositor/meta-module.h"
-
-#include <gmodule.h>
-
-#include "meta/meta-plugin.h"
-
-enum
-{
- PROP_0,
- PROP_PATH,
-};
-
-struct _MetaModulePrivate
-{
- GModule *lib;
- gchar *path;
- GType plugin_type;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaModule, meta_module, G_TYPE_TYPE_MODULE);
-
-static gboolean
-meta_module_load (GTypeModule *gmodule)
-{
- MetaModulePrivate *priv = META_MODULE (gmodule)->priv;
- GType (*register_type) (GTypeModule *) = NULL;
-
- if (priv->lib && priv->plugin_type)
- return TRUE;
-
- g_assert (priv->path);
-
- if (!priv->lib &&
- !(priv->lib = g_module_open (priv->path, 0)))
- {
- g_warning ("Could not load library [%s (%s)]",
- priv->path, g_module_error ());
- return FALSE;
- }
-
- if (g_module_symbol (priv->lib, "meta_plugin_register_type",
- (gpointer *)(void *)&register_type) &&
- register_type)
- {
- GType plugin_type;
-
- if (!(plugin_type = register_type (gmodule)))
- {
- g_warning ("Could not register type for plugin %s",
- priv->path);
- return FALSE;
- }
- else
- {
- priv->plugin_type = plugin_type;
- }
-
- return TRUE;
- }
- else
- g_warning ("Broken plugin module [%s]", priv->path);
-
- return FALSE;
-}
-
-static void
-meta_module_unload (GTypeModule *gmodule)
-{
- MetaModulePrivate *priv = META_MODULE (gmodule)->priv;
-
- g_module_close (priv->lib);
-
- priv->lib = NULL;
- priv->plugin_type = 0;
-}
-
-static void
-meta_module_dispose (GObject *object)
-{
- G_OBJECT_CLASS (meta_module_parent_class)->dispose (object);
-}
-
-static void
-meta_module_finalize (GObject *object)
-{
- MetaModulePrivate *priv = META_MODULE (object)->priv;
-
- g_free (priv->path);
- priv->path = NULL;
-
- G_OBJECT_CLASS (meta_module_parent_class)->finalize (object);
-}
-
-static void
-meta_module_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaModulePrivate *priv = META_MODULE (object)->priv;
-
- switch (prop_id)
- {
- case PROP_PATH:
- g_free (priv->path);
- priv->path = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_module_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaModulePrivate *priv = META_MODULE (object)->priv;
-
- switch (prop_id)
- {
- case PROP_PATH:
- g_value_set_string (value, priv->path);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_module_class_init (MetaModuleClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GTypeModuleClass *gmodule_class = G_TYPE_MODULE_CLASS (klass);
-
- gobject_class->finalize = meta_module_finalize;
- gobject_class->dispose = meta_module_dispose;
- gobject_class->set_property = meta_module_set_property;
- gobject_class->get_property = meta_module_get_property;
-
- gmodule_class->load = meta_module_load;
- gmodule_class->unload = meta_module_unload;
-
- g_object_class_install_property (gobject_class,
- PROP_PATH,
- g_param_spec_string ("path",
- "Path",
- "Load path",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-meta_module_init (MetaModule *self)
-{
- self->priv = meta_module_get_instance_private (self);
-}
-
-GType
-meta_module_get_plugin_type (MetaModule *module)
-{
- MetaModulePrivate *priv = META_MODULE (module)->priv;
-
- return priv->plugin_type;
-}
-
diff --git a/src/compositor/meta-module.h b/src/compositor/meta-module.h
deleted file mode 100644
index dd6d5a685..000000000
--- a/src/compositor/meta-module.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_MODULE_H_
-#define META_MODULE_H_
-
-#include <glib-object.h>
-
-#define META_TYPE_MODULE (meta_module_get_type ())
-#define META_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MODULE, MetaModule))
-#define META_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MODULE, MetaModuleClass))
-#define META_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_MODULE_TYPE))
-#define META_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MODULE))
-#define META_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MODULE, MetaModuleClass))
-
-typedef struct _MetaModule MetaModule;
-typedef struct _MetaModuleClass MetaModuleClass;
-typedef struct _MetaModulePrivate MetaModulePrivate;
-
-struct _MetaModule
-{
- GTypeModule parent;
-
- MetaModulePrivate *priv;
-};
-
-struct _MetaModuleClass
-{
- GTypeModuleClass parent_class;
-};
-
-
-GType meta_module_get_type (void);
-
-GType meta_module_get_plugin_type (MetaModule *module);
-
-#endif
diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c
deleted file mode 100644
index ab7fce663..000000000
--- a/src/compositor/meta-plugin-manager.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "compositor/meta-plugin-manager.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "compositor/compositor-private.h"
-#include "compositor/meta-module.h"
-#include "core/meta-close-dialog-default-private.h"
-#include "core/meta-inhibit-shortcuts-dialog-default-private.h"
-#include "core/window-private.h"
-#include "meta/meta-x11-errors.h"
-#include "meta/prefs.h"
-#include "meta/workspace.h"
-
-static GType plugin_type = G_TYPE_NONE;
-
-struct MetaPluginManager
-{
- MetaCompositor *compositor;
- MetaPlugin *plugin;
-};
-
-void
-meta_plugin_manager_set_plugin_type (GType gtype)
-{
- if (plugin_type != G_TYPE_NONE)
- meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type));
-
- plugin_type = gtype;
-}
-
-/*
- * Loads the given plugin.
- */
-void
-meta_plugin_manager_load (const gchar *plugin_name)
-{
- const gchar *dpath = MUTTER_PLUGIN_DIR "/";
- gchar *path;
- MetaModule *module;
-
- if (g_path_is_absolute (plugin_name))
- path = g_strdup (plugin_name);
- else
- path = g_strconcat (dpath, plugin_name, ".so", NULL);
-
- module = g_object_new (META_TYPE_MODULE, "path", path, NULL);
- if (!module || !g_type_module_use (G_TYPE_MODULE (module)))
- {
- /* This is fatal under the assumption that a monitoring
- * process like gnome-session will take over and handle
- * our untimely exit.
- */
- g_printerr ("Unable to load plugin module [%s]: %s",
- path, g_module_error());
- exit (1);
- }
-
- meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module));
-
- g_type_module_unuse (G_TYPE_MODULE (module));
- g_free (path);
-}
-
-static void
-on_confirm_display_change (MetaMonitorManager *monitors,
- MetaPluginManager *plugin_mgr)
-{
- meta_plugin_manager_confirm_display_change (plugin_mgr);
-}
-
-MetaPluginManager *
-meta_plugin_manager_new (MetaCompositor *compositor)
-{
- MetaPluginManager *plugin_mgr;
- MetaPluginClass *klass;
- MetaPlugin *plugin;
- MetaMonitorManager *monitors;
-
- plugin_mgr = g_new0 (MetaPluginManager, 1);
- plugin_mgr->compositor = compositor;
- plugin_mgr->plugin = plugin = g_object_new (plugin_type, NULL);
-
- _meta_plugin_set_compositor (plugin, compositor);
-
- klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->start)
- klass->start (plugin);
-
- monitors = meta_monitor_manager_get ();
- g_signal_connect (monitors, "confirm-display-change",
- G_CALLBACK (on_confirm_display_change), plugin_mgr);
-
- return plugin_mgr;
-}
-
-static void
-meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr,
- MetaWindowActor *actor)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->kill_window_effects)
- klass->kill_window_effects (plugin, actor);
-}
-
-static void
-meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->kill_switch_workspace)
- klass->kill_switch_workspace (plugin);
-}
-
-/*
- * Public method that the compositor hooks into for events that require
- * no additional parameters.
- *
- * Returns TRUE if the plugin handled the event type (i.e.,
- * if the return value is FALSE, there will be no subsequent call to the
- * manager completed() callback, and the compositor must ensure that any
- * appropriate post-effect cleanup is carried out.
- */
-gboolean
-meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
- MetaWindowActor *actor,
- MetaPluginEffect event)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
- gboolean retval = FALSE;
-
- if (display->display_opening)
- return FALSE;
-
- switch (event)
- {
- case META_PLUGIN_MINIMIZE:
- if (klass->minimize)
- {
- retval = TRUE;
- meta_plugin_manager_kill_window_effects (plugin_mgr,
- actor);
- klass->minimize (plugin, actor);
- }
- break;
- case META_PLUGIN_UNMINIMIZE:
- if (klass->unminimize)
- {
- retval = TRUE;
- meta_plugin_manager_kill_window_effects (plugin_mgr,
- actor);
- klass->unminimize (plugin, actor);
- }
- break;
- case META_PLUGIN_MAP:
- if (klass->map)
- {
- retval = TRUE;
- meta_plugin_manager_kill_window_effects (plugin_mgr,
- actor);
- klass->map (plugin, actor);
- }
- break;
- case META_PLUGIN_DESTROY:
- if (klass->destroy)
- {
- retval = TRUE;
- meta_plugin_manager_kill_window_effects (plugin_mgr,
- actor);
- klass->destroy (plugin, actor);
- }
- break;
- default:
- g_warning ("Incorrect handler called for event %d", event);
- }
-
- return retval;
-}
-
-void
-meta_plugin_manager_event_size_changed (MetaPluginManager *plugin_mgr,
- MetaWindowActor *actor)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->size_changed)
- klass->size_changed (plugin, actor);
-}
-
-gboolean
-meta_plugin_manager_event_size_change (MetaPluginManager *plugin_mgr,
- MetaWindowActor *actor,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return FALSE;
-
- if (!klass->size_change)
- return FALSE;
-
- meta_plugin_manager_kill_window_effects (plugin_mgr, actor);
- klass->size_change (plugin, actor, which_change, old_frame_rect, old_buffer_rect);
- return TRUE;
-}
-
-/*
- * The public method that the compositor hooks into for desktop switching.
- *
- * Returns TRUE if the plugin handled the event type (i.e.,
- * if the return value is FALSE, there will be no subsequent call to the
- * manager completed() callback, and the compositor must ensure that any
- * appropriate post-effect cleanup is carried out.
- */
-gboolean
-meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr,
- gint from,
- gint to,
- MetaMotionDirection direction)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
- gboolean retval = FALSE;
-
- if (display->display_opening)
- return FALSE;
-
- if (klass->switch_workspace)
- {
- retval = TRUE;
- meta_plugin_manager_kill_switch_workspace (plugin_mgr);
- klass->switch_workspace (plugin, from, to, direction);
- }
-
- return retval;
-}
-
-gboolean
-meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr,
- MetaKeyBinding *binding)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->keybinding_filter)
- return klass->keybinding_filter (plugin, binding);
-
- return FALSE;
-}
-
-gboolean
-meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
- XEvent *xev)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
-
- return _meta_plugin_xevent_filter (plugin, xev);
-}
-
-void
-meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->confirm_display_change)
- klass->confirm_display_change (plugin);
- else
- meta_plugin_complete_display_change (plugin, TRUE);
-}
-
-gboolean
-meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr,
- MetaWindow *window,
- MetaRectangle *tile_rect,
- int tile_monitor_number)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return FALSE;
-
- if (klass->show_tile_preview)
- {
- klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number);
- return TRUE;
- }
-
- return FALSE;
-}
-
-gboolean
-meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return FALSE;
-
- if (klass->hide_tile_preview)
- {
- klass->hide_tile_preview (plugin);
- return TRUE;
- }
-
- return FALSE;
-}
-
-void
-meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr,
- MetaWindow *window,
- MetaWindowMenuType menu,
- int x,
- int y)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return;
-
- if (klass->show_window_menu)
- klass->show_window_menu (plugin, window, menu, x, y);
-}
-
-void
-meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *plugin_mgr,
- MetaWindow *window,
- MetaWindowMenuType menu,
- MetaRectangle *rect)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
- MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return;
-
- if (klass->show_window_menu_for_rect)
- klass->show_window_menu_for_rect (plugin, window, menu, rect);
-}
-
-MetaCloseDialog *
-meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->create_close_dialog)
- return klass->create_close_dialog (plugin, window);
-
- return meta_close_dialog_default_new (window);
-}
-
-MetaInhibitShortcutsDialog *
-meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->create_inhibit_shortcuts_dialog)
- return klass->create_inhibit_shortcuts_dialog (plugin, window);
-
- return meta_inhibit_shortcuts_dialog_default_new (window);
-}
-
-void
-meta_plugin_manager_locate_pointer (MetaPluginManager *plugin_mgr)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->locate_pointer)
- klass->locate_pointer (plugin);
-}
diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h
deleted file mode 100644
index d1c007fa1..000000000
--- a/src/compositor/meta-plugin-manager.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_PLUGIN_MANAGER_H_
-#define META_PLUGIN_MANAGER_H_
-
-#include "core/util-private.h"
-#include "meta/meta-plugin.h"
-#include "meta/types.h"
-
-typedef enum
-{
- META_PLUGIN_NONE,
- META_PLUGIN_MINIMIZE,
- META_PLUGIN_MAP,
- META_PLUGIN_DESTROY,
- META_PLUGIN_SWITCH_WORKSPACE,
- META_PLUGIN_UNMINIMIZE,
- META_PLUGIN_SIZE_CHANGE,
-} MetaPluginEffect;
-
-/**
- * MetaPluginManager: (skip)
- *
- */
-typedef struct MetaPluginManager MetaPluginManager;
-
-MetaPluginManager * meta_plugin_manager_new (MetaCompositor *compositor);
-
-META_EXPORT_TEST
-void meta_plugin_manager_load (const gchar *plugin_name);
-
-gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
- MetaWindowActor *actor,
- MetaPluginEffect event);
-
-void meta_plugin_manager_event_size_changed (MetaPluginManager *mgr,
- MetaWindowActor *actor);
-
-gboolean meta_plugin_manager_event_size_change (MetaPluginManager *mgr,
- MetaWindowActor *actor,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect);
-
-gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *mgr,
- gint from,
- gint to,
- MetaMotionDirection direction);
-
-gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr,
- MetaKeyBinding *binding);
-
-gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
- XEvent *xev);
-gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin,
- XEvent *xev);
-
-void meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr);
-
-gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr,
- MetaWindow *window,
- MetaRectangle *tile_rect,
- int tile_monitor_number);
-gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr);
-
-void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr,
- MetaWindow *window,
- MetaWindowMenuType menu,
- int x,
- int y);
-
-void meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *mgr,
- MetaWindow *window,
- MetaWindowMenuType menu,
- MetaRectangle *rect);
-
-MetaCloseDialog * meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window);
-
-MetaInhibitShortcutsDialog *
- meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window);
-
-void meta_plugin_manager_locate_pointer (MetaPluginManager *mgr);
-
-#endif
diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c
deleted file mode 100644
index 188675a4d..000000000
--- a/src/compositor/meta-plugin.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:meta-plugin
- * @title: MetaPlugin
- * @short_description: Entry point for plugins
- *
- */
-
-#include "config.h"
-
-#include "meta/meta-plugin.h"
-
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/extensions/shape.h>
-
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "compositor/compositor-private.h"
-#include "compositor/meta-window-actor-private.h"
-#include "compositor/meta-plugin-manager.h"
-#include "meta/display.h"
-#include "meta/util.h"
-
-
-typedef struct _MetaPluginPrivate
-{
- MetaCompositor *compositor;
-} MetaPluginPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
-
-static void
-meta_plugin_class_init (MetaPluginClass *klass)
-{
-}
-
-static void
-meta_plugin_init (MetaPlugin *self)
-{
-}
-
-const MetaPluginInfo *
-meta_plugin_get_info (MetaPlugin *plugin)
-{
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass && klass->plugin_info)
- return klass->plugin_info (plugin);
-
- return NULL;
-}
-
-gboolean
-_meta_plugin_xevent_filter (MetaPlugin *plugin,
- XEvent *xev)
-{
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->xevent_filter)
- return klass->xevent_filter (plugin, xev);
- else
- return FALSE;
-}
-
-void
-meta_plugin_switch_workspace_completed (MetaPlugin *plugin)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
-
- meta_switch_workspace_completed (priv->compositor);
-}
-
-static void
-meta_plugin_window_effect_completed (MetaPlugin *plugin,
- MetaWindowActor *actor,
- unsigned long event)
-{
- meta_window_actor_effect_completed (actor, event);
-}
-
-void
-meta_plugin_minimize_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MINIMIZE);
-}
-
-void
-meta_plugin_unminimize_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMINIMIZE);
-}
-
-void
-meta_plugin_size_change_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_SIZE_CHANGE);
-}
-
-void
-meta_plugin_map_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MAP);
-}
-
-void
-meta_plugin_destroy_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_DESTROY);
-}
-
-/**
- * meta_plugin_begin_modal:
- * @plugin: a #MetaPlugin
- * @options: flags that modify the behavior of the modal grab
- * @timestamp: the timestamp used for establishing grabs
- *
- * This function is used to grab the keyboard and mouse for the exclusive
- * use of the plugin. Correct operation requires that both the keyboard
- * and mouse are grabbed, or thing will break. (In particular, other
- * passive X grabs in Meta can trigger but not be handled by the normal
- * keybinding handling code.) However, the plugin can establish the keyboard
- * and/or mouse grabs ahead of time and pass in the
- * %META_MODAL_POINTER_ALREADY_GRABBED and/or %META_MODAL_KEYBOARD_ALREADY_GRABBED
- * options. This facility is provided for two reasons: first to allow using
- * this function to establish modality after a passive grab, and second to
- * allow using obscure features of XGrabPointer() and XGrabKeyboard() without
- * having to add them to this API.
- *
- * Return value: whether we successfully grabbed the keyboard and
- * mouse and made the plugin modal.
- */
-gboolean
-meta_plugin_begin_modal (MetaPlugin *plugin,
- MetaModalOptions options,
- guint32 timestamp)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
-
- return meta_begin_modal_for_plugin (priv->compositor, plugin,
- options, timestamp);
-}
-
-/**
- * meta_plugin_end_modal:
- * @plugin: a #MetaPlugin
- * @timestamp: the time used for releasing grabs
- *
- * Ends the modal operation begun with meta_plugin_begin_modal(). This
- * ungrabs both the mouse and keyboard even when
- * %META_MODAL_POINTER_ALREADY_GRABBED or
- * %META_MODAL_KEYBOARD_ALREADY_GRABBED were provided as options
- * when beginnning the modal operation.
- */
-void
-meta_plugin_end_modal (MetaPlugin *plugin,
- guint32 timestamp)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
-
- meta_end_modal_for_plugin (priv->compositor, plugin, timestamp);
-}
-
-/**
- * meta_plugin_get_display:
- * @plugin: a #MetaPlugin
- *
- * Gets the #MetaDisplay corresponding to a plugin.
- *
- * Return value: (transfer none): the #MetaDisplay for the plugin
- */
-MetaDisplay *
-meta_plugin_get_display (MetaPlugin *plugin)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
- MetaDisplay *display = meta_compositor_get_display (priv->compositor);
-
- return display;
-}
-
-void
-_meta_plugin_set_compositor (MetaPlugin *plugin, MetaCompositor *compositor)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
-
- priv->compositor = compositor;
-}
-
-void
-meta_plugin_complete_display_change (MetaPlugin *plugin,
- gboolean ok)
-{
- MetaMonitorManager *manager;
-
- manager = meta_monitor_manager_get ();
- meta_monitor_manager_confirm_configuration (manager, ok);
-}
diff --git a/src/compositor/meta-shadow-factory.c b/src/compositor/meta-shadow-factory.c
deleted file mode 100644
index d6424d3be..000000000
--- a/src/compositor/meta-shadow-factory.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:meta-shadow-factory
- * @title: MetaShadowFactory
- * @short_description: Create and cache shadow textures for arbitrary window shapes
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <string.h>
-
-#include "compositor/cogl-utils.h"
-#include "compositor/region-utils.h"
-#include "meta/meta-shadow-factory.h"
-#include "meta/util.h"
-
-/* This file implements blurring the shape of a window to produce a
- * shadow texture. The details are discussed below; a quick summary
- * of the optimizations we use:
- *
- * - If the window shape is along the lines of a rounded rectangle -
- * a rectangular center portion with stuff at the corners - then
- * the blur of this - the shadow - can also be represented as a
- * 9-sliced texture and the same texture can be used for different
- * size.
- *
- * - We use the fact that a Gaussian blur is separable to do a
- * 2D blur as 1D blur of the rows followed by a 1D blur of the
- * columns.
- *
- * - For better cache efficiency, we blur rows, transpose the image
- * in blocks, blur rows again, and then transpose back.
- *
- * - We approximate the 1D gaussian blur as 3 successive box filters.
- */
-
-typedef struct _MetaShadowCacheKey MetaShadowCacheKey;
-typedef struct _MetaShadowClassInfo MetaShadowClassInfo;
-
-struct _MetaShadowCacheKey
-{
- MetaWindowShape *shape;
- int radius;
- int top_fade;
-};
-
-struct _MetaShadow
-{
- int ref_count;
-
- MetaShadowFactory *factory;
- MetaShadowCacheKey key;
- CoglTexture *texture;
- CoglPipeline *pipeline;
-
- /* The outer order is the distance the shadow extends outside the window
- * shape; the inner border is the unscaled portion inside the window
- * shape */
- int outer_border_top;
- int inner_border_top;
- int outer_border_right;
- int inner_border_right;
- int outer_border_bottom;
- int inner_border_bottom;
- int outer_border_left;
- int inner_border_left;
-
- guint scale_width : 1;
- guint scale_height : 1;
-};
-
-struct _MetaShadowClassInfo
-{
- const char *name; /* const so we can reuse for static definitions */
- MetaShadowParams focused;
- MetaShadowParams unfocused;
-};
-
-struct _MetaShadowFactory
-{
- GObject parent_instance;
-
- /* MetaShadowCacheKey => MetaShadow; the shadows are not referenced
- * by the factory, they are simply removed from the table when freed */
- GHashTable *shadows;
-
- /* class name => MetaShadowClassInfo */
- GHashTable *shadow_classes;
-};
-
-enum
-{
- CHANGED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/* The first element in this array also defines the default parameters
- * for newly created classes */
-MetaShadowClassInfo default_shadow_classes[] = {
- { "normal", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "dialog", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "modal_dialog", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "utility", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "border", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "menu", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
-
- { "popup-menu", { 1, -1, 0, 0, 128 }, { 1, -1, 0, 0, 128 } },
- { "dropdown-menu", { 1, -1, 0, 0, 128 }, { 1, -1, 0, 0, 128 } },
-
- { "attached", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } }
-};
-
-G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
-
-static guint
-meta_shadow_cache_key_hash (gconstpointer val)
-{
- const MetaShadowCacheKey *key = val;
-
- return 59 * key->radius + 67 * key->top_fade + 73 * meta_window_shape_hash (key->shape);
-}
-
-static gboolean
-meta_shadow_cache_key_equal (gconstpointer a,
- gconstpointer b)
-{
- const MetaShadowCacheKey *key_a = a;
- const MetaShadowCacheKey *key_b = b;
-
- return (key_a->radius == key_b->radius && key_a->top_fade == key_b->top_fade &&
- meta_window_shape_equal (key_a->shape, key_b->shape));
-}
-
-MetaShadow *
-meta_shadow_ref (MetaShadow *shadow)
-{
- shadow->ref_count++;
-
- return shadow;
-}
-
-void
-meta_shadow_unref (MetaShadow *shadow)
-{
- shadow->ref_count--;
- if (shadow->ref_count == 0)
- {
- if (shadow->factory)
- {
- g_hash_table_remove (shadow->factory->shadows,
- &shadow->key);
- }
-
- meta_window_shape_unref (shadow->key.shape);
- cogl_object_unref (shadow->texture);
- cogl_object_unref (shadow->pipeline);
-
- g_free (shadow);
- }
-}
-
-/**
- * meta_shadow_paint:
- * @window_x: x position of the region to paint a shadow for
- * @window_y: y position of the region to paint a shadow for
- * @window_width: actual width of the region to paint a shadow for
- * @window_height: actual height of the region to paint a shadow for
- * @clip: (nullable): if non-%NULL specifies the visible portion
- * of the shadow.
- * @clip_strictly: if %TRUE, drawing will be clipped strictly
- * to @clip, otherwise, it will be only used to optimize
- * drawing.
- *
- * Paints the shadow at the given position, for the specified actual
- * size of the region. (Since a #MetaShadow can be shared between
- * different sizes with the same extracted #MetaWindowShape the
- * size needs to be passed in here.)
- */
-void
-meta_shadow_paint (MetaShadow *shadow,
- CoglFramebuffer *framebuffer,
- int window_x,
- int window_y,
- int window_width,
- int window_height,
- guint8 opacity,
- cairo_region_t *clip,
- gboolean clip_strictly)
-{
- float texture_width = cogl_texture_get_width (shadow->texture);
- float texture_height = cogl_texture_get_height (shadow->texture);
- int i, j;
- float src_x[4];
- float src_y[4];
- int dest_x[4];
- int dest_y[4];
- int n_x, n_y;
-
- if (clip && cairo_region_is_empty (clip))
- return;
-
- cogl_pipeline_set_color4ub (shadow->pipeline,
- opacity, opacity, opacity, opacity);
-
- if (shadow->scale_width)
- {
- n_x = 3;
-
- src_x[0] = 0.0;
- src_x[1] = (shadow->inner_border_left + shadow->outer_border_left) / texture_width;
- src_x[2] = (texture_width - (shadow->inner_border_right + shadow->outer_border_right)) / texture_width;
- src_x[3] = 1.0;
-
- dest_x[0] = window_x - shadow->outer_border_left;
- dest_x[1] = window_x + shadow->inner_border_left;
- dest_x[2] = window_x + window_width - shadow->inner_border_right;
- dest_x[3] = window_x + window_width + shadow->outer_border_right;
- }
- else
- {
- n_x = 1;
-
- src_x[0] = 0.0;
- src_x[1] = 1.0;
-
- dest_x[0] = window_x - shadow->outer_border_left;
- dest_x[1] = window_x + window_width + shadow->outer_border_right;
- }
-
- if (shadow->scale_height)
- {
- n_y = 3;
-
- src_y[0] = 0.0;
- src_y[1] = (shadow->inner_border_top + shadow->outer_border_top) / texture_height;
- src_y[2] = (texture_height - (shadow->inner_border_bottom + shadow->outer_border_bottom)) / texture_height;
- src_y[3] = 1.0;
-
- dest_y[0] = window_y - shadow->outer_border_top;
- dest_y[1] = window_y + shadow->inner_border_top;
- dest_y[2] = window_y + window_height - shadow->inner_border_bottom;
- dest_y[3] = window_y + window_height + shadow->outer_border_bottom;
- }
- else
- {
- n_y = 1;
-
- src_y[0] = 0.0;
- src_y[1] = 1.0;
-
- dest_y[0] = window_y - shadow->outer_border_top;
- dest_y[1] = window_y + window_height + shadow->outer_border_bottom;
- }
-
- for (j = 0; j < n_y; j++)
- {
- cairo_rectangle_int_t dest_rect;
- dest_rect.y = dest_y[j];
- dest_rect.height = dest_y[j + 1] - dest_y[j];
-
- if (dest_rect.height == 0)
- continue;
-
- for (i = 0; i < n_x; i++)
- {
- cairo_region_overlap_t overlap;
-
- dest_rect.x = dest_x[i];
- dest_rect.width = dest_x[i + 1] - dest_x[i];
-
- if (dest_rect.width == 0)
- continue;
-
- if (clip)
- overlap = cairo_region_contains_rectangle (clip, &dest_rect);
- else
- overlap = CAIRO_REGION_OVERLAP_IN;
-
- if (overlap == CAIRO_REGION_OVERLAP_OUT)
- continue;
-
- /* There's quite a bit of overhead from allocating a new
- * region in order to find an exact intersection and
- * generating more geometry - we make the assumption that
- * unless we have to clip strictly it will be cheaper to
- * just draw the entire rectangle.
- */
- if (overlap == CAIRO_REGION_OVERLAP_IN ||
- (overlap == CAIRO_REGION_OVERLAP_PART && !clip_strictly))
- {
- cogl_framebuffer_draw_textured_rectangle (framebuffer,
- shadow->pipeline,
- dest_x[i], dest_y[j],
- dest_x[i + 1], dest_y[j + 1],
- src_x[i], src_y[j],
- src_x[i + 1], src_y[j + 1]);
- }
- else if (overlap == CAIRO_REGION_OVERLAP_PART)
- {
- cairo_region_t *intersection;
- int n_rectangles, k;
-
- intersection = cairo_region_create_rectangle (&dest_rect);
- cairo_region_intersect (intersection, clip);
-
- n_rectangles = cairo_region_num_rectangles (intersection);
- for (k = 0; k < n_rectangles; k++)
- {
- cairo_rectangle_int_t rect;
- float src_x1, src_x2, src_y1, src_y2;
-
- cairo_region_get_rectangle (intersection, k, &rect);
-
- /* Separately linear interpolate X and Y coordinates in the source
- * based on the destination X and Y coordinates */
-
- src_x1 = (src_x[i] * (dest_rect.x + dest_rect.width - rect.x) +
- src_x[i + 1] * (rect.x - dest_rect.x)) / dest_rect.width;
- src_x2 = (src_x[i] * (dest_rect.x + dest_rect.width - (rect.x + rect.width)) +
- src_x[i + 1] * (rect.x + rect.width - dest_rect.x)) / dest_rect.width;
-
- src_y1 = (src_y[j] * (dest_rect.y + dest_rect.height - rect.y) +
- src_y[j + 1] * (rect.y - dest_rect.y)) / dest_rect.height;
- src_y2 = (src_y[j] * (dest_rect.y + dest_rect.height - (rect.y + rect.height)) +
- src_y[j + 1] * (rect.y + rect.height - dest_rect.y)) / dest_rect.height;
-
- cogl_framebuffer_draw_textured_rectangle (framebuffer,
- shadow->pipeline,
- rect.x, rect.y,
- rect.x + rect.width, rect.y + rect.height,
- src_x1, src_y1, src_x2, src_y2);
- }
-
- cairo_region_destroy (intersection);
- }
- }
- }
-}
-
-/**
- * meta_shadow_get_bounds:
- * @shadow: a #MetaShadow
- * @window_x: x position of the region to paint a shadow for
- * @window_y: y position of the region to paint a shadow for
- * @window_width: actual width of the region to paint a shadow for
- * @window_height: actual height of the region to paint a shadow for
- *
- * Computes the bounds of the pixels that will be affected by
- * meta_shadow_paint()
- */
-void
-meta_shadow_get_bounds (MetaShadow *shadow,
- int window_x,
- int window_y,
- int window_width,
- int window_height,
- cairo_rectangle_int_t *bounds)
-{
- bounds->x = window_x - shadow->outer_border_left;
- bounds->y = window_y - shadow->outer_border_top;
- bounds->width = window_width + shadow->outer_border_left + shadow->outer_border_right;
- bounds->height = window_height + shadow->outer_border_top + shadow->outer_border_bottom;
-}
-
-static void
-meta_shadow_class_info_free (MetaShadowClassInfo *class_info)
-{
- g_free ((char *)class_info->name);
- g_free (class_info);
-}
-
-static void
-meta_shadow_factory_init (MetaShadowFactory *factory)
-{
- guint i;
-
- factory->shadows = g_hash_table_new (meta_shadow_cache_key_hash,
- meta_shadow_cache_key_equal);
-
- factory->shadow_classes = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- (GDestroyNotify)meta_shadow_class_info_free);
-
- for (i = 0; i < G_N_ELEMENTS (default_shadow_classes); i++)
- {
- MetaShadowClassInfo *class_info = g_new0 (MetaShadowClassInfo, 1);
-
- *class_info = default_shadow_classes[i];
- class_info->name = g_strdup (class_info->name);
-
- g_hash_table_insert (factory->shadow_classes,
- (char *)class_info->name, class_info);
- }
-}
-
-static void
-meta_shadow_factory_finalize (GObject *object)
-{
- MetaShadowFactory *factory = META_SHADOW_FACTORY (object);
- GHashTableIter iter;
- gpointer key, value;
-
- /* Detach from the shadows in the table so we won't try to
- * remove them when they're freed. */
- g_hash_table_iter_init (&iter, factory->shadows);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- MetaShadow *shadow = key;
- shadow->factory = NULL;
- }
-
- g_hash_table_destroy (factory->shadows);
- g_hash_table_destroy (factory->shadow_classes);
-
- G_OBJECT_CLASS (meta_shadow_factory_parent_class)->finalize (object);
-}
-
-static void
-meta_shadow_factory_class_init (MetaShadowFactoryClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_shadow_factory_finalize;
-
- signals[CHANGED] =
- g_signal_new ("changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-MetaShadowFactory *
-meta_shadow_factory_new (void)
-{
- return g_object_new (META_TYPE_SHADOW_FACTORY, NULL);
-}
-
-/**
- * meta_shadow_factory_get_default:
- *
- * Return value: (transfer none): the global singleton shadow factory
- */
-MetaShadowFactory *
-meta_shadow_factory_get_default (void)
-{
- static MetaShadowFactory *factory;
-
- if (factory == NULL)
- factory = meta_shadow_factory_new ();
-
- return factory;
-}
-
-/* We emulate a 1D Gaussian blur by using 3 consecutive box blurs;
- * this produces a result that's within 3% of the original and can be
- * implemented much faster for large filter sizes because of the
- * efficiency of implementation of a box blur. Idea and formula
- * for choosing the box blur size come from:
- *
- * http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
- *
- * The 2D blur is then done by blurring the rows, flipping the
- * image and blurring the columns. (This is possible because the
- * Gaussian kernel is separable - it's the product of a horizontal
- * blur and a vertical blur.)
- */
-static int
-get_box_filter_size (int radius)
-{
- return (int)(0.5 + radius * (0.75 * sqrt(2*M_PI)));
-}
-
-/* The "spread" of the filter is the number of pixels from an original
- * pixel that it's blurred image extends. (A no-op blur that doesn't
- * blur would have a spread of 0.) See comment in blur_rows() for why the
- * odd and even cases are different
- */
-static int
-get_shadow_spread (int radius)
-{
- int d;
-
- if (radius == 0)
- return 0;
-
- d = get_box_filter_size (radius);
-
- if (d % 2 == 1)
- return 3 * (d / 2);
- else
- return 3 * (d / 2) - 1;
-}
-
-/* This applies a single box blur pass to a horizontal range of pixels;
- * since the box blur has the same weight for all pixels, we can
- * implement an efficient sliding window algorithm where we add
- * in pixels coming into the window from the right and remove
- * them when they leave the windw to the left.
- *
- * d is the filter width; for even d shift indicates how the blurred
- * result is aligned with the original - does ' x ' go to ' yy' (shift=1)
- * or 'yy ' (shift=-1)
- */
-static void
-blur_xspan (guchar *row,
- guchar *tmp_buffer,
- int row_width,
- int x0,
- int x1,
- int d,
- int shift)
-{
- int offset;
- int sum = 0;
- int i;
-
- if (d % 2 == 1)
- offset = d / 2;
- else
- offset = (d - shift) / 2;
-
- /* All the conditionals in here look slow, but the branches will
- * be well predicted and there are enough different possibilities
- * that trying to write this as a series of unconditional loops
- * is hard and not an obvious win. The main slow down here seems
- * to be the integer division per pixel; one possible optimization
- * would be to accumulate into two 16-bit integer buffers and
- * only divide down after all three passes. (SSE parallel implementation
- * of the divide step is possible.)
- */
- for (i = x0 - d + offset; i < x1 + offset; i++)
- {
- if (i >= 0 && i < row_width)
- sum += row[i];
-
- if (i >= x0 + offset)
- {
- if (i >= d)
- sum -= row[i - d];
-
- tmp_buffer[i - offset] = (sum + d / 2) / d;
- }
- }
-
- memcpy (row + x0, tmp_buffer + x0, x1 - x0);
-}
-
-static void
-blur_rows (cairo_region_t *convolve_region,
- int x_offset,
- int y_offset,
- guchar *buffer,
- int buffer_width,
- int buffer_height,
- int d)
-{
- int i, j;
- int n_rectangles;
- guchar *tmp_buffer;
-
- tmp_buffer = g_malloc (buffer_width);
-
- n_rectangles = cairo_region_num_rectangles (convolve_region);
- for (i = 0; i < n_rectangles; i++)
- {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (convolve_region, i, &rect);
-
- for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
- {
- guchar *row = buffer + j * buffer_width;
- int x0 = x_offset + rect.x;
- int x1 = x0 + rect.width;
-
- /* We want to produce a symmetric blur that spreads a pixel
- * equally far to the left and right. If d is odd that happens
- * naturally, but for d even, we approximate by using a blur
- * on either side and then a centered blur of size d + 1.
- * (technique also from the SVG specification)
- */
- if (d % 2 == 1)
- {
- blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
- blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
- blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
- }
- else
- {
- blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
- blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
- blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
- }
- }
- }
-
- g_free (tmp_buffer);
-}
-
-static void
-fade_bytes (guchar *bytes,
- int width,
- int distance,
- int total)
-{
- guint32 multiplier = (distance * 0x10000 + 0x8000) / total;
- int i;
-
- for (i = 0; i < width; i++)
- bytes[i] = (bytes[i] * multiplier) >> 16;
-}
-
-/* Swaps width and height. Either swaps in-place and returns the original
- * buffer or allocates a new buffer, frees the original buffer and returns
- * the new buffer.
- */
-static guchar *
-flip_buffer (guchar *buffer,
- int width,
- int height)
-{
- /* Working in blocks increases cache efficiency, compared to reading
- * or writing an entire column at once */
-#define BLOCK_SIZE 16
-
- if (width == height)
- {
- int i0, j0;
-
- for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
- for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
- {
- int max_j = MIN(j0 + BLOCK_SIZE, height);
- int max_i = MIN(i0 + BLOCK_SIZE, width);
- int i, j;
-
- if (i0 == j0)
- {
- for (j = j0; j < max_j; j++)
- for (i = i0; i < j; i++)
- {
- guchar tmp = buffer[j * width + i];
- buffer[j * width + i] = buffer[i * width + j];
- buffer[i * width + j] = tmp;
- }
- }
- else
- {
- for (j = j0; j < max_j; j++)
- for (i = i0; i < max_i; i++)
- {
- guchar tmp = buffer[j * width + i];
- buffer[j * width + i] = buffer[i * width + j];
- buffer[i * width + j] = tmp;
- }
- }
- }
-
- return buffer;
- }
- else
- {
- guchar *new_buffer = g_malloc (height * width);
- int i0, j0;
-
- for (i0 = 0; i0 < width; i0 += BLOCK_SIZE)
- for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
- {
- int max_j = MIN(j0 + BLOCK_SIZE, height);
- int max_i = MIN(i0 + BLOCK_SIZE, width);
- int i, j;
-
- for (i = i0; i < max_i; i++)
- for (j = j0; j < max_j; j++)
- new_buffer[i * height + j] = buffer[j * width + i];
- }
-
- g_free (buffer);
-
- return new_buffer;
- }
-#undef BLOCK_SIZE
-}
-
-static void
-make_shadow (MetaShadow *shadow,
- cairo_region_t *region)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
- CoglContext *ctx = clutter_backend_get_cogl_context (backend);
- GError *error = NULL;
- int d = get_box_filter_size (shadow->key.radius);
- int spread = get_shadow_spread (shadow->key.radius);
- cairo_rectangle_int_t extents;
- cairo_region_t *row_convolve_region;
- cairo_region_t *column_convolve_region;
- guchar *buffer;
- int buffer_width;
- int buffer_height;
- int x_offset;
- int y_offset;
- int n_rectangles, j, k;
-
- cairo_region_get_extents (region, &extents);
-
- /* In the case where top_fade >= 0 and the portion above the top
- * edge of the shape will be cropped, it seems like we could create
- * a smaller buffer and omit the top portion, but actually, in our
- * multi-pass blur algorithm, the blur into the area above the window
- * in the first pass will contribute back to the final pixel values
- * for the top pixels, so we create a buffer as if we weren't cropping
- * and only crop when creating the CoglTexture.
- */
-
- buffer_width = extents.width + 2 * spread;
- buffer_height = extents.height + 2 * spread;
-
- /* Round up so we have aligned rows/columns */
- buffer_width = (buffer_width + 3) & ~3;
- buffer_height = (buffer_height + 3) & ~3;
-
- /* Square buffer allows in-place swaps, which are roughly 70% faster, but we
- * don't want to over-allocate too much memory.
- */
- if (buffer_height < buffer_width && buffer_height > (3 * buffer_width) / 4)
- buffer_height = buffer_width;
- if (buffer_width < buffer_height && buffer_width > (3 * buffer_height) / 4)
- buffer_width = buffer_height;
-
- buffer = g_malloc0 (buffer_width * buffer_height);
-
- /* Blurring with multiple box-blur passes is fast, but (especially for
- * large shadow sizes) we can improve efficiency by restricting the blur
- * to the region that actually needs to be blurred.
- */
- row_convolve_region = meta_make_border_region (region, spread, spread, FALSE);
- column_convolve_region = meta_make_border_region (region, 0, spread, TRUE);
-
- /* Offsets between coordinates of the regions and coordinates in the buffer */
- x_offset = spread;
- y_offset = spread;
-
- /* Step 1: unblurred image */
- n_rectangles = cairo_region_num_rectangles (region);
- for (k = 0; k < n_rectangles; k++)
- {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (region, k, &rect);
- for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
- memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
- }
-
- /* Step 2: swap rows and columns */
- buffer = flip_buffer (buffer, buffer_width, buffer_height);
-
- /* Step 3: blur rows (really columns) */
- blur_rows (column_convolve_region, y_offset, x_offset,
- buffer, buffer_height, buffer_width,
- d);
-
- /* Step 4: swap rows and columns */
- buffer = flip_buffer (buffer, buffer_height, buffer_width);
-
- /* Step 5: blur rows */
- blur_rows (row_convolve_region, x_offset, y_offset,
- buffer, buffer_width, buffer_height,
- d);
-
- /* Step 6: fade out the top, if applicable */
- if (shadow->key.top_fade >= 0)
- {
- for (j = y_offset; j < y_offset + MIN (shadow->key.top_fade, extents.height + shadow->outer_border_bottom); j++)
- fade_bytes(buffer + j * buffer_width, buffer_width, j - y_offset, shadow->key.top_fade);
- }
-
- /* We offset the passed in pixels to crop off the extra area we allocated at the top
- * in the case of top_fade >= 0. We also account for padding at the left for symmetry
- * though that doesn't currently occur.
- */
- shadow->texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx,
- shadow->outer_border_left + extents.width + shadow->outer_border_right,
- shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
- COGL_PIXEL_FORMAT_A_8,
- buffer_width,
- (buffer +
- (y_offset - shadow->outer_border_top) * buffer_width +
- (x_offset - shadow->outer_border_left)),
- &error));
-
- if (error)
- {
- meta_warning ("Failed to allocate shadow texture: %s", error->message);
- g_error_free (error);
- }
-
- cairo_region_destroy (row_convolve_region);
- cairo_region_destroy (column_convolve_region);
- g_free (buffer);
-
- shadow->pipeline = meta_create_texture_pipeline (shadow->texture);
-}
-
-static MetaShadowParams *
-get_shadow_params (MetaShadowFactory *factory,
- const char *class_name,
- gboolean focused,
- gboolean create)
-{
- MetaShadowClassInfo *class_info = g_hash_table_lookup (factory->shadow_classes,
- class_name);
- if (class_info == NULL)
- {
- if (create)
- {
- class_info = g_new0 (MetaShadowClassInfo, 1);
- *class_info = default_shadow_classes[0];
- class_info->name = g_strdup (class_info->name);
-
- g_hash_table_insert (factory->shadow_classes,
- (char *)class_info->name, class_info);
- }
- else
- {
- class_info = &default_shadow_classes[0];
- }
- }
-
- if (focused)
- return &class_info->focused;
- else
- return &class_info->unfocused;
-}
-
-/**
- * meta_shadow_factory_get_shadow:
- * @factory: a #MetaShadowFactory
- * @shape: the size-invariant shape of the window's region
- * @width: the actual width of the window's region
- * @height: the actual height of the window's region
- * @class_name: name of the class of window shadows
- * @focused: whether the shadow is for a focused window
- *
- * Gets the appropriate shadow object for drawing shadows for the
- * specified window shape. The region that we are shadowing is specified
- * as a combination of a size-invariant extracted shape and the size.
- * In some cases, the same shadow object can be shared between sizes;
- * in other cases a different shadow object is used for each size.
- *
- * Return value: (transfer full): a newly referenced #MetaShadow; unref with
- * meta_shadow_unref()
- */
-MetaShadow *
-meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
- MetaWindowShape *shape,
- int width,
- int height,
- const char *class_name,
- gboolean focused)
-{
- MetaShadowParams *params;
- MetaShadowCacheKey key;
- MetaShadow *shadow;
- cairo_region_t *region;
- int spread;
- int shape_border_top, shape_border_right, shape_border_bottom, shape_border_left;
- int inner_border_top, inner_border_right, inner_border_bottom, inner_border_left;
- int outer_border_top, outer_border_right, outer_border_bottom, outer_border_left;
- gboolean scale_width, scale_height;
- gboolean cacheable;
- int center_width, center_height;
-
- g_return_val_if_fail (META_IS_SHADOW_FACTORY (factory), NULL);
- g_return_val_if_fail (shape != NULL, NULL);
-
- /* Using a single shadow texture for different window sizes only works
- * when there is a central scaled area that is greater than twice
- * the spread of the gaussian blur we are applying to get to the
- * shadow image.
- * ********* ***********
- * /----------\ *###########* *#############*
- * | | => **#*********#** => **#***********#**
- * | | **#** **#** **#** **#**
- * | | **#*********#** **#***********#**
- * \----------/ *###########* *#############*
- * ********** ************
- * Original Blur Stretched Blur
- *
- * For smaller sizes, we create a separate shadow image for each size;
- * since we assume that there will be little reuse, we don't try to
- * cache such images but just recreate them. (Since the current cache
- * policy is to only keep around referenced shadows, there wouldn't
- * be any harm in caching them, it would just make the book-keeping
- * a bit tricker.)
- *
- * In the case where we are fading a the top, that also has to fit
- * within the top unscaled border.
- */
-
- params = get_shadow_params (factory, class_name, focused, FALSE);
-
- spread = get_shadow_spread (params->radius);
- meta_window_shape_get_borders (shape,
- &shape_border_top,
- &shape_border_right,
- &shape_border_bottom,
- &shape_border_left);
-
- inner_border_top = MAX (shape_border_top + spread, params->top_fade);
- outer_border_top = params->top_fade >= 0 ? 0 : spread;
- inner_border_right = shape_border_right + spread;
- outer_border_right = spread;
- inner_border_bottom = shape_border_bottom + spread;
- outer_border_bottom = spread;
- inner_border_left = shape_border_left + spread;
- outer_border_left = spread;
-
- scale_width = inner_border_left + inner_border_right <= width;
- scale_height = inner_border_top + inner_border_bottom <= height;
- cacheable = scale_width && scale_height;
-
- if (cacheable)
- {
- key.shape = shape;
- key.radius = params->radius;
- key.top_fade = params->top_fade;
-
- shadow = g_hash_table_lookup (factory->shadows, &key);
- if (shadow)
- return meta_shadow_ref (shadow);
- }
-
- shadow = g_new0 (MetaShadow, 1);
-
- shadow->ref_count = 1;
- shadow->factory = factory;
- shadow->key.shape = meta_window_shape_ref (shape);
- shadow->key.radius = params->radius;
- shadow->key.top_fade = params->top_fade;
-
- shadow->outer_border_top = outer_border_top;
- shadow->inner_border_top = inner_border_top;
- shadow->outer_border_right = outer_border_right;
- shadow->inner_border_right = inner_border_right;
- shadow->outer_border_bottom = outer_border_bottom;
- shadow->inner_border_bottom = inner_border_bottom;
- shadow->outer_border_left = outer_border_left;
- shadow->inner_border_left = inner_border_left;
-
- shadow->scale_width = scale_width;
- if (scale_width)
- center_width = inner_border_left + inner_border_right - (shape_border_left + shape_border_right);
- else
- center_width = width - (shape_border_left + shape_border_right);
-
- shadow->scale_height = scale_height;
- if (scale_height)
- center_height = inner_border_top + inner_border_bottom - (shape_border_top + shape_border_bottom);
- else
- center_height = height - (shape_border_top + shape_border_bottom);
-
- g_assert (center_width >= 0 && center_height >= 0);
-
- region = meta_window_shape_to_region (shape, center_width, center_height);
- make_shadow (shadow, region);
-
- cairo_region_destroy (region);
-
- if (cacheable)
- g_hash_table_insert (factory->shadows, &shadow->key, shadow);
-
- return shadow;
-}
-
-/**
- * meta_shadow_factory_set_params:
- * @factory: a #MetaShadowFactory
- * @class_name: name of the class of shadow to set the params for.
- * the default shadow classes are the names of the different
- * theme frame types (normal, dialog, modal_dialog, utility,
- * border, menu, attached) and in addition, popup-menu
- * and dropdown-menu.
- * @focused: whether the shadow is for a focused window
- * @params: new parameter values
- *
- * Updates the shadow parameters for a particular class of shadows
- * for either the focused or unfocused state. If the class name
- * does not name an existing class, a new class will be created
- * (the other focus state for that class will have default values
- * assigned to it.)
- */
-void
-meta_shadow_factory_set_params (MetaShadowFactory *factory,
- const char *class_name,
- gboolean focused,
- MetaShadowParams *params)
-{
- MetaShadowParams *stored_params;
-
- g_return_if_fail (META_IS_SHADOW_FACTORY (factory));
- g_return_if_fail (class_name != NULL);
- g_return_if_fail (params != NULL);
- g_return_if_fail (params->radius >= 0);
-
- stored_params = get_shadow_params (factory, class_name, focused, TRUE);
-
- *stored_params = *params;
-
- g_signal_emit (factory, signals[CHANGED], 0);
-}
-
-/**
- * meta_shadow_factory_get_params:
- * @factory: a #MetaShadowFactory
- * @class_name: name of the class of shadow to get the params for
- * @focused: whether the shadow is for a focused window
- * @params: (out caller-allocates): location to store the current parameter values
- *
- * Gets the shadow parameters for a particular class of shadows
- * for either the focused or unfocused state. If the class name
- * does not name an existing class, default values will be returned
- * without printing an error.
- */
-void
-meta_shadow_factory_get_params (MetaShadowFactory *factory,
- const char *class_name,
- gboolean focused,
- MetaShadowParams *params)
-{
- MetaShadowParams *stored_params;
-
- g_return_if_fail (META_IS_SHADOW_FACTORY (factory));
- g_return_if_fail (class_name != NULL);
-
- stored_params = get_shadow_params (factory, class_name, focused, FALSE);
-
- if (params)
- *params = *stored_params;
-}
-
-G_DEFINE_BOXED_TYPE (MetaShadow, meta_shadow,
- meta_shadow_ref, meta_shadow_unref)
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
deleted file mode 100644
index 2fe1b8ea4..000000000
--- a/src/compositor/meta-shaped-texture-private.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * shaped texture
- *
- * An actor to draw a texture clipped to a list of rectangles
- *
- * Authored By Neil Roberts <neil@linux.intel.com>
- *
- * Copyright (C) 2008 Intel Corporation
- * 2013 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __META_SHAPED_TEXTURE_PRIVATE_H__
-#define __META_SHAPED_TEXTURE_PRIVATE_H__
-
-#include "backends/meta-monitor-manager-private.h"
-#include "meta/meta-shaped-texture.h"
-
-MetaShapedTexture *meta_shaped_texture_new (void);
-void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture);
-void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
- gboolean is_y_inverted);
-void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
- CoglSnippet *snippet);
-void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
- int fallback_width,
- int fallback_height);
-cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
-gboolean meta_shaped_texture_is_opaque (MetaShapedTexture *stex);
-gboolean meta_shaped_texture_has_alpha (MetaShapedTexture *stex);
-void meta_shaped_texture_set_transform (MetaShapedTexture *stex,
- MetaMonitorTransform transform);
-void meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,
- graphene_rect_t *src_rect);
-void meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex);
-void meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
- int dst_width,
- int dst_height);
-void meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex);
-void meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex,
- int buffer_scale);
-int meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex);
-
-gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
- int x,
- int y,
- int width,
- int height,
- cairo_rectangle_int_t *clip);
-
-int meta_shaped_texture_get_width (MetaShapedTexture *stex);
-int meta_shaped_texture_get_height (MetaShapedTexture *stex);
-
-void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
- cairo_region_t *clip_region);
-void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
- cairo_region_t *opaque_region);
-
-void meta_shaped_texture_ensure_size_valid (MetaShapedTexture *stex);
-
-#endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
deleted file mode 100644
index 6a8af828f..000000000
--- a/src/compositor/meta-shaped-texture.c
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- * Authored By Neil Roberts <neil@linux.intel.com>
- * and Jasper St. Pierre <jstpierre@mecheye.net>
- *
- * Copyright (C) 2008 Intel Corporation
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:meta-shaped-texture
- * @title: MetaShapedTexture
- * @short_description: A ClutterContent which draws a shaped texture
- *
- * A MetaShapedTexture draws a #CoglTexture (often provided from a client
- * surface) in such a way that it matches any required transformations that
- * give its final shape, such as a #MetaMonitorTransform, y-invertedness, or a
- * crop-and-scale operation.
- */
-
-#include "config.h"
-
-#include "backends/meta-monitor-transform.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "core/boxes-private.h"
-
-#include <gdk/gdk.h>
-#include <math.h>
-
-#include "cogl/cogl.h"
-#include "compositor/clutter-utils.h"
-#include "compositor/meta-texture-tower.h"
-#include "compositor/region-utils.h"
-#include "core/boxes-private.h"
-#include "meta/meta-shaped-texture.h"
-
-/* MAX_MIPMAPPING_FPS needs to be as small as possible for the best GPU
- * performance, but higher than the refresh rate of commonly slow updating
- * windows like top or a blinking cursor, so that such windows do get
- * mipmapped.
- */
-#define MAX_MIPMAPPING_FPS 5
-#define MIN_MIPMAP_AGE_USEC (G_USEC_PER_SEC / MAX_MIPMAPPING_FPS)
-
-/* MIN_FAST_UPDATES_BEFORE_UNMIPMAP allows windows to update themselves
- * occasionally without causing mipmapping to be disabled, so long as such
- * an update takes fewer update_area calls than:
- */
-#define MIN_FAST_UPDATES_BEFORE_UNMIPMAP 20
-
-static void meta_shaped_texture_dispose (GObject *object);
-
-static void clutter_content_iface_init (ClutterContentInterface *iface);
-
-enum
-{
- SIZE_CHANGED,
-
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL];
-
-static CoglPipelineKey opaque_overlay_pipeline_key =
- "meta-shaped-texture-opaque-pipeline-key";
-static CoglPipelineKey blended_overlay_pipeline_key =
- "meta-shaped-texture-blended-pipeline-key";
-
-struct _MetaShapedTexture
-{
- GObject parent;
-
- MetaTextureTower *paint_tower;
-
- CoglTexture *texture;
- CoglTexture *mask_texture;
- CoglSnippet *snippet;
-
- CoglPipeline *base_pipeline;
- CoglPipeline *masked_pipeline;
- CoglPipeline *unblended_pipeline;
-
- gboolean is_y_inverted;
-
- /* The region containing only fully opaque pixels */
- cairo_region_t *opaque_region;
-
- /* MetaCullable regions, see that documentation for more details */
- cairo_region_t *clip_region;
-
- gboolean size_invalid;
- MetaMonitorTransform transform;
- gboolean has_viewport_src_rect;
- graphene_rect_t viewport_src_rect;
- gboolean has_viewport_dst_size;
- int viewport_dst_width;
- int viewport_dst_height;
-
- int tex_width, tex_height;
- int fallback_width, fallback_height;
- int dst_width, dst_height;
-
- gint64 prev_invalidation, last_invalidation;
- guint fast_updates;
- guint remipmap_timeout_id;
- gint64 earliest_remipmap;
-
- int buffer_scale;
-
- guint create_mipmaps : 1;
-};
-
-G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
- clutter_content_iface_init));
-
-static void
-meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- gobject_class->dispose = meta_shaped_texture_dispose;
-
- signals[SIZE_CHANGED] = g_signal_new ("size-changed",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-static void
-invalidate_size (MetaShapedTexture *stex)
-{
- stex->size_invalid = TRUE;
-}
-
-static void
-meta_shaped_texture_init (MetaShapedTexture *stex)
-{
- stex->paint_tower = meta_texture_tower_new ();
-
- stex->buffer_scale = 1;
- stex->texture = NULL;
- stex->mask_texture = NULL;
- stex->create_mipmaps = TRUE;
- stex->is_y_inverted = TRUE;
- stex->transform = META_MONITOR_TRANSFORM_NORMAL;
-}
-
-static void
-update_size (MetaShapedTexture *stex)
-{
- int buffer_scale = stex->buffer_scale;
- int dst_width;
- int dst_height;
-
- if (stex->has_viewport_dst_size)
- {
- dst_width = stex->viewport_dst_width;
- dst_height = stex->viewport_dst_height;
- }
- else if (stex->has_viewport_src_rect)
- {
- dst_width = stex->viewport_src_rect.size.width;
- dst_height = stex->viewport_src_rect.size.height;
- }
- else
- {
- if (meta_monitor_transform_is_rotated (stex->transform))
- {
- if (stex->texture)
- {
- dst_width = stex->tex_height / buffer_scale;
- dst_height = stex->tex_width / buffer_scale;
- }
- else
- {
- dst_width = stex->fallback_height / buffer_scale;
- dst_height = stex->fallback_width / buffer_scale;
- }
- }
- else
- {
- if (stex->texture)
- {
- dst_width = stex->tex_width / buffer_scale;
- dst_height = stex->tex_height / buffer_scale;
- }
- else
- {
- dst_width = stex->fallback_width / buffer_scale;
- dst_height = stex->fallback_height / buffer_scale;
- }
- }
- }
-
- stex->size_invalid = FALSE;
-
- if (stex->dst_width != dst_width ||
- stex->dst_height != dst_height)
- {
- stex->dst_width = dst_width;
- stex->dst_height = dst_height;
- meta_shaped_texture_set_mask_texture (stex, NULL);
- clutter_content_invalidate_size (CLUTTER_CONTENT (stex));
- g_signal_emit (stex, signals[SIZE_CHANGED], 0);
- }
-}
-
-void
-meta_shaped_texture_ensure_size_valid (MetaShapedTexture *stex)
-{
- if (stex->size_invalid)
- update_size (stex);
-}
-
-void
-meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
- cairo_region_t *clip_region)
-{
- g_clear_pointer (&stex->clip_region, cairo_region_destroy);
- if (clip_region)
- stex->clip_region = cairo_region_reference (clip_region);
-}
-
-static void
-meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
-{
- g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
- g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
- g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref);
-}
-
-static void
-meta_shaped_texture_dispose (GObject *object)
-{
- MetaShapedTexture *stex = (MetaShapedTexture *) object;
-
- g_clear_handle_id (&stex->remipmap_timeout_id, g_source_remove);
-
- if (stex->paint_tower)
- meta_texture_tower_free (stex->paint_tower);
- stex->paint_tower = NULL;
-
- g_clear_pointer (&stex->texture, cogl_object_unref);
-
- meta_shaped_texture_set_mask_texture (stex, NULL);
- meta_shaped_texture_reset_pipelines (stex);
-
- g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
- g_clear_pointer (&stex->clip_region, cairo_region_destroy);
-
- g_clear_pointer (&stex->snippet, cogl_object_unref);
-
- G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
-}
-
-static CoglPipeline *
-get_base_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- CoglPipeline *pipeline;
- graphene_matrix_t matrix;
-
- if (stex->base_pipeline)
- return stex->base_pipeline;
-
- pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
-
- graphene_matrix_init_identity (&matrix);
-
- if (stex->has_viewport_src_rect)
- {
- float scaled_tex_width = stex->tex_width / (float) stex->buffer_scale;
- float scaled_tex_height = stex->tex_height / (float) stex->buffer_scale;
- graphene_point3d_t p;
-
- graphene_point3d_init (&p,
- stex->viewport_src_rect.origin.x /
- stex->viewport_src_rect.size.width,
- stex->viewport_src_rect.origin.y /
- stex->viewport_src_rect.size.height,
- 0);
- graphene_matrix_translate (&matrix, &p);
-
- if (meta_monitor_transform_is_rotated (stex->transform))
- {
- graphene_matrix_scale (&matrix,
- stex->viewport_src_rect.size.width /
- scaled_tex_height,
- stex->viewport_src_rect.size.height /
- scaled_tex_width,
- 1);
- }
- else
- {
- graphene_matrix_scale (&matrix,
- stex->viewport_src_rect.size.width /
- scaled_tex_width,
- stex->viewport_src_rect.size.height /
- scaled_tex_height,
- 1);
- }
- }
-
- if (stex->transform != META_MONITOR_TRANSFORM_NORMAL)
- {
- graphene_euler_t euler;
-
- graphene_matrix_translate (&matrix,
- &GRAPHENE_POINT3D_INIT (-0.5, -0.5, 0.0));
- switch (stex->transform)
- {
- case META_MONITOR_TRANSFORM_90:
- graphene_euler_init_with_order (&euler, 0.0, 0.0, 90.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_180:
- graphene_euler_init_with_order (&euler, 0.0, 0.0, 180.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_270:
- graphene_euler_init_with_order (&euler, 0.0, 0.0, 270.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED:
- graphene_euler_init_with_order (&euler, 0.0, 180.0, 0.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED_90:
- graphene_euler_init_with_order (&euler, 180.0, 0.0, 90.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED_180:
- graphene_euler_init_with_order (&euler, 0.0, 180.0, 180.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED_270:
- graphene_euler_init_with_order (&euler, 180.0, 0.0, 270.0,
- GRAPHENE_EULER_ORDER_SYXZ);
- break;
- case META_MONITOR_TRANSFORM_NORMAL:
- g_assert_not_reached ();
- }
- graphene_matrix_rotate_euler (&matrix, &euler);
- graphene_matrix_translate (&matrix,
- &GRAPHENE_POINT3D_INIT (0.5, 0.5, 0.0));
- }
-
- if (!stex->is_y_inverted)
- {
- graphene_matrix_translate (&matrix, &GRAPHENE_POINT3D_INIT (0, -1, 0));
- graphene_matrix_scale (&matrix, 1, -1, 1);
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
- }
-
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
- cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
-
- if (stex->snippet)
- cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
-
- stex->base_pipeline = pipeline;
-
- return stex->base_pipeline;
-}
-
-static CoglPipeline *
-get_unmasked_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- return get_base_pipeline (stex, ctx);
-}
-
-static CoglPipeline *
-get_masked_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- if (stex->masked_pipeline)
- return stex->masked_pipeline;
-
- pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 1,
- "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
- NULL);
-
- stex->masked_pipeline = pipeline;
-
- return pipeline;
-}
-
-static CoglPipeline *
-get_unblended_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- if (stex->unblended_pipeline)
- return stex->unblended_pipeline;
-
- pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 0,
- "RGBA = REPLACE (TEXTURE)",
- NULL);
-
- stex->unblended_pipeline = pipeline;
-
- return pipeline;
-}
-
-static CoglPipeline *
-get_opaque_overlay_pipeline (CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- pipeline = cogl_context_get_named_pipeline (ctx,
- &opaque_overlay_pipeline_key);
- if (!pipeline)
- {
- pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_color4ub (pipeline, 0x00, 0x33, 0x00, 0x33);
-
- cogl_context_set_named_pipeline (ctx,
- &opaque_overlay_pipeline_key,
- pipeline);
- }
-
- return pipeline;
-}
-
-static CoglPipeline *
-get_blended_overlay_pipeline (CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- pipeline = cogl_context_get_named_pipeline (ctx,
- &blended_overlay_pipeline_key);
- if (!pipeline)
- {
- pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_color4ub (pipeline, 0x33, 0x00, 0x33, 0x33);
-
- cogl_context_set_named_pipeline (ctx,
- &blended_overlay_pipeline_key,
- pipeline);
- }
-
- return pipeline;
-}
-
-static void
-paint_clipped_rectangle_node (MetaShapedTexture *stex,
- ClutterPaintNode *root_node,
- CoglPipeline *pipeline,
- cairo_rectangle_int_t *rect,
- ClutterActorBox *alloc)
-{
- g_autoptr (ClutterPaintNode) node = NULL;
- float ratio_h, ratio_v;
- float x1, y1, x2, y2;
- float coords[8];
- float alloc_width;
- float alloc_height;
-
- ratio_h = clutter_actor_box_get_width (alloc) / (float) stex->dst_width;
- ratio_v = clutter_actor_box_get_height (alloc) / (float) stex->dst_height;
-
- x1 = alloc->x1 + rect->x * ratio_h;
- y1 = alloc->y1 + rect->y * ratio_v;
- x2 = alloc->x1 + (rect->x + rect->width) * ratio_h;
- y2 = alloc->y1 + (rect->y + rect->height) * ratio_v;
-
- alloc_width = alloc->x2 - alloc->x1;
- alloc_height = alloc->y2 - alloc->y1;
-
- coords[0] = rect->x / alloc_width * ratio_h;
- coords[1] = rect->y / alloc_height * ratio_v;
- coords[2] = (rect->x + rect->width) / alloc_width * ratio_h;
- coords[3] = (rect->y + rect->height) / alloc_height * ratio_v;
-
- coords[4] = coords[0];
- coords[5] = coords[1];
- coords[6] = coords[2];
- coords[7] = coords[3];
-
- node = clutter_pipeline_node_new (pipeline);
- clutter_paint_node_set_static_name (node, "MetaShapedTexture (clipped)");
- clutter_paint_node_add_child (root_node, node);
-
- clutter_paint_node_add_multitexture_rectangle (node,
- &(ClutterActorBox) {
- .x1 = x1,
- .y1 = y1,
- .x2 = x2,
- .y2 = y2,
- },
- coords, 8);
-}
-
-static void
-set_cogl_texture (MetaShapedTexture *stex,
- CoglTexture *cogl_tex)
-{
- int width, height;
-
- cogl_clear_object (&stex->texture);
-
- if (cogl_tex != NULL)
- {
- stex->texture = cogl_object_ref (cogl_tex);
- width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
- height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
- }
- else
- {
- width = 0;
- height = 0;
- }
-
- if (stex->tex_width != width ||
- stex->tex_height != height)
- {
- stex->tex_width = width;
- stex->tex_height = height;
- update_size (stex);
- }
-
- /* NB: We don't queue a redraw of the actor here because we don't
- * know how much of the buffer has changed with respect to the
- * previous buffer. We only queue a redraw in response to surface
- * damage. */
-
- if (stex->create_mipmaps)
- meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
-}
-
-static gboolean
-texture_is_idle_and_not_mipmapped (gpointer user_data)
-{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (user_data);
-
- if ((g_get_monotonic_time () - stex->earliest_remipmap) < 0)
- return G_SOURCE_CONTINUE;
-
- clutter_content_invalidate (CLUTTER_CONTENT (stex));
- stex->remipmap_timeout_id = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-static inline void
-flip_ints (int *x,
- int *y)
-{
- int tmp;
-
- tmp = *x;
- *x = *y;
- *y = tmp;
-}
-
-static void
-do_paint_content (MetaShapedTexture *stex,
- ClutterPaintNode *root_node,
- ClutterPaintContext *paint_context,
- CoglTexture *paint_tex,
- ClutterActorBox *alloc,
- uint8_t opacity)
-{
- int dst_width, dst_height;
- cairo_rectangle_int_t content_rect;
- gboolean use_opaque_region;
- cairo_region_t *blended_tex_region;
- CoglContext *ctx;
- CoglPipelineFilter filter;
- CoglFramebuffer *framebuffer;
- int sample_width, sample_height;
- gboolean debug_paint_opaque_region;
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- dst_width = stex->dst_width;
- dst_height = stex->dst_height;
-
- if (dst_width == 0 || dst_height == 0) /* no contents yet */
- return;
-
- content_rect = (cairo_rectangle_int_t) {
- .x = 0,
- .y = 0,
- .width = dst_width,
- .height = dst_height,
- };
-
- debug_paint_opaque_region =
- meta_get_debug_paint_flags() & META_DEBUG_PAINT_OPAQUE_REGION;
-
- /* Use nearest-pixel interpolation if the texture is unscaled. This
- * improves performance, especially with software rendering.
- */
-
- framebuffer = clutter_paint_node_get_framebuffer (root_node);
- if (!framebuffer)
- framebuffer = clutter_paint_context_get_framebuffer (paint_context);
-
- if (stex->has_viewport_src_rect)
- {
- sample_width = stex->viewport_src_rect.size.width * stex->buffer_scale;
- sample_height = stex->viewport_src_rect.size.height * stex->buffer_scale;
- }
- else
- {
- sample_width = cogl_texture_get_width (stex->texture);
- sample_height = cogl_texture_get_height (stex->texture);
- }
- if (meta_monitor_transform_is_rotated (stex->transform))
- flip_ints (&sample_width, &sample_height);
-
- if (meta_actor_painting_untransformed (framebuffer,
- dst_width, dst_height,
- sample_width, sample_height,
- NULL, NULL))
- filter = COGL_PIPELINE_FILTER_NEAREST;
- else
- filter = COGL_PIPELINE_FILTER_LINEAR;
-
- ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
-
- use_opaque_region = stex->opaque_region && opacity == 255;
-
- if (use_opaque_region)
- {
- if (stex->clip_region)
- blended_tex_region = cairo_region_copy (stex->clip_region);
- else
- blended_tex_region = cairo_region_create_rectangle (&content_rect);
-
- cairo_region_subtract (blended_tex_region, stex->opaque_region);
- }
- else
- {
- if (stex->clip_region)
- blended_tex_region = cairo_region_reference (stex->clip_region);
- else
- blended_tex_region = NULL;
- }
-
- /* Limit to how many separate rectangles we'll draw; beyond this just
- * fall back and draw the whole thing */
-#define MAX_RECTS 16
-
- if (blended_tex_region)
- {
- int n_rects = cairo_region_num_rectangles (blended_tex_region);
- if (n_rects > MAX_RECTS)
- {
- /* Fall back to taking the fully blended path. */
- use_opaque_region = FALSE;
-
- g_clear_pointer (&blended_tex_region, cairo_region_destroy);
- }
- }
-
- /* First, paint the unblended parts, which are part of the opaque region. */
- if (use_opaque_region)
- {
- cairo_region_t *region;
- int n_rects;
- int i;
-
- if (stex->clip_region)
- {
- region = cairo_region_copy (stex->clip_region);
- cairo_region_intersect (region, stex->opaque_region);
- }
- else
- {
- region = cairo_region_reference (stex->opaque_region);
- }
-
- if (!cairo_region_is_empty (region))
- {
- CoglPipeline *opaque_pipeline;
-
- opaque_pipeline = get_unblended_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
-
- n_rects = cairo_region_num_rectangles (region);
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (region, i, &rect);
- paint_clipped_rectangle_node (stex, root_node,
- opaque_pipeline,
- &rect, alloc);
-
- if (G_UNLIKELY (debug_paint_opaque_region))
- {
- CoglPipeline *opaque_overlay_pipeline;
-
- opaque_overlay_pipeline = get_opaque_overlay_pipeline (ctx);
- paint_clipped_rectangle_node (stex, root_node,
- opaque_overlay_pipeline,
- &rect, alloc);
- }
- }
- }
-
- cairo_region_destroy (region);
- }
-
- /* Now, go ahead and paint the blended parts. */
-
- /* We have three cases:
- * 1) blended_tex_region has rectangles - paint the rectangles.
- * 2) blended_tex_region is empty - don't paint anything
- * 3) blended_tex_region is NULL - paint fully-blended.
- *
- * 1) and 3) are the times where we have to paint stuff. This tests
- * for 1) and 3).
- */
- if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
- {
- CoglPipeline *blended_pipeline;
-
- if (stex->mask_texture == NULL)
- {
- blended_pipeline = get_unmasked_pipeline (stex, ctx);
- }
- else
- {
- blended_pipeline = get_masked_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
- cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
- }
-
- cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
-
- CoglColor color;
- cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
- cogl_pipeline_set_color (blended_pipeline, &color);
-
- if (blended_tex_region)
- {
- /* 1) blended_tex_region is not empty. Paint the rectangles. */
- int i;
- int n_rects = cairo_region_num_rectangles (blended_tex_region);
-
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (blended_tex_region, i, &rect);
-
- if (!gdk_rectangle_intersect (&content_rect, &rect, &rect))
- continue;
-
- paint_clipped_rectangle_node (stex, root_node,
- blended_pipeline,
- &rect, alloc);
-
- if (G_UNLIKELY (debug_paint_opaque_region))
- {
- CoglPipeline *blended_overlay_pipeline;
-
- blended_overlay_pipeline = get_blended_overlay_pipeline (ctx);
- paint_clipped_rectangle_node (stex, root_node,
- blended_overlay_pipeline,
- &rect, alloc);
- }
- }
- }
- else
- {
- g_autoptr (ClutterPaintNode) node = NULL;
-
- node = clutter_pipeline_node_new (blended_pipeline);
- clutter_paint_node_set_static_name (node, "MetaShapedTexture (unclipped)");
- clutter_paint_node_add_child (root_node, node);
-
- /* 3) blended_tex_region is NULL. Do a full paint. */
- clutter_paint_node_add_rectangle (node, alloc);
-
- if (G_UNLIKELY (debug_paint_opaque_region))
- {
- CoglPipeline *blended_overlay_pipeline;
- g_autoptr (ClutterPaintNode) node_overlay = NULL;
-
- blended_overlay_pipeline = get_blended_overlay_pipeline (ctx);
-
- node_overlay = clutter_pipeline_node_new (blended_overlay_pipeline);
- clutter_paint_node_set_static_name (node_overlay,
- "MetaShapedTexture (unclipped overlay)");
- clutter_paint_node_add_child (root_node, node_overlay);
- clutter_paint_node_add_rectangle (node_overlay, alloc);
- }
- }
- }
-
- g_clear_pointer (&blended_tex_region, cairo_region_destroy);
-}
-
-static CoglTexture *
-select_texture_for_paint (MetaShapedTexture *stex,
- ClutterPaintContext *paint_context)
-{
- CoglTexture *texture = NULL;
- int64_t now;
-
- if (!stex->texture)
- return NULL;
-
- now = g_get_monotonic_time ();
-
- if (stex->create_mipmaps && stex->last_invalidation)
- {
- int64_t age = now - stex->last_invalidation;
-
- if (age >= MIN_MIPMAP_AGE_USEC ||
- stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
- {
- texture = meta_texture_tower_get_paint_texture (stex->paint_tower,
- paint_context);
- }
- }
-
- if (!texture)
- {
- texture = stex->texture;
-
- if (stex->create_mipmaps)
- {
- /* Minus 1000 to ensure we don't fail the age test in timeout */
- stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
-
- if (!stex->remipmap_timeout_id)
- stex->remipmap_timeout_id =
- g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000,
- texture_is_idle_and_not_mipmapped,
- stex);
- }
- }
-
- return texture;
-}
-
-static void
-meta_shaped_texture_paint_content (ClutterContent *content,
- ClutterActor *actor,
- ClutterPaintNode *root_node,
- ClutterPaintContext *paint_context)
-{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
- ClutterActorBox alloc;
- CoglTexture *paint_tex = NULL;
- uint8_t opacity;
-
- if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
- return;
-
- /* The GL EXT_texture_from_pixmap extension does allow for it to be
- * used together with SGIS_generate_mipmap, however this is very
- * rarely supported. Also, even when it is supported there
- * are distinct performance implications from:
- *
- * - Updating mipmaps that we don't need
- * - Having to reallocate pixmaps on the server into larger buffers
- *
- * So, we just unconditionally use our mipmap emulation code. If we
- * wanted to use SGIS_generate_mipmap, we'd have to query COGL to
- * see if it was supported (no API currently), and then if and only
- * if that was the case, set the clutter texture quality to HIGH.
- * Setting the texture quality to high without SGIS_generate_mipmap
- * support for TFP textures will result in fallbacks to XGetImage.
- */
- paint_tex = select_texture_for_paint (stex, paint_context);
- if (!paint_tex)
- return;
-
- opacity = clutter_actor_get_paint_opacity (actor);
- clutter_actor_get_content_box (actor, &alloc);
-
- do_paint_content (stex, root_node, paint_context, paint_tex, &alloc, opacity);
-}
-
-static gboolean
-meta_shaped_texture_get_preferred_size (ClutterContent *content,
- float *width,
- float *height)
-{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- if (width)
- *width = stex->dst_width;
-
- if (height)
- *height = stex->dst_height;
-
- return TRUE;
-}
-
-static void
-clutter_content_iface_init (ClutterContentInterface *iface)
-{
- iface->paint_content = meta_shaped_texture_paint_content;
- iface->get_preferred_size = meta_shaped_texture_get_preferred_size;
-}
-
-void
-meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
- gboolean create_mipmaps)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- create_mipmaps = create_mipmaps != FALSE;
-
- if (create_mipmaps != stex->create_mipmaps)
- {
- CoglTexture *base_texture;
- stex->create_mipmaps = create_mipmaps;
- base_texture = create_mipmaps ? stex->texture : NULL;
- meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
- }
-}
-
-void
-meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
- CoglTexture *mask_texture)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- g_clear_pointer (&stex->mask_texture, cogl_object_unref);
-
- if (mask_texture != NULL)
- {
- stex->mask_texture = mask_texture;
- cogl_object_ref (stex->mask_texture);
- }
-
- clutter_content_invalidate (CLUTTER_CONTENT (stex));
-}
-
-/**
- * meta_shaped_texture_update_area:
- * @stex: #MetaShapedTexture
- * @x: the x coordinate of the damaged area
- * @y: the y coordinate of the damaged area
- * @width: the width of the damaged area
- * @height: the height of the damaged area
- * @clip: (out): the resulting clip region
- *
- * Repairs the damaged area indicated by @x, @y, @width and @height
- * and potentially queues a redraw.
- *
- * Return value: Whether a redraw have been queued or not
- */
-gboolean
-meta_shaped_texture_update_area (MetaShapedTexture *stex,
- int x,
- int y,
- int width,
- int height,
- cairo_rectangle_int_t *clip)
-{
- MetaMonitorTransform inverted_transform;
- int scaled_and_transformed_width;
- int scaled_and_transformed_height;
-
- if (stex->texture == NULL)
- return FALSE;
-
- *clip = (cairo_rectangle_int_t) {
- .x = x,
- .y = y,
- .width = width,
- .height = height
- };
-
- meta_rectangle_scale_double (clip,
- 1.0 / stex->buffer_scale,
- META_ROUNDING_STRATEGY_GROW,
- clip);
-
- if (meta_monitor_transform_is_rotated (stex->transform))
- {
- scaled_and_transformed_width = stex->tex_height / stex->buffer_scale;
- scaled_and_transformed_height = stex->tex_width / stex->buffer_scale;
- }
- else
- {
- scaled_and_transformed_width = stex->tex_width / stex->buffer_scale;
- scaled_and_transformed_height = stex->tex_height / stex->buffer_scale;
- }
- inverted_transform = meta_monitor_transform_invert (stex->transform);
- meta_rectangle_transform (clip,
- inverted_transform,
- scaled_and_transformed_width,
- scaled_and_transformed_height,
- clip);
-
- if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
- {
- graphene_rect_t viewport;
- graphene_rect_t inverted_viewport;
- float dst_width;
- float dst_height;
- int inverted_dst_width;
- int inverted_dst_height;
-
- if (stex->has_viewport_src_rect)
- {
- viewport = stex->viewport_src_rect;
- }
- else
- {
- viewport = (graphene_rect_t) {
- .origin.x = 0,
- .origin.y = 0,
- .size.width = scaled_and_transformed_width,
- .size.height = scaled_and_transformed_height,
- };
- }
-
- if (stex->has_viewport_dst_size)
- {
- dst_width = (float) stex->viewport_dst_width;
- dst_height = (float) stex->viewport_dst_height;
- }
- else
- {
- dst_width = (float) viewport.size.width;
- dst_height = (float) viewport.size.height;
- }
-
- inverted_viewport = (graphene_rect_t) {
- .origin.x = -(viewport.origin.x * (dst_width / viewport.size.width)),
- .origin.y = -(viewport.origin.y * (dst_height / viewport.size.height)),
- .size.width = dst_width,
- .size.height = dst_height
- };
- inverted_dst_width = ceilf (viewport.size.width);
- inverted_dst_height = ceilf (viewport.size.height);
-
- meta_rectangle_crop_and_scale (clip,
- &inverted_viewport,
- inverted_dst_width,
- inverted_dst_height,
- clip);
- }
-
- meta_texture_tower_update_area (stex->paint_tower,
- x,
- y,
- width,
- height);
-
- stex->prev_invalidation = stex->last_invalidation;
- stex->last_invalidation = g_get_monotonic_time ();
-
- if (stex->prev_invalidation)
- {
- gint64 interval = stex->last_invalidation - stex->prev_invalidation;
- gboolean fast_update = interval < MIN_MIPMAP_AGE_USEC;
-
- if (!fast_update)
- stex->fast_updates = 0;
- else if (stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
- stex->fast_updates++;
- }
-
- return TRUE;
-}
-
-/**
- * meta_shaped_texture_set_texture:
- * @stex: The #MetaShapedTexture
- * @pixmap: The #CoglTexture to display
- */
-void
-meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- if (stex->texture == texture)
- return;
-
- set_cogl_texture (stex, texture);
-}
-
-/**
- * meta_shaped_texture_set_is_y_inverted: (skip)
- */
-void
-meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
- gboolean is_y_inverted)
-{
- if (stex->is_y_inverted == is_y_inverted)
- return;
-
- meta_shaped_texture_reset_pipelines (stex);
-
- stex->is_y_inverted = is_y_inverted;
-}
-
-/**
- * meta_shaped_texture_set_snippet: (skip)
- */
-void
-meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
- CoglSnippet *snippet)
-{
- if (stex->snippet == snippet)
- return;
-
- meta_shaped_texture_reset_pipelines (stex);
-
- g_clear_pointer (&stex->snippet, cogl_object_unref);
- if (snippet)
- stex->snippet = cogl_object_ref (snippet);
-}
-
-/**
- * meta_shaped_texture_get_texture:
- * @stex: The #MetaShapedTexture
- *
- * Returns: (transfer none): the unshaped texture
- */
-CoglTexture *
-meta_shaped_texture_get_texture (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
- return COGL_TEXTURE (stex->texture);
-}
-
-/**
- * meta_shaped_texture_set_opaque_region:
- * @stex: a #MetaShapedTexture
- * @opaque_region: (transfer full): the region of the texture that
- * can have blending turned off.
- *
- * As most windows have a large portion that does not require blending,
- * we can easily turn off blending if we know the areas that do not
- * require blending. This sets the region where we will not blend for
- * optimization purposes.
- */
-void
-meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
- cairo_region_t *opaque_region)
-{
- g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
- if (opaque_region)
- stex->opaque_region = cairo_region_reference (opaque_region);
-}
-
-cairo_region_t *
-meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex)
-{
- return stex->opaque_region;
-}
-
-gboolean
-meta_shaped_texture_has_alpha (MetaShapedTexture *stex)
-{
- CoglTexture *texture;
-
- texture = stex->texture;
- if (!texture)
- return TRUE;
-
- switch (cogl_texture_get_components (texture))
- {
- case COGL_TEXTURE_COMPONENTS_A:
- case COGL_TEXTURE_COMPONENTS_RGBA:
- return TRUE;
- case COGL_TEXTURE_COMPONENTS_RG:
- case COGL_TEXTURE_COMPONENTS_RGB:
- case COGL_TEXTURE_COMPONENTS_DEPTH:
- return FALSE;
- }
-
- g_warn_if_reached ();
- return FALSE;
-}
-
-gboolean
-meta_shaped_texture_is_opaque (MetaShapedTexture *stex)
-{
- CoglTexture *texture;
- cairo_rectangle_int_t opaque_rect;
-
- texture = stex->texture;
- if (!texture)
- return FALSE;
-
- if (!meta_shaped_texture_has_alpha (stex))
- return TRUE;
-
- if (!stex->opaque_region)
- return FALSE;
-
- if (cairo_region_num_rectangles (stex->opaque_region) != 1)
- return FALSE;
-
- cairo_region_get_extents (stex->opaque_region, &opaque_rect);
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- return meta_rectangle_equal (&opaque_rect,
- &(MetaRectangle) {
- .width = stex->dst_width,
- .height = stex->dst_height
- });
-}
-
-void
-meta_shaped_texture_set_transform (MetaShapedTexture *stex,
- MetaMonitorTransform transform)
-{
- if (stex->transform == transform)
- return;
-
- stex->transform = transform;
-
- meta_shaped_texture_reset_pipelines (stex);
- invalidate_size (stex);
-}
-
-/**
- * meta_shaped_texture_set_viewport_src_rect:
- * @stex: A #MetaShapedTexture
- * @src_rect: The viewport source rectangle
- *
- * Sets the viewport area that can be used to crop the original texture. The
- * cropped result can then be optionally scaled afterwards using
- * meta_shaped_texture_set_viewport_dst_size() as part of a crop-and-scale
- * operation.
- *
- * Note that the viewport's geometry should be provided in the coordinate space
- * of the texture received by the client, which might've been scaled as noted by
- * meta_shaped_texture_set_buffer_scale().
- *
- * %NULL is an invalid value for @src_rect. Use
- * meta_shaped_texture_reset_viewport_src_rect() if you want to remove the
- * cropping source rectangle.
- */
-void
-meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,
- graphene_rect_t *src_rect)
-{
- if (!stex->has_viewport_src_rect ||
- !G_APPROX_VALUE (stex->viewport_src_rect.origin.x,
- src_rect->origin.x, FLT_EPSILON) ||
- !G_APPROX_VALUE (stex->viewport_src_rect.origin.y,
- src_rect->origin.y, FLT_EPSILON) ||
- !G_APPROX_VALUE (stex->viewport_src_rect.size.width,
- src_rect->size.width, FLT_EPSILON) ||
- !G_APPROX_VALUE (stex->viewport_src_rect.size.height,
- src_rect->size.height, FLT_EPSILON))
- {
- stex->has_viewport_src_rect = TRUE;
- stex->viewport_src_rect = *src_rect;
- meta_shaped_texture_reset_pipelines (stex);
- invalidate_size (stex);
- }
-}
-
-void
-meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex)
-{
- if (!stex->has_viewport_src_rect)
- return;
-
- stex->has_viewport_src_rect = FALSE;
- meta_shaped_texture_reset_pipelines (stex);
- invalidate_size (stex);
-}
-
-/**
- * meta_shaped_texture_set_viewport_dst_size:
- * @stex: #MetaShapedTexture
- * @dst_width: The final viewport width (> 0)
- * @dst_height: The final viewport height (> 0)
- *
- * Sets a viewport size on @stex of the given @width and @height, which may
- * lead to scaling the texture. If you need to have cropping, use
- * meta_shaped_texture_set_viewport_src_rect() first, after which the scaling
- * stemming from this method will be applied.
- *
- * If you no longer want to have any scaling, use
- * meta_shaped_texture_reset_viewport_dst_size() to clear the current
- * parameters.
- */
-void
-meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
- int dst_width,
- int dst_height)
-{
- if (!stex->has_viewport_dst_size ||
- stex->viewport_dst_width != dst_width ||
- stex->viewport_dst_height != dst_height)
- {
- stex->has_viewport_dst_size = TRUE;
- stex->viewport_dst_width = dst_width;
- stex->viewport_dst_height = dst_height;
- invalidate_size (stex);
- }
-}
-
-void
-meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
-{
- if (!stex->has_viewport_dst_size)
- return;
-
- stex->has_viewport_dst_size = FALSE;
- invalidate_size (stex);
-}
-
-static gboolean
-should_get_via_offscreen (MetaShapedTexture *stex)
-{
- if (!cogl_texture_is_get_data_supported (stex->texture))
- return TRUE;
-
- if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
- return TRUE;
-
- switch (stex->transform)
- {
- case META_MONITOR_TRANSFORM_90:
- case META_MONITOR_TRANSFORM_180:
- case META_MONITOR_TRANSFORM_270:
- case META_MONITOR_TRANSFORM_FLIPPED:
- case META_MONITOR_TRANSFORM_FLIPPED_90:
- case META_MONITOR_TRANSFORM_FLIPPED_180:
- case META_MONITOR_TRANSFORM_FLIPPED_270:
- return TRUE;
- case META_MONITOR_TRANSFORM_NORMAL:
- break;
- }
-
- return FALSE;
-}
-
-static cairo_surface_t *
-get_image_via_offscreen (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip,
- int image_width,
- int image_height)
-{
- g_autoptr (ClutterPaintNode) root_node = NULL;
- ClutterBackend *clutter_backend = clutter_get_default_backend ();
- CoglContext *cogl_context =
- clutter_backend_get_cogl_context (clutter_backend);
- CoglTexture *image_texture;
- GError *error = NULL;
- CoglOffscreen *offscreen;
- CoglFramebuffer *fb;
- graphene_matrix_t projection_matrix;
- cairo_rectangle_int_t fallback_clip;
- ClutterColor clear_color;
- ClutterPaintContext *paint_context;
- cairo_surface_t *surface;
-
- if (!clip)
- {
- fallback_clip = (cairo_rectangle_int_t) {
- .width = image_width,
- .height = image_height,
- };
- clip = &fallback_clip;
- }
-
- image_texture =
- COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context,
- image_width,
- image_height));
- cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (image_texture),
- FALSE);
- if (!cogl_texture_allocate (COGL_TEXTURE (image_texture), &error))
- {
- g_error_free (error);
- cogl_object_unref (image_texture);
- return FALSE;
- }
-
- offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (image_texture));
- fb = COGL_FRAMEBUFFER (offscreen);
- cogl_object_unref (image_texture);
- if (!cogl_framebuffer_allocate (fb, &error))
- {
- g_error_free (error);
- g_object_unref (fb);
- return FALSE;
- }
-
- cogl_framebuffer_push_matrix (fb);
- graphene_matrix_init_translate (&projection_matrix,
- &GRAPHENE_POINT3D_INIT (-(image_width / 2.0),
- -(image_height / 2.0),
- 0));
- graphene_matrix_scale (&projection_matrix,
- 1.0 / (image_width / 2.0),
- -1.0 / (image_height / 2.0), 0);
-
- cogl_framebuffer_set_projection_matrix (fb, &projection_matrix);
-
- clear_color = (ClutterColor) { 0, 0, 0, 0 };
-
- root_node = clutter_root_node_new (fb, &clear_color, COGL_BUFFER_BIT_COLOR);
- clutter_paint_node_set_static_name (root_node, "MetaShapedTexture.offscreen");
-
- paint_context =
- clutter_paint_context_new_for_framebuffer (fb, NULL,
- CLUTTER_PAINT_FLAG_NONE);
-
- do_paint_content (stex, root_node, paint_context,
- stex->texture,
- &(ClutterActorBox) {
- 0, 0,
- image_width,
- image_height,
- },
- 255);
-
- clutter_paint_node_paint (root_node, paint_context);
- clutter_paint_context_destroy (paint_context);
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- clip->width, clip->height);
- cogl_framebuffer_read_pixels (fb,
- clip->x, clip->y,
- clip->width, clip->height,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- cairo_image_surface_get_data (surface));
- g_object_unref (fb);
-
- cairo_surface_mark_dirty (surface);
-
- return surface;
-}
-
-/**
- * meta_shaped_texture_get_image:
- * @stex: A #MetaShapedTexture
- * @clip: (nullable): A clipping rectangle, to help prevent extra processing.
- * In the case that the clipping rectangle is partially or fully
- * outside the bounds of the texture, the rectangle will be clipped.
- *
- * Flattens the two layers of the shaped texture into one ARGB32
- * image by alpha blending the two images, and returns the flattened
- * image.
- *
- * Returns: (nullable) (transfer full): a new cairo surface to be freed with
- * cairo_surface_destroy().
- */
-cairo_surface_t *
-meta_shaped_texture_get_image (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip)
-{
- cairo_rectangle_int_t *image_clip = NULL;
- CoglTexture *texture, *mask_texture;
- cairo_surface_t *surface;
-
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
-
- texture = COGL_TEXTURE (stex->texture);
-
- if (texture == NULL)
- return NULL;
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- if (stex->dst_width == 0 || stex->dst_height == 0)
- return NULL;
-
- if (clip != NULL)
- {
- cairo_rectangle_int_t dst_rect;
-
- image_clip = alloca (sizeof (cairo_rectangle_int_t));
- dst_rect = (cairo_rectangle_int_t) {
- .width = stex->dst_width,
- .height = stex->dst_height,
- };
-
- if (!meta_rectangle_intersect (&dst_rect, clip,
- image_clip))
- return NULL;
-
- *image_clip = (MetaRectangle) {
- .x = image_clip->x * stex->buffer_scale,
- .y = image_clip->y * stex->buffer_scale,
- .width = image_clip->width * stex->buffer_scale,
- .height = image_clip->height * stex->buffer_scale,
- };
- }
-
- if (should_get_via_offscreen (stex))
- {
- int image_width;
- int image_height;
-
- image_width = stex->dst_width * stex->buffer_scale;
- image_height = stex->dst_height * stex->buffer_scale;
- return get_image_via_offscreen (stex,
- image_clip,
- image_width,
- image_height);
- }
-
- if (image_clip)
- texture = cogl_texture_new_from_sub_texture (texture,
- image_clip->x,
- image_clip->y,
- image_clip->width,
- image_clip->height);
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- cogl_texture_get_width (texture),
- cogl_texture_get_height (texture));
-
- cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
- cairo_image_surface_get_stride (surface),
- cairo_image_surface_get_data (surface));
-
- cairo_surface_mark_dirty (surface);
-
- if (image_clip)
- cogl_object_unref (texture);
-
- mask_texture = stex->mask_texture;
- if (mask_texture != NULL)
- {
- cairo_t *cr;
- cairo_surface_t *mask_surface;
-
- if (image_clip)
- mask_texture =
- cogl_texture_new_from_sub_texture (mask_texture,
- image_clip->x,
- image_clip->y,
- image_clip->width,
- image_clip->height);
-
- mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
- cogl_texture_get_width (mask_texture),
- cogl_texture_get_height (mask_texture));
-
- cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
- cairo_image_surface_get_stride (mask_surface),
- cairo_image_surface_get_data (mask_surface));
-
- cairo_surface_mark_dirty (mask_surface);
-
- cr = cairo_create (surface);
- cairo_set_source_surface (cr, mask_surface, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
- cairo_paint (cr);
- cairo_destroy (cr);
-
- cairo_surface_destroy (mask_surface);
-
- if (image_clip)
- cogl_object_unref (mask_texture);
- }
-
- return surface;
-}
-
-void
-meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
- int fallback_width,
- int fallback_height)
-{
- stex->fallback_width = fallback_width;
- stex->fallback_height = fallback_height;
-
- invalidate_size (stex);
-}
-
-MetaShapedTexture *
-meta_shaped_texture_new (void)
-{
- return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
-}
-
-/**
- * meta_shaped_texture_set_buffer_scale:
- * @stex: A #MetaShapedTexture
- * @buffer_scale: The scale that should be applied to coorsinate space
- *
- * Instructs @stex to interpret the geometry of the input texture by scaling it
- * with @buffer_scale. This means that the #CoglTexture that is provided by a
- * client is already scaled by that factor.
- */
-void
-meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex,
- int buffer_scale)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- if (buffer_scale == stex->buffer_scale)
- return;
-
- stex->buffer_scale = buffer_scale;
-
- invalidate_size (stex);
-}
-
-int
-meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 1.0);
-
- return stex->buffer_scale;
-}
-
-/**
- * meta_shaped_texture_get_width:
- * @stex: A #MetaShapedTexture
- *
- * Returns: The final width of @stex after its shaping operations are applied.
- */
-int
-meta_shaped_texture_get_width (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0);
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- return stex->dst_width;
-}
-
-/**
- * meta_shaped_texture_get_height:
- * @stex: A #MetaShapedTexture
- *
- * Returns: The final height of @stex after its shaping operations are applied.
- */
-int
-meta_shaped_texture_get_height (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0);
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- return stex->dst_height;
-}
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
deleted file mode 100644
index a182ad851..000000000
--- a/src/compositor/meta-surface-actor-wayland.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2013 Red Hat
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include "config.h"
-
-#include "compositor/meta-surface-actor-wayland.h"
-
-#include <math.h>
-
-#include "backends/meta-backend-private.h"
-#include "backends/meta-logical-monitor.h"
-#include "cogl/cogl-wayland-server.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "compositor/region-utils.h"
-#include "wayland/meta-wayland-buffer.h"
-#include "wayland/meta-wayland-private.h"
-#include "wayland/meta-window-wayland.h"
-
-struct _MetaSurfaceActorWayland
-{
- MetaSurfaceActor parent;
-
- MetaWaylandSurface *surface;
-};
-
-G_DEFINE_TYPE (MetaSurfaceActorWayland,
- meta_surface_actor_wayland,
- META_TYPE_SURFACE_ACTOR)
-
-static void
-meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
- int x,
- int y,
- int width,
- int height)
-{
- meta_surface_actor_update_area (actor, x, y, width, height);
-}
-
-static gboolean
-meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
-{
- MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
-
- return meta_shaped_texture_is_opaque (stex);
-}
-
-CoglScanout *
-meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
- CoglOnscreen *onscreen)
-{
- MetaWaylandSurface *surface;
- CoglScanout *scanout;
-
- surface = meta_surface_actor_wayland_get_surface (self);
- if (!surface)
- return NULL;
-
- scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
- if (!scanout)
- return NULL;
-
- return scanout;
-}
-
-#define UNOBSCURED_TRESHOLD 0.1
-
-ClutterStageView *
-meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
- ClutterStage *stage)
-{
- ClutterStageView *current_primary_view = NULL;
- float highest_refresh_rate = 0.f;
- float biggest_unobscurred_fraction = 0.f;
- GList *l;
-
- for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- float refresh_rate;
- float unobscurred_fraction = 1.f;
-
- if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
- {
- if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
- stage_view))
- continue;
- }
- else
- {
- if (l->next || biggest_unobscurred_fraction > 0.f)
- {
- if (meta_surface_actor_is_obscured_on_stage_view (actor,
- stage_view,
- &unobscurred_fraction))
- continue;
- }
- else
- {
- if (meta_surface_actor_is_obscured (actor))
- continue;
- }
- }
-
- refresh_rate = clutter_stage_view_get_refresh_rate (stage_view);
-
- if ((refresh_rate > highest_refresh_rate &&
- (unobscurred_fraction > UNOBSCURED_TRESHOLD ||
- biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD)) ||
- (biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD &&
- unobscurred_fraction > UNOBSCURED_TRESHOLD))
- {
- current_primary_view = stage_view;
- highest_refresh_rate = refresh_rate;
- biggest_unobscurred_fraction = unobscurred_fraction;
- }
- }
-
- return current_primary_view;
-}
-
-static void
-meta_surface_actor_wayland_dispose (GObject *object)
-{
- MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
- MetaShapedTexture *stex;
-
- stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
- if (stex)
- meta_shaped_texture_set_texture (stex, NULL);
-
- if (self->surface)
- {
- g_object_remove_weak_pointer (G_OBJECT (self->surface),
- (gpointer *) &self->surface);
- self->surface = NULL;
- }
-
- G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
-}
-
-static void
-meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
-{
- MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
- surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
-
- object_class->dispose = meta_surface_actor_wayland_dispose;
-}
-
-static void
-meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self)
-{
-}
-
-MetaSurfaceActor *
-meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
-{
- MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL);
-
- g_assert (meta_is_wayland_compositor ());
-
- self->surface = surface;
- g_object_add_weak_pointer (G_OBJECT (self->surface),
- (gpointer *) &self->surface);
-
- return META_SURFACE_ACTOR (self);
-}
-
-MetaWaylandSurface *
-meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self)
-{
- return self->surface;
-}
diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h
deleted file mode 100644
index 10eb3326a..000000000
--- a/src/compositor/meta-surface-actor-wayland.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2013 Red Hat
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#ifndef __META_SURFACE_ACTOR_WAYLAND_H__
-#define __META_SURFACE_ACTOR_WAYLAND_H__
-
-#include <glib-object.h>
-
-#include "backends/meta-monitor-manager-private.h"
-#include "compositor/meta-surface-actor.h"
-#include "wayland/meta-wayland-private.h"
-#include "wayland/meta-wayland.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_SURFACE_ACTOR_WAYLAND (meta_surface_actor_wayland_get_type ())
-G_DECLARE_FINAL_TYPE (MetaSurfaceActorWayland,
- meta_surface_actor_wayland,
- META, SURFACE_ACTOR_WAYLAND,
- MetaSurfaceActor)
-
-MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
-MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
-void meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self);
-
-double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
-
-void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
- MetaRectangle *rect);
-
-void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
- struct wl_list *frame_callbacks);
-
-CoglScanout * meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
- CoglOnscreen *onscreen);
-
-ClutterStageView * meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
- ClutterStage *stage);
-
-G_END_DECLS
-
-#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
deleted file mode 100644
index 41ae2dffb..000000000
--- a/src/compositor/meta-surface-actor-x11.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2013 Red Hat
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Owen Taylor <otaylor@redhat.com>
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include "config.h"
-
-#include "compositor/meta-surface-actor-x11.h"
-
-#include <X11/extensions/Xcomposite.h>
-
-#include "cogl/winsys/cogl-texture-pixmap-x11.h"
-#include "compositor/meta-cullable.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "compositor/meta-window-actor-private.h"
-#include "core/window-private.h"
-#include "meta/meta-x11-errors.h"
-#include "x11/meta-x11-display-private.h"
-#include "x11/window-x11.h"
-
-struct _MetaSurfaceActorX11
-{
- MetaSurfaceActor parent;
-
- MetaWindow *window;
-
- MetaDisplay *display;
-
- CoglTexture *texture;
- Pixmap pixmap;
- Damage damage;
-
- int last_width;
- int last_height;
-
- /* This is used to detect fullscreen windows that need to be unredirected */
- guint full_damage_frames_count;
- guint does_full_damage : 1;
-
- /* Other state... */
- guint received_damage : 1;
- guint size_changed : 1;
-
- guint unredirected : 1;
-};
-
-G_DEFINE_TYPE (MetaSurfaceActorX11,
- meta_surface_actor_x11,
- META_TYPE_SURFACE_ACTOR)
-
-static void
-free_damage (MetaSurfaceActorX11 *self)
-{
- MetaDisplay *display = self->display;
- Display *xdisplay;
-
- if (self->damage == None)
- return;
-
- xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- meta_x11_error_trap_push (display->x11_display);
- XDamageDestroy (xdisplay, self->damage);
- self->damage = None;
- meta_x11_error_trap_pop (display->x11_display);
-}
-
-static void
-detach_pixmap (MetaSurfaceActorX11 *self)
-{
- MetaDisplay *display = self->display;
- MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
- Display *xdisplay;
-
- if (self->pixmap == None)
- return;
-
- xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- /* Get rid of all references to the pixmap before freeing it; it's unclear whether
- * you are supposed to be able to free a GLXPixmap after freeing the underlying
- * pixmap, but it certainly doesn't work with current DRI/Mesa
- */
- meta_shaped_texture_set_texture (stex, NULL);
- cogl_flush ();
-
- meta_x11_error_trap_push (display->x11_display);
- XFreePixmap (xdisplay, self->pixmap);
- self->pixmap = None;
- meta_x11_error_trap_pop (display->x11_display);
-
- g_clear_pointer (&self->texture, cogl_object_unref);
-}
-
-static void
-set_pixmap (MetaSurfaceActorX11 *self,
- Pixmap pixmap)
-{
- CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
- MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
- GError *error = NULL;
- CoglTexture *texture;
-
- g_assert (self->pixmap == None);
- self->pixmap = pixmap;
-
- texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error));
-
- if (error != NULL)
- {
- g_warning ("Failed to allocate stex texture: %s", error->message);
- g_error_free (error);
- }
- else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
- g_warning ("NOTE: Not using GLX TFP!");
-
- self->texture = texture;
- meta_shaped_texture_set_texture (stex, texture);
-}
-
-static void
-update_pixmap (MetaSurfaceActorX11 *self)
-{
- MetaDisplay *display = self->display;
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- if (self->size_changed)
- {
- detach_pixmap (self);
- self->size_changed = FALSE;
- }
-
- if (self->pixmap == None)
- {
- Pixmap new_pixmap;
- Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window);
-
- meta_x11_error_trap_push (display->x11_display);
- new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
-
- if (meta_x11_error_trap_pop_with_return (display->x11_display) != Success)
- {
- /* Probably a BadMatch if the window isn't viewable; we could
- * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync
- * to avoid this, but there's no reason to take two round trips
- * when one will do. (We need that Sync if we want to handle failures
- * for any reason other than !viewable. That's unlikely, but maybe
- * we'll BadAlloc or something.)
- */
- new_pixmap = None;
- }
-
- if (new_pixmap == None)
- {
- meta_verbose ("Unable to get named pixmap for %s",
- meta_window_get_description (self->window));
- return;
- }
-
- set_pixmap (self, new_pixmap);
- }
-}
-
-gboolean
-meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self)
-{
- return (self->pixmap != None) && !self->unredirected;
-}
-
-static void
-meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
- int x, int y, int width, int height)
-{
- MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
-
- self->received_damage = TRUE;
-
- if (meta_window_is_fullscreen (self->window) && !self->unredirected && !self->does_full_damage)
- {
- MetaRectangle window_rect;
- meta_window_get_frame_rect (self->window, &window_rect);
-
- if (x == 0 &&
- y == 0 &&
- window_rect.width == width &&
- window_rect.height == height)
- self->full_damage_frames_count++;
- else
- self->full_damage_frames_count = 0;
-
- if (self->full_damage_frames_count >= 100)
- self->does_full_damage = TRUE;
- }
-
- if (!meta_surface_actor_x11_is_visible (self))
- return;
-
- cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture),
- x, y, width, height);
- meta_surface_actor_update_area (actor, x, y, width, height);
-}
-
-void
-meta_surface_actor_x11_handle_updates (MetaSurfaceActorX11 *self)
-{
- MetaDisplay *display = self->display;
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- if (self->received_damage)
- {
- meta_x11_error_trap_push (display->x11_display);
- XDamageSubtract (xdisplay, self->damage, None, None);
- meta_x11_error_trap_pop (display->x11_display);
-
- self->received_damage = FALSE;
- }
-
- update_pixmap (self);
-}
-
-static gboolean
-meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor)
-{
- MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
- MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
-
- if (meta_surface_actor_x11_is_unredirected (self))
- return TRUE;
-
- return meta_shaped_texture_is_opaque (stex);
-}
-
-gboolean
-meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self)
-{
- if (!meta_surface_actor_x11_is_opaque (META_SURFACE_ACTOR (self)))
- return FALSE;
-
- if (!self->does_full_damage &&
- !meta_window_is_override_redirect (self->window))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-sync_unredirected (MetaSurfaceActorX11 *self)
-{
- MetaDisplay *display = self->display;
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
- Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window);
-
- meta_x11_error_trap_push (display->x11_display);
-
- if (self->unredirected)
- {
- XCompositeUnredirectWindow (xdisplay, xwindow, CompositeRedirectManual);
- XSync (xdisplay, False);
- detach_pixmap (self);
- }
- else
- {
- XCompositeRedirectWindow (xdisplay, xwindow, CompositeRedirectManual);
- XSync (xdisplay, False);
- clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
- }
-
- meta_x11_error_trap_pop (display->x11_display);
-}
-
-void
-meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self,
- gboolean unredirected)
-{
- if (self->unredirected == unredirected)
- return;
-
- self->unredirected = unredirected;
- sync_unredirected (self);
-}
-
-gboolean
-meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self)
-{
- return self->unredirected;
-}
-
-static void
-release_x11_resources (MetaSurfaceActorX11 *self)
-{
- detach_pixmap (self);
- free_damage (self);
-}
-
-static void
-meta_surface_actor_x11_dispose (GObject *object)
-{
- MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object);
-
- release_x11_resources (self);
-
- G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object);
-}
-
-static void
-meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
-
- object_class->dispose = meta_surface_actor_x11_dispose;
-
- surface_actor_class->process_damage = meta_surface_actor_x11_process_damage;
- surface_actor_class->is_opaque = meta_surface_actor_x11_is_opaque;
-}
-
-static void
-meta_surface_actor_x11_init (MetaSurfaceActorX11 *self)
-{
- self->last_width = -1;
- self->last_height = -1;
-}
-
-static void
-create_damage (MetaSurfaceActorX11 *self)
-{
- Display *xdisplay = meta_x11_display_get_xdisplay (self->display->x11_display);
- Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window);
-
- self->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
-}
-
-static void
-window_decorated_notify (MetaWindow *window,
- GParamSpec *pspec,
- gpointer user_data)
-{
- MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data);
-
- release_x11_resources (self);
- create_damage (self);
-}
-
-static void
-reset_texture (MetaSurfaceActorX11 *self)
-{
- MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
-
- if (!self->texture)
- return;
-
- /* Setting the texture to NULL will cause all the FBO's cached by the
- * shaped texture's MetaTextureTower to be discarded and recreated.
- */
- meta_shaped_texture_set_texture (stex, NULL);
- meta_shaped_texture_set_texture (stex, self->texture);
-}
-
-MetaSurfaceActor *
-meta_surface_actor_x11_new (MetaWindow *window)
-{
- MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL);
- MetaDisplay *display = meta_window_get_display (window);
-
- g_assert (!meta_is_wayland_compositor ());
-
- self->window = window;
- self->display = display;
-
- g_signal_connect_object (self->display, "gl-video-memory-purged",
- G_CALLBACK (reset_texture), self, G_CONNECT_SWAPPED);
-
- create_damage (self);
- g_signal_connect_object (self->window, "notify::decorated",
- G_CALLBACK (window_decorated_notify), self, 0);
-
- g_signal_connect_object (meta_window_actor_from_window (window), "destroy",
- G_CALLBACK (release_x11_resources), self,
- G_CONNECT_SWAPPED);
-
- self->unredirected = FALSE;
- sync_unredirected (self);
-
- clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
- return META_SURFACE_ACTOR (self);
-}
-
-void
-meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
- int width, int height)
-{
- MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
-
- if (self->last_width == width &&
- self->last_height == height)
- return;
-
- self->size_changed = TRUE;
- self->last_width = width;
- self->last_height = height;
- meta_shaped_texture_set_fallback_size (stex, width, height);
-}
diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h
deleted file mode 100644
index 0a8517236..000000000
--- a/src/compositor/meta-surface-actor-x11.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2013 Red Hat
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Owen Taylor <otaylor@redhat.com>
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#ifndef __META_SURFACE_ACTOR_X11_H__
-#define __META_SURFACE_ACTOR_X11_H__
-
-#include <glib-object.h>
-
-#include <X11/extensions/Xdamage.h>
-
-#include "compositor/meta-surface-actor.h"
-#include "meta/display.h"
-#include "meta/window.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_SURFACE_ACTOR_X11 (meta_surface_actor_x11_get_type ())
-G_DECLARE_FINAL_TYPE (MetaSurfaceActorX11,
- meta_surface_actor_x11,
- META, SURFACE_ACTOR_X11,
- MetaSurfaceActor)
-
-MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window);
-
-void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
- int width, int height);
-gboolean meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self);
-
-void meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self,
- gboolean unredirected);
-
-gboolean meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self);
-
-gboolean meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self);
-
-void meta_surface_actor_x11_handle_updates (MetaSurfaceActorX11 *self);
-
-G_END_DECLS
-
-#endif /* __META_SURFACE_ACTOR_X11_H__ */
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
deleted file mode 100644
index 48042b227..000000000
--- a/src/compositor/meta-surface-actor.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:meta-surface-actor
- * @title: MetaSurfaceActor
- * @short_description: An actor representing a surface in the scene graph
- *
- * MetaSurfaceActor is an abstract class which represents a surface in the
- * Clutter scene graph. A subclass can implement the specifics of a surface
- * depending on the way it is handled by a display protocol.
- *
- * An important feature of #MetaSurfaceActor is that it allows you to set an
- * "input region": all events that occur in the surface, but outside of the
- * input region are to be explicitly ignored. By default, this region is to
- * %NULL, which means events on the whole surface is allowed.
- */
-
-#include "config.h"
-
-#include "compositor/meta-surface-actor.h"
-
-#include "clutter/clutter.h"
-#include "compositor/clutter-utils.h"
-#include "compositor/meta-cullable.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "compositor/meta-window-actor-private.h"
-#include "compositor/region-utils.h"
-#include "meta/meta-shaped-texture.h"
-
-typedef struct _MetaSurfaceActorPrivate
-{
- MetaShapedTexture *texture;
-
- cairo_region_t *input_region;
-
- /* MetaCullable regions, see that documentation for more details */
- cairo_region_t *unobscured_region;
-
- /* Freeze/thaw accounting */
- cairo_region_t *pending_damage;
- guint frozen : 1;
-} MetaSurfaceActorPrivate;
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
- G_ADD_PRIVATE (MetaSurfaceActor)
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
-
-enum
-{
- REPAINT_SCHEDULED,
- SIZE_CHANGED,
-
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL];
-
-typedef enum
-{
- IN_STAGE_PERSPECTIVE,
- IN_ACTOR_PERSPECTIVE
-} ScalePerspectiveType;
-
-static cairo_region_t *
-effective_unobscured_region (MetaSurfaceActor *surface_actor)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (surface_actor);
- ClutterActor *actor = CLUTTER_ACTOR (surface_actor);
-
- /* Fail if we have any mapped clones. */
- if (clutter_actor_has_mapped_clones (actor))
- return NULL;
-
- return priv->unobscured_region;
-}
-
-static cairo_region_t*
-get_scaled_region (MetaSurfaceActor *surface_actor,
- cairo_region_t *region,
- ScalePerspectiveType scale_perspective)
-{
- MetaWindowActor *window_actor;
- cairo_region_t *scaled_region = NULL;
- int geometry_scale;
- float x, y;
-
- window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
- geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
-
- clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
- cairo_region_translate (region, x, y);
-
- switch (scale_perspective)
- {
- case IN_STAGE_PERSPECTIVE:
- scaled_region = meta_region_scale_double (region,
- geometry_scale,
- META_ROUNDING_STRATEGY_GROW);
- break;
- case IN_ACTOR_PERSPECTIVE:
- scaled_region = meta_region_scale_double (region,
- 1.0 / geometry_scale,
- META_ROUNDING_STRATEGY_GROW);
- break;
- }
-
- g_assert (scaled_region != NULL);
- cairo_region_translate (region, -x, -y);
- cairo_region_translate (scaled_region, -x, -y);
-
- return scaled_region;
-}
-
-static void
-set_unobscured_region (MetaSurfaceActor *surface_actor,
- cairo_region_t *unobscured_region)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (surface_actor);
-
- g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
- if (unobscured_region)
- {
- if (cairo_region_is_empty (unobscured_region))
- {
- priv->unobscured_region = cairo_region_reference (unobscured_region);
- }
- else
- {
- cairo_rectangle_int_t bounds = { 0, };
- float width, height;
-
- clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
- &width,
- &height);
- bounds = (cairo_rectangle_int_t) {
- .width = width,
- .height = height,
- };
-
- priv->unobscured_region = get_scaled_region (surface_actor,
- unobscured_region,
- IN_ACTOR_PERSPECTIVE);
-
- cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
- }
- }
-}
-
-static void
-set_clip_region (MetaSurfaceActor *surface_actor,
- cairo_region_t *clip_region)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (surface_actor);
- MetaShapedTexture *stex = priv->texture;
-
- if (clip_region && !cairo_region_is_empty (clip_region))
- {
- cairo_region_t *region;
-
- region = get_scaled_region (surface_actor,
- clip_region,
- IN_ACTOR_PERSPECTIVE);
- meta_shaped_texture_set_clip_region (stex, region);
-
- cairo_region_destroy (region);
- }
- else
- {
- meta_shaped_texture_set_clip_region (stex, clip_region);
- }
-}
-
-static void
-meta_surface_actor_pick (ClutterActor *actor,
- ClutterPickContext *pick_context)
-{
- MetaSurfaceActor *self = META_SURFACE_ACTOR (actor);
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
- ClutterActorIter iter;
- ClutterActor *child;
-
- if (!clutter_actor_should_pick (actor, pick_context))
- return;
-
- /* If there is no region then use the regular pick */
- if (priv->input_region == NULL)
- {
- ClutterActorClass *actor_class =
- CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class);
-
- actor_class->pick (actor, pick_context);
- }
- else
- {
- int n_rects;
- int i;
-
- n_rects = cairo_region_num_rectangles (priv->input_region);
-
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- ClutterActorBox box;
-
- cairo_region_get_rectangle (priv->input_region, i, &rect);
-
- box.x1 = rect.x;
- box.y1 = rect.y;
- box.x2 = rect.x + rect.width;
- box.y2 = rect.y + rect.height;
- clutter_actor_pick_box (actor, pick_context, &box);
- }
- }
-
- clutter_actor_iter_init (&iter, actor);
-
- while (clutter_actor_iter_next (&iter, &child))
- clutter_actor_pick (child, pick_context);
-}
-
-static gboolean
-meta_surface_actor_get_paint_volume (ClutterActor *actor,
- ClutterPaintVolume *volume)
-{
- return clutter_paint_volume_set_from_allocation (volume, actor);
-}
-
-static void
-meta_surface_actor_dispose (GObject *object)
-{
- MetaSurfaceActor *self = META_SURFACE_ACTOR (object);
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- g_clear_pointer (&priv->input_region, cairo_region_destroy);
- g_clear_object (&priv->texture);
-
- set_unobscured_region (self, NULL);
-
- G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
-}
-
-static void
-meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
- object_class->dispose = meta_surface_actor_dispose;
- actor_class->pick = meta_surface_actor_pick;
- actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
-
- signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- signals[SIZE_CHANGED] = g_signal_new ("size-changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-gboolean
-meta_surface_actor_is_opaque (MetaSurfaceActor *self)
-{
- return META_SURFACE_ACTOR_GET_CLASS (self)->is_opaque (self);
-}
-
-static void
-meta_surface_actor_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (surface_actor);
- uint8_t opacity = clutter_actor_get_opacity (CLUTTER_ACTOR (cullable));
-
- set_unobscured_region (surface_actor, unobscured_region);
- set_clip_region (surface_actor, clip_region);
-
- if (opacity == 0xff)
- {
- cairo_region_t *opaque_region;
- cairo_region_t *scaled_opaque_region;
-
- opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
-
- if (!opaque_region)
- return;
-
- scaled_opaque_region = get_scaled_region (surface_actor,
- opaque_region,
- IN_STAGE_PERSPECTIVE);
-
- if (unobscured_region)
- cairo_region_subtract (unobscured_region, scaled_opaque_region);
- if (clip_region)
- cairo_region_subtract (clip_region, scaled_opaque_region);
-
- cairo_region_destroy (scaled_opaque_region);
- }
-}
-
-static gboolean
-meta_surface_actor_is_untransformed (MetaCullable *cullable)
-{
- ClutterActor *actor = CLUTTER_ACTOR (cullable);
- MetaWindowActor *window_actor;
- float width, height;
- graphene_point3d_t verts[4];
- int geometry_scale;
-
- clutter_actor_get_size (actor, &width, &height);
- clutter_actor_get_abs_allocation_vertices (actor, verts);
-
- window_actor = meta_window_actor_from_actor (actor);
- geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
-
- return meta_actor_vertices_are_untransformed (verts,
- width * geometry_scale,
- height * geometry_scale,
- NULL, NULL);
-}
-
-static void
-meta_surface_actor_reset_culling (MetaCullable *cullable)
-{
- MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
-
- set_clip_region (surface_actor, NULL);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_surface_actor_cull_out;
- iface->is_untransformed = meta_surface_actor_is_untransformed;
- iface->reset_culling = meta_surface_actor_reset_culling;
-}
-
-static void
-texture_size_changed (MetaShapedTexture *texture,
- gpointer user_data)
-{
- MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data);
- g_signal_emit (actor, signals[SIZE_CHANGED], 0);
-}
-
-static void
-meta_surface_actor_init (MetaSurfaceActor *self)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- priv->texture = meta_shaped_texture_new ();
- g_signal_connect_object (priv->texture, "size-changed",
- G_CALLBACK (texture_size_changed), self, 0);
- clutter_actor_set_content (CLUTTER_ACTOR (self),
- CLUTTER_CONTENT (priv->texture));
- clutter_actor_set_request_mode (CLUTTER_ACTOR (self),
- CLUTTER_REQUEST_CONTENT_SIZE);
-}
-
-/**
- * meta_surface_actor_get_image:
- * @self: A #MetaSurfaceActor
- * @clip: (nullable): A clipping rectangle. The clip region is in
- * the same coordinate space as the contents preferred size.
- * For a shaped texture of a wl_surface, this means surface
- * coordinate space. If NULL, the whole content will be used.
- *
- * Get the image from the texture content. The resulting size of
- * the returned image may be different from the preferred size of
- * the shaped texture content.
- *
- * Returns: (nullable) (transfer full): a new cairo surface to be freed
- * with cairo_surface_destroy().
- */
-cairo_surface_t *
-meta_surface_actor_get_image (MetaSurfaceActor *self,
- cairo_rectangle_int_t *clip)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- return meta_shaped_texture_get_image (priv->texture, clip);
-}
-
-MetaShapedTexture *
-meta_surface_actor_get_texture (MetaSurfaceActor *self)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- return priv->texture;
-}
-
-void
-meta_surface_actor_update_area (MetaSurfaceActor *self,
- int x,
- int y,
- int width,
- int height)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
- gboolean repaint_scheduled = FALSE;
- cairo_rectangle_int_t clip;
-
- if (meta_shaped_texture_update_area (priv->texture, x, y, width, height, &clip))
- {
- cairo_region_t *unobscured_region;
-
- unobscured_region = effective_unobscured_region (self);
-
- if (unobscured_region)
- {
- cairo_region_t *intersection;
-
- if (cairo_region_is_empty (unobscured_region))
- return;
-
- intersection = cairo_region_copy (unobscured_region);
- cairo_region_intersect_rectangle (intersection, &clip);
-
- if (!cairo_region_is_empty (intersection))
- {
- cairo_rectangle_int_t damage_rect;
-
- cairo_region_get_extents (intersection, &damage_rect);
- clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &damage_rect);
- repaint_scheduled = TRUE;
- }
-
- cairo_region_destroy (intersection);
- }
- else
- {
- clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &clip);
- repaint_scheduled = TRUE;
- }
- }
-
- if (repaint_scheduled)
- g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
-}
-
-gboolean
-meta_surface_actor_is_obscured (MetaSurfaceActor *self)
-{
- cairo_region_t *unobscured_region;
-
- unobscured_region = effective_unobscured_region (self);
-
- if (unobscured_region)
- return cairo_region_is_empty (unobscured_region);
- else
- return FALSE;
-}
-
-gboolean
-meta_surface_actor_is_obscured_on_stage_view (MetaSurfaceActor *self,
- ClutterStageView *stage_view,
- float *unobscurred_fraction)
-{
- cairo_region_t *unobscured_region;
-
- unobscured_region = effective_unobscured_region (self);
-
- if (unobscured_region)
- {
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
- cairo_region_t *intersection_region;
- cairo_rectangle_int_t stage_rect;
- float x, y;
- float bounds_width, bounds_height;
- float bounds_size;
- int intersection_size = 0;
- int n_rects, i;
-
- if (cairo_region_is_empty (unobscured_region))
- return TRUE;
-
- intersection_region = cairo_region_copy (unobscured_region);
- clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
- cairo_region_translate (intersection_region, x, y);
-
- clutter_stage_view_get_layout (stage_view, &stage_rect);
- cairo_region_intersect_rectangle (intersection_region,
- &stage_rect);
-
- if (cairo_region_is_empty (intersection_region))
- {
- cairo_region_destroy (intersection_region);
- return TRUE;
- }
- else if (!unobscurred_fraction)
- {
- cairo_region_destroy (intersection_region);
- return FALSE;
- }
-
- clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
- &bounds_width,
- &bounds_height);
- bounds_size = bounds_width * bounds_height;
-
- n_rects = cairo_region_num_rectangles (intersection_region);
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (intersection_region, i, &rect);
- intersection_size += (rect.width - rect.x) * (rect.height - rect.x);
- }
- cairo_region_destroy (intersection_region);
-
- g_return_val_if_fail (bounds_size > 0, FALSE);
-
- *unobscurred_fraction = CLAMP (intersection_size / bounds_size, 0, 1);
- return FALSE;
- }
-
- return !clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (self),
- stage_view);
-}
-
-void
-meta_surface_actor_set_input_region (MetaSurfaceActor *self,
- cairo_region_t *region)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- if (priv->input_region)
- cairo_region_destroy (priv->input_region);
-
- if (region)
- priv->input_region = cairo_region_reference (region);
- else
- priv->input_region = NULL;
-}
-
-void
-meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
- cairo_region_t *region)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- meta_shaped_texture_set_opaque_region (priv->texture, region);
-}
-
-cairo_region_t *
-meta_surface_actor_get_opaque_region (MetaSurfaceActor *self)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- return meta_shaped_texture_get_opaque_region (priv->texture);
-}
-
-void
-meta_surface_actor_process_damage (MetaSurfaceActor *self,
- int x, int y, int width, int height)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- if (meta_surface_actor_is_frozen (self))
- {
- /* The window is frozen due to an effect in progress: we ignore damage
- * here on the off chance that this will stop the corresponding
- * texture_from_pixmap from being update.
- *
- * pending_damage tracks any damage that happened while the window was
- * frozen so that when can apply it when the window becomes unfrozen.
- *
- * It should be noted that this is an unreliable mechanism since it's
- * quite likely that drivers will aim to provide a zero-copy
- * implementation of the texture_from_pixmap extension and in those cases
- * any drawing done to the window is always immediately reflected in the
- * texture regardless of damage event handling.
- */
- cairo_rectangle_int_t rect = { .x = x, .y = y, .width = width, .height = height };
-
- if (!priv->pending_damage)
- priv->pending_damage = cairo_region_create_rectangle (&rect);
- else
- cairo_region_union_rectangle (priv->pending_damage, &rect);
- return;
- }
-
- META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
-}
-
-void
-meta_surface_actor_set_frozen (MetaSurfaceActor *self,
- gboolean frozen)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- if (priv->frozen == frozen)
- return;
-
- priv->frozen = frozen;
-
- if (!frozen && priv->pending_damage)
- {
- int i, n_rects = cairo_region_num_rectangles (priv->pending_damage);
- cairo_rectangle_int_t rect;
-
- /* Since we ignore damage events while a window is frozen for certain effects
- * we need to apply the tracked damage now. */
-
- for (i = 0; i < n_rects; i++)
- {
- cairo_region_get_rectangle (priv->pending_damage, i, &rect);
- meta_surface_actor_process_damage (self, rect.x, rect.y,
- rect.width, rect.height);
- }
- g_clear_pointer (&priv->pending_damage, cairo_region_destroy);
- }
-}
-
-gboolean
-meta_surface_actor_is_frozen (MetaSurfaceActor *self)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- return priv->frozen;
-}
-
-void
-meta_surface_actor_set_transform (MetaSurfaceActor *self,
- MetaMonitorTransform transform)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- meta_shaped_texture_set_transform (priv->texture, transform);
-}
-
-void
-meta_surface_actor_set_viewport_src_rect (MetaSurfaceActor *self,
- graphene_rect_t *src_rect)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- meta_shaped_texture_set_viewport_src_rect (priv->texture, src_rect);
-}
-
-void
-meta_surface_actor_reset_viewport_src_rect (MetaSurfaceActor *self)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- meta_shaped_texture_reset_viewport_src_rect (priv->texture);
-}
-
-void
-meta_surface_actor_set_viewport_dst_size (MetaSurfaceActor *self,
- int dst_width,
- int dst_height)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- meta_shaped_texture_set_viewport_dst_size (priv->texture,
- dst_width,
- dst_height);
-}
-
-void
-meta_surface_actor_reset_viewport_dst_size (MetaSurfaceActor *self)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- meta_shaped_texture_reset_viewport_dst_size (priv->texture);
-}
diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h
deleted file mode 100644
index a61251049..000000000
--- a/src/compositor/meta-surface-actor.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_SURFACE_ACTOR_PRIVATE_H
-#define META_SURFACE_ACTOR_PRIVATE_H
-
-#include "config.h"
-
-#include "backends/meta-backend-types.h"
-#include "meta/meta-shaped-texture.h"
-#include "meta/window.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_SURFACE_ACTOR (meta_surface_actor_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaSurfaceActor,
- meta_surface_actor,
- META, SURFACE_ACTOR,
- ClutterActor)
-
-struct _MetaSurfaceActorClass
-{
- /*< private >*/
- ClutterActorClass parent_class;
-
- void (* process_damage) (MetaSurfaceActor *actor,
- int x, int y, int width, int height);
- gboolean (* is_opaque) (MetaSurfaceActor *actor);
-};
-
-cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
- cairo_rectangle_int_t *clip);
-
-MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
-
-void meta_surface_actor_update_area (MetaSurfaceActor *self,
- int x,
- int y,
- int width,
- int height);
-
-gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
-gboolean meta_surface_actor_is_obscured_on_stage_view (MetaSurfaceActor *self,
- ClutterStageView *stage_view,
- float *unobscurred_fraction);
-
-void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
- cairo_region_t *region);
-void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
- cairo_region_t *region);
-cairo_region_t * meta_surface_actor_get_opaque_region (MetaSurfaceActor *self);
-
-void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
- int x, int y, int width, int height);
-
-gboolean meta_surface_actor_is_opaque (MetaSurfaceActor *actor);
-
-gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor);
-void meta_surface_actor_set_frozen (MetaSurfaceActor *actor,
- gboolean frozen);
-
-void meta_surface_actor_set_transform (MetaSurfaceActor *self,
- MetaMonitorTransform transform);
-void meta_surface_actor_set_viewport_src_rect (MetaSurfaceActor *self,
- graphene_rect_t *src_rect);
-void meta_surface_actor_reset_viewport_src_rect (MetaSurfaceActor *self);
-void meta_surface_actor_set_viewport_dst_size (MetaSurfaceActor *self,
- int dst_width,
- int dst_height);
-void meta_surface_actor_reset_viewport_dst_size (MetaSurfaceActor *self);
-G_END_DECLS
-
-#endif /* META_SURFACE_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
deleted file mode 100644
index 917bf1235..000000000
--- a/src/compositor/meta-sync-ring.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * This is based on an original C++ implementation for compiz that
- * carries the following copyright notice:
- *
- *
- * Copyright © 2011 NVIDIA Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of NVIDIA
- * Corporation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. NVIDIA Corporation makes no representations about the
- * suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- * Authors: James Jones <jajones@nvidia.com>
- */
-
-#include "config.h"
-
-#include "compositor/meta-sync-ring.h"
-
-#include <string.h>
-#include <GL/gl.h>
-#include <GL/glx.h>
-#include <X11/extensions/sync.h>
-
-#include "clutter/clutter.h"
-#include "cogl/cogl.h"
-#include "meta/util.h"
-
-/* Theory of operation:
- *
- * We use a ring of NUM_SYNCS fence objects. On each frame we advance
- * to the next fence in the ring. For each fence we do:
- *
- * 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
- * 2. NUM_SYNCS / 2 frames later, fence should be triggered
- * 3. fence is XSyncResetFence()'d
- * 4. NUM_SYNCS / 2 frames later, fence should be reset
- * 5. go back to 1 and re-use fence
- *
- * glClientWaitSync() and XAlarms are used in steps 2 and 4,
- * respectively, to double-check the expectections.
- */
-
-#define NUM_SYNCS 10
-#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
-#define MAX_REBOOT_ATTEMPTS 2
-
-typedef enum
-{
- META_SYNC_STATE_READY,
- META_SYNC_STATE_WAITING,
- META_SYNC_STATE_DONE,
- META_SYNC_STATE_RESET_PENDING,
-} MetaSyncState;
-
-typedef struct
-{
- Display *xdisplay;
-
- XSyncFence xfence;
- GLsync gl_x11_sync;
- GLsync gpu_fence;
-
- XSyncCounter xcounter;
- XSyncAlarm xalarm;
- XSyncValue next_counter_value;
-
- MetaSyncState state;
-} MetaSync;
-
-typedef struct
-{
- Display *xdisplay;
- int xsync_event_base;
- int xsync_error_base;
-
- GHashTable *alarm_to_sync;
-
- MetaSync *syncs_array[NUM_SYNCS];
- guint current_sync_idx;
- MetaSync *current_sync;
- guint warmup_syncs;
-
- guint reboots;
-} MetaSyncRing;
-
-static MetaSyncRing meta_sync_ring = { 0 };
-
-static XSyncValue SYNC_VALUE_ZERO;
-static XSyncValue SYNC_VALUE_ONE;
-
-static const char* (*meta_gl_get_string) (GLenum name);
-static void (*meta_gl_get_integerv) (GLenum pname,
- GLint *params);
-static const char* (*meta_gl_get_stringi) (GLenum name,
- GLuint index);
-static void (*meta_gl_delete_sync) (GLsync sync);
-static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
- GLbitfield flags,
- GLuint64 timeout);
-static void (*meta_gl_wait_sync) (GLsync sync,
- GLbitfield flags,
- GLuint64 timeout);
-static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
- GLintptr external_sync,
- GLbitfield flags);
-static GLsync (*meta_gl_fence_sync) (GLenum condition,
- GLbitfield flags);
-
-static MetaSyncRing *
-meta_sync_ring_get (void)
-{
- if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
- return NULL;
-
- return &meta_sync_ring;
-}
-
-static gboolean
-load_gl_symbol (const char *name,
- void **func)
-{
- *func = cogl_get_proc_address (name);
- if (!*func)
- {
- meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"", name);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean
-check_gl_extensions (void)
-{
- ClutterBackend *backend;
- CoglContext *cogl_context;
- CoglDisplay *cogl_display;
- CoglRenderer *cogl_renderer;
-
- backend = clutter_get_default_backend ();
- cogl_context = clutter_backend_get_cogl_context (backend);
- cogl_display = cogl_context_get_display (cogl_context);
- cogl_renderer = cogl_display_get_renderer (cogl_display);
-
- switch (cogl_renderer_get_driver (cogl_renderer))
- {
- case COGL_DRIVER_GL3:
- {
- int num_extensions, i;
- gboolean arb_sync = FALSE;
- gboolean x11_sync_object = FALSE;
-
- meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
-
- for (i = 0; i < num_extensions; ++i)
- {
- const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
-
- if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
- arb_sync = TRUE;
- else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
- x11_sync_object = TRUE;
- }
-
- return arb_sync && x11_sync_object;
- }
- case COGL_DRIVER_GL:
- {
- const char *extensions = meta_gl_get_string (GL_EXTENSIONS);
- return (extensions != NULL &&
- strstr (extensions, "GL_ARB_sync") != NULL &&
- strstr (extensions, "GL_EXT_x11_sync_object") != NULL);
- }
- default:
- break;
- }
-
- return FALSE;
-}
-
-static gboolean
-load_required_symbols (void)
-{
- static gboolean success = FALSE;
-
- if (success)
- return TRUE;
-
- /* We don't link against libGL directly because cogl may want to
- * use something else. This assumes that cogl has been initialized
- * and dynamically loaded libGL at this point.
- */
-
- if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string))
- goto out;
- if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
- goto out;
- if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
- goto out;
-
- if (!check_gl_extensions ())
- {
- meta_verbose ("MetaSyncRing: couldn't find required GL extensions");
- goto out;
- }
-
- if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
- goto out;
- if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
- goto out;
- if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
- goto out;
- if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
- goto out;
- if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync))
- goto out;
-
- success = TRUE;
- out:
- return success;
-}
-
-static void
-meta_sync_insert (MetaSync *self)
-{
- g_return_if_fail (self->state == META_SYNC_STATE_READY);
-
- XSyncTriggerFence (self->xdisplay, self->xfence);
- XFlush (self->xdisplay);
-
- meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED);
- self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-
- self->state = META_SYNC_STATE_WAITING;
-}
-
-static GLenum
-meta_sync_check_update_finished (MetaSync *self,
- GLuint64 timeout)
-{
- GLenum status = GL_WAIT_FAILED;
-
- switch (self->state)
- {
- case META_SYNC_STATE_DONE:
- status = GL_ALREADY_SIGNALED;
- break;
- case META_SYNC_STATE_WAITING:
- status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout);
- if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
- {
- self->state = META_SYNC_STATE_DONE;
- meta_gl_delete_sync (self->gpu_fence);
- self->gpu_fence = 0;
- }
- break;
- default:
- break;
- }
-
- g_warn_if_fail (status != GL_WAIT_FAILED);
-
- return status;
-}
-
-static void
-meta_sync_reset (MetaSync *self)
-{
- XSyncAlarmAttributes attrs;
- int overflow;
-
- g_return_if_fail (self->state == META_SYNC_STATE_DONE);
-
- XSyncResetFence (self->xdisplay, self->xfence);
-
- attrs.trigger.wait_value = self->next_counter_value;
-
- XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
- XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
-
- XSyncValueAdd (&self->next_counter_value,
- self->next_counter_value,
- SYNC_VALUE_ONE,
- &overflow);
-
- self->state = META_SYNC_STATE_RESET_PENDING;
-}
-
-static void
-meta_sync_handle_event (MetaSync *self,
- XSyncAlarmNotifyEvent *event)
-{
- g_return_if_fail (event->alarm == self->xalarm);
- g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
-
- self->state = META_SYNC_STATE_READY;
-}
-
-static MetaSync *
-meta_sync_new (Display *xdisplay)
-{
- MetaSync *self;
- XSyncAlarmAttributes attrs;
-
- self = g_malloc0 (sizeof (MetaSync));
-
- self->xdisplay = xdisplay;
-
- self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
- self->gl_x11_sync = 0;
- self->gpu_fence = 0;
-
- self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
-
- attrs.trigger.counter = self->xcounter;
- attrs.trigger.value_type = XSyncAbsolute;
- attrs.trigger.wait_value = SYNC_VALUE_ONE;
- attrs.trigger.test_type = XSyncPositiveTransition;
- attrs.events = TRUE;
- self->xalarm = XSyncCreateAlarm (xdisplay,
- XSyncCACounter |
- XSyncCAValueType |
- XSyncCAValue |
- XSyncCATestType |
- XSyncCAEvents,
- &attrs);
-
- XSyncIntToValue (&self->next_counter_value, 1);
-
- self->state = META_SYNC_STATE_READY;
-
- return self;
-}
-
-static void
-meta_sync_import (MetaSync *self)
-{
- g_return_if_fail (self->gl_x11_sync == 0);
- self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
-}
-
-static Bool
-alarm_event_predicate (Display *dpy,
- XEvent *event,
- XPointer data)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return False;
-
- if (event->type == ring->xsync_event_base + XSyncAlarmNotify)
- {
- if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
- return True;
- }
- return False;
-}
-
-static void
-meta_sync_free (MetaSync *self)
-{
- /* When our assumptions don't hold, something has gone wrong but we
- * don't know what, so we reboot the ring. While doing that, we
- * trigger fences before deleting them to try to get ourselves out
- * of a potentially stuck GPU state.
- */
- switch (self->state)
- {
- case META_SYNC_STATE_WAITING:
- meta_gl_delete_sync (self->gpu_fence);
- break;
- case META_SYNC_STATE_DONE:
- /* nothing to do */
- break;
- case META_SYNC_STATE_RESET_PENDING:
- {
- XEvent event;
- XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
- meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
- }
- G_GNUC_FALLTHROUGH;
- case META_SYNC_STATE_READY:
- XSyncTriggerFence (self->xdisplay, self->xfence);
- XFlush (self->xdisplay);
- break;
- default:
- break;
- }
-
- meta_gl_delete_sync (self->gl_x11_sync);
- XSyncDestroyFence (self->xdisplay, self->xfence);
- XSyncDestroyCounter (self->xdisplay, self->xcounter);
- XSyncDestroyAlarm (self->xdisplay, self->xalarm);
-
- g_free (self);
-}
-
-gboolean
-meta_sync_ring_init (Display *xdisplay)
-{
- gint major, minor;
- guint i;
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- g_return_val_if_fail (xdisplay != NULL, FALSE);
- g_return_val_if_fail (ring->xdisplay == NULL, FALSE);
-
- if (!load_required_symbols ())
- return FALSE;
-
- if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, &ring->xsync_error_base) ||
- !XSyncInitialize (xdisplay, &major, &minor))
- return FALSE;
-
- XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
- XSyncIntToValue (&SYNC_VALUE_ONE, 1);
-
- ring->xdisplay = xdisplay;
-
- ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
-
- for (i = 0; i < NUM_SYNCS; ++i)
- {
- MetaSync *sync = meta_sync_new (ring->xdisplay);
- ring->syncs_array[i] = sync;
- g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
- }
- /* Since the connection we create the X fences on isn't the same as
- * the one used for the GLX context, we need to XSync() here to
- * ensure glImportSync() succeeds. */
- XSync (xdisplay, False);
- for (i = 0; i < NUM_SYNCS; ++i)
- meta_sync_import (ring->syncs_array[i]);
-
- ring->current_sync_idx = 0;
- ring->current_sync = ring->syncs_array[0];
- ring->warmup_syncs = 0;
-
- return TRUE;
-}
-
-void
-meta_sync_ring_destroy (void)
-{
- guint i;
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return;
-
- g_return_if_fail (ring->xdisplay != NULL);
-
- ring->current_sync_idx = 0;
- ring->current_sync = NULL;
- ring->warmup_syncs = 0;
-
- for (i = 0; i < NUM_SYNCS; ++i)
- meta_sync_free (ring->syncs_array[i]);
-
- g_hash_table_destroy (ring->alarm_to_sync);
-
- ring->xsync_event_base = 0;
- ring->xsync_error_base = 0;
- ring->xdisplay = NULL;
-}
-
-static gboolean
-meta_sync_ring_reboot (Display *xdisplay)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- meta_sync_ring_destroy ();
-
- ring->reboots += 1;
-
- if (!meta_sync_ring_get ())
- {
- meta_warning ("MetaSyncRing: Too many reboots -- disabling");
- return FALSE;
- }
-
- return meta_sync_ring_init (xdisplay);
-}
-
-gboolean
-meta_sync_ring_after_frame (void)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
-
- if (ring->warmup_syncs >= NUM_SYNCS / 2)
- {
- guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
- MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
-
- GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
- if (status == GL_TIMEOUT_EXPIRED)
- {
- meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?");
- status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
- }
-
- if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
- {
- meta_warning ("MetaSyncRing: Timed out waiting for sync object.");
- return meta_sync_ring_reboot (ring->xdisplay);
- }
-
- meta_sync_reset (sync_to_reset);
- }
- else
- {
- ring->warmup_syncs += 1;
- }
-
- ring->current_sync_idx += 1;
- ring->current_sync_idx %= NUM_SYNCS;
-
- ring->current_sync = ring->syncs_array[ring->current_sync_idx];
-
- return TRUE;
-}
-
-gboolean
-meta_sync_ring_insert_wait (void)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
-
- if (ring->current_sync->state != META_SYNC_STATE_READY)
- {
- meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?");
- if (!meta_sync_ring_reboot (ring->xdisplay))
- return FALSE;
- }
-
- meta_sync_insert (ring->current_sync);
-
- return TRUE;
-}
-
-void
-meta_sync_ring_handle_event (XEvent *xevent)
-{
- XSyncAlarmNotifyEvent *event;
- MetaSync *sync;
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return;
-
- g_return_if_fail (ring->xdisplay != NULL);
-
- if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify))
- return;
-
- event = (XSyncAlarmNotifyEvent *) xevent;
-
- sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
- if (sync)
- meta_sync_handle_event (sync, event);
-}
diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h
deleted file mode 100644
index d9739455b..000000000
--- a/src/compositor/meta-sync-ring.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _META_SYNC_RING_H_
-#define _META_SYNC_RING_H_
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-gboolean meta_sync_ring_init (Display *dpy);
-void meta_sync_ring_destroy (void);
-gboolean meta_sync_ring_after_frame (void);
-gboolean meta_sync_ring_insert_wait (void);
-void meta_sync_ring_handle_event (XEvent *event);
-
-#endif /* _META_SYNC_RING_H_ */
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
deleted file mode 100644
index 1fc4623e5..000000000
--- a/src/compositor/meta-texture-tower.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * MetaTextureTower
- *
- * Mipmap emulation by creation of scaled down images
- *
- * Copyright (C) 2009 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <string.h>
-
-#include "compositor/meta-texture-tower.h"
-
-#ifndef M_LOG2E
-#define M_LOG2E 1.4426950408889634074
-#endif
-
-#define MAX_TEXTURE_LEVELS 12
-
-/* If the texture format in memory doesn't match this, then Mesa
- * will do the conversion, so things will still work, but it might
- * be slow depending on how efficient Mesa is. These should be the
- * native formats unless the display is 16bpp. If conversions
- * here are a bottleneck, investigate whether we are converting when
- * storing window data *into* the texture before adding extra code
- * to handle multiple texture formats.
- */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_BGRA_8888_PRE
-#else
-#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_ARGB_8888_PRE
-#endif
-
-typedef struct
-{
- guint16 x1;
- guint16 y1;
- guint16 x2;
- guint16 y2;
-} Box;
-
-struct _MetaTextureTower
-{
- int n_levels;
- CoglTexture *textures[MAX_TEXTURE_LEVELS];
- CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
- Box invalid[MAX_TEXTURE_LEVELS];
- CoglPipeline *pipeline_template;
-};
-
-/**
- * meta_texture_tower_new:
- *
- * Creates a new texture tower. The base texture has to be set with
- * meta_texture_tower_set_base_texture() before use.
- *
- * Return value: the new texture tower. Free with meta_texture_tower_free()
- */
-MetaTextureTower *
-meta_texture_tower_new (void)
-{
- MetaTextureTower *tower;
-
- tower = g_new0 (MetaTextureTower, 1);
-
- return tower;
-}
-
-/**
- * meta_texture_tower_free:
- * @tower: a #MetaTextureTower
- *
- * Frees a texture tower created with meta_texture_tower_new().
- */
-void
-meta_texture_tower_free (MetaTextureTower *tower)
-{
- g_return_if_fail (tower != NULL);
-
- if (tower->pipeline_template != NULL)
- cogl_object_unref (tower->pipeline_template);
-
- meta_texture_tower_set_base_texture (tower, NULL);
-
- g_free (tower);
-}
-
-/**
- * meta_texture_tower_set_base_texture:
- * @tower: a #MetaTextureTower
- * @texture: the new texture used as a base for scaled down versions
- *
- * Sets the base texture that is the scaled texture that the
- * scaled textures of the tower are derived from. The texture itself
- * will be used as level 0 of the tower and will be referenced until
- * unset or until the tower is freed.
- */
-void
-meta_texture_tower_set_base_texture (MetaTextureTower *tower,
- CoglTexture *texture)
-{
- int i;
-
- g_return_if_fail (tower != NULL);
-
- if (texture == tower->textures[0])
- return;
-
- if (tower->textures[0] != NULL)
- {
- for (i = 1; i < tower->n_levels; i++)
- {
- cogl_clear_object (&tower->textures[i]);
- g_clear_object (&tower->fbos[i]);
- }
-
- cogl_object_unref (tower->textures[0]);
- }
-
- tower->textures[0] = texture;
-
- if (tower->textures[0] != NULL)
- {
- int width, height;
-
- cogl_object_ref (tower->textures[0]);
-
- width = cogl_texture_get_width (tower->textures[0]);
- height = cogl_texture_get_height (tower->textures[0]);
-
- tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
- tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
-
- meta_texture_tower_update_area (tower, 0, 0, width, height);
- }
- else
- {
- tower->n_levels = 0;
- }
-}
-
-/**
- * meta_texture_tower_update_area:
- * @tower: a #MetaTextureTower
- * @x: X coordinate of upper left of rectangle that changed
- * @y: Y coordinate of upper left of rectangle that changed
- * @width: width of rectangle that changed
- * @height: height rectangle that changed
- *
- * Mark a region of the base texture as having changed; the next
- * time a scaled down version of the base texture is retrieved,
- * the appropriate area of the scaled down texture will be updated.
- */
-void
-meta_texture_tower_update_area (MetaTextureTower *tower,
- int x,
- int y,
- int width,
- int height)
-{
- int texture_width, texture_height;
- Box invalid;
- int i;
-
- g_return_if_fail (tower != NULL);
-
- if (tower->textures[0] == NULL)
- return;
-
- texture_width = cogl_texture_get_width (tower->textures[0]);
- texture_height = cogl_texture_get_height (tower->textures[0]);
-
- invalid.x1 = x;
- invalid.y1 = y;
- invalid.x2 = x + width;
- invalid.y2 = y + height;
-
- for (i = 1; i < tower->n_levels; i++)
- {
- texture_width = MAX (1, texture_width / 2);
- texture_height = MAX (1, texture_height / 2);
-
- invalid.x1 = invalid.x1 / 2;
- invalid.y1 = invalid.y1 / 2;
- invalid.x2 = MIN (texture_width, (invalid.x2 + 1) / 2);
- invalid.y2 = MIN (texture_height, (invalid.y2 + 1) / 2);
-
- if (tower->invalid[i].x1 == tower->invalid[i].x2 ||
- tower->invalid[i].y1 == tower->invalid[i].y2)
- {
- tower->invalid[i] = invalid;
- }
- else
- {
- tower->invalid[i].x1 = MIN (tower->invalid[i].x1, invalid.x1);
- tower->invalid[i].y1 = MIN (tower->invalid[i].y1, invalid.y1);
- tower->invalid[i].x2 = MAX (tower->invalid[i].x2, invalid.x2);
- tower->invalid[i].y2 = MAX (tower->invalid[i].y2, invalid.y2);
- }
- }
-}
-
-/* It generally looks worse if we scale up a window texture by even a
- * small amount than if we scale it down using bilinear filtering, so
- * we always pick the *larger* adjacent level. */
-#define LOD_BIAS (-0.49)
-
-/* This determines the appropriate level of detail to use when drawing the
- * texture, in a way that corresponds to what the GL specification does
- * when mip-mapping. This is probably fancier and slower than what we need,
- * but we do the computation only once each time we paint a window, and
- * its easier to just use the equations from the specification than to
- * come up with something simpler.
- *
- * If window is being painted at an angle from the viewer, then we have to
- * pick a point in the texture; we use the middle of the texture (which is
- * why the width/height are passed in.) This is not the normal case for
- * Meta.
- */
-static int
-get_paint_level (ClutterPaintContext *paint_context,
- int width,
- int height)
-{
- CoglFramebuffer *framebuffer;
- graphene_matrix_t projection, modelview, pm;
- float xx, xy, xw;
- float yx, yy, yw;
- float wx, wy, ww;
- float v[4];
- double viewport_width, viewport_height;
- double u0, v0;
- double xc, yc, wc;
- double dxdu_, dxdv_, dydu_, dydv_;
- double det_, det_sq;
- double rho_sq;
- double lambda;
-
- /* See
- * http://www.opengl.org/registry/doc/glspec32.core.20090803.pdf
- * Section 3.8.9, p. 1.6.2. Here we have
- *
- * u(x,y) = x_o;
- * v(x,y) = y_o;
- *
- * Since we are mapping 1:1 from object coordinates into pixel
- * texture coordinates, the clip coordinates are:
- *
- * (x_c) (x_o) (u)
- * (y_c) = (M_projection)(M_modelview) (y_o) = (PM) (v)
- * (z_c) (z_o) (0)
- * (w_c) (w_o) (1)
- */
-
- framebuffer = clutter_paint_context_get_framebuffer (paint_context);
- cogl_framebuffer_get_projection_matrix (framebuffer, &projection);
- cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview);
-
- graphene_matrix_multiply (&modelview, &projection, &pm);
-
- xx = graphene_matrix_get_value (&pm, 0, 0);
- xy = graphene_matrix_get_value (&pm, 0, 1);
- xw = graphene_matrix_get_value (&pm, 0, 3);
- yx = graphene_matrix_get_value (&pm, 1, 0);
- yy = graphene_matrix_get_value (&pm, 1, 1);
- yw = graphene_matrix_get_value (&pm, 1, 3);
- wx = graphene_matrix_get_value (&pm, 3, 0);
- wy = graphene_matrix_get_value (&pm, 3, 1);
- ww = graphene_matrix_get_value (&pm, 3, 3);
-
- cogl_framebuffer_get_viewport4fv (framebuffer, v);
- viewport_width = v[2];
- viewport_height = v[3];
-
- u0 = width / 2.;
- v0 = height / 2.;
-
- xc = xx * u0 + yx * v0 + wx;
- yc = xy * u0 + yy * v0 + wy;
- wc = xw * u0 + yw * v0 + ww;
-
- /* We'll simplify the equations below for a bit of micro-optimization.
- * The commented out code is the unsimplified version.
-
- // Partial derivates of window coordinates:
- //
- // x_w = 0.5 * viewport_width * x_c / w_c + viewport_center_x
- // y_w = 0.5 * viewport_height * y_c / w_c + viewport_center_y
- //
- // with respect to u, v, using
- // d(a/b)/dx = da/dx * (1/b) - a * db/dx / (b^2)
-
- dxdu = 0.5 * viewport_width * (xx - xw * (xc/wc)) / wc;
- dxdv = 0.5 * viewport_width * (yx - yw * (xc/wc)) / wc;
- dydu = 0.5 * viewport_height * (xy - xw * (yc/wc)) / wc;
- dydv = 0.5 * viewport_height * (yy - yw * (yc/wc)) / wc;
-
- // Compute the inverse partials as the matrix inverse
- det = dxdu * dydv - dxdv * dydu;
-
- dudx = dydv / det;
- dudy = - dxdv / det;
- dvdx = - dydu / det;
- dvdy = dvdu / det;
-
- // Scale factor; maximum of the distance in texels for a change of 1 pixel
- // in the X direction or 1 pixel in the Y direction
- rho = MAX (sqrt (dudx * dudx + dvdx * dvdx), sqrt(dudy * dudy + dvdy * dvdy));
-
- // Level of detail
- lambda = log2 (rho) + LOD_BIAS;
- */
-
- /* dxdu * wc, etc */
- dxdu_ = 0.5 * viewport_width * (xx - xw * (xc/wc));
- dxdv_ = 0.5 * viewport_width * (yx - yw * (xc/wc));
- dydu_ = 0.5 * viewport_height * (xy - xw * (yc/wc));
- dydv_ = 0.5 * viewport_height * (yy - yw * (yc/wc));
-
- /* det * wc^2 */
- det_ = dxdu_ * dydv_ - dxdv_ * dydu_;
- det_sq = det_ * det_;
- if (det_sq == 0.0)
- return -1;
-
- /* (rho * det * wc)^2 */
- rho_sq = MAX (dydv_ * dydv_ + dydu_ * dydu_, dxdv_ * dxdv_ + dxdu_ * dxdu_);
- lambda = 0.5 * M_LOG2E * log (rho_sq * wc * wc / det_sq) + LOD_BIAS;
-
-#if 0
- g_print ("%g %g %g\n", 0.5 * viewport_width * xx / ww, 0.5 * viewport_height * yy / ww, lambda);
-#endif
-
- if (lambda <= 0.)
- return 0;
- else
- return (int)(0.5 + lambda);
-}
-
-static void
-texture_tower_create_texture (MetaTextureTower *tower,
- int level,
- int width,
- int height)
-{
- tower->textures[level] = cogl_texture_new_with_size (width, height,
- COGL_TEXTURE_NO_AUTO_MIPMAP,
- TEXTURE_FORMAT);
-
- tower->invalid[level].x1 = 0;
- tower->invalid[level].y1 = 0;
- tower->invalid[level].x2 = width;
- tower->invalid[level].y2 = height;
-}
-
-static void
-texture_tower_revalidate (MetaTextureTower *tower,
- int level)
-{
- CoglTexture *source_texture = tower->textures[level - 1];
- int source_texture_width = cogl_texture_get_width (source_texture);
- int source_texture_height = cogl_texture_get_height (source_texture);
- CoglTexture *dest_texture = tower->textures[level];
- int dest_texture_width = cogl_texture_get_width (dest_texture);
- int dest_texture_height = cogl_texture_get_height (dest_texture);
- Box *invalid = &tower->invalid[level];
- CoglFramebuffer *fb;
- GError *catch_error = NULL;
- CoglPipeline *pipeline;
-
- if (tower->fbos[level] == NULL)
- tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);
-
- fb = COGL_FRAMEBUFFER (tower->fbos[level]);
-
- if (!cogl_framebuffer_allocate (fb, &catch_error))
- {
- g_error_free (catch_error);
- return;
- }
-
- cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.);
-
- if (!tower->pipeline_template)
- {
- CoglContext *ctx =
- clutter_backend_get_cogl_context (clutter_get_default_backend ());
- tower->pipeline_template = cogl_pipeline_new (ctx);
- cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
- }
-
- pipeline = cogl_pipeline_copy (tower->pipeline_template);
- cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);
-
- cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
- invalid->x1, invalid->y1,
- invalid->x2, invalid->y2,
- (2. * invalid->x1) / source_texture_width,
- (2. * invalid->y1) / source_texture_height,
- (2. * invalid->x2) / source_texture_width,
- (2. * invalid->y2) / source_texture_height);
-
- cogl_object_unref (pipeline);
-
- tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
- tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
-}
-
-/**
- * meta_texture_tower_get_paint_texture:
- * @tower: a #MetaTextureTower
- * @paint_context: a #ClutterPaintContext
- *
- * Gets the texture from the tower that best matches the current
- * rendering scale. (On the assumption here the texture is going to
- * be rendered with vertex coordinates that correspond to its
- * size in pixels, so a 200x200 texture will be rendered on the
- * rectangle (0, 0, 200, 200).
- *
- * Return value: the COGL texture handle to use for painting, or
- * %NULL if no base texture has yet been set.
- */
-CoglTexture *
-meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
- ClutterPaintContext *paint_context)
-{
- int texture_width, texture_height;
- int level;
-
- g_return_val_if_fail (tower != NULL, NULL);
-
- if (tower->textures[0] == NULL)
- return NULL;
-
- texture_width = cogl_texture_get_width (tower->textures[0]);
- texture_height = cogl_texture_get_height (tower->textures[0]);
-
- level = get_paint_level (paint_context, texture_width, texture_height);
- if (level < 0) /* singular paint matrix, scaled to nothing */
- return NULL;
- level = MIN (level, tower->n_levels - 1);
-
- if (tower->textures[level] == NULL ||
- (tower->invalid[level].x2 != tower->invalid[level].x1 &&
- tower->invalid[level].y2 != tower->invalid[level].y1))
- {
- int i;
-
- for (i = 1; i <= level; i++)
- {
- /* Use "floor" convention here to be consistent with the NPOT texture extension */
- texture_width = MAX (1, texture_width / 2);
- texture_height = MAX (1, texture_height / 2);
-
- if (tower->textures[i] == NULL)
- texture_tower_create_texture (tower, i, texture_width, texture_height);
- }
-
- for (i = 1; i <= level; i++)
- {
- if (tower->invalid[level].x2 != tower->invalid[level].x1 &&
- tower->invalid[level].y2 != tower->invalid[level].y1)
- texture_tower_revalidate (tower, i);
- }
- }
-
- return tower->textures[level];
-}
diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h
deleted file mode 100644
index 1f5b37146..000000000
--- a/src/compositor/meta-texture-tower.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * MetaTextureTower
- *
- * Mipmap emulation by creation of scaled down images
- *
- * Copyright (C) 2009 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_TEXTURE_TOWER_H__
-#define __META_TEXTURE_TOWER_H__
-
-#include "clutter/clutter.h"
-
-G_BEGIN_DECLS
-
-/**
- * SECTION:MetaTextureTower
- * @short_description: mipmap emulation by creation of scaled down images
- *
- * A #MetaTextureTower is used to get good looking scaled down images when
- * we can't use the GL drivers mipmap support. There are two separate reasons
- *
- * - Some cards (including radeon cards <= r5xx) only support
- * TEXTURE_RECTANGLE_ARB and not NPOT textures. Rectangular textures
- * are defined not to support mipmapping.
- * - Even when NPOT textures are available, the combination of NPOT
- * textures, texture_from_pixmap, and mipmapping doesn't typically
- * work, since the X server doesn't allocate pixmaps in the right
- * layout for mipmapping.
- *
- * So, what we do is create the "mipmap" levels ourselves by successive
- * power-of-two scaledowns, and when rendering pick the single texture
- * that best matches the scale we are rendering at. (Since we aren't
- * typically using perspective transforms, we'll frequently have a single
- * scale for the entire texture.)
- */
-
-typedef struct _MetaTextureTower MetaTextureTower;
-
-MetaTextureTower *meta_texture_tower_new (void);
-void meta_texture_tower_free (MetaTextureTower *tower);
-void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
- CoglTexture *texture);
-void meta_texture_tower_update_area (MetaTextureTower *tower,
- int x,
- int y,
- int width,
- int height);
-CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
- ClutterPaintContext *paint_context);
-
-G_END_DECLS
-
-#endif /* __META_TEXTURE_TOWER_H__ */
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
deleted file mode 100644
index 64741e416..000000000
--- a/src/compositor/meta-window-actor-private.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_WINDOW_ACTOR_PRIVATE_H
-#define META_WINDOW_ACTOR_PRIVATE_H
-
-#include <X11/extensions/Xdamage.h>
-
-#include "compositor/meta-plugin-manager.h"
-#include "compositor/meta-surface-actor.h"
-#include "meta/compositor-mutter.h"
-
-struct _MetaWindowActorClass
-{
- ClutterActorClass parent;
-
- void (*frame_complete) (MetaWindowActor *actor,
- ClutterFrameInfo *frame_info,
- int64_t presentation_time);
-
- void (*assign_surface_actor) (MetaWindowActor *actor,
- MetaSurfaceActor *surface_actor);
-
- void (*queue_frame_drawn) (MetaWindowActor *actor,
- gboolean skip_sync_delay);
-
- void (*before_paint) (MetaWindowActor *actor,
- ClutterStageView *stage_view);
- void (*after_paint) (MetaWindowActor *actor,
- ClutterStageView *stage_view);
-
- void (*queue_destroy) (MetaWindowActor *actor);
- void (*set_frozen) (MetaWindowActor *actor,
- gboolean frozen);
- void (*update_regions) (MetaWindowActor *actor);
- gboolean (*can_freeze_commits) (MetaWindowActor *actor);
-};
-
-typedef enum
-{
- META_WINDOW_ACTOR_CHANGE_SIZE = 1 << 0,
- META_WINDOW_ACTOR_CHANGE_POSITION = 1 << 1
-} MetaWindowActorChanges;
-
-void meta_window_actor_queue_destroy (MetaWindowActor *self);
-
-void meta_window_actor_show (MetaWindowActor *self,
- MetaCompEffect effect);
-void meta_window_actor_hide (MetaWindowActor *self,
- MetaCompEffect effect);
-
-void meta_window_actor_size_change (MetaWindowActor *self,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect);
-
-void meta_window_actor_before_paint (MetaWindowActor *self,
- ClutterStageView *stage_view);
-void meta_window_actor_after_paint (MetaWindowActor *self,
- ClutterStageView *stage_view);
-void meta_window_actor_frame_complete (MetaWindowActor *self,
- ClutterFrameInfo *frame_info,
- gint64 presentation_time);
-
-gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
-
-MetaWindowActorChanges meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
- gboolean did_placement);
-
-void meta_window_actor_update_opacity (MetaWindowActor *self);
-void meta_window_actor_mapped (MetaWindowActor *self);
-void meta_window_actor_unmapped (MetaWindowActor *self);
-void meta_window_actor_sync_updates_frozen (MetaWindowActor *self);
-void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
- gboolean no_delay_frame);
-
-void meta_window_actor_effect_completed (MetaWindowActor *actor,
- MetaPluginEffect event);
-
-MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
-
-void meta_window_actor_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_actor);
-
-MetaWindowActor *meta_window_actor_from_window (MetaWindow *window);
-MetaWindowActor *meta_window_actor_from_actor (ClutterActor *actor);
-
-void meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
- int geometry_scale);
-
-int meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor);
-
-void meta_window_actor_notify_damaged (MetaWindowActor *window_actor);
-
-gboolean meta_window_actor_is_frozen (MetaWindowActor *self);
-
-gboolean meta_window_actor_is_opaque (MetaWindowActor *self);
-
-void meta_window_actor_update_regions (MetaWindowActor *self);
-
-gboolean meta_window_actor_can_freeze_commits (MetaWindowActor *self);
-
-#endif /* META_WINDOW_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-window-actor-wayland.c b/src/compositor/meta-window-actor-wayland.c
deleted file mode 100644
index b1fe61641..000000000
--- a/src/compositor/meta-window-actor-wayland.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2018 Endless, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Georges Basile Stavracas Neto <gbsneto@gnome.org>
- */
-
-#include "compositor/meta-surface-actor-wayland.h"
-#include "compositor/meta-window-actor-wayland.h"
-#include "meta/meta-window-actor.h"
-#include "wayland/meta-wayland-surface.h"
-
-struct _MetaWindowActorWayland
-{
- MetaWindowActor parent;
-};
-
-G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR)
-
-typedef struct _SurfaceTreeTraverseData
-{
- MetaWindowActor *window_actor;
- int index;
-} SurfaceTreeTraverseData;
-
-static gboolean
-set_surface_actor_index (GNode *node,
- gpointer data)
-{
- MetaWaylandSurface *surface = node->data;
- MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface);
- SurfaceTreeTraverseData *traverse_data = data;
-
- if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor),
- CLUTTER_ACTOR (surface_actor)))
- {
- clutter_actor_set_child_at_index (
- CLUTTER_ACTOR (traverse_data->window_actor),
- CLUTTER_ACTOR (surface_actor),
- traverse_data->index);
- }
- else
- {
- clutter_actor_insert_child_at_index (
- CLUTTER_ACTOR (traverse_data->window_actor),
- CLUTTER_ACTOR (surface_actor),
- traverse_data->index);
- }
- traverse_data->index++;
-
- return FALSE;
-}
-
-void
-meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
-{
- MetaSurfaceActor *surface_actor =
- meta_window_actor_get_surface (actor);
- MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
- META_SURFACE_ACTOR_WAYLAND (surface_actor));
- GNode *root_node = surface->subsurface_branch_node;
- SurfaceTreeTraverseData traverse_data;
-
- traverse_data = (SurfaceTreeTraverseData) {
- .window_actor = actor,
- .index = 0,
- };
- g_node_traverse (root_node,
- G_IN_ORDER,
- G_TRAVERSE_LEAVES,
- -1,
- set_surface_actor_index,
- &traverse_data);
-}
-
-static void
-meta_window_actor_wayland_assign_surface_actor (MetaWindowActor *actor,
- MetaSurfaceActor *surface_actor)
-{
- MetaWindowActorClass *parent_class =
- META_WINDOW_ACTOR_CLASS (meta_window_actor_wayland_parent_class);
-
- g_warn_if_fail (!meta_window_actor_get_surface (actor));
-
- parent_class->assign_surface_actor (actor, surface_actor);
-
- meta_window_actor_wayland_rebuild_surface_tree (actor);
-}
-
-static void
-meta_window_actor_wayland_frame_complete (MetaWindowActor *actor,
- ClutterFrameInfo *frame_info,
- int64_t presentation_time)
-{
-}
-
-static void
-meta_window_actor_wayland_queue_frame_drawn (MetaWindowActor *actor,
- gboolean skip_sync_delay)
-{
-}
-
-static void
-meta_window_actor_wayland_before_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
-}
-
-static void
-meta_window_actor_wayland_after_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
-}
-
-static void
-meta_window_actor_wayland_queue_destroy (MetaWindowActor *actor)
-{
-}
-
-static void
-meta_window_actor_wayland_set_frozen (MetaWindowActor *actor,
- gboolean frozen)
-{
-}
-
-static void
-meta_window_actor_wayland_update_regions (MetaWindowActor *actor)
-{
-}
-
-static gboolean
-meta_window_actor_wayland_can_freeze_commits (MetaWindowActor *actor)
-{
- return FALSE;
-}
-
-static void
-meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
-{
- MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
-
- window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
- window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete;
- window_actor_class->queue_frame_drawn = meta_window_actor_wayland_queue_frame_drawn;
- window_actor_class->before_paint = meta_window_actor_wayland_before_paint;
- window_actor_class->after_paint = meta_window_actor_wayland_after_paint;
- window_actor_class->queue_destroy = meta_window_actor_wayland_queue_destroy;
- window_actor_class->set_frozen = meta_window_actor_wayland_set_frozen;
- window_actor_class->update_regions = meta_window_actor_wayland_update_regions;
- window_actor_class->can_freeze_commits = meta_window_actor_wayland_can_freeze_commits;
-}
-
-static void
-meta_window_actor_wayland_init (MetaWindowActorWayland *self)
-{
-}
diff --git a/src/compositor/meta-window-actor-wayland.h b/src/compositor/meta-window-actor-wayland.h
deleted file mode 100644
index d94de8106..000000000
--- a/src/compositor/meta-window-actor-wayland.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 Endless, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Georges Basile Stavracas Neto <gbsneto@gnome.org>
- */
-
-#ifndef META_WINDOW_ACTOR_WAYLAND_H
-#define META_WINDOW_ACTOR_WAYLAND_H
-
-#include "compositor/meta-window-actor-private.h"
-#include "wayland/meta-wayland-surface.h"
-
-#define META_TYPE_WINDOW_ACTOR_WAYLAND (meta_window_actor_wayland_get_type())
-G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
- meta_window_actor_wayland,
- META, WINDOW_ACTOR_WAYLAND,
- MetaWindowActor)
-
-void meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor);
-
-#endif /*META_WINDOW_ACTOR_WAYLAND_H */
diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
deleted file mode 100644
index e18b1b28b..000000000
--- a/src/compositor/meta-window-actor-x11.c
+++ /dev/null
@@ -1,1693 +0,0 @@
-/*
- * Copyright (C) 2018 Endless, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Georges Basile Stavracas Neto <gbsneto@gnome.org>
- */
-
-#include "config.h"
-
-#include "compositor/meta-window-actor-x11.h"
-
-#include "backends/meta-logical-monitor.h"
-#include "clutter/clutter-frame-clock.h"
-#include "compositor/compositor-private.h"
-#include "compositor/meta-cullable.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "compositor/meta-surface-actor.h"
-#include "compositor/meta-surface-actor-x11.h"
-#include "compositor/region-utils.h"
-#include "core/frame.h"
-#include "core/window-private.h"
-#include "meta/compositor.h"
-#include "meta/meta-enum-types.h"
-#include "meta/meta-shadow-factory.h"
-#include "meta/meta-window-actor.h"
-#include "meta/meta-x11-errors.h"
-#include "meta/window.h"
-#include "x11/window-x11.h"
-#include "x11/meta-x11-display-private.h"
-#include "x11/window-x11.h"
-
-enum
-{
- PROP_SHADOW_MODE = 1,
- PROP_SHADOW_CLASS
-};
-
-struct _MetaWindowActorX11
-{
- MetaWindowActor parent;
-
- /* List of FrameData for recent frames */
- GList *frames;
-
- guint send_frame_messages_timer;
- int64_t frame_drawn_time;
- gboolean pending_schedule_update_now;
- ClutterFrameClock *frame_clock;
-
- gulong repaint_scheduled_id;
- gulong size_changed_id;
-
- /* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN
- * client message for one or more messages in ->frames */
- gboolean needs_frame_drawn;
- gboolean repaint_scheduled;
-
- /*
- * MetaShadowFactory only caches shadows that are actually in use;
- * to avoid unnecessary recomputation we do two things: 1) we store
- * both a focused and unfocused shadow for the window. If the window
- * doesn't have different focused and unfocused shadow parameters,
- * these will be the same. 2) when the shadow potentially changes we
- * don't immediately unreference the old shadow, we just flag it as
- * dirty and recompute it when we next need it (recompute_focused_shadow,
- * recompute_unfocused_shadow.) Because of our extraction of
- * size-invariant window shape, we'll often find that the new shadow
- * is the same as the old shadow.
- */
- MetaShadow *focused_shadow;
- MetaShadow *unfocused_shadow;
-
- /* A region that matches the shape of the window, including frame bounds */
- cairo_region_t *shape_region;
- /* The region we should clip to when painting the shadow */
- cairo_region_t *shadow_clip;
- /* The frame region */
- cairo_region_t *frame_bounds;
-
- /* Extracted size-invariant shape used for shadows */
- MetaWindowShape *shadow_shape;
- char *shadow_class;
-
- MetaShadowFactory *shadow_factory;
- gulong shadow_factory_changed_handler_id;
-
- MetaShadowMode shadow_mode;
-
- gboolean needs_reshape;
- gboolean recompute_focused_shadow;
- gboolean recompute_unfocused_shadow;
- gboolean is_frozen;
-};
-
-static MetaCullableInterface *cullable_parent_iface;
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaWindowActorX11, meta_window_actor_x11, META_TYPE_WINDOW_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init))
-
-/* Each time the application updates the sync request counter to a new even value
- * value, we queue a frame into the windows list of frames. Once we're painting
- * an update "in response" to the window, we fill in frame_counter with the
- * Cogl counter for that frame, and send _NET_WM_FRAME_DRAWN at the end of the
- * frame. _NET_WM_FRAME_TIMINGS is sent when we get a frame_complete callback.
- *
- * As an exception, if a window is completely obscured, we try to throttle drawning
- * to a slower frame rate. In this case, frame_counter stays -1 until
- * send_frame_message_timeout() runs, at which point we send both the
- * _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages.
- */
-typedef struct
-{
- uint64_t sync_request_serial;
- int64_t frame_counter;
- int64_t frame_drawn_time;
-} FrameData;
-
-static void
-frame_data_free (FrameData *frame)
-{
- g_free (frame);
-}
-
-static void
-surface_repaint_scheduled (MetaSurfaceActor *actor,
- gpointer user_data)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (user_data);
-
- actor_x11->repaint_scheduled = TRUE;
-}
-
-static void
-remove_frame_messages_timer (MetaWindowActorX11 *actor_x11)
-{
- g_assert (actor_x11->send_frame_messages_timer != 0);
-
- g_clear_handle_id (&actor_x11->send_frame_messages_timer, g_source_remove);
-}
-
-static void
-do_send_frame_drawn (MetaWindowActorX11 *actor_x11,
- FrameData *frame)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaDisplay *display = meta_window_get_display (window);
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
- int64_t now_us;
-
- XClientMessageEvent ev = { 0, };
-
- now_us = g_get_monotonic_time ();
- frame->frame_drawn_time =
- meta_compositor_monotonic_to_high_res_xserver_time (display->compositor,
- now_us);
- actor_x11->frame_drawn_time = frame->frame_drawn_time;
-
- ev.type = ClientMessage;
- ev.window = meta_window_get_xwindow (window);
- ev.message_type = display->x11_display->atom__NET_WM_FRAME_DRAWN;
- ev.format = 32;
- ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT (0xffffffff);
- ev.data.l[1] = frame->sync_request_serial >> 32;
- ev.data.l[2] = frame->frame_drawn_time & G_GUINT64_CONSTANT (0xffffffff);
- ev.data.l[3] = frame->frame_drawn_time >> 32;
-
- meta_x11_error_trap_push (display->x11_display);
- XSendEvent (xdisplay, ev.window, False, 0, (XEvent *) &ev);
- XFlush (xdisplay);
- meta_x11_error_trap_pop (display->x11_display);
-}
-
-static void
-do_send_frame_timings (MetaWindowActorX11 *actor_x11,
- FrameData *frame,
- int refresh_interval,
- int64_t presentation_time)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaDisplay *display = meta_window_get_display (window);
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- XClientMessageEvent ev = { 0, };
-
- ev.type = ClientMessage;
- ev.window = meta_window_get_xwindow (window);
- ev.message_type = display->x11_display->atom__NET_WM_FRAME_TIMINGS;
- ev.format = 32;
- ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT (0xffffffff);
- ev.data.l[1] = frame->sync_request_serial >> 32;
-
- if (presentation_time != 0)
- {
- MetaCompositor *compositor = display->compositor;
- int64_t presentation_time_server;
-
- presentation_time_server =
- meta_compositor_monotonic_to_high_res_xserver_time (compositor,
- presentation_time);
- int64_t presentation_time_offset = presentation_time_server - frame->frame_drawn_time;
- if (presentation_time_offset == 0)
- presentation_time_offset = 1;
-
- if ((int32_t)presentation_time_offset == presentation_time_offset)
- ev.data.l[2] = presentation_time_offset;
- }
-
- ev.data.l[3] = refresh_interval;
- ev.data.l[4] = 1000 * META_SYNC_DELAY;
-
- meta_x11_error_trap_push (display->x11_display);
- XSendEvent (xdisplay, ev.window, False, 0, (XEvent *) &ev);
- XFlush (xdisplay);
- meta_x11_error_trap_pop (display->x11_display);
-}
-
-static void
-send_frame_timings (MetaWindowActorX11 *actor_x11,
- FrameData *frame,
- ClutterFrameInfo *frame_info,
- int64_t presentation_time)
-{
- float refresh_rate;
- int refresh_interval;
-
- refresh_rate = frame_info->refresh_rate;
- /* 0.0 is a flag for not known, but sanity-check against other odd numbers */
- if (refresh_rate >= 1.0)
- refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
- else
- refresh_interval = 0;
-
- do_send_frame_timings (actor_x11, frame, refresh_interval, presentation_time);
-}
-
-static gboolean
-send_frame_messages_timeout (gpointer data)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (data);
- GList *l;
-
- for (l = actor_x11->frames; l;)
- {
- GList *l_next = l->next;
- FrameData *frame = l->data;
-
- if (frame->frame_counter == -1)
- {
- do_send_frame_drawn (actor_x11, frame);
- do_send_frame_timings (actor_x11, frame, 0, 0);
-
- actor_x11->frames = g_list_delete_link (actor_x11->frames, l);
- frame_data_free (frame);
- }
-
- l = l_next;
- }
-
- actor_x11->needs_frame_drawn = FALSE;
- actor_x11->send_frame_messages_timer = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-queue_send_frame_messages_timeout (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaDisplay *display = meta_window_get_display (window);
- MetaLogicalMonitor *logical_monitor;
- int64_t now_us;
- int64_t current_time;
- float refresh_rate;
- int interval, offset;
-
- if (actor_x11->send_frame_messages_timer != 0)
- return;
-
- logical_monitor = meta_window_get_main_logical_monitor (window);
- if (logical_monitor)
- {
- GList *monitors = meta_logical_monitor_get_monitors (logical_monitor);
- MetaMonitor *monitor;
- MetaMonitorMode *mode;
-
- monitor = g_list_first (monitors)->data;
- mode = meta_monitor_get_current_mode (monitor);
-
- refresh_rate = meta_monitor_mode_get_refresh_rate (mode);
- }
- else
- {
- refresh_rate = 60.0f;
- }
-
- now_us = g_get_monotonic_time ();
- current_time =
- meta_compositor_monotonic_to_high_res_xserver_time (display->compositor,
- now_us);
- interval = (int) (1000000 / refresh_rate) * 6;
- offset = MAX (0, actor_x11->frame_drawn_time + interval - current_time) / 1000;
-
- /* The clutter master clock source has already been added with META_PRIORITY_REDRAW,
- * so the timer will run *after* the clutter frame handling, if a frame is ready
- * to be drawn when the timer expires.
- */
- actor_x11->send_frame_messages_timer =
- g_timeout_add_full (META_PRIORITY_REDRAW, offset,
- send_frame_messages_timeout,
- actor_x11, NULL);
- g_source_set_name_by_id (actor_x11->send_frame_messages_timer,
- "[mutter] send_frame_messages_timeout");
-}
-
-static void
-assign_frame_counter_to_frames (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaCompositor *compositor = window->display->compositor;
- ClutterStage *stage = meta_compositor_get_stage (compositor);
- GList *l;
-
- /* If the window is obscured, then we're expecting to deal with sending
- * frame messages in a timeout, rather than in this paint cycle.
- */
- if (actor_x11->send_frame_messages_timer != 0)
- return;
-
- for (l = actor_x11->frames; l; l = l->next)
- {
- FrameData *frame = l->data;
-
- if (frame->frame_counter == -1)
- frame->frame_counter = clutter_stage_get_frame_counter (stage);
- }
-}
-
-static void
-meta_window_actor_x11_frame_complete (MetaWindowActor *actor,
- ClutterFrameInfo *frame_info,
- int64_t presentation_time)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- GList *l;
-
- if (meta_window_actor_is_destroyed (actor))
- return;
-
- for (l = actor_x11->frames; l;)
- {
- GList *l_next = l->next;
- FrameData *frame = l->data;
- int64_t frame_counter = frame_info->frame_counter;
-
- if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter)
- {
- MetaWindow *window =
- meta_window_actor_get_meta_window (actor);
-
- if (G_UNLIKELY (frame->frame_drawn_time == 0))
- g_warning ("%s: Frame has assigned frame counter but no frame drawn time",
- window->desc);
- if (G_UNLIKELY (frame->frame_counter < frame_counter))
- g_debug ("%s: frame_complete callback never occurred for frame %" G_GINT64_FORMAT,
- window->desc, frame->frame_counter);
-
- actor_x11->frames = g_list_delete_link (actor_x11->frames, l);
- send_frame_timings (actor_x11, frame, frame_info, presentation_time);
- frame_data_free (frame);
- }
-
- l = l_next;
- }
-}
-
-static void
-surface_size_changed (MetaSurfaceActor *actor,
- gpointer user_data)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (user_data);
-
- meta_window_actor_x11_update_shape (actor_x11);
-}
-
-static void
-meta_window_actor_x11_assign_surface_actor (MetaWindowActor *actor,
- MetaSurfaceActor *surface_actor)
-{
- MetaWindowActorClass *parent_class =
- META_WINDOW_ACTOR_CLASS (meta_window_actor_x11_parent_class);
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- MetaSurfaceActor *prev_surface_actor;
-
- prev_surface_actor = meta_window_actor_get_surface (actor);
- if (prev_surface_actor)
- {
- g_warn_if_fail (meta_is_wayland_compositor ());
-
- g_clear_signal_handler (&actor_x11->size_changed_id, prev_surface_actor);
- clutter_actor_remove_child (CLUTTER_ACTOR (actor),
- CLUTTER_ACTOR (prev_surface_actor));
- }
-
- parent_class->assign_surface_actor (actor, surface_actor);
-
- clutter_actor_add_child (CLUTTER_ACTOR (actor),
- CLUTTER_ACTOR (surface_actor));
-
- meta_window_actor_x11_update_shape (actor_x11);
-
- actor_x11->size_changed_id =
- g_signal_connect (surface_actor, "size-changed",
- G_CALLBACK (surface_size_changed),
- actor_x11);
- actor_x11->repaint_scheduled_id =
- g_signal_connect (surface_actor, "repaint-scheduled",
- G_CALLBACK (surface_repaint_scheduled),
- actor_x11);
-}
-
-static void
-meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor,
- gboolean skip_sync_delay)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- MetaWindow *window =
- meta_window_actor_get_meta_window (actor);
- FrameData *frame;
-
- if (meta_window_actor_is_destroyed (actor))
- return;
-
- frame = g_new0 (FrameData, 1);
- frame->frame_counter = -1;
- frame->sync_request_serial = window->sync_request_serial;
-
- actor_x11->frames = g_list_prepend (actor_x11->frames, frame);
-
- actor_x11->needs_frame_drawn = TRUE;
-
- if (skip_sync_delay)
- {
- if (actor_x11->frame_clock)
- clutter_frame_clock_schedule_update_now (actor_x11->frame_clock);
- else
- actor_x11->pending_schedule_update_now = TRUE;
- }
-
- if (!actor_x11->repaint_scheduled)
- {
- MetaSurfaceActor *surface;
- gboolean is_obscured;
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
-
- if (surface)
- is_obscured = meta_surface_actor_is_obscured (surface);
- else
- is_obscured = FALSE;
-
- /* A frame was marked by the client without actually doing any
- * damage or any unobscured, or while we had the window frozen
- * (e.g. during an interactive resize.) We need to make sure that the
- * before_paint/after_paint functions get called, enabling us to
- * send a _NET_WM_FRAME_DRAWN. We need to do full damage to ensure that
- * the window is actually repainted, otherwise any subregion we would pass
- * might end up being either outside of any stage view, or be occluded by
- * something else, which could potentially result in no frame being drawn
- * after all. If the window is completely obscured, or completely off
- * screen we fire off the send_frame_messages timeout.
- */
- if (is_obscured ||
- !clutter_actor_peek_stage_views (CLUTTER_ACTOR (actor)))
- {
- queue_send_frame_messages_timeout (actor_x11);
- }
- else if (surface)
- {
- clutter_actor_queue_redraw (CLUTTER_ACTOR (surface));
- actor_x11->repaint_scheduled = TRUE;
- }
- }
-}
-
-static gboolean
-has_shadow (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
-
- if (actor_x11->shadow_mode == META_SHADOW_MODE_FORCED_OFF)
- return FALSE;
- if (actor_x11->shadow_mode == META_SHADOW_MODE_FORCED_ON)
- return TRUE;
-
- /* Leaving out shadows for maximized and fullscreen windows is an efficiency
- * win and also prevents the unsightly effect of the shadow of maximized
- * window appearing on an adjacent window */
- if ((meta_window_get_maximized (window) == META_MAXIMIZE_BOTH) ||
- meta_window_is_fullscreen (window))
- return FALSE;
-
- /*
- * If we have two snap-tiled windows, we don't want the shadow to obstruct
- * the other window.
- */
- if (meta_window_get_tile_match (window))
- return FALSE;
-
- /*
- * Always put a shadow around windows with a frame - This should override
- * the restriction about not putting a shadow around ARGB windows.
- */
- if (meta_window_get_frame (window))
- return TRUE;
-
- /*
- * Do not add shadows to non-opaque (ARGB32) windows, as we can't easily
- * generate shadows for them.
- */
- if (!meta_window_actor_is_opaque (META_WINDOW_ACTOR (actor_x11)))
- return FALSE;
-
- /*
- * If a window specifies that it has custom frame extents, that likely
- * means that it is drawing a shadow itself. Don't draw our own.
- */
- if (window->has_custom_frame_extents)
- return FALSE;
-
- /*
- * Generate shadows for all other windows.
- */
- return TRUE;
-}
-
-gboolean
-meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaSurfaceActor *surface;
- MetaSurfaceActorX11 *surface_x11;
-
- if (meta_window_actor_is_destroyed (META_WINDOW_ACTOR (actor_x11)))
- return FALSE;
-
- if (!meta_window_x11_can_unredirect (window_x11))
- return FALSE;
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- if (!surface)
- return FALSE;
-
- if (!META_IS_SURFACE_ACTOR_X11 (surface))
- return FALSE;
-
- surface_x11 = META_SURFACE_ACTOR_X11 (surface);
- return meta_surface_actor_x11_should_unredirect (surface_x11);
-}
-
-void
-meta_window_actor_x11_set_unredirected (MetaWindowActorX11 *actor_x11,
- gboolean unredirected)
-{
- MetaSurfaceActor *surface;
- MetaSurfaceActorX11 *surface_x11;
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- g_assert (surface);
-
- g_return_if_fail (META_IS_SURFACE_ACTOR_X11 (surface));
-
- surface_x11 = META_SURFACE_ACTOR_X11 (surface);
- meta_surface_actor_x11_set_unredirected (surface_x11, unredirected);
-}
-
-static const char *
-get_shadow_class (MetaWindowActorX11 *actor_x11)
-{
- if (actor_x11->shadow_class)
- {
- return actor_x11->shadow_class;
- }
- else
- {
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaWindowType window_type;
-
- window_type = meta_window_get_window_type (window);
- switch (window_type)
- {
- case META_WINDOW_DROPDOWN_MENU:
- case META_WINDOW_COMBO:
- return "dropdown-menu";
- case META_WINDOW_POPUP_MENU:
- return "popup-menu";
- default:
- {
- MetaFrameType frame_type;
-
- frame_type = meta_window_get_frame_type (window);
- return meta_frame_type_to_string (frame_type);
- }
- }
- }
-}
-
-static void
-get_shadow_params (MetaWindowActorX11 *actor_x11,
- gboolean appears_focused,
- MetaShadowParams *params)
-{
- const char *shadow_class = get_shadow_class (actor_x11);
-
- meta_shadow_factory_get_params (actor_x11->shadow_factory,
- shadow_class, appears_focused,
- params);
-}
-
-static void
-get_shape_bounds (MetaWindowActorX11 *actor_x11,
- cairo_rectangle_int_t *bounds)
-{
- cairo_region_get_extents (actor_x11->shape_region, bounds);
-}
-
-static void
-get_shadow_bounds (MetaWindowActorX11 *actor_x11,
- gboolean appears_focused,
- cairo_rectangle_int_t *bounds)
-{
- MetaShadow *shadow;
- cairo_rectangle_int_t shape_bounds;
- MetaShadowParams params;
-
- shadow = appears_focused ? actor_x11->focused_shadow
- : actor_x11->unfocused_shadow;
-
- get_shape_bounds (actor_x11, &shape_bounds);
- get_shadow_params (actor_x11, appears_focused, &params);
-
- meta_shadow_get_bounds (shadow,
- params.x_offset + shape_bounds.x,
- params.y_offset + shape_bounds.y,
- shape_bounds.width,
- shape_bounds.height,
- bounds);
-}
-
-/* If we have an ARGB32 window that we decorate with a frame, it's
- * probably something like a translucent terminal - something where
- * the alpha channel represents transparency rather than a shape. We
- * don't want to show the shadow through the translucent areas since
- * the shadow is wrong for translucent windows (it should be
- * translucent itself and colored), and not only that, will /look/
- * horribly wrong - a misplaced big black blob. As a hack, what we
- * want to do is just draw the shadow as normal outside the frame, and
- * inside the frame draw no shadow. This is also not even close to
- * the right result, but looks OK. We also apply this approach to
- * windows set to be partially translucent with _NET_WM_WINDOW_OPACITY.
- */
-static gboolean
-clip_shadow_under_window (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
-
- if (window->frame)
- return TRUE;
-
- return meta_window_actor_is_opaque (META_WINDOW_ACTOR (actor_x11));
-}
-
-/**
- * set_clip_region_beneath:
- * @actor_x11: a #MetaWindowActorX11
- * @clip_region: the region of the screen that isn't completely
- * obscured beneath the main window texture.
- *
- * Provides a hint as to what areas need to be drawn *beneath*
- * the main window texture. This is the relevant clip region
- * when drawing the shadow, properly accounting for areas of the
- * shadow hid by the window itself. This will be set before painting
- * then unset afterwards.
- */
-static void
-set_clip_region_beneath (MetaWindowActorX11 *actor_x11,
- cairo_region_t *beneath_region)
-{
- MetaWindow *window;
- gboolean appears_focused;
-
- window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- appears_focused = meta_window_appears_focused (window);
- if (appears_focused ? actor_x11->focused_shadow : actor_x11->unfocused_shadow)
- {
- g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
-
- if (beneath_region)
- {
- actor_x11->shadow_clip = cairo_region_copy (beneath_region);
-
- if (clip_shadow_under_window (actor_x11))
- {
- if (actor_x11->frame_bounds)
- cairo_region_subtract (actor_x11->shadow_clip, actor_x11->frame_bounds);
- }
- }
- else
- {
- actor_x11->shadow_clip = NULL;
- }
- }
-}
-
-static void
-check_needs_shadow (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaShadow *old_shadow = NULL;
- MetaShadow **shadow_location;
- gboolean recompute_shadow;
- gboolean should_have_shadow;
- gboolean appears_focused;
-
- /* Calling has_shadow() here at every pre-paint is cheap
- * and avoids the need to explicitly handle window type changes, which
- * we would do if tried to keep track of when we might be adding or removing
- * a shadow more explicitly. We only keep track of changes to the *shape* of
- * the shadow with actor_x11->recompute_shadow.
- */
-
- should_have_shadow = has_shadow (actor_x11);
- appears_focused = meta_window_appears_focused (window);
-
- if (appears_focused)
- {
- recompute_shadow = actor_x11->recompute_focused_shadow;
- actor_x11->recompute_focused_shadow = FALSE;
- shadow_location = &actor_x11->focused_shadow;
- }
- else
- {
- recompute_shadow = actor_x11->recompute_unfocused_shadow;
- actor_x11->recompute_unfocused_shadow = FALSE;
- shadow_location = &actor_x11->unfocused_shadow;
- }
-
- if (!should_have_shadow || recompute_shadow)
- {
- if (*shadow_location != NULL)
- {
- old_shadow = *shadow_location;
- *shadow_location = NULL;
- }
- }
-
- if (!*shadow_location && should_have_shadow)
- {
- MetaShadowFactory *factory = actor_x11->shadow_factory;
- const char *shadow_class = get_shadow_class (actor_x11);
- cairo_rectangle_int_t shape_bounds;
-
- if (!actor_x11->shadow_shape)
- {
- actor_x11->shadow_shape =
- meta_window_shape_new (actor_x11->shape_region);
- }
-
- get_shape_bounds (actor_x11, &shape_bounds);
- *shadow_location =
- meta_shadow_factory_get_shadow (factory,
- actor_x11->shadow_shape,
- shape_bounds.width, shape_bounds.height,
- shadow_class, appears_focused);
- }
-
- if (old_shadow)
- meta_shadow_unref (old_shadow);
-}
-
-void
-meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11,
- XDamageNotifyEvent *event)
-{
- MetaSurfaceActor *surface;
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- if (surface)
- meta_surface_actor_process_damage (surface,
- event->area.x,
- event->area.y,
- event->area.width,
- event->area.height);
-
- meta_window_actor_notify_damaged (META_WINDOW_ACTOR (actor_x11));
-}
-
-static cairo_region_t *
-scan_visible_region (guchar *mask_data,
- int stride,
- cairo_region_t *scan_area)
-{
- int i, n_rects = cairo_region_num_rectangles (scan_area);
- MetaRegionBuilder builder;
-
- meta_region_builder_init (&builder);
-
- for (i = 0; i < n_rects; i++)
- {
- int x, y;
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (scan_area, i, &rect);
-
- for (y = rect.y; y < (rect.y + rect.height); y++)
- {
- for (x = rect.x; x < (rect.x + rect.width); x++)
- {
- int x2 = x;
- while (mask_data[y * stride + x2] == 255 && x2 < (rect.x + rect.width))
- x2++;
-
- if (x2 > x)
- {
- meta_region_builder_add_rectangle (&builder, x, y, x2 - x, 1);
- x = x2;
- }
- }
- }
- }
-
- return meta_region_builder_finish (&builder);
-}
-
-static void
-get_client_area_rect_from_texture (MetaWindowActorX11 *actor_x11,
- MetaShapedTexture *shaped_texture,
- cairo_rectangle_int_t *client_area)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- cairo_rectangle_int_t surface_rect = { 0 };
-
- surface_rect.width = meta_shaped_texture_get_width (shaped_texture);
- surface_rect.height = meta_shaped_texture_get_height (shaped_texture);
- meta_window_x11_surface_rect_to_client_rect (window,
- &surface_rect,
- client_area);
-}
-
-static void
-get_client_area_rect (MetaWindowActorX11 *actor_x11,
- cairo_rectangle_int_t *client_area)
-{
- MetaSurfaceActor *surface =
- meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaShapedTexture *stex = meta_surface_actor_get_texture (surface);
-
- if (!meta_window_x11_always_update_shape (window) || !stex)
- {
- meta_window_get_client_area_rect (window, client_area);
- return;
- }
-
- get_client_area_rect_from_texture (actor_x11, stex, client_area);
-}
-
-static void
-build_and_scan_frame_mask (MetaWindowActorX11 *actor_x11,
- cairo_region_t *shape_region)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- CoglContext *ctx = clutter_backend_get_cogl_context (backend);
- MetaSurfaceActor *surface =
- meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- uint8_t *mask_data;
- unsigned int tex_width, tex_height;
- MetaShapedTexture *stex;
- CoglTexture2D *mask_texture;
- int stride;
- cairo_t *cr;
- cairo_surface_t *image;
- GError *error = NULL;
-
- stex = meta_surface_actor_get_texture (surface);
- g_return_if_fail (stex);
-
- meta_shaped_texture_set_mask_texture (stex, NULL);
-
- tex_width = meta_shaped_texture_get_width (stex);
- tex_height = meta_shaped_texture_get_height (stex);
-
- stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width);
-
- /* Create data for an empty image */
- mask_data = g_malloc0 (stride * tex_height);
-
- image = cairo_image_surface_create_for_data (mask_data,
- CAIRO_FORMAT_A8,
- tex_width,
- tex_height,
- stride);
- cr = cairo_create (image);
-
- gdk_cairo_region (cr, shape_region);
- cairo_fill (cr);
-
- if (window->frame)
- {
- cairo_region_t *frame_paint_region, *scanned_region;
- cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
- cairo_rectangle_int_t client_area;
- cairo_rectangle_int_t frame_rect;
-
- /* If we update the shape regardless of the frozen state of the actor,
- * as with Xwayland to avoid the black shadow effect, we ought to base
- * the frame size on the buffer size rather than the reported window's
- * frame size, as the buffer may not have been committed yet at this
- * point.
- */
- if (meta_window_x11_always_update_shape (window))
- {
- meta_window_x11_surface_rect_to_frame_rect (window, &rect, &frame_rect);
- get_client_area_rect_from_texture (actor_x11, stex, &client_area);
- }
- else
- {
- meta_window_get_frame_rect (window, &frame_rect);
- meta_window_get_client_area_rect (window, &client_area);
- }
-
- /* Make sure we don't paint the frame over the client window. */
- frame_paint_region = cairo_region_create_rectangle (&rect);
- cairo_region_subtract_rectangle (frame_paint_region, &client_area);
-
- gdk_cairo_region (cr, frame_paint_region);
- cairo_clip (cr);
-
- meta_frame_get_mask (window->frame, &frame_rect, cr);
-
- cairo_surface_flush (image);
- scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
- cairo_region_union (shape_region, scanned_region);
- cairo_region_destroy (scanned_region);
- cairo_region_destroy (frame_paint_region);
- }
-
- cairo_destroy (cr);
- cairo_surface_destroy (image);
-
- mask_texture = cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
- COGL_PIXEL_FORMAT_A_8,
- stride, mask_data, &error);
-
- if (error)
- {
- g_warning ("Failed to allocate mask texture: %s", error->message);
- g_error_free (error);
- }
-
- if (mask_texture)
- {
- meta_shaped_texture_set_mask_texture (stex, COGL_TEXTURE (mask_texture));
- cogl_object_unref (mask_texture);
- }
- else
- {
- meta_shaped_texture_set_mask_texture (stex, NULL);
- }
-
- g_free (mask_data);
-}
-
-static void
-invalidate_shadow (MetaWindowActorX11 *actor_x11)
-{
- actor_x11->recompute_focused_shadow = TRUE;
- actor_x11->recompute_unfocused_shadow = TRUE;
-
- if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11)))
- return;
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (actor_x11));
- clutter_actor_invalidate_paint_volume (CLUTTER_ACTOR (actor_x11));
-}
-
-static void
-update_shape_region (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- cairo_region_t *region = NULL;
- cairo_rectangle_int_t client_area;
-
- get_client_area_rect (actor_x11, &client_area);
-
- if (window->frame && window->shape_region)
- {
- region = cairo_region_copy (window->shape_region);
- cairo_region_translate (region, client_area.x, client_area.y);
- }
- else if (window->shape_region != NULL)
- {
- region = cairo_region_reference (window->shape_region);
- }
- else
- {
- /* If we don't have a shape on the server, that means that
- * we have an implicit shape of one rectangle covering the
- * entire window. */
- region = cairo_region_create_rectangle (&client_area);
- }
-
- if (window->shape_region || window->frame)
- build_and_scan_frame_mask (actor_x11, region);
-
- g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
- actor_x11->shape_region = region;
-
- g_clear_pointer (&actor_x11->shadow_shape, meta_window_shape_unref);
-
- invalidate_shadow (actor_x11);
-}
-
-static void
-update_input_region (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaSurfaceActor *surface =
- meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- cairo_region_t *region;
-
- if (window->shape_region && window->input_region)
- {
- region = cairo_region_copy (window->shape_region);
- cairo_region_intersect (region, window->input_region);
- }
- else if (window->shape_region)
- {
- region = cairo_region_reference (window->shape_region);
- }
- else if (window->input_region)
- {
- region = cairo_region_reference (window->input_region);
- }
- else
- {
- region = NULL;
- }
-
- meta_surface_actor_set_input_region (surface, region);
- cairo_region_destroy (region);
-}
-
-static gboolean
-is_actor_maybe_transparent (MetaWindowActorX11 *actor_x11)
-{
- MetaSurfaceActor *surface;
- MetaShapedTexture *stex;
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- if (!surface)
- return TRUE;
-
- if (META_IS_SURFACE_ACTOR_X11 (surface) &&
- meta_surface_actor_x11_is_unredirected (META_SURFACE_ACTOR_X11 (surface)))
- return FALSE;
-
- stex = meta_surface_actor_get_texture (surface);
- if (!meta_shaped_texture_has_alpha (stex))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-update_opaque_region (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- gboolean is_maybe_transparent;
- cairo_region_t *opaque_region;
- MetaSurfaceActor *surface;
-
- is_maybe_transparent = is_actor_maybe_transparent (actor_x11);
- if (is_maybe_transparent && window->opaque_region)
- {
- cairo_rectangle_int_t client_area;
-
- get_client_area_rect (actor_x11, &client_area);
-
- /* The opaque region is defined to be a part of the
- * window which ARGB32 will always paint with opaque
- * pixels. For these regions, we want to avoid painting
- * windows and shadows beneath them.
- *
- * If the client gives bad coordinates where it does not
- * fully paint, the behavior is defined by the specification
- * to be undefined, and considered a client bug. In mutter's
- * case, graphical glitches will occur.
- */
- opaque_region = cairo_region_copy (window->opaque_region);
- cairo_region_translate (opaque_region, client_area.x, client_area.y);
- cairo_region_intersect (opaque_region, actor_x11->shape_region);
- }
- else if (is_maybe_transparent)
- {
- opaque_region = NULL;
- }
- else
- {
- opaque_region = cairo_region_reference (actor_x11->shape_region);
- }
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- meta_surface_actor_set_opaque_region (surface, opaque_region);
- cairo_region_destroy (opaque_region);
-}
-
-static void
-update_frame_bounds (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
-
- g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
- actor_x11->frame_bounds =
- cairo_region_copy (meta_window_get_frame_bounds (window));
-}
-
-static void
-update_regions (MetaWindowActorX11 *actor_x11)
-{
- if (!actor_x11->needs_reshape)
- return;
-
- update_shape_region (actor_x11);
- update_input_region (actor_x11);
- update_opaque_region (actor_x11);
-
- actor_x11->needs_reshape = FALSE;
-}
-
-static void
-check_needs_reshape (MetaWindowActorX11 *actor_x11)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
-
- if (meta_window_x11_always_update_shape (window))
- return;
-
- update_regions (actor_x11);
-}
-
-void
-meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11)
-{
- MetaSurfaceActor *surface =
- meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
-
- actor_x11->needs_reshape = TRUE;
-
- if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11)))
- return;
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (surface));
-}
-
-static void
-handle_updates (MetaWindowActorX11 *actor_x11)
-{
- MetaSurfaceActor *surface =
- meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- MetaWindow *window;
-
- if (META_IS_SURFACE_ACTOR_X11 (surface) &&
- meta_surface_actor_x11_is_unredirected (META_SURFACE_ACTOR_X11 (surface)))
- return;
-
- window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11)))
- {
- /* The window is frozen due to a pending animation: we'll wait until
- * the animation finishes to repair the window.
- *
- * However, with Xwayland, we still might need to update the shape
- * region as the wl_buffer will be set to plain black on resize,
- * which causes the shadows to look bad.
- */
- if (surface && meta_window_x11_always_update_shape (window))
- check_needs_reshape (actor_x11);
-
- return;
- }
-
- if (META_IS_SURFACE_ACTOR_X11 (surface))
- {
- MetaSurfaceActorX11 *surface_x11 = META_SURFACE_ACTOR_X11 (surface);
-
- meta_surface_actor_x11_handle_updates (surface_x11);
- }
-
- if (META_IS_SURFACE_ACTOR_X11 (surface) &&
- !meta_surface_actor_x11_is_visible (META_SURFACE_ACTOR_X11 (surface)))
- return;
-
- update_frame_bounds (actor_x11);
- check_needs_reshape (actor_x11);
- check_needs_shadow (actor_x11);
-}
-
-static void
-handle_stage_views_changed (MetaWindowActorX11 *actor_x11)
-{
- ClutterActor *actor = CLUTTER_ACTOR (actor_x11);
-
- actor_x11->frame_clock = clutter_actor_pick_frame_clock (actor, NULL);
- if (actor_x11->frame_clock && actor_x11->pending_schedule_update_now)
- {
- clutter_frame_clock_schedule_update_now (actor_x11->frame_clock);
- actor_x11->pending_schedule_update_now = FALSE;
- }
-}
-
-static void
-meta_window_actor_x11_before_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
-
- handle_updates (actor_x11);
-
- assign_frame_counter_to_frames (actor_x11);
-}
-
-static void
-meta_window_actor_x11_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- MetaWindow *window;
- gboolean appears_focused;
- MetaShadow *shadow;
-
- /* This window got damage when obscured; we set up a timer
- * to send frame completion events, but since we're drawing
- * the window now (for some other reason) cancel the timer
- * and send the completion events normally */
- if (actor_x11->send_frame_messages_timer != 0)
- {
- remove_frame_messages_timer (actor_x11);
- assign_frame_counter_to_frames (actor_x11);
- }
-
- window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- appears_focused = meta_window_appears_focused (window);
- shadow = appears_focused ? actor_x11->focused_shadow
- : actor_x11->unfocused_shadow;
-
- if (shadow)
- {
- MetaShadowParams params;
- cairo_rectangle_int_t shape_bounds;
- cairo_region_t *clip = actor_x11->shadow_clip;
- CoglFramebuffer *framebuffer;
-
- get_shape_bounds (actor_x11, &shape_bounds);
- get_shadow_params (actor_x11, appears_focused, &params);
-
- /* The frame bounds are already subtracted from actor_x11->shadow_clip
- * if that exists.
- */
- if (!clip && clip_shadow_under_window (actor_x11))
- {
- cairo_rectangle_int_t bounds;
-
- get_shadow_bounds (actor_x11, appears_focused, &bounds);
- clip = cairo_region_create_rectangle (&bounds);
-
- if (actor_x11->frame_bounds)
- cairo_region_subtract (clip, actor_x11->frame_bounds);
- }
-
- framebuffer = clutter_paint_context_get_framebuffer (paint_context);
- meta_shadow_paint (shadow,
- framebuffer,
- params.x_offset + shape_bounds.x,
- params.y_offset + shape_bounds.y,
- shape_bounds.width,
- shape_bounds.height,
- (clutter_actor_get_paint_opacity (actor) *
- params.opacity * window->opacity) / (255 * 255),
- clip,
- clip_shadow_under_window (actor_x11));
-
- if (clip && clip != actor_x11->shadow_clip)
- cairo_region_destroy (clip);
- }
-
- CLUTTER_ACTOR_CLASS (meta_window_actor_x11_parent_class)->paint (actor,
- paint_context);
-}
-
-static void
-meta_window_actor_x11_after_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- MetaWindow *window;
-
- actor_x11->repaint_scheduled = FALSE;
-
- if (meta_window_actor_is_destroyed (actor))
- return;
-
- /* If the window had damage, but wasn't actually redrawn because
- * it is obscured, we should wait until timer expiration before
- * sending _NET_WM_FRAME_* messages.
- */
- if (actor_x11->send_frame_messages_timer == 0 &&
- actor_x11->needs_frame_drawn)
- {
- GList *l;
-
- for (l = actor_x11->frames; l; l = l->next)
- {
- FrameData *frame = l->data;
-
- if (frame->frame_drawn_time == 0)
- do_send_frame_drawn (actor_x11, frame);
- }
-
- actor_x11->needs_frame_drawn = FALSE;
- }
-
- /* This is for Xwayland, and a no-op on plain Xorg */
- window = meta_window_actor_get_meta_window (actor);
- if (meta_window_x11_should_thaw_after_paint (window))
- {
- meta_window_x11_thaw_commits (window);
- meta_window_x11_set_thaw_after_paint (window, FALSE);
- }
-}
-
-static gboolean
-meta_window_actor_x11_get_paint_volume (ClutterActor *actor,
- ClutterPaintVolume *volume)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- MetaWindow *window;
- gboolean appears_focused;
- MetaSurfaceActor *surface;
-
- /* The paint volume is computed before paint functions are called
- * so our bounds might not be updated yet. Force an update. */
- handle_updates (actor_x11);
-
- window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- appears_focused = meta_window_appears_focused (window);
- if (appears_focused ? actor_x11->focused_shadow : actor_x11->unfocused_shadow)
- {
- cairo_rectangle_int_t shadow_bounds;
- ClutterActorBox shadow_box;
-
- /* We could compute an full clip region as we do for the window
- * texture, but the shadow is relatively cheap to draw, and
- * a little more complex to clip, so we just catch the case where
- * the shadow is completely obscured and doesn't need to be drawn
- * at all.
- */
-
- get_shadow_bounds (actor_x11, appears_focused, &shadow_bounds);
- shadow_box.x1 = shadow_bounds.x;
- shadow_box.x2 = shadow_bounds.x + shadow_bounds.width;
- shadow_box.y1 = shadow_bounds.y;
- shadow_box.y2 = shadow_bounds.y + shadow_bounds.height;
-
- clutter_paint_volume_union_box (volume, &shadow_box);
- }
-
- surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- if (surface)
- {
- ClutterActor *surface_actor = CLUTTER_ACTOR (surface);
- const ClutterPaintVolume *child_volume;
-
- child_volume = clutter_actor_get_transformed_paint_volume (surface_actor,
- actor);
- if (!child_volume)
- return FALSE;
-
- clutter_paint_volume_union (volume, child_volume);
- }
-
- return TRUE;
-}
-
-static void
-meta_window_actor_x11_queue_destroy (MetaWindowActor *actor)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
-
- if (actor_x11->send_frame_messages_timer != 0)
- remove_frame_messages_timer (actor_x11);
-}
-
-static void
-meta_window_actor_x11_set_frozen (MetaWindowActor *actor,
- gboolean frozen)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
- MetaWindow *window = meta_window_actor_get_meta_window (actor);
-
- if (actor_x11->is_frozen == frozen)
- return;
-
- actor_x11->is_frozen = frozen;
-
- if (frozen)
- meta_window_x11_freeze_commits (window);
- else
- meta_window_x11_thaw_commits (window);
-}
-
-static void
-meta_window_actor_x11_update_regions (MetaWindowActor *actor)
-{
- update_regions (META_WINDOW_ACTOR_X11 (actor));
-}
-
-static gboolean
-meta_window_actor_x11_can_freeze_commits (MetaWindowActor *actor)
-{
- ClutterActor *clutter_actor = CLUTTER_ACTOR (actor);
-
- return clutter_actor_is_mapped (clutter_actor);
-}
-
-static void
-meta_window_actor_x11_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object);
-
- switch (prop_id)
- {
- case PROP_SHADOW_MODE:
- {
- MetaShadowMode newv = g_value_get_enum (value);
-
- if (newv == actor_x11->shadow_mode)
- return;
-
- actor_x11->shadow_mode = newv;
-
- invalidate_shadow (actor_x11);
- }
- break;
- case PROP_SHADOW_CLASS:
- {
- const char *newv = g_value_get_string (value);
-
- if (g_strcmp0 (newv, actor_x11->shadow_class) == 0)
- return;
-
- g_free (actor_x11->shadow_class);
- actor_x11->shadow_class = g_strdup (newv);
-
- invalidate_shadow (actor_x11);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_window_actor_x11_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object);
-
- switch (prop_id)
- {
- case PROP_SHADOW_MODE:
- g_value_set_enum (value, actor_x11->shadow_mode);
- break;
- case PROP_SHADOW_CLASS:
- g_value_set_string (value, actor_x11->shadow_class);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_window_actor_x11_constructed (GObject *object)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object);
- MetaWindowActor *actor = META_WINDOW_ACTOR (actor_x11);
- MetaWindow *window = meta_window_actor_get_meta_window (actor);
-
- /*
- * Start off with an empty shape region to maintain the invariant that it's
- * always set.
- */
- actor_x11->shape_region = cairo_region_create ();
-
- G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->constructed (object);
-
- /* If a window doesn't start off with updates frozen, we should
- * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
- */
- if (window->extended_sync_request_counter &&
- !meta_window_updates_are_frozen (window))
- meta_window_actor_queue_frame_drawn (actor, FALSE);
-}
-
-static void
-meta_window_actor_x11_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- MetaWindowActorX11 *self = META_WINDOW_ACTOR_X11 (cullable);
-
- cullable_parent_iface->cull_out (cullable, unobscured_region, clip_region);
-
- set_clip_region_beneath (self, clip_region);
-}
-
-static void
-meta_window_actor_x11_reset_culling (MetaCullable *cullable)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (cullable);
-
- g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
-
- cullable_parent_iface->reset_culling (cullable);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- cullable_parent_iface = g_type_interface_peek_parent (iface);
-
- iface->cull_out = meta_window_actor_x11_cull_out;
- iface->reset_culling = meta_window_actor_x11_reset_culling;
-}
-
-static void
-meta_window_actor_x11_dispose (GObject *object)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object);
- MetaSurfaceActor *surface_actor;
-
- g_clear_signal_handler (&actor_x11->shadow_factory_changed_handler_id,
- actor_x11->shadow_factory);
-
- if (actor_x11->send_frame_messages_timer != 0)
- remove_frame_messages_timer (actor_x11);
-
- surface_actor = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
- if (surface_actor)
- {
- g_clear_signal_handler (&actor_x11->repaint_scheduled_id, surface_actor);
- g_clear_signal_handler (&actor_x11->size_changed_id, surface_actor);
- }
-
- g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
- g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
- g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
-
- g_clear_pointer (&actor_x11->shadow_class, g_free);
- g_clear_pointer (&actor_x11->focused_shadow, meta_shadow_unref);
- g_clear_pointer (&actor_x11->unfocused_shadow, meta_shadow_unref);
- g_clear_pointer (&actor_x11->shadow_shape, meta_window_shape_unref);
-
- G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->dispose (object);
-}
-
-static void
-meta_window_actor_x11_finalize (GObject *object)
-{
- MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object);
-
- g_list_free_full (actor_x11->frames, (GDestroyNotify) frame_data_free);
-
- G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->finalize (object);
-}
-
-static void
-meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
- MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
- GParamSpec *pspec;
-
- window_actor_class->frame_complete = meta_window_actor_x11_frame_complete;
- window_actor_class->assign_surface_actor = meta_window_actor_x11_assign_surface_actor;
- window_actor_class->queue_frame_drawn = meta_window_actor_x11_queue_frame_drawn;
- window_actor_class->before_paint = meta_window_actor_x11_before_paint;
- window_actor_class->after_paint = meta_window_actor_x11_after_paint;
- window_actor_class->queue_destroy = meta_window_actor_x11_queue_destroy;
- window_actor_class->set_frozen = meta_window_actor_x11_set_frozen;
- window_actor_class->update_regions = meta_window_actor_x11_update_regions;
- window_actor_class->can_freeze_commits = meta_window_actor_x11_can_freeze_commits;
-
- actor_class->paint = meta_window_actor_x11_paint;
- actor_class->get_paint_volume = meta_window_actor_x11_get_paint_volume;
-
- object_class->constructed = meta_window_actor_x11_constructed;
- object_class->set_property = meta_window_actor_x11_set_property;
- object_class->get_property = meta_window_actor_x11_get_property;
- object_class->dispose = meta_window_actor_x11_dispose;
- object_class->finalize = meta_window_actor_x11_finalize;
-
- pspec = g_param_spec_enum ("shadow-mode",
- "Shadow mode",
- "Decides when to paint shadows",
- META_TYPE_SHADOW_MODE,
- META_SHADOW_MODE_AUTO,
- G_PARAM_READWRITE);
-
- g_object_class_install_property (object_class,
- PROP_SHADOW_MODE,
- pspec);
-
- pspec = g_param_spec_string ("shadow-class",
- "Name of the shadow class for this window.",
- "NULL means to use the default shadow class for this window type",
- NULL,
- G_PARAM_READWRITE);
-
- g_object_class_install_property (object_class,
- PROP_SHADOW_CLASS,
- pspec);
-}
-
-static void
-meta_window_actor_x11_init (MetaWindowActorX11 *self)
-{
- /* We do this now since we might be going right back into the frozen state. */
- g_signal_connect (self, "thawed", G_CALLBACK (handle_updates), NULL);
-
- g_signal_connect (self, "stage-views-changed",
- G_CALLBACK (handle_stage_views_changed), NULL);
-
- self->shadow_factory = meta_shadow_factory_get_default ();
- self->shadow_factory_changed_handler_id =
- g_signal_connect_swapped (self->shadow_factory,
- "changed",
- G_CALLBACK (invalidate_shadow),
- self);
-}
diff --git a/src/compositor/meta-window-actor-x11.h b/src/compositor/meta-window-actor-x11.h
deleted file mode 100644
index 86b80034d..000000000
--- a/src/compositor/meta-window-actor-x11.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2018 Endless, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Written by:
- * Georges Basile Stavracas Neto <gbsneto@gnome.org>
- */
-
-#ifndef META_WINDOW_ACTOR_X11_H
-#define META_WINDOW_ACTOR_X11_H
-
-#include "compositor/meta-window-actor-private.h"
-
-#define META_TYPE_WINDOW_ACTOR_X11 (meta_window_actor_x11_get_type())
-G_DECLARE_FINAL_TYPE (MetaWindowActorX11,
- meta_window_actor_x11,
- META, WINDOW_ACTOR_X11,
- MetaWindowActor)
-
-void meta_window_actor_x11_process_x11_damage (MetaWindowActorX11 *actor_x11,
- XDamageNotifyEvent *event);
-
-gboolean meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11);
-
-void meta_window_actor_x11_set_unredirected (MetaWindowActorX11 *actor_x11,
- gboolean unredirected);
-
-void meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11);
-
-void meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11,
- XDamageNotifyEvent *event);
-
-#endif /* META_WINDOW_ACTOR_X11_H */
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
deleted file mode 100644
index d4fc9a43a..000000000
--- a/src/compositor/meta-window-actor.c
+++ /dev/null
@@ -1,1559 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:meta-window-actor
- * @title: MetaWindowActor
- * @short_description: An actor representing a top-level window in the scene
- * graph
- *
- * #MetaWindowActor is a #ClutterActor that adds a notion of a window to the
- * Clutter scene graph. It contains a #MetaWindow which provides the windowing
- * API, and the #MetaCompositor that handles it. For the actual content of the
- * window, it contains a #MetaSurfaceActor.
- *
- * #MetaWindowActor takes care of the rendering features you need for your
- * window. For example, it will take the windows' requested opacity and use
- * that for clutter_actor_set_opacity(). Furthermore, it will also draw a
- * shadow around the window (using #MetaShadow) and deal with synchronization
- * between events of the window and the actual render loop. See
- * MetaWindowActor::first-frame for an example of the latter.
- */
-
-#include "config.h"
-
-#include <gdk/gdk.h>
-#include <math.h>
-#include <string.h>
-
-#include "backends/meta-screen-cast-window.h"
-#include "compositor/compositor-private.h"
-#include "compositor/meta-cullable.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "compositor/meta-surface-actor-x11.h"
-#include "compositor/meta-surface-actor.h"
-#include "compositor/meta-window-actor-private.h"
-#include "core/boxes-private.h"
-#include "core/window-private.h"
-#include "meta/window.h"
-
-#ifdef HAVE_WAYLAND
-#include "compositor/meta-surface-actor-wayland.h"
-#include "wayland/meta-wayland-surface.h"
-#endif
-
-typedef enum
-{
- INITIALLY_FROZEN,
- DRAWING_FIRST_FRAME,
- EMITTED_FIRST_FRAME
-} FirstFrameState;
-
-typedef struct _MetaWindowActorPrivate
-{
- MetaWindow *window;
- MetaCompositor *compositor;
-
- MetaSurfaceActor *surface;
-
- int geometry_scale;
-
- /*
- * These need to be counters rather than flags, since more plugins
- * can implement same effect; the practicality of stacking effects
- * might be dubious, but we have to at least handle it correctly.
- */
- gint minimize_in_progress;
- gint unminimize_in_progress;
- gint size_change_in_progress;
- gint map_in_progress;
- gint destroy_in_progress;
-
- guint freeze_count;
-
- guint visible : 1;
- guint disposed : 1;
-
- guint needs_destroy : 1;
-
- guint updates_frozen : 1;
- guint first_frame_state : 2; /* FirstFrameState */
-} MetaWindowActorPrivate;
-
-enum
-{
- FIRST_FRAME,
- EFFECTS_COMPLETED,
- DAMAGED,
- THAWED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-enum
-{
- PROP_META_WINDOW = 1,
-};
-
-static void meta_window_actor_dispose (GObject *object);
-static void meta_window_actor_constructed (GObject *object);
-static void meta_window_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void meta_window_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_actor);
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-static void screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface);
-
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR,
- G_ADD_PRIVATE (MetaWindowActor)
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)
- G_IMPLEMENT_INTERFACE (META_TYPE_SCREEN_CAST_WINDOW, screen_cast_window_iface_init));
-
-static void
-meta_window_actor_class_init (MetaWindowActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- object_class->dispose = meta_window_actor_dispose;
- object_class->set_property = meta_window_actor_set_property;
- object_class->get_property = meta_window_actor_get_property;
- object_class->constructed = meta_window_actor_constructed;
-
- klass->assign_surface_actor = meta_window_actor_real_assign_surface_actor;
-
- /**
- * MetaWindowActor::first-frame:
- * @actor: the #MetaWindowActor instance
- *
- * The ::first-frame signal will be emitted the first time a frame
- * of window contents has been drawn by the application and Mutter
- * has had the chance to drawn that frame to the screen. If the
- * window starts off initially hidden, obscured, or on on a
- * different workspace, the ::first-frame signal will be emitted
- * even though the user doesn't see the contents.
- *
- * MetaDisplay::window-created is a good place to connect to this
- * signal - at that point, the MetaWindowActor for the window
- * exists, but the window has reliably not yet been drawn.
- * Connecting to an existing window that has already been drawn to
- * the screen is not useful.
- */
- signals[FIRST_FRAME] =
- g_signal_new ("first-frame",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- /**
- * MetaWindowActor::effects-completed:
- * @actor: the #MetaWindowActor instance
- *
- * The ::effects-completed signal will be emitted once all pending compositor
- * effects are completed.
- */
- signals[EFFECTS_COMPLETED] =
- g_signal_new ("effects-completed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- /**
- * MetaWindowActor::damaged:
- * @actor: the #MetaWindowActor instance
- *
- * Notify that one or more of the surfaces of the window have been damaged.
- */
- signals[DAMAGED] =
- g_signal_new ("damaged",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- /**
- * MetaWindowActor::thawed:
- * @actor: the #MetaWindowActor instance
- */
- signals[THAWED] =
- g_signal_new ("thawed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- pspec = g_param_spec_object ("meta-window",
- "MetaWindow",
- "The displayed MetaWindow",
- META_TYPE_WINDOW,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_META_WINDOW,
- pspec);
-}
-
-static void
-meta_window_actor_init (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- priv->geometry_scale = 1;
-}
-
-static void
-window_appears_focused_notify (MetaWindow *mw,
- GParamSpec *arg1,
- gpointer data)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
-}
-
-gboolean
-meta_window_actor_is_opaque (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- if (window->opacity != 0xff)
- return FALSE;
-
- if (!priv->surface)
- return FALSE;
-
- return meta_surface_actor_is_opaque (priv->surface);
-}
-
-gboolean
-meta_window_actor_is_frozen (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->surface == NULL || priv->freeze_count > 0;
-}
-
-void
-meta_window_actor_update_regions (MetaWindowActor *self)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->update_regions (self);
-}
-
-gboolean
-meta_window_actor_can_freeze_commits (MetaWindowActor *self)
-{
- g_return_val_if_fail (META_IS_WINDOW_ACTOR (self), FALSE);
-
- return META_WINDOW_ACTOR_GET_CLASS (self)->can_freeze_commits (self);
-}
-
-static void
-meta_window_actor_set_frozen (MetaWindowActor *self,
- gboolean frozen)
-{
- ClutterActor *child;
- ClutterActorIter iter;
-
- clutter_actor_iter_init (&iter, CLUTTER_ACTOR (self));
- while (clutter_actor_iter_next (&iter, &child))
- {
- if (META_IS_SURFACE_ACTOR (child))
- meta_surface_actor_set_frozen (META_SURFACE_ACTOR (child), frozen);
- }
-
- META_WINDOW_ACTOR_GET_CLASS (self)->set_frozen (self, frozen);
-}
-
-/**
- * meta_window_actor_freeze:
- * @self: The #MetaWindowActor
- *
- * Freezes the #MetaWindowActor, which inhibits updates and geometry
- * changes of the window. This property is refcounted, so make sure
- * to call meta_window_actor_thaw() the exact same amount of times
- * as this function to allow updates again.
- */
-void
-meta_window_actor_freeze (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv;
-
- g_return_if_fail (META_IS_WINDOW_ACTOR (self));
-
- priv = meta_window_actor_get_instance_private (self);
-
- if (priv->freeze_count == 0 && priv->surface)
- meta_window_actor_set_frozen (self, TRUE);
-
- priv->freeze_count ++;
-}
-
-static void
-meta_window_actor_sync_thawed_state (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- if (priv->first_frame_state == INITIALLY_FROZEN)
- priv->first_frame_state = DRAWING_FIRST_FRAME;
-
- if (priv->surface)
- meta_window_actor_set_frozen (self, FALSE);
-
- /* We sometimes ignore moves and resizes on frozen windows */
- meta_window_actor_sync_actor_geometry (self, FALSE);
-}
-
-/**
- * meta_window_actor_thaw:
- * @self: The #MetaWindowActor
- *
- * Thaws/unfreezes the #MetaWindowActor to allow updates and geometry
- * changes after a window was frozen using meta_window_actor_freeze().
- */
-void
-meta_window_actor_thaw (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv;
-
- g_return_if_fail (META_IS_WINDOW_ACTOR (self));
-
- priv = meta_window_actor_get_instance_private (self);
-
- if (priv->freeze_count <= 0)
- g_error ("Error in freeze/thaw accounting");
-
- priv->freeze_count--;
- if (priv->freeze_count > 0)
- return;
-
- /* We still might be frozen due to lack of a MetaSurfaceActor */
- if (meta_window_actor_is_frozen (self))
- return;
-
- meta_window_actor_sync_thawed_state (self);
-
- g_signal_emit (self, signals[THAWED], 0);
-}
-
-static void
-meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_actor)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- g_clear_object (&priv->surface);
- priv->surface = g_object_ref_sink (surface_actor);
-
- if (meta_window_actor_is_frozen (self))
- meta_window_actor_set_frozen (self, TRUE);
- else
- meta_window_actor_sync_thawed_state (self);
-}
-
-void
-meta_window_actor_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_actor)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->assign_surface_actor (self,
- surface_actor);
-}
-
-static void
-init_surface_actor (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
- MetaSurfaceActor *surface_actor;
-
- if (!meta_is_wayland_compositor ())
- surface_actor = meta_surface_actor_x11_new (window);
-#ifdef HAVE_WAYLAND
- else if (window->surface)
- surface_actor = meta_wayland_surface_get_actor (window->surface);
-#endif
- else
- surface_actor = NULL;
-
- if (surface_actor)
- meta_window_actor_assign_surface_actor (self, surface_actor);
-}
-
-static void
-meta_window_actor_constructed (GObject *object)
-{
- MetaWindowActor *self = META_WINDOW_ACTOR (object);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- priv->compositor = window->display->compositor;
-
- /* Hang our compositor window state off the MetaWindow for fast retrieval */
- meta_window_set_compositor_private (window, object);
-
- init_surface_actor (self);
-
- meta_window_actor_update_opacity (self);
-
- meta_window_actor_sync_updates_frozen (self);
-
- if (meta_window_actor_is_frozen (self))
- priv->first_frame_state = INITIALLY_FROZEN;
- else
- priv->first_frame_state = DRAWING_FIRST_FRAME;
-
- meta_window_actor_sync_actor_geometry (self, priv->window->placed);
-}
-
-static void
-meta_window_actor_dispose (GObject *object)
-{
- MetaWindowActor *self = META_WINDOW_ACTOR (object);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
-
- if (priv->disposed)
- {
- G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
- return;
- }
-
- priv->disposed = TRUE;
-
- meta_compositor_remove_window_actor (compositor, self);
-
- g_clear_object (&priv->window);
-
- if (priv->surface)
- {
- clutter_actor_remove_child (CLUTTER_ACTOR (self),
- CLUTTER_ACTOR (priv->surface));
- g_clear_object (&priv->surface);
- }
-
- G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
-}
-
-static void
-meta_window_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaWindowActor *self = META_WINDOW_ACTOR (object);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- switch (prop_id)
- {
- case PROP_META_WINDOW:
- priv->window = g_value_dup_object (value);
- g_signal_connect_object (priv->window, "notify::appears-focused",
- G_CALLBACK (window_appears_focused_notify), self, 0);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_window_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaWindowActor *self = META_WINDOW_ACTOR (object);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- switch (prop_id)
- {
- case PROP_META_WINDOW:
- g_value_set_object (value, priv->window);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * meta_window_actor_get_meta_window:
- * @self: a #MetaWindowActor
- *
- * Gets the #MetaWindow object that the the #MetaWindowActor is displaying
- *
- * Return value: (transfer none): the displayed #MetaWindow
- */
-MetaWindow *
-meta_window_actor_get_meta_window (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->window;
-}
-
-/**
- * meta_window_actor_get_texture:
- * @self: a #MetaWindowActor
- *
- * Gets the ClutterActor that is used to display the contents of the window,
- * or NULL if no texture is shown yet, because the window is not mapped.
- *
- * Return value: (transfer none): the #ClutterActor for the contents
- */
-MetaShapedTexture *
-meta_window_actor_get_texture (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- if (priv->surface)
- return meta_surface_actor_get_texture (priv->surface);
- else
- return NULL;
-}
-
-/**
- * meta_window_actor_get_surface:
- * @self: a #MetaWindowActor
- *
- * Gets the MetaSurfaceActor that draws the content of this window,
- * or NULL if there is no surface yet associated with this window.
- *
- * Return value: (transfer none): the #MetaSurfaceActor for the contents
- */
-MetaSurfaceActor *
-meta_window_actor_get_surface (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->surface;
-}
-
-/**
- * meta_window_actor_is_destroyed:
- * @self: a #MetaWindowActor
- *
- * Gets whether the X window that the actor was displaying has been destroyed
- *
- * Return value: %TRUE when the window is destroyed, otherwise %FALSE
- */
-gboolean
-meta_window_actor_is_destroyed (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->disposed || priv->needs_destroy;
-}
-
-void
-meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
- gboolean no_delay_frame)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->queue_frame_drawn (self,
- no_delay_frame);
-}
-
-gboolean
-meta_window_actor_effect_in_progress (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return (priv->minimize_in_progress ||
- priv->size_change_in_progress ||
- priv->map_in_progress ||
- priv->destroy_in_progress);
-}
-
-static gboolean
-is_freeze_thaw_effect (MetaPluginEffect event)
-{
- switch (event)
- {
- case META_PLUGIN_DESTROY:
- return TRUE;
- break;
- default:
- return FALSE;
- }
-}
-
-static gboolean
-start_simple_effect (MetaWindowActor *self,
- MetaPluginEffect event)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
- MetaPluginManager *plugin_mgr =
- meta_compositor_get_plugin_manager (compositor);
- gint *counter = NULL;
- gboolean use_freeze_thaw = FALSE;
-
- g_assert (plugin_mgr != NULL);
-
- switch (event)
- {
- case META_PLUGIN_NONE:
- return FALSE;
- case META_PLUGIN_MINIMIZE:
- counter = &priv->minimize_in_progress;
- break;
- case META_PLUGIN_UNMINIMIZE:
- counter = &priv->unminimize_in_progress;
- break;
- case META_PLUGIN_MAP:
- counter = &priv->map_in_progress;
- break;
- case META_PLUGIN_DESTROY:
- counter = &priv->destroy_in_progress;
- break;
- case META_PLUGIN_SIZE_CHANGE:
- case META_PLUGIN_SWITCH_WORKSPACE:
- g_assert_not_reached ();
- break;
- }
-
- g_assert (counter);
-
- use_freeze_thaw = is_freeze_thaw_effect (event);
-
- if (use_freeze_thaw)
- meta_window_actor_freeze (self);
-
- (*counter)++;
-
- if (!meta_plugin_manager_event_simple (plugin_mgr, self, event))
- {
- (*counter)--;
- if (use_freeze_thaw)
- meta_window_actor_thaw (self);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-meta_window_actor_after_effects (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- ClutterStage *stage;
- ClutterSeat *seat;
-
- stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (self)));
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
-
- if (priv->needs_destroy)
- {
- clutter_actor_destroy (CLUTTER_ACTOR (self));
- }
- else
- {
- g_signal_emit (self, signals[EFFECTS_COMPLETED], 0);
- meta_window_actor_sync_visibility (self);
- meta_window_actor_sync_actor_geometry (self, FALSE);
- }
-
- clutter_stage_repick_device (stage, clutter_seat_get_pointer (seat));
-}
-
-void
-meta_window_actor_effect_completed (MetaWindowActor *self,
- MetaPluginEffect event)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- gboolean inconsistent = FALSE;
-
- /* NB: Keep in mind that when effects get completed it possible
- * that the corresponding MetaWindow may have be been destroyed.
- * In this case priv->window will == NULL */
-
- switch (event)
- {
- case META_PLUGIN_NONE:
- break;
- case META_PLUGIN_MINIMIZE:
- {
- priv->minimize_in_progress--;
- if (priv->minimize_in_progress < 0)
- {
- g_warning ("Error in minimize accounting.");
- priv->minimize_in_progress = 0;
- inconsistent = TRUE;
- }
- }
- break;
- case META_PLUGIN_UNMINIMIZE:
- {
- priv->unminimize_in_progress--;
- if (priv->unminimize_in_progress < 0)
- {
- g_warning ("Error in unminimize accounting.");
- priv->unminimize_in_progress = 0;
- inconsistent = TRUE;
- }
- }
- break;
- case META_PLUGIN_MAP:
- /*
- * Make sure that the actor is at the correct place in case
- * the plugin fscked.
- */
- priv->map_in_progress--;
-
- if (priv->map_in_progress < 0)
- {
- g_warning ("Error in map accounting.");
- priv->map_in_progress = 0;
- inconsistent = TRUE;
- }
- break;
- case META_PLUGIN_DESTROY:
- priv->destroy_in_progress--;
-
- if (priv->destroy_in_progress < 0)
- {
- g_warning ("Error in destroy accounting.");
- priv->destroy_in_progress = 0;
- inconsistent = TRUE;
- }
- break;
- case META_PLUGIN_SIZE_CHANGE:
- priv->size_change_in_progress--;
- if (priv->size_change_in_progress < 0)
- {
- g_warning ("Error in size change accounting.");
- priv->size_change_in_progress = 0;
- inconsistent = TRUE;
- }
- break;
- case META_PLUGIN_SWITCH_WORKSPACE:
- g_assert_not_reached ();
- break;
- }
-
- if (is_freeze_thaw_effect (event) && !inconsistent)
- meta_window_actor_thaw (self);
-
- if (!meta_window_actor_effect_in_progress (self))
- meta_window_actor_after_effects (self);
-}
-
-void
-meta_window_actor_queue_destroy (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
- MetaWindowType window_type = meta_window_get_window_type (window);
-
- meta_window_set_compositor_private (window, NULL);
-
- META_WINDOW_ACTOR_GET_CLASS (self)->queue_destroy (self);
-
- if (window_type == META_WINDOW_DROPDOWN_MENU ||
- window_type == META_WINDOW_POPUP_MENU ||
- window_type == META_WINDOW_TOOLTIP ||
- window_type == META_WINDOW_NOTIFICATION ||
- window_type == META_WINDOW_COMBO ||
- window_type == META_WINDOW_DND ||
- window_type == META_WINDOW_OVERRIDE_OTHER)
- {
- /*
- * No effects, just kill it.
- */
- clutter_actor_destroy (CLUTTER_ACTOR (self));
- return;
- }
-
- priv->needs_destroy = TRUE;
-
- if (!meta_window_actor_effect_in_progress (self))
- clutter_actor_destroy (CLUTTER_ACTOR (self));
-}
-
-MetaWindowActorChanges
-meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
- gboolean did_placement)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaRectangle window_rect;
- ClutterActor *actor = CLUTTER_ACTOR (self);
- MetaWindowActorChanges changes = 0;
-
- meta_window_get_buffer_rect (priv->window, &window_rect);
-
- /* When running as a Wayland compositor we catch size changes when new
- * buffers are attached */
- if (META_IS_SURFACE_ACTOR_X11 (priv->surface))
- meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface),
- window_rect.width, window_rect.height);
-
- /* Normally we want freezing a window to also freeze its position; this allows
- * windows to atomically move and resize together, either under app control,
- * or because the user is resizing from the left/top. But on initial placement
- * we need to assign a position, since immediately after the window
- * is shown, the map effect will go into effect and prevent further geometry
- * updates.
- */
- if (meta_window_actor_is_frozen (self) && !did_placement)
- return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
-
- if (clutter_actor_has_allocation (actor))
- {
- ClutterActorBox box;
- float old_x, old_y;
- float old_width, old_height;
-
- clutter_actor_get_allocation_box (actor, &box);
-
- old_x = box.x1;
- old_y = box.y1;
- old_width = box.x2 - box.x1;
- old_height = box.y2 - box.y1;
-
- if (old_x != window_rect.x || old_y != window_rect.y)
- changes |= META_WINDOW_ACTOR_CHANGE_POSITION;
-
- if (old_width != window_rect.width || old_height != window_rect.height)
- changes |= META_WINDOW_ACTOR_CHANGE_SIZE;
- }
- else
- {
- changes = META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
- }
-
- if (changes & META_WINDOW_ACTOR_CHANGE_POSITION)
- clutter_actor_set_position (actor, window_rect.x, window_rect.y);
-
- if (changes & META_WINDOW_ACTOR_CHANGE_SIZE)
- clutter_actor_set_size (actor, window_rect.width, window_rect.height);
-
- return changes;
-}
-
-void
-meta_window_actor_show (MetaWindowActor *self,
- MetaCompEffect effect)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
- MetaPluginEffect event;
-
- g_return_if_fail (!priv->visible);
-
- priv->visible = TRUE;
-
- switch (effect)
- {
- case META_COMP_EFFECT_CREATE:
- event = META_PLUGIN_MAP;
- break;
- case META_COMP_EFFECT_UNMINIMIZE:
- event = META_PLUGIN_UNMINIMIZE;
- break;
- case META_COMP_EFFECT_NONE:
- event = META_PLUGIN_NONE;
- break;
- default:
- g_assert_not_reached();
- }
-
- if (event == META_PLUGIN_MAP)
- meta_window_actor_sync_actor_geometry (self, TRUE);
-
- if (meta_compositor_is_switching_workspace (compositor) ||
- !start_simple_effect (self, event))
- {
- clutter_actor_show (CLUTTER_ACTOR (self));
- }
-}
-
-void
-meta_window_actor_hide (MetaWindowActor *self,
- MetaCompEffect effect)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
- MetaPluginEffect event;
-
- g_return_if_fail (priv->visible);
-
- priv->visible = FALSE;
-
- /* If a plugin is animating a workspace transition, we have to
- * hold off on hiding the window, and do it after the workspace
- * switch completes
- */
- if (meta_compositor_is_switching_workspace (compositor))
- return;
-
- switch (effect)
- {
- case META_COMP_EFFECT_DESTROY:
- event = META_PLUGIN_DESTROY;
- break;
- case META_COMP_EFFECT_MINIMIZE:
- event = META_PLUGIN_MINIMIZE;
- break;
- case META_COMP_EFFECT_NONE:
- event = META_PLUGIN_NONE;
- break;
- default:
- g_assert_not_reached();
- }
-
- if (!start_simple_effect (self, event))
- clutter_actor_hide (CLUTTER_ACTOR (self));
-}
-
-void
-meta_window_actor_size_change (MetaWindowActor *self,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
- MetaPluginManager *plugin_mgr =
- meta_compositor_get_plugin_manager (compositor);
-
- priv->size_change_in_progress++;
-
- if (!meta_plugin_manager_event_size_change (plugin_mgr, self,
- which_change, old_frame_rect, old_buffer_rect))
- priv->size_change_in_progress--;
-}
-
-#if 0
-/* Print out a region; useful for debugging */
-static void
-print_region (cairo_region_t *region)
-{
- int n_rects;
- int i;
-
- n_rects = cairo_region_num_rectangles (region);
- g_print ("[");
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (region, i, &rect);
- g_print ("+%d+%dx%dx%d ",
- rect.x, rect.y, rect.width, rect.height);
- }
- g_print ("]\n");
-}
-#endif
-
-#if 0
-/* Dump a region to a PNG file; useful for debugging */
-static void
-see_region (cairo_region_t *region,
- int width,
- int height,
- char *filename)
-{
- cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
- cairo_t *cr = cairo_create (surface);
-
- gdk_cairo_region (cr, region);
- cairo_fill (cr);
-
- cairo_surface_write_to_png (surface, filename);
- cairo_destroy (cr);
- cairo_surface_destroy (surface);
-}
-#endif
-
-
-static void
-meta_window_actor_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
-}
-
-static void
-meta_window_actor_reset_culling (MetaCullable *cullable)
-{
- meta_cullable_reset_culling_children (cullable);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_window_actor_cull_out;
- iface->reset_culling = meta_window_actor_reset_culling;
-}
-
-void
-meta_window_actor_sync_visibility (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- if (CLUTTER_ACTOR_IS_VISIBLE (self) != priv->visible)
- {
- if (priv->visible)
- clutter_actor_show (CLUTTER_ACTOR (self));
- else
- clutter_actor_hide (CLUTTER_ACTOR (self));
- }
-}
-
-void
-meta_window_actor_before_paint (MetaWindowActor *self,
- ClutterStageView *stage_view)
-{
- if (meta_window_actor_is_destroyed (self))
- return;
-
- META_WINDOW_ACTOR_GET_CLASS (self)->before_paint (self, stage_view);
-}
-
-void
-meta_window_actor_after_paint (MetaWindowActor *self,
- ClutterStageView *stage_view)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- META_WINDOW_ACTOR_GET_CLASS (self)->after_paint (self, stage_view);
-
- if (meta_window_actor_is_destroyed (self))
- return;
-
- if (priv->first_frame_state == DRAWING_FIRST_FRAME)
- {
- priv->first_frame_state = EMITTED_FIRST_FRAME;
- g_signal_emit (self, signals[FIRST_FRAME], 0);
- }
-}
-
-void
-meta_window_actor_frame_complete (MetaWindowActor *self,
- ClutterFrameInfo *frame_info,
- gint64 presentation_time)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->frame_complete (self,
- frame_info,
- presentation_time);
-}
-
-void
-meta_window_actor_update_opacity (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- if (priv->surface)
- clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
-}
-
-static void
-meta_window_actor_set_updates_frozen (MetaWindowActor *self,
- gboolean updates_frozen)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- updates_frozen = updates_frozen != FALSE;
-
- if (priv->updates_frozen != updates_frozen)
- {
- priv->updates_frozen = updates_frozen;
- if (updates_frozen)
- meta_window_actor_freeze (self);
- else
- meta_window_actor_thaw (self);
- }
-}
-
-void
-meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
-}
-
-MetaWindowActor *
-meta_window_actor_from_window (MetaWindow *window)
-{
- return META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
-}
-
-void
-meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
- int geometry_scale)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
- graphene_matrix_t child_transform;
-
- if (priv->geometry_scale == geometry_scale)
- return;
-
- priv->geometry_scale = geometry_scale;
-
- graphene_matrix_init_scale (&child_transform,
- geometry_scale,
- geometry_scale,
- 1);
- clutter_actor_set_child_transform (CLUTTER_ACTOR (window_actor),
- &child_transform);
-}
-
-int
-meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
-
- return priv->geometry_scale;
-}
-
-static void
-meta_window_actor_get_buffer_bounds (MetaScreenCastWindow *screen_cast_window,
- MetaRectangle *bounds)
-{
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
- MetaShapedTexture *stex;
- int buffer_scale;
-
- stex = meta_surface_actor_get_texture (priv->surface);
- buffer_scale = meta_shaped_texture_get_buffer_scale (stex);
- *bounds = (MetaRectangle) {
- .width = meta_shaped_texture_get_width (stex) * buffer_scale,
- .height = meta_shaped_texture_get_height (stex) * buffer_scale,
- };
-}
-
-static void
-meta_window_actor_transform_relative_position (MetaScreenCastWindow *screen_cast_window,
- double x,
- double y,
- double *x_out,
- double *y_out)
-
-{
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
- MetaRectangle bounds;
- graphene_point3d_t v1 = { 0.f, }, v2 = { 0.f, };
-
- meta_window_actor_get_buffer_bounds (screen_cast_window, &bounds);
-
- v1.x = CLAMP ((float) x,
- bounds.x,
- bounds.x + bounds.width);
- v1.y = CLAMP ((float) y,
- bounds.y,
- bounds.y + bounds.height);
-
- clutter_actor_apply_transform_to_point (CLUTTER_ACTOR (priv->surface),
- &v1,
- &v2);
-
- *x_out = (double) v2.x;
- *y_out = (double) v2.y;
-}
-
-static gboolean
-meta_window_actor_transform_cursor_position (MetaScreenCastWindow *screen_cast_window,
- MetaCursorSprite *cursor_sprite,
- graphene_point_t *cursor_position,
- float *out_cursor_scale,
- graphene_point_t *out_relative_cursor_position)
-{
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
- MetaWindow *window;
-
- window = priv->window;
- if (!meta_window_has_pointer (window))
- return FALSE;
-
- if (cursor_sprite &&
- meta_cursor_sprite_get_cogl_texture (cursor_sprite) &&
- out_cursor_scale)
- {
- MetaShapedTexture *stex;
- double texture_scale;
- float cursor_texture_scale;
-
- stex = meta_surface_actor_get_texture (priv->surface);
- texture_scale = meta_shaped_texture_get_buffer_scale (stex);
- cursor_texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
-
- *out_cursor_scale = texture_scale / cursor_texture_scale;
- }
-
- if (out_relative_cursor_position)
- {
- clutter_actor_transform_stage_point (CLUTTER_ACTOR (priv->surface),
- cursor_position->x,
- cursor_position->y,
- &out_relative_cursor_position->x,
- &out_relative_cursor_position->y);
- }
-
- return TRUE;
-}
-
-static void
-meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window,
- MetaRectangle *bounds,
- uint8_t *data)
-{
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
- cairo_surface_t *image;
- uint8_t *cr_data;
- int cr_stride;
- int cr_width;
- int cr_height;
- int bpp = 4;
-
- if (meta_window_actor_is_destroyed (window_actor))
- return;
-
- image = meta_window_actor_get_image (window_actor, bounds);
- cr_data = cairo_image_surface_get_data (image);
- cr_width = cairo_image_surface_get_width (image);
- cr_height = cairo_image_surface_get_height (image);
- cr_stride = cairo_image_surface_get_stride (image);
-
- if (cr_width == bounds->width && cr_height == bounds->height)
- {
- memcpy (data, cr_data, cr_height * cr_stride);
- }
- else
- {
- int width = MIN (bounds->width, cr_width);
- int height = MIN (bounds->height, cr_height);
- int stride = width * bpp;
- uint8_t *src, *dst;
-
- src = cr_data;
- dst = data;
-
- for (int i = 0; i < height; i++)
- {
- memcpy (dst, src, stride);
- if (width < bounds->width)
- memset (dst + stride, 0, (bounds->width * bpp) - stride);
-
- src += cr_stride;
- dst += bounds->width * bpp;
- }
-
- for (int i = height; i < bounds->height; i++)
- {
- memset (dst, 0, bounds->width * bpp);
- dst += bounds->width * bpp;
- }
- }
-
- cairo_surface_destroy (image);
-}
-
-static gboolean
-meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
- MetaRectangle *bounds,
- CoglFramebuffer *framebuffer)
-{
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
- ClutterActor *actor = CLUTTER_ACTOR (window_actor);
- ClutterPaintContext *paint_context;
- MetaRectangle scaled_clip;
- CoglColor clear_color;
- float resource_scale;
- float width, height;
- float x, y;
-
- if (meta_window_actor_is_destroyed (window_actor))
- return FALSE;
-
- clutter_actor_get_size (actor, &width, &height);
-
- if (width == 0 || height == 0)
- return FALSE;
-
- resource_scale = clutter_actor_get_resource_scale (actor);
-
- clutter_actor_inhibit_culling (actor);
-
- width = ceilf (width * resource_scale);
- height = ceilf (height * resource_scale);
-
- clutter_actor_get_position (actor, &x, &y);
-
- cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
- cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
- cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0);
- cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
-
- meta_rectangle_scale_double (bounds, resource_scale,
- META_ROUNDING_STRATEGY_GROW,
- &scaled_clip);
- meta_rectangle_intersect (&scaled_clip,
- &(MetaRectangle) {
- .width = width,
- .height = height,
- },
- &scaled_clip);
-
- cogl_framebuffer_push_rectangle_clip (framebuffer,
- scaled_clip.x, scaled_clip.y,
- scaled_clip.x + scaled_clip.width,
- scaled_clip.y + scaled_clip.height);
-
- cogl_framebuffer_push_matrix (framebuffer);
- cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
- cogl_framebuffer_translate (framebuffer, -x, -y, 0);
-
- paint_context =
- clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
- CLUTTER_PAINT_FLAG_NONE);
- clutter_actor_paint (actor, paint_context);
- clutter_paint_context_destroy (paint_context);
-
- cogl_framebuffer_pop_matrix (framebuffer);
- cogl_framebuffer_pop_clip (framebuffer);
-
- clutter_actor_uninhibit_culling (actor);
-
- return TRUE;
-}
-
-static gboolean
-meta_window_actor_has_damage (MetaScreenCastWindow *screen_cast_window)
-{
- return clutter_actor_has_damage (CLUTTER_ACTOR (screen_cast_window));
-}
-
-static void
-screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
-{
- iface->get_buffer_bounds = meta_window_actor_get_buffer_bounds;
- iface->transform_relative_position = meta_window_actor_transform_relative_position;
- iface->transform_cursor_position = meta_window_actor_transform_cursor_position;
- iface->capture_into = meta_window_actor_capture_into;
- iface->blit_to_framebuffer = meta_window_actor_blit_to_framebuffer;
- iface->has_damage = meta_window_actor_has_damage;
-}
-
-MetaWindowActor *
-meta_window_actor_from_actor (ClutterActor *actor)
-{
- if (!META_IS_SURFACE_ACTOR (actor))
- return NULL;
-
- do
- {
- actor = clutter_actor_get_parent (actor);
-
- if (META_IS_WINDOW_ACTOR (actor))
- return META_WINDOW_ACTOR (actor);
- }
- while (actor != NULL);
-
- return NULL;
-}
-
-void
-meta_window_actor_notify_damaged (MetaWindowActor *window_actor)
-{
- g_signal_emit (window_actor, signals[DAMAGED], 0);
-}
-
-/**
- * meta_window_actor_get_image:
- * @self: A #MetaWindowActor
- * @clip: (nullable): A clipping rectangle, to help prevent extra processing.
- * In the case that the clipping rectangle is partially or fully
- * outside the bounds of the actor, the rectangle will be clipped.
- *
- * Flattens the layers of @self into one ARGB32 image by alpha blending
- * the images, and returns the flattened image.
- *
- * Returns: (nullable) (transfer full): a new cairo surface to be freed with
- * cairo_surface_destroy().
- */
-cairo_surface_t *
-meta_window_actor_get_image (MetaWindowActor *self,
- MetaRectangle *clip)
-{
- MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
- ClutterActor *actor = CLUTTER_ACTOR (self);
- MetaBackend *backend = meta_get_backend ();
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- CoglContext *cogl_context =
- clutter_backend_get_cogl_context (clutter_backend);
- float resource_scale;
- float width, height;
- CoglTexture2D *texture;
- g_autoptr (GError) error = NULL;
- CoglOffscreen *offscreen;
- CoglFramebuffer *framebuffer;
- CoglColor clear_color;
- float x, y;
- MetaRectangle scaled_clip;
- ClutterPaintContext *paint_context;
- cairo_surface_t *surface = NULL;
-
- if (!priv->surface)
- return NULL;
-
- clutter_actor_inhibit_culling (actor);
-
- if (clutter_actor_get_n_children (actor) == 1)
- {
- MetaShapedTexture *stex;
- MetaRectangle *surface_clip = NULL;
-
- if (clip)
- {
-
- int geometry_scale;
-
- geometry_scale =
- meta_window_actor_get_geometry_scale (self);
-
- surface_clip = g_alloca (sizeof (MetaRectangle));
- surface_clip->x = clip->x / geometry_scale,
- surface_clip->y = clip->y / geometry_scale;
- surface_clip->width = clip->width / geometry_scale;
- surface_clip->height = clip->height / geometry_scale;
- }
-
- stex = meta_surface_actor_get_texture (priv->surface);
- surface = meta_shaped_texture_get_image (stex, surface_clip);
- goto out;
- }
-
- clutter_actor_get_size (actor, &width, &height);
-
- if (width == 0 || height == 0)
- goto out;
-
- resource_scale = clutter_actor_get_resource_scale (actor);
-
- width = ceilf (width * resource_scale);
- height = ceilf (height * resource_scale);
-
- texture = cogl_texture_2d_new_with_size (cogl_context, width, height);
- if (!texture)
- goto out;
-
- cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
- FALSE);
-
- offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
- framebuffer = COGL_FRAMEBUFFER (offscreen);
-
- cogl_object_unref (texture);
-
- if (!cogl_framebuffer_allocate (framebuffer, &error))
- {
- g_warning ("Failed to allocate framebuffer for screenshot: %s",
- error->message);
- g_object_unref (framebuffer);
- cogl_object_unref (texture);
- goto out;
- }
-
- cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
- clutter_actor_get_position (actor, &x, &y);
-
- cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
- cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0);
- cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
- cogl_framebuffer_translate (framebuffer, -x, -y, 0);
-
- paint_context =
- clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
- CLUTTER_PAINT_FLAG_NONE);
- clutter_actor_paint (actor, paint_context);
- clutter_paint_context_destroy (paint_context);
-
- if (clip)
- {
- meta_rectangle_scale_double (clip, resource_scale,
- META_ROUNDING_STRATEGY_GROW,
- &scaled_clip);
- meta_rectangle_intersect (&scaled_clip,
- &(MetaRectangle) {
- .width = width,
- .height = height,
- },
- &scaled_clip);
- }
- else
- {
- scaled_clip = (MetaRectangle) {
- .width = width,
- .height = height,
- };
- }
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- scaled_clip.width, scaled_clip.height);
- cogl_framebuffer_read_pixels (framebuffer,
- scaled_clip.x, scaled_clip.y,
- scaled_clip.width, scaled_clip.height,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- cairo_image_surface_get_data (surface));
-
- g_object_unref (framebuffer);
-
- cairo_surface_mark_dirty (surface);
-
-out:
- clutter_actor_uninhibit_culling (actor);
- return surface;
-}
diff --git a/src/compositor/meta-window-group-private.h b/src/compositor/meta-window-group-private.h
deleted file mode 100644
index c3467066b..000000000
--- a/src/compositor/meta-window-group-private.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_WINDOW_GROUP_PRIVATE_H
-#define META_WINDOW_GROUP_PRIVATE_H
-
-#include "meta/display.h"
-#include "meta/meta-window-group.h"
-
-/**
- * MetaWindowGroup:
- *
- * This class is a subclass of ClutterActor with special handling for
- * #MetaCullable when painting children. It uses code similar to
- * meta_cullable_cull_out_children(), but also has additional special
- * cases for the undirected window, and similar.
- */
-
-
-typedef struct _MetaWindowGroupPrivate MetaWindowGroupPrivate;
-
-ClutterActor *meta_window_group_new (MetaDisplay *display);
-
-#endif /* META_WINDOW_GROUP_PRIVATE_H */
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
deleted file mode 100644
index d526805fe..000000000
--- a/src/compositor/meta-window-group.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#include "config.h"
-
-#include <gdk/gdk.h>
-#include <math.h>
-
-#include "compositor/clutter-utils.h"
-#include "compositor/compositor-private.h"
-#include "compositor/meta-cullable.h"
-#include "compositor/meta-window-actor-private.h"
-#include "compositor/meta-window-group-private.h"
-#include "core/display-private.h"
-#include "core/window-private.h"
-
-struct _MetaWindowGroupClass
-{
- ClutterActorClass parent_class;
-};
-
-struct _MetaWindowGroup
-{
- ClutterActor parent;
-
- MetaDisplay *display;
-};
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
-
-static void
-meta_window_group_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
-}
-
-static void
-meta_window_group_reset_culling (MetaCullable *cullable)
-{
- meta_cullable_reset_culling_children (cullable);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_window_group_cull_out;
- iface->reset_culling = meta_window_group_reset_culling;
-}
-
-static void
-meta_window_group_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context)
-{
- MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
- ClutterActorClass *parent_actor_class =
- CLUTTER_ACTOR_CLASS (meta_window_group_parent_class);
- ClutterActor *stage = clutter_actor_get_stage (actor);
- const cairo_region_t *redraw_clip;
- cairo_region_t *clip_region;
- cairo_region_t *unobscured_region;
- cairo_rectangle_int_t visible_rect;
- int paint_x_origin, paint_y_origin;
- int screen_width, screen_height;
-
- redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
- if (!redraw_clip)
- {
- parent_actor_class->paint (actor, paint_context);
- return;
- }
-
- meta_display_get_size (window_group->display, &screen_width, &screen_height);
-
- /* Normally we expect an actor to be drawn at it's position on the screen.
- * However, if we're inside the paint of a ClutterClone, that won't be the
- * case and we need to compensate. We look at the position of the window
- * group under the current model-view matrix and the position of the actor.
- * If they are both simply integer translations, then we can compensate
- * easily, otherwise we give up.
- *
- * Possible cleanup: work entirely in paint space - we can compute the
- * combination of the model-view matrix with the local matrix for each child
- * actor and get a total transformation for that actor for how we are
- * painting currently, and never worry about how actors are positioned
- * on the stage.
- */
- if (clutter_actor_is_in_clone_paint (actor))
- {
- CoglFramebuffer *fb;
-
- fb = clutter_paint_context_get_framebuffer (paint_context);
- if (!meta_actor_painting_untransformed (fb,
- screen_width,
- screen_height,
- screen_width,
- screen_height,
- &paint_x_origin,
- &paint_y_origin) ||
- !meta_cullable_is_untransformed (META_CULLABLE (actor)))
- {
- parent_actor_class->paint (actor, paint_context);
- return;
- }
- }
- else
- {
- paint_x_origin = 0;
- paint_y_origin = 0;
- }
-
- visible_rect.x = visible_rect.y = 0;
- visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
- visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
-
- unobscured_region = cairo_region_create_rectangle (&visible_rect);
-
- /* Get the clipped redraw bounds so that we can avoid painting shadows on
- * windows that don't need to be painted in this frame. In the case of a
- * multihead setup with mismatched monitor sizes, we could intersect this
- * with an accurate union of the monitors to avoid painting shadows that are
- * visible only in the holes. */
- clip_region = cairo_region_copy (redraw_clip);
-
- cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
-
- meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
-
- cairo_region_destroy (unobscured_region);
- cairo_region_destroy (clip_region);
-
- parent_actor_class->paint (actor, paint_context);
-
- meta_cullable_reset_culling (META_CULLABLE (window_group));
-}
-
-/* Adapted from clutter_actor_update_default_paint_volume() */
-static gboolean
-meta_window_group_get_paint_volume (ClutterActor *self,
- ClutterPaintVolume *volume)
-{
- ClutterActorIter iter;
- ClutterActor *child;
-
- clutter_actor_iter_init (&iter, self);
- while (clutter_actor_iter_next (&iter, &child))
- {
- const ClutterPaintVolume *child_volume;
-
- if (!CLUTTER_ACTOR_IS_MAPPED (child))
- continue;
-
- child_volume = clutter_actor_get_transformed_paint_volume (child, self);
- if (child_volume == NULL)
- return FALSE;
-
- clutter_paint_volume_union (volume, child_volume);
- }
-
- return TRUE;
-}
-
-/* This is a workaround for Clutter's awful allocation tracking.
- * Without this, any time the window group changed size, which is
- * any time windows are dragged around, we'll do a full repaint
- * of the window group, which includes the background actor, meaning
- * a full-stage repaint.
- *
- * Since actors are allowed to paint outside their allocation, and
- * since child actors are allowed to be outside their parents, this
- * doesn't affect anything, but it means that we'll get much more
- * sane and consistent clipped repaints from Clutter. */
-static void
-meta_window_group_get_preferred_width (ClutterActor *actor,
- gfloat for_height,
- gfloat *min_width,
- gfloat *nat_width)
-{
- *min_width = 0;
- *nat_width = 0;
-}
-
-static void
-meta_window_group_get_preferred_height (ClutterActor *actor,
- gfloat for_width,
- gfloat *min_height,
- gfloat *nat_height)
-{
- *min_height = 0;
- *nat_height = 0;
-}
-
-static void
-meta_window_group_class_init (MetaWindowGroupClass *klass)
-{
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
- actor_class->paint = meta_window_group_paint;
- actor_class->get_paint_volume = meta_window_group_get_paint_volume;
- actor_class->get_preferred_width = meta_window_group_get_preferred_width;
- actor_class->get_preferred_height = meta_window_group_get_preferred_height;
-}
-
-static void
-meta_window_group_init (MetaWindowGroup *window_group)
-{
-}
-
-ClutterActor *
-meta_window_group_new (MetaDisplay *display)
-{
- MetaWindowGroup *window_group;
-
- window_group = g_object_new (META_TYPE_WINDOW_GROUP, NULL);
-
- window_group->display = display;
-
- return CLUTTER_ACTOR (window_group);
-}
diff --git a/src/compositor/meta-window-shape.c b/src/compositor/meta-window-shape.c
deleted file mode 100644
index 3bb6409c4..000000000
--- a/src/compositor/meta-window-shape.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * MetaWindowShape
- *
- * Extracted invariant window shape
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "meta/meta-window-shape.h"
-
-#include <string.h>
-
-#include "compositor/region-utils.h"
-
-struct _MetaWindowShape
-{
- guint ref_count;
-
- int top, right, bottom, left;
- int n_rectangles;
- cairo_rectangle_int_t *rectangles;
- guint hash;
-};
-
-MetaWindowShape *
-meta_window_shape_new (cairo_region_t *region)
-{
- MetaWindowShape *shape;
- MetaRegionIterator iter;
- cairo_rectangle_int_t extents;
- int max_yspan_y1 = 0;
- int max_yspan_y2 = 0;
- int max_xspan_x1 = -1;
- int max_xspan_x2 = -1;
- guint hash;
-
- shape = g_new0 (MetaWindowShape, 1);
- shape->ref_count = 1;
-
- cairo_region_get_extents (region, &extents);
-
- shape->n_rectangles = cairo_region_num_rectangles (region);
-
- if (shape->n_rectangles == 0)
- {
- shape->rectangles = NULL;
- shape->top = shape->right = shape->bottom = shape->left = 0;
- shape->hash = 0;
- return shape;
- }
-
- for (meta_region_iterator_init (&iter, region);
- !meta_region_iterator_at_end (&iter);
- meta_region_iterator_next (&iter))
- {
- int max_line_xspan_x1 = -1;
- int max_line_xspan_x2 = -1;
-
- if (iter.rectangle.width > max_line_xspan_x2 - max_line_xspan_x1)
- {
- max_line_xspan_x1 = iter.rectangle.x;
- max_line_xspan_x2 = iter.rectangle.x + iter.rectangle.width;
- }
-
- if (iter.line_end)
- {
- if (iter.rectangle.height > max_yspan_y2 - max_yspan_y1)
- {
- max_yspan_y1 = iter.rectangle.y;
- max_yspan_y2 = iter.rectangle.y + iter.rectangle.height;
- }
-
- if (max_xspan_x1 < 0) /* First line */
- {
- max_xspan_x1 = max_line_xspan_x1;
- max_xspan_x2 = max_line_xspan_x2;
- }
- else
- {
- max_xspan_x1 = MAX (max_xspan_x1, max_line_xspan_x1);
- max_xspan_x2 = MIN (max_xspan_x2, max_line_xspan_x2);
-
- if (max_xspan_x2 < max_xspan_x1)
- max_xspan_x2 = max_xspan_x1;
- }
- }
- }
-
-#if 0
- g_print ("xspan: %d -> %d, yspan: %d -> %d\n",
- max_xspan_x1, max_xspan_x2,
- max_yspan_y1, max_yspan_y2);
-#endif
-
- shape->top = max_yspan_y1 - extents.y;
- shape->right = extents.x + extents.width - max_xspan_x2;
- shape->bottom = extents.y + extents.height - max_yspan_y2;
- shape->left = max_xspan_x1 - extents.x;
-
- shape->rectangles = g_new (cairo_rectangle_int_t, shape->n_rectangles);
-
- hash = 0;
- for (meta_region_iterator_init (&iter, region);
- !meta_region_iterator_at_end (&iter);
- meta_region_iterator_next (&iter))
- {
- int x1, x2, y1, y2;
-
- x1 = iter.rectangle.x;
- x2 = iter.rectangle.x + iter.rectangle.width;
- y1 = iter.rectangle.y;
- y2 = iter.rectangle.y + iter.rectangle.height;
-
- if (x1 > max_xspan_x1)
- x1 -= MIN (x1, max_xspan_x2 - 1) - max_xspan_x1;
- if (x2 > max_xspan_x1)
- x2 -= MIN (x2, max_xspan_x2 - 1) - max_xspan_x1;
- if (y1 > max_yspan_y1)
- y1 -= MIN (y1, max_yspan_y2 - 1) - max_yspan_y1;
- if (y2 > max_yspan_y1)
- y2 -= MIN (y2, max_yspan_y2 - 1) - max_yspan_y1;
-
- shape->rectangles[iter.i].x = x1 - extents.x;
- shape->rectangles[iter.i].y = y1 - extents.y;
- shape->rectangles[iter.i].width = x2 - x1;
- shape->rectangles[iter.i].height = y2 - y1;
-
-#if 0
- g_print ("%d: +%d+%dx%dx%d => +%d+%dx%dx%d\n",
- iter.i, iter.rectangle.x, iter.rectangle.y, iter.rectangle.width, iter.rectangle.height,
- shape->rectangles[iter.i].x, shape->rectangles[iter.i].y,
- hape->rectangles[iter.i].width, shape->rectangles[iter.i].height);
-#endif
-
- hash = hash * 31 + x1 * 17 + x2 * 27 + y1 * 37 + y2 * 43;
- }
-
- shape->hash = hash;
-
-#if 0
- g_print ("%d %d %d %d: %#x\n\n", shape->top, shape->right, shape->bottom, shape->left, shape->hash);
-#endif
-
- return shape;
-}
-
-MetaWindowShape *
-meta_window_shape_ref (MetaWindowShape *shape)
-{
- shape->ref_count++;
-
- return shape;
-}
-
-void
-meta_window_shape_unref (MetaWindowShape *shape)
-{
- shape->ref_count--;
- if (shape->ref_count == 0)
- {
- g_free (shape->rectangles);
- g_free (shape);
- }
-}
-
-guint
-meta_window_shape_hash (MetaWindowShape *shape)
-{
- return shape->hash;
-}
-
-gboolean
-meta_window_shape_equal (MetaWindowShape *shape_a,
- MetaWindowShape *shape_b)
-{
- if (shape_a->n_rectangles != shape_b->n_rectangles)
- return FALSE;
-
- return memcmp (shape_a->rectangles, shape_b->rectangles,
- sizeof (cairo_rectangle_int_t) * shape_a->n_rectangles) == 0;
-}
-
-void
-meta_window_shape_get_borders (MetaWindowShape *shape,
- int *border_top,
- int *border_right,
- int *border_bottom,
- int *border_left)
-{
- if (border_top)
- *border_top = shape->top;
- if (border_right)
- *border_right = shape->right;
- if (border_bottom)
- *border_bottom = shape->bottom;
- if (border_left)
- *border_left = shape->left;
-}
-
-/**
- * meta_window_shape_to_region:
- * @shape: a #MetaWindowShape
- * @center_width: size of the central region horizontally
- * @center_height: size of the central region vertically
- *
- * Converts the shape to to a cairo_region_t using the given width
- * and height for the central scaled region.
- *
- * Return value: a newly created region
- */
-cairo_region_t *
-meta_window_shape_to_region (MetaWindowShape *shape,
- int center_width,
- int center_height)
-{
- cairo_region_t *region;
- int i;
-
- region = cairo_region_create ();
-
- for (i = 0; i < shape->n_rectangles; i++)
- {
- cairo_rectangle_int_t rect = shape->rectangles[i];
-
- if (rect.x <= shape->left && rect.x + rect.width >= shape->left + 1)
- rect.width += center_width;
- else if (rect.x >= shape->left + 1)
- rect.x += center_width;
-
- if (rect.y <= shape->top && rect.y + rect.height >= shape->top + 1)
- rect.height += center_height;
- else if (rect.y >= shape->top + 1)
- rect.y += center_height;
-
- cairo_region_union_rectangle (region, &rect);
- }
-
- return region;
-}
-
-G_DEFINE_BOXED_TYPE (MetaWindowShape, meta_window_shape,
- meta_window_shape_ref, meta_window_shape_unref)
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
deleted file mode 100644
index c89c84121..000000000
--- a/src/compositor/plugins/default.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "meta/display.h"
-
-#include <glib/gi18n-lib.h>
-#include <gmodule.h>
-#include <string.h>
-
-#include "clutter/clutter.h"
-#include "meta/meta-backend.h"
-#include "meta/meta-background-actor.h"
-#include "meta/meta-background-content.h"
-#include "meta/meta-background-group.h"
-#include "meta/meta-monitor-manager.h"
-#include "meta/meta-plugin.h"
-#include "meta/util.h"
-#include "meta/window.h"
-
-#define DESTROY_TIMEOUT 100
-#define MINIMIZE_TIMEOUT 250
-#define MAP_TIMEOUT 250
-#define SWITCH_TIMEOUT 500
-
-#define ACTOR_DATA_KEY "MCCP-Default-actor-data"
-#define DISPLAY_TILE_PREVIEW_DATA_KEY "MCCP-Default-display-tile-preview-data"
-
-#define META_TYPE_DEFAULT_PLUGIN (meta_default_plugin_get_type ())
-#define META_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPlugin))
-#define META_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPluginClass))
-#define META_IS_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_DEFAULT_PLUGIN_TYPE))
-#define META_IS_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEFAULT_PLUGIN))
-#define META_DEFAULT_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPluginClass))
-
-typedef struct _MetaDefaultPlugin MetaDefaultPlugin;
-typedef struct _MetaDefaultPluginClass MetaDefaultPluginClass;
-typedef struct _MetaDefaultPluginPrivate MetaDefaultPluginPrivate;
-
-struct _MetaDefaultPlugin
-{
- MetaPlugin parent;
-
- MetaDefaultPluginPrivate *priv;
-};
-
-struct _MetaDefaultPluginClass
-{
- MetaPluginClass parent_class;
-};
-
-static GQuark actor_data_quark = 0;
-static GQuark display_tile_preview_data_quark = 0;
-
-static void start (MetaPlugin *plugin);
-static void minimize (MetaPlugin *plugin,
- MetaWindowActor *actor);
-static void map (MetaPlugin *plugin,
- MetaWindowActor *actor);
-static void destroy (MetaPlugin *plugin,
- MetaWindowActor *actor);
-
-static void switch_workspace (MetaPlugin *plugin,
- gint from,
- gint to,
- MetaMotionDirection direction);
-
-static void kill_window_effects (MetaPlugin *plugin,
- MetaWindowActor *actor);
-static void kill_switch_workspace (MetaPlugin *plugin);
-
-static void show_tile_preview (MetaPlugin *plugin,
- MetaWindow *window,
- MetaRectangle *tile_rect,
- int tile_monitor_number);
-static void hide_tile_preview (MetaPlugin *plugin);
-
-static void confirm_display_change (MetaPlugin *plugin);
-
-static const MetaPluginInfo * plugin_info (MetaPlugin *plugin);
-
-/*
- * Plugin private data that we store in the .plugin_private member.
- */
-struct _MetaDefaultPluginPrivate
-{
- /* Valid only when switch_workspace effect is in progress */
- ClutterTimeline *tml_switch_workspace1;
- ClutterTimeline *tml_switch_workspace2;
- ClutterActor *desktop1;
- ClutterActor *desktop2;
-
- ClutterActor *background_group;
-
- MetaPluginInfo info;
-};
-
-META_PLUGIN_DECLARE_WITH_CODE (MetaDefaultPlugin, meta_default_plugin,
- G_ADD_PRIVATE_DYNAMIC (MetaDefaultPlugin));
-
-/*
- * Per actor private data we attach to each actor.
- */
-typedef struct _ActorPrivate
-{
- ClutterActor *orig_parent;
-
- ClutterTimeline *tml_minimize;
- ClutterTimeline *tml_destroy;
- ClutterTimeline *tml_map;
-} ActorPrivate;
-
-/* callback data for when animations complete */
-typedef struct
-{
- ClutterActor *actor;
- MetaPlugin *plugin;
-} EffectCompleteData;
-
-
-typedef struct _DisplayTilePreview
-{
- ClutterActor *actor;
-
- GdkRGBA *preview_color;
-
- MetaRectangle tile_rect;
-} DisplayTilePreview;
-
-static void
-meta_default_plugin_dispose (GObject *object)
-{
- /* MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (object)->priv;
- */
- G_OBJECT_CLASS (meta_default_plugin_parent_class)->dispose (object);
-}
-
-static void
-meta_default_plugin_finalize (GObject *object)
-{
- G_OBJECT_CLASS (meta_default_plugin_parent_class)->finalize (object);
-}
-
-static void
-meta_default_plugin_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_default_plugin_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- MetaPluginClass *plugin_class = META_PLUGIN_CLASS (klass);
-
- gobject_class->finalize = meta_default_plugin_finalize;
- gobject_class->dispose = meta_default_plugin_dispose;
- gobject_class->set_property = meta_default_plugin_set_property;
- gobject_class->get_property = meta_default_plugin_get_property;
-
- plugin_class->start = start;
- plugin_class->map = map;
- plugin_class->minimize = minimize;
- plugin_class->destroy = destroy;
- plugin_class->switch_workspace = switch_workspace;
- plugin_class->show_tile_preview = show_tile_preview;
- plugin_class->hide_tile_preview = hide_tile_preview;
- plugin_class->plugin_info = plugin_info;
- plugin_class->kill_window_effects = kill_window_effects;
- plugin_class->kill_switch_workspace = kill_switch_workspace;
- plugin_class->confirm_display_change = confirm_display_change;
-}
-
-static void
-meta_default_plugin_init (MetaDefaultPlugin *self)
-{
- MetaDefaultPluginPrivate *priv;
-
- self->priv = priv = meta_default_plugin_get_instance_private (self);
-
- priv->info.name = "Default Effects";
- priv->info.version = "0.1";
- priv->info.author = "Intel Corp.";
- priv->info.license = "GPL";
- priv->info.description = "This is an example of a plugin implementation.";
-}
-
-/*
- * Actor private data accessor
- */
-static void
-free_actor_private (gpointer data)
-{
- if (G_LIKELY (data != NULL))
- g_free (data);
-}
-
-static ActorPrivate *
-get_actor_private (MetaWindowActor *actor)
-{
- ActorPrivate *priv = g_object_get_qdata (G_OBJECT (actor), actor_data_quark);
-
- if (G_UNLIKELY (actor_data_quark == 0))
- actor_data_quark = g_quark_from_static_string (ACTOR_DATA_KEY);
-
- if (G_UNLIKELY (!priv))
- {
- priv = g_new0 (ActorPrivate, 1);
-
- g_object_set_qdata_full (G_OBJECT (actor),
- actor_data_quark, priv,
- free_actor_private);
- }
-
- return priv;
-}
-
-static ClutterTimeline *
-actor_animate (ClutterActor *actor,
- ClutterAnimationMode mode,
- guint duration,
- const gchar *first_property,
- ...)
-{
- va_list args;
- ClutterTransition *transition;
-
- clutter_actor_save_easing_state (actor);
- clutter_actor_set_easing_mode (actor, mode);
- clutter_actor_set_easing_duration (actor, duration);
-
- va_start (args, first_property);
- g_object_set_valist (G_OBJECT (actor), first_property, args);
- va_end (args);
-
- transition = clutter_actor_get_transition (actor, first_property);
-
- clutter_actor_restore_easing_state (actor);
-
- return CLUTTER_TIMELINE (transition);
-}
-
-static void
-on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
-{
- MetaPlugin *plugin = META_PLUGIN (data);
- MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
- MetaDisplay *display = meta_plugin_get_display (plugin);
- GList *l = meta_get_window_actors (display);
-
- while (l)
- {
- ClutterActor *a = l->data;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (a);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- if (apriv->orig_parent)
- {
- g_object_ref (a);
- clutter_actor_remove_child (clutter_actor_get_parent (a), a);
- clutter_actor_add_child (apriv->orig_parent, a);
- g_object_unref (a);
- apriv->orig_parent = NULL;
- }
-
- l = l->next;
- }
-
- clutter_actor_destroy (priv->desktop1);
- clutter_actor_destroy (priv->desktop2);
-
- priv->tml_switch_workspace1 = NULL;
- priv->tml_switch_workspace2 = NULL;
- priv->desktop1 = NULL;
- priv->desktop2 = NULL;
-
- meta_plugin_switch_workspace_completed (plugin);
-}
-
-static void
-on_monitors_changed (MetaMonitorManager *monitor_manager,
- MetaPlugin *plugin)
-{
- MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
- MetaDisplay *display = meta_plugin_get_display (plugin);
-
- int i, n;
- GRand *rand = g_rand_new_with_seed (123456);
-
- clutter_actor_destroy_all_children (self->priv->background_group);
-
- n = meta_display_get_n_monitors (display);
- for (i = 0; i < n; i++)
- {
- MetaBackgroundContent *background_content;
- ClutterContent *content;
- MetaRectangle rect;
- ClutterActor *background_actor;
- MetaBackground *background;
- uint8_t red;
- uint8_t green;
- uint8_t blue;
- ClutterColor color;
-
- meta_display_get_monitor_geometry (display, i, &rect);
-
- background_actor = meta_background_actor_new (display, i);
- content = clutter_actor_get_content (background_actor);
- background_content = META_BACKGROUND_CONTENT (content);
-
- clutter_actor_set_position (background_actor, rect.x, rect.y);
- clutter_actor_set_size (background_actor, rect.width, rect.height);
-
- /* Don't use rand() here, mesa calls srand() internally when
- parsing the driconf XML, but it's nice if the colors are
- reproducible.
- */
-
- blue = g_rand_int_range (rand, 0, 255);
- green = g_rand_int_range (rand, 0, 255);
- red = g_rand_int_range (rand, 0, 255);
- clutter_color_init (&color, red, green, blue, 255);
-
- background = meta_background_new (display);
- meta_background_set_color (background, &color);
- meta_background_content_set_background (background_content, background);
- g_object_unref (background);
-
- meta_background_content_set_vignette (background_content, TRUE, 0.5, 0.5);
-
- clutter_actor_add_child (self->priv->background_group, background_actor);
- }
-
- g_rand_free (rand);
-}
-
-static void
-init_keymap (MetaDefaultPlugin *self)
-{
- g_autoptr (GError) error = NULL;
- g_autoptr (GDBusProxy) proxy = NULL;
- g_autoptr (GVariant) result = NULL;
- g_autoptr (GVariant) props = NULL;
- g_autofree char *x11_layout = NULL;
- g_autofree char *x11_options = NULL;
- g_autofree char *x11_variant = NULL;
-
- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.locale1",
- "/org/freedesktop/locale1",
- "org.freedesktop.DBus.Properties",
- NULL,
- &error);
- if (!proxy)
- {
- g_message ("Failed to acquire org.freedesktop.locale1 proxy: %s, "
- "probably running in CI",
- error->message);
- return;
- }
-
- result = g_dbus_proxy_call_sync (proxy,
- "GetAll",
- g_variant_new ("(s)",
- "org.freedesktop.locale1"),
- G_DBUS_CALL_FLAGS_NONE,
- 100,
- NULL,
- &error);
- if (!result)
- {
- g_warning ("Failed to retrieve locale properties: %s", error->message);
- return;
- }
-
- props = g_variant_get_child_value (result, 0);
- if (!props)
- {
- g_warning ("No locale properties found");
- return;
- }
-
- if (!g_variant_lookup (props, "X11Layout", "s", &x11_layout))
- x11_layout = g_strdup ("us");
-
- if (!g_variant_lookup (props, "X11Options", "s", &x11_options))
- x11_options = g_strdup ("");
-
- if (!g_variant_lookup (props, "X11Variant", "s", &x11_variant))
- x11_variant = g_strdup ("");
-
- meta_backend_set_keymap (meta_get_backend (),
- x11_layout, x11_variant, x11_options);
-}
-
-static void
-start (MetaPlugin *plugin)
-{
- MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
- MetaDisplay *display = meta_plugin_get_display (plugin);
- MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
-
- self->priv->background_group = meta_background_group_new ();
- clutter_actor_insert_child_below (meta_get_window_group_for_display (display),
- self->priv->background_group, NULL);
-
- g_signal_connect (monitor_manager, "monitors-changed",
- G_CALLBACK (on_monitors_changed), plugin);
-
- on_monitors_changed (monitor_manager, plugin);
-
- if (meta_is_wayland_compositor ())
- init_keymap (self);
-
- clutter_actor_show (meta_get_stage_for_display (display));
-}
-
-static void
-switch_workspace (MetaPlugin *plugin,
- gint from, gint to,
- MetaMotionDirection direction)
-{
- MetaDisplay *display;
- MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
- GList *l;
- ClutterActor *workspace0 = clutter_actor_new ();
- ClutterActor *workspace1 = clutter_actor_new ();
- ClutterActor *stage;
- int screen_width, screen_height;
-
- display = meta_plugin_get_display (plugin);
- stage = meta_get_stage_for_display (display);
-
- meta_display_get_size (display,
- &screen_width,
- &screen_height);
-
- clutter_actor_set_pivot_point (workspace1, 1.0, 1.0);
- clutter_actor_set_position (workspace1,
- screen_width,
- screen_height);
-
- clutter_actor_set_scale (workspace1, 0.0, 0.0);
-
- clutter_actor_add_child (stage, workspace1);
- clutter_actor_add_child (stage, workspace0);
-
- if (from == to)
- {
- meta_plugin_switch_workspace_completed (plugin);
- return;
- }
-
- l = g_list_last (meta_get_window_actors (display));
-
- while (l)
- {
- MetaWindowActor *window_actor = l->data;
- ActorPrivate *apriv = get_actor_private (window_actor);
- ClutterActor *actor = CLUTTER_ACTOR (window_actor);
- MetaWorkspace *workspace;
- gint win_workspace;
-
- workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor));
- win_workspace = meta_workspace_index (workspace);
-
- if (win_workspace == to || win_workspace == from)
- {
- ClutterActor *parent = win_workspace == to ? workspace1 : workspace0;
- apriv->orig_parent = clutter_actor_get_parent (actor);
-
- g_object_ref (actor);
- clutter_actor_remove_child (clutter_actor_get_parent (actor), actor);
- clutter_actor_add_child (parent, actor);
- clutter_actor_show (actor);
- clutter_actor_set_child_below_sibling (parent, actor, NULL);
- g_object_unref (actor);
- }
- else if (win_workspace < 0)
- {
- /* Sticky window */
- apriv->orig_parent = NULL;
- }
- else
- {
- /* Window on some other desktop */
- clutter_actor_hide (actor);
- apriv->orig_parent = NULL;
- }
-
- l = l->prev;
- }
-
- priv->desktop1 = workspace0;
- priv->desktop2 = workspace1;
-
- priv->tml_switch_workspace1 = actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
- SWITCH_TIMEOUT,
- "scale-x", 1.0,
- "scale-y", 1.0,
- NULL);
- g_signal_connect (priv->tml_switch_workspace1,
- "completed",
- G_CALLBACK (on_switch_workspace_effect_complete),
- plugin);
-
- priv->tml_switch_workspace2 = actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
- SWITCH_TIMEOUT,
- "scale-x", 0.0,
- "scale-y", 0.0,
- NULL);
-}
-
-
-/*
- * Minimize effect completion callback; this function restores actor state, and
- * calls the manager callback function.
- */
-static void
-on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
-{
- /*
- * Must reverse the effect of the effect; must hide it first to ensure
- * that the restoration will not be visible.
- */
- MetaPlugin *plugin = data->plugin;
- ActorPrivate *apriv;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
-
- apriv = get_actor_private (META_WINDOW_ACTOR (data->actor));
- apriv->tml_minimize = NULL;
-
- clutter_actor_hide (data->actor);
-
- /* FIXME - we shouldn't assume the original scale, it should be saved
- * at the start of the effect */
- clutter_actor_set_scale (data->actor, 1.0, 1.0);
-
- /* Now notify the manager that we are done with this effect */
- meta_plugin_minimize_completed (plugin, window_actor);
-
- g_free (data);
-}
-
-/*
- * Simple minimize handler: it applies a scale effect (which must be reversed on
- * completion).
- */
-static void
-minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
-{
- MetaWindowType type;
- MetaRectangle icon_geometry;
- MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
- ClutterTimeline *timeline = NULL;
- ClutterActor *actor = CLUTTER_ACTOR (window_actor);
-
-
- type = meta_window_get_window_type (meta_window);
-
- if (!meta_window_get_icon_geometry(meta_window, &icon_geometry))
- {
- icon_geometry.x = 0;
- icon_geometry.y = 0;
- }
-
- if (type == META_WINDOW_NORMAL)
- {
- timeline = actor_animate (actor,
- CLUTTER_EASE_IN_SINE,
- MINIMIZE_TIMEOUT,
- "scale-x", 0.0,
- "scale-y", 0.0,
- "x", (double)icon_geometry.x,
- "y", (double)icon_geometry.y,
- NULL);
- }
-
- if (timeline)
- {
- EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- apriv->tml_minimize = timeline;
- data->plugin = plugin;
- data->actor = actor;
- g_signal_connect (apriv->tml_minimize, "completed",
- G_CALLBACK (on_minimize_effect_complete),
- data);
- }
- else
- meta_plugin_minimize_completed (plugin, window_actor);
-}
-
-static void
-on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
-{
- /*
- * Must reverse the effect of the effect.
- */
- MetaPlugin *plugin = data->plugin;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- apriv->tml_map = NULL;
-
- /* Now notify the manager that we are done with this effect */
- meta_plugin_map_completed (plugin, window_actor);
-
- g_free (data);
-}
-
-/*
- * Simple map handler: it applies a scale effect which must be reversed on
- * completion).
- */
-static void
-map (MetaPlugin *plugin, MetaWindowActor *window_actor)
-{
- MetaWindowType type;
- ClutterActor *actor = CLUTTER_ACTOR (window_actor);
- MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
-
- type = meta_window_get_window_type (meta_window);
-
- if (type == META_WINDOW_NORMAL)
- {
- EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- clutter_actor_set_pivot_point (actor, 0.5, 0.5);
- clutter_actor_set_opacity (actor, 0);
- clutter_actor_set_scale (actor, 0.5, 0.5);
- clutter_actor_show (actor);
-
- apriv->tml_map = actor_animate (actor,
- CLUTTER_EASE_OUT_QUAD,
- MAP_TIMEOUT,
- "opacity", 255,
- "scale-x", 1.0,
- "scale-y", 1.0,
- NULL);
- data->actor = actor;
- data->plugin = plugin;
- g_signal_connect (apriv->tml_map, "completed",
- G_CALLBACK (on_map_effect_complete),
- data);
- }
- else
- meta_plugin_map_completed (plugin, window_actor);
-}
-
-/*
- * Destroy effect completion callback; this is a simple effect that requires no
- * further action than notifying the manager that the effect is completed.
- */
-static void
-on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
-{
- MetaPlugin *plugin = data->plugin;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- apriv->tml_destroy = NULL;
-
- meta_plugin_destroy_completed (plugin, window_actor);
-}
-
-/*
- * Simple TV-out like effect.
- */
-static void
-destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
-{
- MetaWindowType type;
- ClutterActor *actor = CLUTTER_ACTOR (window_actor);
- MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
- ClutterTimeline *timeline = NULL;
-
- type = meta_window_get_window_type (meta_window);
-
- if (type == META_WINDOW_NORMAL)
- {
- timeline = actor_animate (actor,
- CLUTTER_EASE_OUT_QUAD,
- DESTROY_TIMEOUT,
- "opacity", 0,
- "scale-x", 0.8,
- "scale-y", 0.8,
- NULL);
- }
-
- if (timeline)
- {
- EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- apriv->tml_destroy = timeline;
- data->plugin = plugin;
- data->actor = actor;
- g_signal_connect (apriv->tml_destroy, "completed",
- G_CALLBACK (on_destroy_effect_complete),
- data);
- }
- else
- meta_plugin_destroy_completed (plugin, window_actor);
-}
-
-/*
- * Tile preview private data accessor
- */
-static void
-free_display_tile_preview (DisplayTilePreview *preview)
-{
-
- if (G_LIKELY (preview != NULL)) {
- clutter_actor_destroy (preview->actor);
- g_free (preview);
- }
-}
-
-static void
-on_display_closing (MetaDisplay *display,
- DisplayTilePreview *preview)
-{
- free_display_tile_preview (preview);
-}
-
-static DisplayTilePreview *
-get_display_tile_preview (MetaDisplay *display)
-{
- DisplayTilePreview *preview;
-
- if (!display_tile_preview_data_quark)
- {
- display_tile_preview_data_quark =
- g_quark_from_static_string (DISPLAY_TILE_PREVIEW_DATA_KEY);
- }
-
- preview = g_object_get_qdata (G_OBJECT (display),
- display_tile_preview_data_quark);
- if (!preview)
- {
- preview = g_new0 (DisplayTilePreview, 1);
-
- preview->actor = clutter_actor_new ();
- clutter_actor_set_background_color (preview->actor, CLUTTER_COLOR_Blue);
- clutter_actor_set_opacity (preview->actor, 100);
-
- clutter_actor_add_child (meta_get_window_group_for_display (display), preview->actor);
- g_signal_connect (display,
- "closing",
- G_CALLBACK (on_display_closing),
- preview);
- g_object_set_qdata (G_OBJECT (display),
- display_tile_preview_data_quark,
- preview);
- }
-
- return preview;
-}
-
-static void
-show_tile_preview (MetaPlugin *plugin,
- MetaWindow *window,
- MetaRectangle *tile_rect,
- int tile_monitor_number)
-{
- MetaDisplay *display = meta_plugin_get_display (plugin);
- DisplayTilePreview *preview = get_display_tile_preview (display);
- ClutterActor *window_actor;
-
- if (clutter_actor_is_visible (preview->actor)
- && preview->tile_rect.x == tile_rect->x
- && preview->tile_rect.y == tile_rect->y
- && preview->tile_rect.width == tile_rect->width
- && preview->tile_rect.height == tile_rect->height)
- return; /* nothing to do */
-
- clutter_actor_set_position (preview->actor, tile_rect->x, tile_rect->y);
- clutter_actor_set_size (preview->actor, tile_rect->width, tile_rect->height);
-
- clutter_actor_show (preview->actor);
-
- window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
- clutter_actor_set_child_below_sibling (clutter_actor_get_parent (preview->actor),
- preview->actor,
- window_actor);
-
- preview->tile_rect = *tile_rect;
-}
-
-static void
-hide_tile_preview (MetaPlugin *plugin)
-{
- MetaDisplay *display = meta_plugin_get_display (plugin);
- DisplayTilePreview *preview = get_display_tile_preview (display);
-
- clutter_actor_hide (preview->actor);
-}
-
-static void
-finish_timeline (ClutterTimeline *timeline)
-{
- g_object_ref (timeline);
- clutter_timeline_stop (timeline);
- g_signal_emit_by_name (timeline, "completed", NULL);
- g_object_unref (timeline);
-}
-
-static void
-kill_switch_workspace (MetaPlugin *plugin)
-{
- MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
-
- if (priv->tml_switch_workspace1)
- {
- g_object_ref (priv->tml_switch_workspace1);
- clutter_timeline_stop (priv->tml_switch_workspace1);
- clutter_timeline_stop (priv->tml_switch_workspace2);
- g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL);
- g_object_unref (priv->tml_switch_workspace1);
- }
-}
-
-static void
-kill_window_effects (MetaPlugin *plugin,
- MetaWindowActor *window_actor)
-{
- ActorPrivate *apriv;
-
- apriv = get_actor_private (window_actor);
-
- if (apriv->tml_minimize)
- finish_timeline (apriv->tml_minimize);
-
- if (apriv->tml_map)
- finish_timeline (apriv->tml_map);
-
- if (apriv->tml_destroy)
- finish_timeline (apriv->tml_destroy);
-}
-
-static const MetaPluginInfo *
-plugin_info (MetaPlugin *plugin)
-{
- MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
-
- return &priv->info;
-}
-
-static void
-on_dialog_closed (GPid pid,
- gint status,
- gpointer user_data)
-{
- MetaPlugin *plugin = user_data;
- gboolean ok;
-
- ok = g_spawn_check_exit_status (status, NULL);
- meta_plugin_complete_display_change (plugin, ok);
-}
-
-static void
-confirm_display_change (MetaPlugin *plugin)
-{
- GPid pid;
-
- pid = meta_show_dialog ("--question",
- "Does the display look OK?",
- "20",
- NULL,
- "_Keep This Configuration",
- "_Restore Previous Configuration",
- "preferences-desktop-display",
- 0,
- NULL, NULL);
-
- g_child_watch_add (pid, on_dialog_closed, plugin);
-}
diff --git a/src/compositor/plugins/meson.build b/src/compositor/plugins/meson.build
deleted file mode 100644
index 9dd06814d..000000000
--- a/src/compositor/plugins/meson.build
+++ /dev/null
@@ -1,20 +0,0 @@
-default_plugin_c_args = [
- '-fPIC',
- '-DG_LOG_DOMAIN="mutter"',
- '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
-]
-
-default_plugin = shared_module('default',
- sources: ['default.c'],
- include_directories: mutter_includes,
- c_args: default_plugin_c_args,
- dependencies: [
- glib_dep,
- gtk3_dep,
- json_glib_dep,
- gsettings_desktop_schemas_dep,
- libmutter_clutter_dep,
- ],
- install_dir: join_paths(pkglibdir, 'plugins'),
- install: true,
-)
diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c
deleted file mode 100644
index ac4048a98..000000000
--- a/src/compositor/region-utils.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for region manipulation
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "backends/meta-monitor-transform.h"
-#include "compositor/region-utils.h"
-#include "core/boxes-private.h"
-
-#include <math.h>
-
-#define META_REGION_MAX_STACK_RECTS 256
-
-#define META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED(n_rects, rects) \
- g_autofree cairo_rectangle_int_t *G_PASTE(__n, __LINE__) = NULL; \
- if (n_rects < META_REGION_MAX_STACK_RECTS) \
- rects = g_newa (cairo_rectangle_int_t, n_rects); \
- else \
- rects = G_PASTE(__n, __LINE__) = g_new (cairo_rectangle_int_t, n_rects);
-
-/* MetaRegionBuilder */
-
-/* Various algorithms in this file require unioning together a set of rectangles
- * that are unsorted or overlap; unioning such a set of rectangles 1-by-1
- * using cairo_region_union_rectangle() produces O(N^2) behavior (if the union
- * adds or removes rectangles in the middle of the region, then it has to
- * move all the rectangles after that.) To avoid this behavior, MetaRegionBuilder
- * creates regions for small groups of rectangles and merges them together in
- * a binary tree.
- *
- * Possible improvement: From a glance at the code, accumulating all the rectangles
- * into a flat array and then calling the (not usefully documented)
- * cairo_region_create_rectangles() would have the same behavior and would be
- * simpler and a bit more efficient.
- */
-
-/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
- * But using 8 may be more robust to systems with slow malloc(). */
-#define MAX_CHUNK_RECTANGLES 8
-
-void
-meta_region_builder_init (MetaRegionBuilder *builder)
-{
- int i;
- for (i = 0; i < META_REGION_BUILDER_MAX_LEVELS; i++)
- builder->levels[i] = NULL;
- builder->n_levels = 1;
-}
-
-void
-meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
- int x,
- int y,
- int width,
- int height)
-{
- cairo_rectangle_int_t rect;
- int i;
-
- if (builder->levels[0] == NULL)
- builder->levels[0] = cairo_region_create ();
-
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
-
- cairo_region_union_rectangle (builder->levels[0], &rect);
- if (cairo_region_num_rectangles (builder->levels[0]) >= MAX_CHUNK_RECTANGLES)
- {
- for (i = 1; i < builder->n_levels + 1; i++)
- {
- if (builder->levels[i] == NULL)
- {
- if (i < META_REGION_BUILDER_MAX_LEVELS)
- {
- builder->levels[i] = builder->levels[i - 1];
- builder->levels[i - 1] = NULL;
- if (i == builder->n_levels)
- builder->n_levels++;
- }
-
- break;
- }
- else
- {
- cairo_region_union (builder->levels[i], builder->levels[i - 1]);
- cairo_region_destroy (builder->levels[i - 1]);
- builder->levels[i - 1] = NULL;
- }
- }
- }
-}
-
-cairo_region_t *
-meta_region_builder_finish (MetaRegionBuilder *builder)
-{
- cairo_region_t *result = NULL;
- int i;
-
- for (i = 0; i < builder->n_levels; i++)
- {
- if (builder->levels[i])
- {
- if (result == NULL)
- result = builder->levels[i];
- else
- {
- cairo_region_union(result, builder->levels[i]);
- cairo_region_destroy (builder->levels[i]);
- }
- }
- }
-
- if (result == NULL)
- result = cairo_region_create ();
-
- return result;
-}
-
-
-/* MetaRegionIterator */
-
-void
-meta_region_iterator_init (MetaRegionIterator *iter,
- cairo_region_t *region)
-{
- iter->region = region;
- iter->i = 0;
- iter->n_rectangles = cairo_region_num_rectangles (region);
- iter->line_start = TRUE;
-
- if (iter->n_rectangles > 1)
- {
- cairo_region_get_rectangle (region, 0, &iter->rectangle);
- cairo_region_get_rectangle (region, 1, &iter->next_rectangle);
-
- iter->line_end = iter->next_rectangle.y != iter->rectangle.y;
- }
- else if (iter->n_rectangles > 0)
- {
- cairo_region_get_rectangle (region, 0, &iter->rectangle);
- iter->line_end = TRUE;
- }
-}
-
-gboolean
-meta_region_iterator_at_end (MetaRegionIterator *iter)
-{
- return iter->i >= iter->n_rectangles;
-}
-
-void
-meta_region_iterator_next (MetaRegionIterator *iter)
-{
- iter->i++;
- iter->rectangle = iter->next_rectangle;
- iter->line_start = iter->line_end;
-
- if (iter->i + 1 < iter->n_rectangles)
- {
- cairo_region_get_rectangle (iter->region, iter->i + 1, &iter->next_rectangle);
- iter->line_end = iter->next_rectangle.y != iter->rectangle.y;
- }
- else
- {
- iter->line_end = TRUE;
- }
-}
-
-cairo_region_t *
-meta_region_scale_double (cairo_region_t *region,
- double scale,
- MetaRoundingStrategy rounding_strategy)
-{
- int n_rects, i;
- cairo_rectangle_int_t *rects;
- cairo_region_t *scaled_region;
-
- g_return_val_if_fail (scale > 0.0, NULL);
-
- if (G_APPROX_VALUE (scale, 1.f, FLT_EPSILON))
- return cairo_region_copy (region);
-
- n_rects = cairo_region_num_rectangles (region);
- META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects);
- for (i = 0; i < n_rects; i++)
- {
- cairo_region_get_rectangle (region, i, &rects[i]);
-
- meta_rectangle_scale_double (&rects[i], scale, rounding_strategy,
- &rects[i]);
- }
-
- scaled_region = cairo_region_create_rectangles (rects, n_rects);
-
- return scaled_region;
-}
-
-cairo_region_t *
-meta_region_scale (cairo_region_t *region, int scale)
-{
- int n_rects, i;
- cairo_rectangle_int_t *rects;
- cairo_region_t *scaled_region;
-
- if (scale == 1)
- return cairo_region_copy (region);
-
- n_rects = cairo_region_num_rectangles (region);
- META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects);
- for (i = 0; i < n_rects; i++)
- {
- cairo_region_get_rectangle (region, i, &rects[i]);
- rects[i].x *= scale;
- rects[i].y *= scale;
- rects[i].width *= scale;
- rects[i].height *= scale;
- }
-
- scaled_region = cairo_region_create_rectangles (rects, n_rects);
-
- return scaled_region;
-}
-
-static void
-add_expanded_rect (MetaRegionBuilder *builder,
- int x,
- int y,
- int width,
- int height,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- if (flip)
- meta_region_builder_add_rectangle (builder,
- y - y_amount, x - x_amount,
- height + 2 * y_amount, width + 2 * x_amount);
- else
- meta_region_builder_add_rectangle (builder,
- x - x_amount, y - y_amount,
- width + 2 * x_amount, height + 2 * y_amount);
-}
-
-static cairo_region_t *
-expand_region (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- MetaRegionBuilder builder;
- int n;
- int i;
-
- meta_region_builder_init (&builder);
-
- n = cairo_region_num_rectangles (region);
- for (i = 0; i < n; i++)
- {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (region, i, &rect);
- add_expanded_rect (&builder,
- rect.x, rect.y, rect.width, rect.height,
- x_amount, y_amount, flip);
- }
-
- return meta_region_builder_finish (&builder);
-}
-
-/* This computes a (clipped version) of the inverse of the region
- * and expands it by the given amount */
-static cairo_region_t *
-expand_region_inverse (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- MetaRegionBuilder builder;
- MetaRegionIterator iter;
- cairo_rectangle_int_t extents;
-
- int last_x;
-
- meta_region_builder_init (&builder);
-
- cairo_region_get_extents (region, &extents);
- add_expanded_rect (&builder,
- extents.x, extents.y - 1, extents.width, 1,
- x_amount, y_amount, flip);
- add_expanded_rect (&builder,
- extents.x - 1, extents.y, 1, extents.height,
- x_amount, y_amount, flip);
- add_expanded_rect (&builder,
- extents.x + extents.width, extents.y, 1, extents.height,
- x_amount, y_amount, flip);
- add_expanded_rect (&builder,
- extents.x, extents.y + extents.height, extents.width, 1,
- x_amount, y_amount, flip);
-
- last_x = extents.x;
- for (meta_region_iterator_init (&iter, region);
- !meta_region_iterator_at_end (&iter);
- meta_region_iterator_next (&iter))
- {
- if (iter.rectangle.x > last_x)
- add_expanded_rect (&builder,
- last_x, iter.rectangle.y,
- iter.rectangle.x - last_x, iter.rectangle.height,
- x_amount, y_amount, flip);
-
- if (iter.line_end)
- {
- if (extents.x + extents.width > iter.rectangle.x + iter.rectangle.width)
- add_expanded_rect (&builder,
- iter.rectangle.x + iter.rectangle.width, iter.rectangle.y,
- (extents.x + extents.width) - (iter.rectangle.x + iter.rectangle.width), iter.rectangle.height,
- x_amount, y_amount, flip);
- last_x = extents.x;
- }
- else
- last_x = iter.rectangle.x + iter.rectangle.width;
- }
-
- return meta_region_builder_finish (&builder);
-}
-
-/**
- * meta_make_border_region:
- * @region: a #cairo_region_t
- * @x_amount: distance from the border to extend horizontally
- * @y_amount: distance from the border to extend vertically
- * @flip: if true, the result is computed with x and y interchanged
- *
- * Computes the "border region" of a given region, which is roughly
- * speaking the set of points near the boundary of the region. If we
- * define the operation of growing a region as computing the set of
- * points within a given manhattan distance of the region, then the
- * border is 'grow(region) intersect grow(inverse(region))'.
- *
- * If we create an image by filling the region with a solid color,
- * the border is the region affected by blurring the region.
- *
- * Return value: a new region which is the border of the given region
- */
-cairo_region_t *
-meta_make_border_region (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- cairo_region_t *border_region;
- cairo_region_t *inverse_region;
-
- border_region = expand_region (region, x_amount, y_amount, flip);
- inverse_region = expand_region_inverse (region, x_amount, y_amount, flip);
- cairo_region_intersect (border_region, inverse_region);
- cairo_region_destroy (inverse_region);
-
- return border_region;
-}
-
-cairo_region_t *
-meta_region_transform (const cairo_region_t *region,
- MetaMonitorTransform transform,
- int width,
- int height)
-{
- int n_rects, i;
- cairo_rectangle_int_t *rects;
- cairo_region_t *transformed_region;
-
- if (transform == META_MONITOR_TRANSFORM_NORMAL)
- return cairo_region_copy (region);
-
- n_rects = cairo_region_num_rectangles (region);
- META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects);
- for (i = 0; i < n_rects; i++)
- {
- cairo_region_get_rectangle (region, i, &rects[i]);
-
- meta_rectangle_transform (&rects[i],
- transform,
- width,
- height,
- &rects[i]);
- }
-
- transformed_region = cairo_region_create_rectangles (rects, n_rects);
-
- return transformed_region;
-}
-
-cairo_region_t *
-meta_region_crop_and_scale (cairo_region_t *region,
- graphene_rect_t *src_rect,
- int dst_width,
- int dst_height)
-{
- int n_rects, i;
- cairo_rectangle_int_t *rects;
- cairo_region_t *viewport_region;
-
- if (G_APPROX_VALUE (src_rect->size.width, dst_width, FLT_EPSILON) &&
- G_APPROX_VALUE (src_rect->size.height, dst_height, FLT_EPSILON) &&
- G_APPROX_VALUE (roundf (src_rect->origin.x),
- src_rect->origin.x, FLT_EPSILON) &&
- G_APPROX_VALUE (roundf (src_rect->origin.y),
- src_rect->origin.y, FLT_EPSILON))
- {
- viewport_region = cairo_region_copy (region);
-
- if (!G_APPROX_VALUE (src_rect->origin.x, 0, FLT_EPSILON) ||
- !G_APPROX_VALUE (src_rect->origin.y, 0, FLT_EPSILON))
- {
- cairo_region_translate (viewport_region,
- (int) src_rect->origin.x,
- (int) src_rect->origin.y);
- }
-
- return viewport_region;
- }
-
- n_rects = cairo_region_num_rectangles (region);
- META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects);
- for (i = 0; i < n_rects; i++)
- {
- cairo_region_get_rectangle (region, i, &rects[i]);
-
- meta_rectangle_crop_and_scale (&rects[i],
- src_rect,
- dst_width,
- dst_height,
- &rects[i]);
- }
-
- viewport_region = cairo_region_create_rectangles (rects, n_rects);
-
- return viewport_region;
-}
diff --git a/src/compositor/region-utils.h b/src/compositor/region-utils.h
deleted file mode 100644
index 298c5540e..000000000
--- a/src/compositor/region-utils.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for region manipulation
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_REGION_UTILS_H__
-#define __META_REGION_UTILS_H__
-
-#include <cairo.h>
-#include <glib.h>
-
-#include "backends/meta-backend-types.h"
-#include "clutter/clutter.h"
-#include "core/boxes-private.h"
-
-/**
- * MetaRegionIterator:
- * @region: region being iterated
- * @rectangle: current rectangle
- * @line_start: whether the current rectangle starts a horizontal band
- * @line_end: whether the current rectangle ends a horizontal band
- *
- * cairo_region_t is a yx banded region; sometimes its useful to iterate through
- * such a region treating the start and end of each horizontal band in a distinct
- * fashion.
- *
- * Usage:
- *
- * MetaRegionIterator iter;
- * for (meta_region_iterator_init (&iter, region);
- * !meta_region_iterator_at_end (&iter);
- * meta_region_iterator_next (&iter))
- * {
- * [ Use iter.rectangle, iter.line_start, iter.line_end ]
- * }
- */
-typedef struct _MetaRegionIterator MetaRegionIterator;
-
-struct _MetaRegionIterator {
- cairo_region_t *region;
- cairo_rectangle_int_t rectangle;
- gboolean line_start;
- gboolean line_end;
- int i;
-
- /*< private >*/
- int n_rectangles;
- cairo_rectangle_int_t next_rectangle;
-};
-
-typedef struct _MetaRegionBuilder MetaRegionBuilder;
-
-#define META_REGION_BUILDER_MAX_LEVELS 16
-struct _MetaRegionBuilder {
- /* To merge regions in binary tree order, we need to keep track of
- * the regions that we've already merged together at different
- * levels of the tree. We fill in an array in the pattern:
- *
- * |a |
- * |b |a |
- * |c | |ab |
- * |d |c |ab |
- * |e | | |abcd|
- */
- cairo_region_t *levels[META_REGION_BUILDER_MAX_LEVELS];
- int n_levels;
-};
-
-void meta_region_builder_init (MetaRegionBuilder *builder);
-void meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
- int x,
- int y,
- int width,
- int height);
-cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder);
-
-void meta_region_iterator_init (MetaRegionIterator *iter,
- cairo_region_t *region);
-gboolean meta_region_iterator_at_end (MetaRegionIterator *iter);
-void meta_region_iterator_next (MetaRegionIterator *iter);
-
-cairo_region_t * meta_region_scale (cairo_region_t *region,
- int scale);
-
-cairo_region_t * meta_region_scale_double (cairo_region_t *region,
- double scale,
- MetaRoundingStrategy rounding_strategy);
-
-cairo_region_t * meta_make_border_region (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip);
-
-cairo_region_t * meta_region_transform (const cairo_region_t *region,
- MetaMonitorTransform transform,
- int width,
- int height);
-
-cairo_region_t * meta_region_crop_and_scale (cairo_region_t *region,
- graphene_rect_t *src_rect,
- int dst_width,
- int dst_height);
-
-#endif /* __META_REGION_UTILS_H__ */