Bug Summary

File:compositor/compositor-xrender.c
Warning:line 567, column 20
Access of the heap area at negative byte offset

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name compositor-xrender.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -I ./include -D CROMA_LIBEXECDIR="/usr/libexec" -D HOST_ALIAS="" -D CROMA_LOCALEDIR="/usr/share/locale" -D CROMA_PKGDATADIR="/usr/share/croma" -D CROMA_DATADIR="/usr/share" -D G_LOG_DOMAIN="croma" -D SN_API_NOT_YET_FROZEN=1 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -D _REENTRANT -D _REENTRANT -I /usr/include/startup-notification-1.0 -I /usr/include/libgtop-2.0 -D PIC -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-04-08-092045-30398-1 -x c compositor/compositor-xrender.c
1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3/*
4 * Copyright (C) 2007 Iain Holmes
5 * Based on xcompmgr - (c) 2003 Keith Packard
6 * xfwm4 - (c) 2005-2007 Olivier Fourdan
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#define _GNU_SOURCE
25#define _XOPEN_SOURCE700 500 /* for usleep() */
26
27#include <config.h>
28
29#ifdef HAVE_COMPOSITE_EXTENSIONS1
30
31#include <stdlib.h>
32#include <string.h>
33#include <math.h>
34#include <unistd.h>
35
36#include <cdk/cdk.h>
37#include <cdk/cdkx.h>
38#include <ctk/ctk.h>
39
40#include <cairo/cairo-xlib.h>
41
42#include "display.h"
43#include "../core/display-private.h"
44#include "screen.h"
45#include "frame.h"
46#include "errors.h"
47#include "window.h"
48#include "compositor-private.h"
49#include "compositor-xrender.h"
50#include "xprops.h"
51#include <X11/Xatom.h>
52#include <X11/extensions/shape.h>
53#include <X11/extensions/Xcomposite.h>
54#include <X11/extensions/Xdamage.h>
55#include <X11/extensions/Xfixes.h>
56#include <X11/extensions/Xrender.h>
57
58#ifdef HAVE_PRESENT
59#include <X11/extensions/Xpresent.h>
60#endif
61
62#define USE_IDLE_REPAINT1 1
63
64typedef enum _MetaCompWindowType
65{
66 META_COMP_WINDOW_NORMAL,
67 META_COMP_WINDOW_DND,
68 META_COMP_WINDOW_DESKTOP,
69 META_COMP_WINDOW_DOCK,
70 META_COMP_WINDOW_MENU,
71 META_COMP_WINDOW_DROP_DOWN_MENU,
72 META_COMP_WINDOW_TOOLTIP,
73} MetaCompWindowType;
74
75typedef enum _MetaShadowType
76{
77 META_SHADOW_SMALL,
78 META_SHADOW_MEDIUM,
79 META_SHADOW_LARGE,
80 LAST_SHADOW_TYPE
81} MetaShadowType;
82
83typedef struct _MetaCompositorXRender
84{
85 MetaCompositor compositor;
86
87 MetaDisplay *display;
88
89 Atom atom_x_root_pixmap;
90 Atom atom_x_set_root;
91 Atom atom_net_wm_window_opacity;
92 Atom atom_net_wm_window_type_dnd;
93
94 Atom atom_net_wm_window_type;
95 Atom atom_net_wm_window_type_desktop;
96 Atom atom_net_wm_window_type_dock;
97 Atom atom_net_wm_window_type_menu;
98 Atom atom_net_wm_window_type_dialog;
99 Atom atom_net_wm_window_type_normal;
100 Atom atom_net_wm_window_type_utility;
101 Atom atom_net_wm_window_type_splash;
102 Atom atom_net_wm_window_type_toolbar;
103 Atom atom_net_wm_window_type_dropdown_menu;
104 Atom atom_net_wm_window_type_tooltip;
105
106#ifdef USE_IDLE_REPAINT1
107 guint repaint_id;
108#endif
109 guint enabled : 1;
110 guint show_redraw : 1;
111 guint debug : 1;
112
113#ifdef HAVE_PRESENT
114 guint has_present : 1;
115 int present_major;
116#endif /* HAVE_PRESENT */
117} MetaCompositorXRender;
118
119typedef struct _conv
120{
121 int size;
122 double *data;
123} conv;
124
125typedef struct _shadow
126{
127 conv *gaussian_map;
128 guchar *shadow_corner;
129 guchar *shadow_top;
130} shadow;
131
132#define NUM_BUFFER2 2
133typedef struct _MetaCompScreen
134{
135 MetaScreen *screen;
136 GList *windows;
137 GHashTable *windows_by_xid;
138
139 MetaWindow *focus_window;
140
141 Window output;
142
143 gboolean have_shadows;
144 shadow *shadows[LAST_SHADOW_TYPE];
145
146 Picture root_picture;
147 Picture root_buffers[NUM_BUFFER2];
148 Pixmap root_pixmaps[NUM_BUFFER2];
149 int root_current;
150 Picture black_picture;
151 Picture trans_black_picture;
152 Picture root_tile;
153 XserverRegion all_damage;
154#ifdef HAVE_PRESENT
155 XserverRegion prev_damage;
156
157 XID present_eid;
158 gboolean use_present;
159 gboolean present_pending;
160#endif /* HAVE_PRESENT */
161
162 guint overlays;
163 gboolean compositor_active;
164 gboolean clip_changed;
165
166 GSList *dock_windows;
167} MetaCompScreen;
168
169typedef struct _MetaCompWindow
170{
171 MetaScreen *screen;
172 MetaWindow *window; /* May be NULL if this window isn't managed by Croma */
173 Window id;
174 XWindowAttributes attrs;
175
176 Pixmap back_pixmap;
177
178 /* When the window is shaded back_pixmap will be replaced with the pixmap
179 for the shaded window. This is a copy of the original unshaded window
180 so that we can still see what the window looked like when it is needed
181 for the _get_window_pixmap function */
182 Pixmap shaded_back_pixmap;
183
184 int mode;
185
186 gboolean damaged;
187 gboolean shaped;
188
189 XRectangle shape_bounds;
190
191 MetaCompWindowType type;
192
193 Damage damage;
194 Picture picture;
195 Picture alpha_pict;
196
197 gboolean needs_shadow;
198 MetaShadowType shadow_type;
199 Picture shadow_pict;
200
201 XserverRegion border_size;
202 XserverRegion extents;
203
204 Picture shadow;
205 int shadow_dx;
206 int shadow_dy;
207 int shadow_width;
208 int shadow_height;
209
210 guint opacity;
211
212 XserverRegion border_clip;
213
214 gboolean updates_frozen;
215 gboolean update_pending;
216} MetaCompWindow;
217
218#define OPAQUE0xffffffff 0xffffffff
219
220#define WINDOW_SOLID0 0
221#define WINDOW_ARGB1 1
222
223#define SHADOW_SMALL_RADIUS3.0 3.0
224#define SHADOW_MEDIUM_RADIUS6.0 6.0
225#define SHADOW_LARGE_RADIUS12.0 12.0
226
227#define SHADOW_SMALL_OFFSET_X(3.0 * -3 / 2) (SHADOW_SMALL_RADIUS3.0 * -3 / 2)
228#define SHADOW_SMALL_OFFSET_Y(3.0 * -3 / 2) (SHADOW_SMALL_RADIUS3.0 * -3 / 2)
229#define SHADOW_MEDIUM_OFFSET_X(6.0 * -3 / 2) (SHADOW_MEDIUM_RADIUS6.0 * -3 / 2)
230#define SHADOW_MEDIUM_OFFSET_Y(6.0 * -5 / 4) (SHADOW_MEDIUM_RADIUS6.0 * -5 / 4)
231#define SHADOW_LARGE_OFFSET_X-15 -15
232#define SHADOW_LARGE_OFFSET_Y-15 -15
233
234#define SHADOW_OPACITY0.66 0.66
235
236#define TRANS_OPACITY0.75 0.75
237
238#define DISPLAY_COMPOSITOR(display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
((MetaCompositorXRender *) meta_display_get_compositor (display))
239
240/* Gaussian stuff for creating the shadows */
241static double
242gaussian (double r,
243 double x,
244 double y)
245{
246 return ((1 / (sqrt (2 * G_PI3.1415926535897932384626433832795028841971693993751 * r))) *
247 exp ((- (x * x + y * y)) / (2 * r * r)));
248}
249
250static conv *
251make_gaussian_map (double r)
252{
253 conv *c;
254 int size, centre;
255 int x, y;
256 double t, g;
257
258 size = ((int) ceil ((r * 3)) + 1) & ~1;
259 centre = size / 2;
260 c = g_malloc (sizeof (conv) + size * size * sizeof (double));
261 c->size = size;
262 c->data = (double *) (c + 1);
263 t = 0.0;
264
265 for (y = 0; y < size; y++)
266 {
267 for (x = 0; x < size; x++)
268 {
269 g = gaussian (r, (double) (x - centre), (double) (y - centre));
270 t += g;
271 c->data[y * size + x] = g;
272 }
273 }
274
275 for (y = 0; y < size; y++)
276 {
277 for (x = 0; x < size; x++)
278 {
279 c->data[y * size + x] /= t;
280 }
281 }
282
283 return c;
284}
285
286static void
287dump_xserver_region (const char *location,
288 MetaDisplay *display,
289 XserverRegion region)
290{
291 MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
;
292 Display *xdisplay = meta_display_get_xdisplay (display);
293 int nrects;
294 XRectangle bounds;
295
296 if (!compositor->debug)
297 return;
298
299 if (region)
300 {
301 XRectangle *rects;
302
303 rects = XFixesFetchRegionAndBounds (xdisplay, region, &nrects, &bounds);
304 if (nrects > 0)
305 {
306 int i;
307 fprintf (stderrstderr, "%s (XSR): %d rects, bounds: %d,%d (%d,%d)\n",
308 location, nrects, bounds.x, bounds.y, bounds.width, bounds.height);
309 for (i = 1; i < nrects; i++)
310 fprintf (stderrstderr, "\t%d,%d (%d,%d)\n",
311 rects[i].x, rects[i].y, rects[i].width, rects[i].height);
312 }
313 else
314 fprintf (stderrstderr, "%s (XSR): empty\n", location);
315 XFree (rects);
316 }
317 else
318 fprintf (stderrstderr, "%s (XSR): null\n", location);
319}
320
321/*
322* A picture will help
323*
324* -center 0 width width+center
325* -center +-----+-------------------+-----+
326* | | | |
327* | | | |
328* 0 +-----+-------------------+-----+
329* | | | |
330* | | | |
331* | | | |
332* height +-----+-------------------+-----+
333* | | | |
334* height+ | | | |
335* center +-----+-------------------+-----+
336*/
337static guchar
338sum_gaussian (conv *map,
339 double opacity,
340 int x,
341 int y,
342 int width,
343 int height)
344{
345 double *g_line;
346 double v;
347 int fx, fy;
348 int fx_start, fx_end;
349 int fy_start, fy_end;
350 int g_size, centre;
351
352 g_line = map->data;
353 g_size = map->size;
354 centre = g_size / 2;
355 fx_start = centre - x;
356 if (fx_start
30.1
'fx_start' is >= 0
< 0)
31
Taking false branch
357 fx_start = 0;
358
359 fx_end = width + centre - x;
360 if (fx_end > g_size)
32
Assuming 'fx_end' is <= 'g_size'
33
Taking false branch
361 fx_end = g_size;
362
363 fy_start = centre - y;
364 if (fy_start
33.1
'fy_start' is >= 0
< 0)
34
Taking false branch
365 fy_start = 0;
366
367 fy_end = height + centre - y;
368 if (fy_end > g_size)
35
Assuming 'fy_end' is <= 'g_size'
36
Taking false branch
369 fy_end = g_size;
370
371 g_line = g_line + fy_start * g_size + fx_start;
372
373 v = 0.0;
374 for (fy = fy_start; fy < fy_end; fy++)
37
Assuming 'fy' is >= 'fy_end'
38
Loop condition is false. Execution continues on line 385
375 {
376 double *g_data;
377
378 g_data = g_line;
379 g_line += g_size;
380
381 for (fx = fx_start; fx < fx_end; fx++)
382 v += *g_data++;
383 }
384
385 if (v > 1.0)
39
Assuming the condition is false
40
Taking false branch
386 v = 1.0;
387
388 return ((guchar) (v * opacity * 255.0));
389}
390
391/* precompute shadow corners and sides to save time for large windows */
392static void
393presum_gaussian (shadow *shad)
394{
395 int centre;
396 int opacity, x, y;
397 int msize;
398 conv *map;
399
400 map = shad->gaussian_map;
401 msize = map->size;
402 centre = map->size / 2;
403
404 if (shad->shadow_corner)
405 g_free (shad->shadow_corner);
406 if (shad->shadow_top)
407 g_free (shad->shadow_top);
408
409 shad->shadow_corner = (guchar *)(g_malloc ((msize + 1) * (msize + 1) * 26));
410 shad->shadow_top = (guchar *) (g_malloc ((msize + 1) * 26));
411
412 for (x = 0; x <= msize; x++)
413 {
414
415 shad->shadow_top[25 * (msize + 1) + x] =
416 sum_gaussian (map, 1, x - centre, centre, msize * 2, msize * 2);
417 for (opacity = 0; opacity < 25; opacity++)
418 {
419 shad->shadow_top[opacity * (msize + 1) + x] =
420 shad->shadow_top[25 * (msize + 1) + x] * opacity / 25;
421 }
422
423 for (y = 0; y <= x; y++)
424 {
425 shad->shadow_corner[25 * (msize + 1) * (msize + 1)
426 + y * (msize + 1)
427 + x]
428 = sum_gaussian (map, 1, x - centre, y - centre,
429 msize * 2, msize * 2);
430
431 shad->shadow_corner[25 * (msize + 1) * (msize + 1)
432 + x * (msize + 1) + y] =
433 shad->shadow_corner[25 * (msize + 1) * (msize + 1)
434 + y * (msize + 1) + x];
435
436 for (opacity = 0; opacity < 25; opacity++)
437 {
438 shad->shadow_corner[opacity * (msize + 1) * (msize + 1)
439 + y * (msize + 1) + x]
440 = shad->shadow_corner[opacity * (msize + 1) * (msize + 1)
441 + x * (msize + 1) + y]
442 = shad->shadow_corner[25 * (msize + 1) * (msize + 1)
443 + y * (msize + 1) + x] * opacity / 25;
444 }
445 }
446 }
447}
448
449static void
450generate_shadows (MetaCompScreen *info)
451{
452 double radii[LAST_SHADOW_TYPE] = {SHADOW_SMALL_RADIUS3.0,
453 SHADOW_MEDIUM_RADIUS6.0,
454 SHADOW_LARGE_RADIUS12.0};
455 int i;
456
457 for (i = 0; i < LAST_SHADOW_TYPE; i++) {
458 shadow *shad = g_new0 (shadow, 1)((shadow *) g_malloc0_n ((1), sizeof (shadow)));
459
460 shad->gaussian_map = make_gaussian_map (radii[i]);
461 presum_gaussian (shad);
462
463 info->shadows[i] = shad;
464 }
465}
466
467static XImage *
468make_shadow (MetaDisplay *display,
469 MetaScreen *screen,
470 MetaShadowType shadow_type,
471 double opacity,
472 int width,
473 int height)
474{
475 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
476 Display *xdisplay = meta_display_get_xdisplay (display);
477 XImage *ximage;
478 guchar *data;
479 shadow *shad;
480 int msize;
481 int ylimit, xlimit;
482 int swidth, sheight;
483 int centre;
484 int x, y;
485 guchar d;
486 int x_diff;
487 int opacity_int = (int)(opacity * 25);
488 int screen_number = meta_screen_get_screen_number (screen);
489
490 if (info==NULL((void*)0))
24
Assuming 'info' is not equal to NULL
25
Taking false branch
491 {
492 return NULL((void*)0);
493 }
494
495 shad = info->shadows[shadow_type];
496 msize = shad->gaussian_map->size;
497 swidth = width + msize;
498 sheight = height + msize;
499 centre = msize / 2;
500
501 data = g_malloc (swidth * sheight * sizeof (guchar));
502
503 ximage = XCreateImage (xdisplay, DefaultVisual (xdisplay, screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
,
504 8, ZPixmap2, 0, (char *) data,
505 swidth, sheight, 8, swidth * sizeof (guchar));
506 if (!ximage)
26
Assuming 'ximage' is non-null
27
Taking false branch
507 {
508 g_free (data);
509 return NULL((void*)0);
510 }
511
512 /*
513 * Build the gaussian in sections
514 */
515
516 /*
517 * centre (fill the complete data array
518 */
519 if (msize > 0)
28
Assuming 'msize' is <= 0
29
Taking false branch
520 d = shad->shadow_top[opacity_int * (msize + 1) + msize];
521 else
522 d = sum_gaussian (shad->gaussian_map, opacity, centre,
30
Calling 'sum_gaussian'
41
Returning from 'sum_gaussian'
523 centre, width, height);
524 memset (data, d, sheight * swidth);
525
526 /*
527 * corners
528 */
529 ylimit = msize;
530 if (ylimit > sheight / 2)
42
Assuming the condition is true
43
Taking true branch
531 ylimit = (sheight + 1) / 2;
532
533 xlimit = msize;
534 if (xlimit > swidth / 2)
44
Assuming the condition is false
45
Taking false branch
535 xlimit = (swidth + 1) / 2;
536
537 for (y = 0; y < ylimit; y++)
46
Assuming 'y' is < 'ylimit'
47
Loop condition is true. Entering loop body
49
Assuming 'y' is >= 'ylimit'
50
Loop condition is false. Execution continues on line 556
538 {
539 for (x = 0; x
47.1
'x' is >= 'xlimit'
< xlimit; x++)
48
Loop condition is false. Execution continues on line 537
540 {
541
542 if (xlimit == msize && ylimit == msize)
543 d = shad->shadow_corner[opacity_int * (msize + 1) * (msize + 1) + y * (msize + 1) + x];
544 else
545 d = sum_gaussian (shad->gaussian_map, opacity, x - centre,
546 y - centre, width, height);
547
548 data[y * swidth + x] = d;
549 data[(sheight - y - 1) * swidth + x] = d;
550 data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
551 data[y * swidth + (swidth - x - 1)] = d;
552 }
553 }
554
555 /* top/bottom */
556 x_diff = swidth - (msize * 2);
557 if (x_diff > 0 && ylimit
51.1
'ylimit' is > 0
> 0)
51
Assuming 'x_diff' is > 0
52
Taking true branch
558 {
559 for (y = 0; y < ylimit; y++)
53
Loop condition is true. Entering loop body
560 {
561 if (ylimit
53.1
'ylimit' is not equal to 'msize'
== msize)
54
Taking false branch
562 d = shad->shadow_top[opacity_int * (msize + 1) + y];
563 else
564 d = sum_gaussian (shad->gaussian_map, opacity, centre,
565 y - centre, width, height);
566
567 memset (&data[y * swidth + msize], d, x_diff);
55
Access of the heap area at negative byte offset
568 memset (&data[(sheight - y - 1) * swidth + msize], d, x_diff);
569 }
570 }
571
572 /*
573 * sides
574 */
575 for (x = 0; x < xlimit; x++)
576 {
577 if (xlimit == msize)
578 d = shad->shadow_top[opacity_int * (msize + 1) + x];
579 else
580 d = sum_gaussian (shad->gaussian_map, opacity, x - centre,
581 centre, width, height);
582
583 for (y = msize; y < sheight - msize; y++)
584 {
585 data[y * swidth + x] = d;
586 data[y * swidth + (swidth - x - 1)] = d;
587 }
588 }
589
590 ximage->data = (char *) data;
591
592 return ximage;
593}
594
595double shadow_offsets_x[LAST_SHADOW_TYPE] = {SHADOW_SMALL_OFFSET_X(3.0 * -3 / 2),
596 SHADOW_MEDIUM_OFFSET_X(6.0 * -3 / 2),
597 SHADOW_LARGE_OFFSET_X-15};
598double shadow_offsets_y[LAST_SHADOW_TYPE] = {SHADOW_SMALL_OFFSET_Y(3.0 * -3 / 2),
599 SHADOW_MEDIUM_OFFSET_Y(6.0 * -5 / 4),
600 SHADOW_LARGE_OFFSET_Y-15};
601
602static XserverRegion
603cairo_region_to_xserver_region (Display *xdisplay,
604 cairo_region_t *region)
605{
606 int n_rects, i;
607 XRectangle *rects;
608 XserverRegion xregion;
609
610 n_rects = cairo_region_num_rectangles (region);
611 rects = g_new (XRectangle, n_rects)((XRectangle *) g_malloc_n ((n_rects), sizeof (XRectangle)));
612
613 for (i = 0; i < n_rects; i++)
614 {
615 cairo_rectangle_int_t rect;
616
617 cairo_region_get_rectangle (region, i, &rect);
618
619 rects[i].x = rect.x;
620 rects[i].y = rect.y;
621 rects[i].width = rect.width;
622 rects[i].height = rect.height;
623 }
624
625 xregion = XFixesCreateRegion (xdisplay, rects, n_rects);
626 g_free (rects);
627
628 return xregion;
629}
630
631static void
632shadow_picture_clip (Display *xdisplay,
633 Picture shadow_picture,
634 MetaCompWindow *cw,
635 MetaFrameBorders borders,
636 int width,
637 int height)
638{
639 int shadow_dx;
640 int shadow_dy;
641 cairo_region_t *visible_region;
642 XRectangle rect;
643 XserverRegion region1;
644 XserverRegion region2;
645
646 if (!cw->window)
647 return;
648
649 visible_region = meta_window_get_frame_bounds (cw->window);
650
651 if (visible_region == NULL((void*)0))
652 return;
653
654 shadow_dx = -1 * (int) shadow_offsets_x [cw->shadow_type] - borders.invisible.left;
655 shadow_dy = -1 * (int) shadow_offsets_y [cw->shadow_type] - borders.invisible.top;
656
657 rect.x = 0;
658 rect.y = 0;
659 rect.width = width;
660 rect.height = height;
661
662 region1 = XFixesCreateRegion (xdisplay, &rect, 1);
663 region2 = cairo_region_to_xserver_region (xdisplay, visible_region);
664
665 XFixesTranslateRegion (xdisplay, region2,
666 shadow_dx, shadow_dy);
667
668 XFixesSubtractRegion (xdisplay, region1, region1, region2);
669 XFixesSetPictureClipRegion (xdisplay, shadow_picture, 0, 0, region1);
670
671 XFixesDestroyRegion (xdisplay, region1);
672 XFixesDestroyRegion (xdisplay, region2);
673}
674
675static Picture
676shadow_picture (MetaDisplay *display,
677 MetaScreen *screen,
678 MetaCompWindow *cw,
679 double opacity,
680 MetaFrameBorders borders,
681 int width,
682 int height,
683 int *wp,
684 int *hp)
685{
686 Display *xdisplay = meta_display_get_xdisplay (display);
687 XImage *shadow_image;
688 Pixmap shadow_pixmap;
689 Picture shadow_picture;
690 Window xroot = meta_screen_get_xroot (screen);
691 GC gc;
692
693 shadow_image = make_shadow (display, screen, cw->shadow_type,
23
Calling 'make_shadow'
694 opacity, width, height);
695 if (!shadow_image)
696 return None0L;
697
698 shadow_pixmap = XCreatePixmap (xdisplay, xroot,
699 shadow_image->width, shadow_image->height, 8);
700 if (!shadow_pixmap)
701 {
702 XDestroyImage (shadow_image)((*((shadow_image)->f.destroy_image))((shadow_image)));
703 return None0L;
704 }
705
706 shadow_picture = XRenderCreatePicture (xdisplay, shadow_pixmap,
707 XRenderFindStandardFormat (xdisplay, PictStandardA82),
708 0, 0);
709 if (!shadow_picture)
710 {
711 XDestroyImage (shadow_image)((*((shadow_image)->f.destroy_image))((shadow_image)));
712 XFreePixmap (xdisplay, shadow_pixmap);
713 return None0L;
714 }
715
716 shadow_picture_clip (xdisplay, shadow_picture, cw, borders,
717 shadow_image->width, shadow_image->height);
718
719 gc = XCreateGC (xdisplay, shadow_pixmap, 0, 0);
720 if (!gc)
721 {
722 XDestroyImage (shadow_image)((*((shadow_image)->f.destroy_image))((shadow_image)));
723 XFreePixmap (xdisplay, shadow_pixmap);
724 XRenderFreePicture (xdisplay, shadow_picture);
725 return None0L;
726 }
727
728 XPutImage (xdisplay, shadow_pixmap, gc, shadow_image, 0, 0, 0, 0,
729 shadow_image->width, shadow_image->height);
730 *wp = shadow_image->width;
731 *hp = shadow_image->height;
732
733 XFreeGC (xdisplay, gc);
734 XDestroyImage (shadow_image)((*((shadow_image)->f.destroy_image))((shadow_image)));
735 XFreePixmap (xdisplay, shadow_pixmap);
736
737 return shadow_picture;
738}
739
740static MetaCompWindow *
741find_window_for_screen (MetaScreen *screen,
742 Window xwindow)
743{
744 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
745
746 if (info == NULL((void*)0))
747 return NULL((void*)0);
748
749 return g_hash_table_lookup (info->windows_by_xid, (gpointer) xwindow);
750}
751
752static MetaCompWindow *
753find_window_in_display (MetaDisplay *display,
754 Window xwindow)
755{
756 GSList *index;
757
758 for (index = meta_display_get_screens (display); index; index = index->next)
759 {
760 MetaCompWindow *cw = find_window_for_screen (index->data, xwindow);
761
762 if (cw != NULL((void*)0))
763 return cw;
764 }
765
766 return NULL((void*)0);
767}
768
769static MetaCompWindow *
770find_window_for_child_window_in_display (MetaDisplay *display,
771 Window xwindow)
772{
773 Window ignored1, *ignored2;
774 Window parent;
775 guint ignored_children;
776
777 XQueryTree (meta_display_get_xdisplay (display), xwindow, &ignored1,
778 &parent, &ignored2, &ignored_children);
779
780 if (parent != None0L)
781 return find_window_in_display (display, parent);
782
783 return NULL((void*)0);
784}
785
786#ifdef HAVE_PRESENT
787static MetaScreen *
788find_screen_from_output(MetaDisplay *display, Window output)
789{
790 int i;
791 Display *xdisplay = meta_display_get_xdisplay(display);
792
793 for (i = 0; i < ScreenCount(xdisplay)(((_XPrivDisplay)(xdisplay))->nscreens); i++)
794 {
795 MetaScreen *screen = meta_display_screen_for_x_screen(display,
796 ScreenOfDisplay(xdisplay, i)(&((_XPrivDisplay)(xdisplay))->screens[i]));
797 MetaCompScreen *info = meta_screen_get_compositor_data(screen);
798
799 if (info->output == output)
800 return screen;
801 }
802 return NULL((void*)0);
803}
804#endif /* HAVE_PRESENT */
805
806static Picture
807solid_picture (MetaDisplay *display,
808 MetaScreen *screen,
809 gboolean argb,
810 double a,
811 double r,
812 double g,
813 double b)
814{
815 Display *xdisplay = meta_display_get_xdisplay (display);
816 Pixmap pixmap;
817 Picture picture;
818 XRenderPictureAttributes pa;
819 XRenderPictFormat *render_format;
820 XRenderColor c;
821 Window xroot = meta_screen_get_xroot (screen);
822
823 render_format = XRenderFindStandardFormat (xdisplay,
824 argb ? PictStandardARGB320 : PictStandardA82);
825
826 pixmap = XCreatePixmap (xdisplay, xroot, 1, 1, argb ? 32 : 8);
827 g_return_val_if_fail (pixmap != None, None)do { if ((pixmap != 0L)) { } else { g_return_if_fail_warning (
"croma", ((const char*) (__func__)), "pixmap != None"); return
(0L); } } while (0)
;
828
829 pa.repeat = TRUE(!(0));
830 picture = XRenderCreatePicture (xdisplay, pixmap, render_format,
831 CPRepeat(1 << 0), &pa);
832 if (picture == None0L)
833 {
834 XFreePixmap (xdisplay, pixmap);
835 g_warning ("(picture != None) failed");
836 return None0L;
837 }
838
839 c.alpha = a * 0xffff;
840 c.red = r * 0xffff;
841 c.green = g * 0xffff;
842 c.blue = b * 0xffff;
843
844 XRenderFillRectangle (xdisplay, PictOpSrc1, picture, &c, 0, 0, 1, 1);
845 XFreePixmap (xdisplay, pixmap);
846
847 return picture;
848}
849
850static Picture
851root_tile (MetaScreen *screen)
852{
853 MetaDisplay *display = meta_screen_get_display (screen);
854 Display *xdisplay = meta_display_get_xdisplay (display);
855 Picture picture;
856 Pixmap pixmap;
857 gboolean fill = FALSE(0);
858 XRenderPictureAttributes pa;
859 XRenderPictFormat *format;
860 int p;
861 Atom background_atoms[2];
862 Atom pixmap_atom;
863 int screen_number = meta_screen_get_screen_number (screen);
864 Window xroot = meta_screen_get_xroot (screen);
865
866 pixmap = None0L;
867 background_atoms[0] = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
->atom_x_root_pixmap;
868 background_atoms[1] = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
->atom_x_set_root;
869
870 pixmap_atom = XInternAtom (xdisplay, "PIXMAP", False0);
871 for (p = 0; p < 2; p++)
872 {
873 Atom actual_type;
874 int actual_format;
875 gulong nitems, bytes_after;
876 guchar *prop;
877
878 if (XGetWindowProperty (xdisplay, xroot,
879 background_atoms[p],
880 0, 4, FALSE(0), AnyPropertyType0L,
881 &actual_type, &actual_format,
882 &nitems, &bytes_after, &prop) == Success0)
883 {
884 if (actual_type == pixmap_atom &&
885 actual_format == 32 &&
886 nitems == 1)
887 {
888 memcpy (&pixmap, prop, 4);
889 XFree (prop);
890 fill = FALSE(0);
891 break;
892 }
893 }
894 }
895
896 if (!pixmap)
897 {
898 pixmap = XCreatePixmap (xdisplay, xroot, 1, 1,
899 DefaultDepth (xdisplay, screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_depth)
);
900 g_return_val_if_fail (pixmap != None, None)do { if ((pixmap != 0L)) { } else { g_return_if_fail_warning (
"croma", ((const char*) (__func__)), "pixmap != None"); return
(0L); } } while (0)
;
901 fill = TRUE(!(0));
902 }
903
904 pa.repeat = TRUE(!(0));
905 format = XRenderFindVisualFormat (xdisplay, DefaultVisual (xdisplay,((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
906 screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
);
907 g_return_val_if_fail (format != NULL, None)do { if ((format != ((void*)0))) { } else { g_return_if_fail_warning
("croma", ((const char*) (__func__)), "format != NULL"); return
(0L); } } while (0)
;
908
909 picture = XRenderCreatePicture (xdisplay, pixmap, format, CPRepeat(1 << 0), &pa);
910 if ((picture != None0L) && (fill))
911 {
912 XRenderColor c;
913
914 /* Background default to just plain black */
915 c.red = 0x0000;
916 c.green = 0x0000;
917 c.blue = 0x0000;
918 c.alpha = 0xffff;
919
920 XRenderFillRectangle (xdisplay, PictOpSrc1, picture, &c, 0, 0, 1, 1);
921 XFreePixmap (xdisplay, pixmap);
922 }
923
924 return picture;
925}
926
927static Pixmap
928create_root_pixmap (MetaScreen *screen)
929{
930 MetaDisplay *display = meta_screen_get_display (screen);
931 Display *xdisplay = meta_display_get_xdisplay (display);
932 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
933 Window xroot = meta_screen_get_xroot (screen);
934 Pixmap pixmap;
935 int depth, screen_width, screen_height, screen_number;
936
937 if (info == NULL((void*)0))
938 {
939 return None0L;
940 }
941
942 meta_screen_get_size (screen, &screen_width, &screen_height);
943 screen_number = meta_screen_get_screen_number (screen);
944
945 depth = DefaultDepth (xdisplay, screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_depth)
;
946 pixmap = XCreatePixmap (xdisplay, xroot,
947 screen_width, screen_height,
948 depth);
949
950 return pixmap;
951}
952
953static Picture
954create_root_buffer (MetaScreen *screen, Pixmap root_pixmap)
955{
956 MetaDisplay *display = meta_screen_get_display (screen);
957 Display *xdisplay = meta_display_get_xdisplay (display);
958 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
959 Picture pict;
960 XRenderPictFormat *format;
961 Visual *visual;
962 int screen_number;
963
964 if (info == NULL((void*)0))
965 {
966 return None0L;
967 }
968 g_return_val_if_fail (root_pixmap != None, None)do { if ((root_pixmap != 0L)) { } else { g_return_if_fail_warning
("croma", ((const char*) (__func__)), "root_pixmap != None")
; return (0L); } } while (0)
;
969
970 screen_number = meta_screen_get_screen_number (screen);
971 visual = DefaultVisual (xdisplay, screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
;
972
973 format = XRenderFindVisualFormat (xdisplay, visual);
974 g_return_val_if_fail (format != NULL, None)do { if ((format != ((void*)0))) { } else { g_return_if_fail_warning
("croma", ((const char*) (__func__)), "format != NULL"); return
(0L); } } while (0)
;
975
976 pict = XRenderCreatePicture (xdisplay, root_pixmap, format, 0, NULL((void*)0));
977 return pict;
978}
979
980static void
981paint_root (MetaScreen *screen,
982 Picture root_buffer)
983{
984 MetaDisplay *display = meta_screen_get_display (screen);
985 Display *xdisplay = meta_display_get_xdisplay (display);
986 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
987 int width, height;
988
989 if (info == NULL((void*)0))
990 {
991 return;
992 }
993
994 g_return_if_fail (root_buffer != None)do { if ((root_buffer != 0L)) { } else { g_return_if_fail_warning
("croma", ((const char*) (__func__)), "root_buffer != None")
; return; } } while (0)
;
995
996 if (info->root_tile == None0L)
997 {
998 info->root_tile = root_tile (screen);
999 g_return_if_fail (info->root_tile != None)do { if ((info->root_tile != 0L)) { } else { g_return_if_fail_warning
("croma", ((const char*) (__func__)), "info->root_tile != None"
); return; } } while (0)
;
1000 }
1001
1002 meta_screen_get_size (screen, &width, &height);
1003 XRenderComposite (xdisplay, PictOpSrc1, info->root_tile, None0L, root_buffer,
1004 0, 0, 0, 0, 0, 0, width, height);
1005}
1006
1007static gboolean
1008window_has_shadow (MetaCompWindow *cw)
1009{
1010 MetaCompScreen *info = meta_screen_get_compositor_data (cw->screen);
1011
1012 if (info == NULL((void*)0) || info->have_shadows == FALSE(0))
1013 return FALSE(0);
1014
1015 /* Always put a shadow around windows with a frame - This should override
1016 the restriction about not putting a shadow around shaped windows
1017 as the frame might be the reason the window is shaped */
1018 if (cw->window)
1019 {
1020 /* Do not add shadows for maximized windows */
1021 if (meta_window_is_maximized (cw->window))
1022 {
1023 meta_verbosemeta_verbose_real ("Window has no shadow because it is maximized\n");
1024 return FALSE(0);
1025 }
1026
1027 if (meta_window_get_frame (cw->window)) {
1028 meta_verbosemeta_verbose_real ("Window has shadow because it has a frame\n");
1029 return TRUE(!(0));
1030 }
1031 }
1032
1033 /* Do not add shadows to ARGB windows */
1034 if (cw->mode == WINDOW_ARGB1) {
1035 meta_verbosemeta_verbose_real ("Window has no shadow as it is ARGB\n");
1036 return FALSE(0);
1037 }
1038
1039 /* Never put a shadow around shaped windows */
1040 if (cw->shaped) {
1041 meta_verbosemeta_verbose_real ("Window has no shadow as it is shaped\n");
1042 return FALSE(0);
1043 }
1044
1045 /* Don't put shadow around DND icon windows */
1046 if (cw->type == META_COMP_WINDOW_DND ||
1047 cw->type == META_COMP_WINDOW_DESKTOP) {
1048 meta_verbosemeta_verbose_real ("Window has no shadow as it is DND or Desktop\n");
1049 return FALSE(0);
1050 }
1051
1052 if (cw->mode != WINDOW_ARGB1) {
1053 meta_verbosemeta_verbose_real ("Window has shadow as it is not ARGB\n");
1054 return TRUE(!(0));
1055 }
1056
1057 if (cw->type == META_COMP_WINDOW_MENU ||
1058 cw->type == META_COMP_WINDOW_DROP_DOWN_MENU) {
1059 meta_verbosemeta_verbose_real ("Window has shadow as it is a menu\n");
1060 return TRUE(!(0));
1061 }
1062
1063 if (cw->type == META_COMP_WINDOW_TOOLTIP) {
1064 meta_verbosemeta_verbose_real ("Window has shadow as it is a tooltip\n");
1065 return TRUE(!(0));
1066 }
1067
1068 meta_verbosemeta_verbose_real ("Window has no shadow as it fell through\n");
1069 return FALSE(0);
1070}
1071
1072static XserverRegion
1073win_extents (MetaCompWindow *cw)
1074{
1075 MetaScreen *screen = cw->screen;
1076 MetaDisplay *display = meta_screen_get_display (screen);
1077 Display *xdisplay = meta_display_get_xdisplay (display);
1078 XRectangle r;
1079
1080 r.x = cw->attrs.x;
1081 r.y = cw->attrs.y;
1082 r.width = cw->attrs.width + cw->attrs.border_width * 2;
1083 r.height = cw->attrs.height + cw->attrs.border_width * 2;
1084
1085 if (cw->needs_shadow
17.1
Field 'needs_shadow' is 1
)
18
Taking true branch
1086 {
1087 MetaFrameBorders borders;
1088 XRectangle sr;
1089
1090 meta_frame_borders_clear (&borders);
1091
1092 if (cw->window
18.1
Field 'window' is null
)
19
Taking false branch
1093 {
1094 MetaFrame *frame = meta_window_get_frame (cw->window);
1095
1096 if (frame)
1097 meta_frame_calc_borders (frame, &borders);
1098 }
1099
1100 cw->shadow_dx = (int) shadow_offsets_x [cw->shadow_type] + borders.invisible.left;
1101 cw->shadow_dy = (int) shadow_offsets_y [cw->shadow_type] + borders.invisible.top;
1102
1103 if (!cw->shadow
19.1
Field 'shadow' is 0
)
20
Taking true branch
1104 {
1105 double opacity = SHADOW_OPACITY0.66;
1106 int invisible_width = borders.invisible.left + borders.invisible.right;
1107 int invisible_height = borders.invisible.top + borders.invisible.bottom;
1108
1109 if (cw->opacity
20.1
Field 'opacity' is equal to -1
!= (guint) OPAQUE0xffffffff)
21
Taking false branch
1110 opacity = opacity * ((double) cw->opacity) / ((double) OPAQUE0xffffffff);
1111
1112 cw->shadow = shadow_picture (display, screen, cw, opacity, borders,
22
Calling 'shadow_picture'
1113 cw->attrs.width - invisible_width + cw->attrs.border_width * 2,
1114 cw->attrs.height - invisible_height + cw->attrs.border_width * 2,
1115 &cw->shadow_width, &cw->shadow_height);
1116 }
1117
1118 sr.x = cw->attrs.x + cw->shadow_dx;
1119 sr.y = cw->attrs.y + cw->shadow_dy;
1120 sr.width = cw->shadow_width;
1121 sr.height = cw->shadow_height;
1122
1123 if (sr.x < r.x)
1124 {
1125 r.width = (r.x + r.width) - sr.x;
1126 r.x = sr.x;
1127 }
1128
1129 if (sr.y < r.y)
1130 {
1131 r.height = (r.y + r.height) - sr.y;
1132 r.y = sr.y;
1133 }
1134
1135 if (sr.x + sr.width > r.x + r.width)
1136 r.width = sr.x + sr.width - r.x;
1137
1138 if (sr.y + sr.height > r.y + r.height)
1139 r.height = sr.y + sr.height - r.y;
1140 }
1141
1142 return XFixesCreateRegion (xdisplay, &r, 1);
1143}
1144
1145static XserverRegion
1146border_size (MetaCompWindow *cw)
1147{
1148 MetaScreen *screen = cw->screen;
1149 MetaDisplay *display = meta_screen_get_display (screen);
1150 Display *xdisplay = meta_display_get_xdisplay (display);
1151 XserverRegion visible = None0L;
1152 XserverRegion border;
1153
1154 if (cw->window)
1155 {
1156 cairo_region_t *visible_region;
1157
1158 visible_region = meta_window_get_frame_bounds (cw->window);
1159
1160 if (visible_region != NULL((void*)0))
1161 visible = cairo_region_to_xserver_region (xdisplay, visible_region);
1162 }
1163
1164 meta_error_trap_push (display);
1165 border = XFixesCreateRegionFromWindow (xdisplay, cw->id,
1166 WindowRegionBounding0);
1167 meta_error_trap_pop (display, FALSE(0));
1168
1169 g_return_val_if_fail (border != None, None)do { if ((border != 0L)) { } else { g_return_if_fail_warning (
"croma", ((const char*) (__func__)), "border != None"); return
(0L); } } while (0)
;
1170 XFixesTranslateRegion (xdisplay, border,
1171 cw->attrs.x + cw->attrs.border_width,
1172 cw->attrs.y + cw->attrs.border_width);
1173
1174 if (visible != None0L)
1175 {
1176 XFixesTranslateRegion (xdisplay, visible,
1177 cw->attrs.x + cw->attrs.border_width,
1178 cw->attrs.y + cw->attrs.border_width);
1179
1180 XFixesIntersectRegion (xdisplay, visible, visible, border);
1181 XFixesDestroyRegion (xdisplay, border);
1182
1183 return visible;
1184 }
1185
1186 return border;
1187}
1188
1189static XRenderPictFormat *
1190get_window_format (MetaCompWindow *cw)
1191{
1192 MetaScreen *screen = cw->screen;
1193 MetaDisplay *display = meta_screen_get_display (screen);
1194 Display *xdisplay = meta_display_get_xdisplay (display);
1195 XRenderPictFormat *format;
1196 int screen_number = meta_screen_get_screen_number (screen);
1197
1198 format = XRenderFindVisualFormat (xdisplay, cw->attrs.visual);
1199 if (!format)
1200 format = XRenderFindVisualFormat (xdisplay,
1201 DefaultVisual (xdisplay, screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
);
1202 return format;
1203}
1204
1205static Picture
1206get_window_picture (MetaCompWindow *cw)
1207{
1208 MetaScreen *screen = cw->screen;
1209 MetaDisplay *display = meta_screen_get_display (screen);
1210 Display *xdisplay = meta_display_get_xdisplay (display);
1211 XRenderPictureAttributes pa;
1212 XRenderPictFormat *format;
1213 Drawable draw;
1214 int error_code;
1215
1216 draw = cw->id;
1217
1218 meta_error_trap_push (display);
1219
1220 if (cw->back_pixmap == None0L)
1221 cw->back_pixmap = XCompositeNameWindowPixmap (xdisplay, cw->id);
1222
1223 error_code = meta_error_trap_pop_with_return (display, FALSE(0));
1224 if (error_code != 0)
1225 cw->back_pixmap = None0L;
1226
1227 if (cw->back_pixmap != None0L)
1228 draw = cw->back_pixmap;
1229
1230 format = get_window_format (cw);
1231 if (format)
1232 {
1233 Picture pict;
1234
1235 pa.subwindow_mode = IncludeInferiors1;
1236
1237 meta_error_trap_push (display);
1238 pict = XRenderCreatePicture (xdisplay, draw, format, CPSubwindowMode(1 << 8), &pa);
1239 meta_error_trap_pop (display, FALSE(0));
1240
1241 return pict;
1242 }
1243
1244 return None0L;
1245}
1246
1247static void
1248paint_dock_shadows (MetaScreen *screen,
1249 Picture root_buffer,
1250 XserverRegion region)
1251{
1252 MetaDisplay *display = meta_screen_get_display (screen);
1253 Display *xdisplay = meta_display_get_xdisplay (display);
1254 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1255 GSList *d;
1256
1257 if (info == NULL((void*)0))
1258 {
1259 return;
1260 }
1261
1262 for (d = info->dock_windows; d; d = d->next)
1263 {
1264 MetaCompWindow *cw = d->data;
1265 XserverRegion shadow_clip;
1266
1267 if (cw->shadow)
1268 {
1269 shadow_clip = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
1270 XFixesIntersectRegion (xdisplay, shadow_clip,
1271 cw->border_clip, region);
1272
1273 XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, shadow_clip);
1274
1275 XRenderComposite (xdisplay, PictOpOver3, info->black_picture,
1276 cw->shadow, root_buffer,
1277 0, 0, 0, 0,
1278 cw->attrs.x + cw->shadow_dx,
1279 cw->attrs.y + cw->shadow_dy,
1280 cw->shadow_width, cw->shadow_height);
1281 XFixesDestroyRegion (xdisplay, shadow_clip);
1282 }
1283 }
1284}
1285
1286#ifdef HAVE_PRESENT
1287static gboolean
1288present_flip (MetaScreen *screen, XserverRegion region, Pixmap pixmap)
1289{
1290 static uint32_t present_serial;
1291 gboolean debug;
1292
1293 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1294 MetaDisplay *display = meta_screen_get_display (screen);
1295 Display *xdisplay = meta_display_get_xdisplay (display);
1296
1297 meta_error_trap_push (display);
1298 XPresentPixmap(xdisplay,
1299 info->output,
1300 pixmap,
1301 present_serial,
1302 None0L,
1303 region,
1304 0, 0,
1305 None0L, None0L, None0L, PresentOptionNone0,
1306 0, 1, 0, NULL((void*)0), 0);
1307
1308 int error_code;
1309 error_code = meta_error_trap_pop_with_return (display, FALSE(0));
1310 if (error_code)
1311 {
1312 debug = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
->debug;
1313
1314 if (debug)
1315 fprintf (stderrstderr, "XPresentPixmap window %p pixmap %p error: %i\n",
1316 (void *)info->output, (void *)pixmap, error_code);
1317
1318 if (error_code == BadWindow3)
1319 g_warning ("XPresent is not compatible with your current system configuration.");
1320
1321 /* Disable the Present extension for this session to prevent frozen windows */
1322 info->use_present = FALSE(0);
1323 return FALSE(0);
1324 }
1325
1326 present_serial++;
1327
1328 return TRUE(!(0));
1329}
1330#endif /* HAVE_PRESENT */
1331
1332static void
1333paint_windows (MetaScreen *screen,
1334 GList *windows,
1335 Picture root_buffer,
1336 Pixmap root_pixmap,
1337 XserverRegion region)
1338{
1339 MetaDisplay *display = meta_screen_get_display (screen);
1340 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1341 Display *xdisplay = meta_display_get_xdisplay (display);
1342 GList *index, *last;
1343 int screen_width, screen_height;
1344 MetaCompWindow *cw;
1345 XserverRegion paint_region, desktop_region;
1346
1347 if (info == NULL((void*)0))
1348 {
1349 return;
1350 }
1351
1352 meta_screen_get_size (screen, &screen_width, &screen_height);
1353
1354 if (region == None0L)
1355 {
1356 XRectangle r;
1357 r.x = 0;
1358 r.y = 0;
1359 r.width = screen_width;
1360 r.height = screen_height;
1361 paint_region = XFixesCreateRegion (xdisplay, &r, 1);
1362 }
1363 else
1364 {
1365 paint_region = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
1366 XFixesCopyRegion (xdisplay, paint_region, region);
1367 }
1368
1369 desktop_region = None0L;
1370
1371 /*
1372 * Painting from top to bottom, reducing the clipping area at
1373 * each iteration. Only the opaque windows are painted 1st.
1374 */
1375 last = NULL((void*)0);
1376 for (index = windows; index; index = index->next)
1377 {
1378 /* Store the last window we dealt with */
1379 last = index;
1380
1381 cw = (MetaCompWindow *) index->data;
1382 if (!cw->damaged)
1383 {
1384 /* Not damaged */
1385 continue;
1386 }
1387
1388 if (cw->attrs.map_state != IsViewable2)
1389 continue;
1390
1391#if 0
1392 if ((cw->attrs.x + cw->attrs.width < 1) ||
1393 (cw->attrs.y + cw->attrs.height < 1) ||
1394 (cw->attrs.x >= screen_width) || (cw->attrs.y >= screen_height))
1395 {
1396 /* Off screen */
1397 continue;
1398 }
1399#endif
1400
1401 if (cw->picture == None0L)
1402 cw->picture = get_window_picture (cw);
1403
1404 /* If the clip region of the screen has been changed
1405 then we need to recreate the extents of the window */
1406 if (info->clip_changed)
1407 {
1408 if (cw->border_size)
1409 {
1410 XFixesDestroyRegion (xdisplay, cw->border_size);
1411 cw->border_size = None0L;
1412 }
1413
1414#if 0
1415 if (cw->extents)
1416 {
1417 XFixesDestroyRegion (xdisplay, cw->extents);
1418 cw->extents = None0L;
1419 }
1420#endif
1421 }
1422
1423 if (cw->border_size == None0L)
1424 cw->border_size = border_size (cw);
1425
1426 if (cw->extents == None0L)
1427 cw->extents = win_extents (cw);
1428
1429 if (cw->mode == WINDOW_SOLID0)
1430 {
1431 int x, y, wid, hei;
1432
1433 x = cw->attrs.x;
1434 y = cw->attrs.y;
1435 wid = cw->attrs.width + cw->attrs.border_width * 2;
1436 hei = cw->attrs.height + cw->attrs.border_width * 2;
1437
1438 XFixesSetPictureClipRegion (xdisplay, root_buffer,
1439 0, 0, paint_region);
1440 XRenderComposite (xdisplay, PictOpSrc1, cw->picture,
1441 None0L, root_buffer, 0, 0, 0, 0,
1442 x, y, wid, hei);
1443
1444 if (cw->type == META_COMP_WINDOW_DESKTOP)
1445 {
1446 if(desktop_region)
1447 {
1448 XFixesUnionRegion (xdisplay, desktop_region, desktop_region, paint_region);
1449 }
1450 else
1451 {
1452 desktop_region = XFixesCreateRegion (xdisplay, 0, 0);
1453 XFixesCopyRegion (xdisplay, desktop_region, paint_region);
1454 }
1455 }
1456
1457 XFixesSubtractRegion (xdisplay, paint_region,
1458 paint_region, cw->border_size);
1459 }
1460
1461 if (!cw->border_clip)
1462 {
1463 cw->border_clip = XFixesCreateRegion (xdisplay, 0, 0);
1464 XFixesCopyRegion (xdisplay, cw->border_clip, paint_region);
1465 }
1466 }
1467
1468 XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, paint_region);
1469 paint_root (screen, root_buffer);
1470
1471 paint_dock_shadows (screen, root_buffer, desktop_region == None0L ?
1472 paint_region : desktop_region);
1473 if (desktop_region != None0L)
1474 XFixesDestroyRegion (xdisplay, desktop_region);
1475
1476 /*
1477 * Painting from bottom to top, translucent windows and shadows are painted
1478 */
1479 for (index = last; index; index = index->prev)
1480 {
1481 cw = (MetaCompWindow *) index->data;
1482
1483 if (cw->picture)
1484 {
1485 if (cw->shadow && cw->type != META_COMP_WINDOW_DOCK)
1486 {
1487 XserverRegion shadow_clip;
1488
1489 shadow_clip = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
1490 XFixesSubtractRegion (xdisplay, shadow_clip, cw->border_clip,
1491 cw->border_size);
1492 XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
1493 shadow_clip);
1494
1495 XRenderComposite (xdisplay, PictOpOver3, info->black_picture,
1496 cw->shadow, root_buffer,
1497 0, 0, 0, 0,
1498 cw->attrs.x + cw->shadow_dx,
1499 cw->attrs.y + cw->shadow_dy,
1500 cw->shadow_width, cw->shadow_height);
1501 if (shadow_clip)
1502 XFixesDestroyRegion (xdisplay, shadow_clip);
1503 }
1504
1505 if ((cw->opacity != (guint) OPAQUE0xffffffff) && !(cw->alpha_pict))
1506 {
1507 cw->alpha_pict = solid_picture (display, screen, FALSE(0),
1508 (double) cw->opacity / OPAQUE0xffffffff,
1509 0, 0, 0);
1510 }
1511
1512 XFixesIntersectRegion (xdisplay, cw->border_clip, cw->border_clip,
1513 cw->border_size);
1514 XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
1515 cw->border_clip);
1516 if (cw->mode == WINDOW_ARGB1)
1517 {
1518 int x, y, wid, hei;
1519
1520 x = cw->attrs.x;
1521 y = cw->attrs.y;
1522 wid = cw->attrs.width + cw->attrs.border_width * 2;
1523 hei = cw->attrs.height + cw->attrs.border_width * 2;
1524
1525 XRenderComposite (xdisplay, PictOpOver3, cw->picture,
1526 cw->alpha_pict, root_buffer, 0, 0, 0, 0,
1527 x, y, wid, hei);
1528 }
1529 }
1530
1531 if (cw->border_clip)
1532 {
1533 XFixesDestroyRegion (xdisplay, cw->border_clip);
1534 cw->border_clip = None0L;
1535 }
1536 }
1537
1538
1539 XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, region);
1540
1541#ifdef HAVE_PRESENT
1542 if (info->use_present)
1543 info->present_pending = present_flip (screen, region, root_pixmap);
1544
1545 if (!info->use_present || !info->present_pending)
1546#endif /* HAVE_PRESENT */
1547 {
1548 XRenderComposite (xdisplay, PictOpSrc1, root_buffer, None0L,
1549 info->root_picture, 0, 0, 0, 0, 0, 0,
1550 screen_width, screen_height);
1551 }
1552
1553 XFlush (xdisplay);
1554 XFixesDestroyRegion (xdisplay, paint_region);
1555}
1556
1557static void
1558paint_all (MetaScreen *screen,
1559 XserverRegion region,
1560 int b)
1561{
1562 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1563 MetaDisplay *display = meta_screen_get_display (screen);
1564 Display *xdisplay = meta_display_get_xdisplay (display);
1565 int screen_width, screen_height;
1566
1567 meta_screen_get_size (screen, &screen_width, &screen_height);
1568
1569 if (DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
->show_redraw)
1570 {
1571 Picture overlay;
1572
1573 dump_xserver_region ("paint_all", display, region);
1574
1575 /* Make a random colour overlay */
1576 overlay = solid_picture (display, screen, TRUE(!(0)), 1, /* 0.3, alpha */
1577 ((double) (rand () % 100)) / 100.0,
1578 ((double) (rand () % 100)) / 100.0,
1579 ((double) (rand () % 100)) / 100.0);
1580
1581 /* Set clipping to the given region */
1582 XFixesSetPictureClipRegion (xdisplay, info->root_picture, 0, 0, region);
1583
1584 XRenderComposite (xdisplay, PictOpOver3, overlay, None0L, info->root_picture,
1585 0, 0, 0, 0, 0, 0, screen_width, screen_height);
1586 XRenderFreePicture (xdisplay, overlay);
1587 XFlush (xdisplay);
1588 usleep (100 * 1000);
1589 }
1590
1591 if (info->root_pixmaps[b] == None0L)
1592 info->root_pixmaps[b] = create_root_pixmap (screen);
1593
1594 if (info->root_buffers[b] == None0L)
1595 info->root_buffers[b] = create_root_buffer (screen, info->root_pixmaps[b]);
1596
1597 paint_windows (screen, info->windows, info->root_buffers[b], info->root_pixmaps[b], region);
1598}
1599
1600static void
1601repair_screen (MetaScreen *screen)
1602{
1603 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1604 MetaDisplay *display = meta_screen_get_display (screen);
1605 Display *xdisplay = meta_display_get_xdisplay (display);
1606
1607 g_return_if_fail(info != NULL)do { if ((info != ((void*)0))) { } else { g_return_if_fail_warning
("croma", ((const char*) (__func__)), "info != NULL"); return
; } } while (0)
;
1608
1609 if (info->all_damage != None0L)
1610 {
1611#ifdef HAVE_PRESENT
1612 if (info->use_present)
1613 {
1614 if (!info->present_pending)
1615 {
1616 XserverRegion damage = info->all_damage;
1617 meta_error_trap_push (display);
1618 if (info->prev_damage)
1619 {
1620 XFixesUnionRegion(xdisplay, info->prev_damage, info->prev_damage, damage);
1621 damage = info->prev_damage;
1622 }
1623
1624 paint_all (screen, damage, info->root_current);
1625
1626 if (++info->root_current >= NUM_BUFFER2)
1627 info->root_current = 0;
1628
1629 if (info->prev_damage)
1630 XFixesDestroyRegion (xdisplay, info->prev_damage);
1631
1632 info->prev_damage = info->all_damage;
1633 info->all_damage = None0L;
1634 info->clip_changed = FALSE(0);
1635 meta_error_trap_pop (display, FALSE(0));
1636 }
1637 }
1638 else
1639#endif /* HAVE_PRESENT */
1640 {
1641 meta_error_trap_push (display);
1642 paint_all (screen, info->all_damage, info->root_current);
1643 XFixesDestroyRegion (xdisplay, info->all_damage);
1644 info->all_damage = None0L;
1645 info->clip_changed = FALSE(0);
1646 meta_error_trap_pop (display, FALSE(0));
1647 }
1648 }
1649}
1650
1651static void
1652repair_display (MetaDisplay *display)
1653{
1654 GSList *screens = meta_display_get_screens (display);
1655 MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
;
1656
1657#ifdef USE_IDLE_REPAINT1
1658 if (compositor->repaint_id > 0)
1659 {
1660 g_source_remove (compositor->repaint_id);
1661 compositor->repaint_id = 0;
1662 }
1663#endif
1664
1665 for (; screens; screens = screens->next)
1666 repair_screen ((MetaScreen *) screens->data);
1667}
1668
1669#ifdef USE_IDLE_REPAINT1
1670static gboolean
1671compositor_idle_cb (gpointer data)
1672{
1673 MetaCompositorXRender *compositor = (MetaCompositorXRender *) data;
1674
1675 compositor->repaint_id = 0;
1676 repair_display (compositor->display);
1677
1678 return FALSE(0);
1679}
1680
1681static void
1682add_repair (MetaDisplay *display)
1683{
1684 MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
;
1685
1686 if (compositor->repaint_id > 0)
1687 return;
1688
1689#if 1
1690 compositor->repaint_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE100,
1691 compositor_idle_cb, compositor,
1692 NULL((void*)0));
1693#else
1694 /* Limit it to 50fps */
1695 compositor->repaint_id = g_timeout_add_full (G_PRIORITY_HIGH-100, 20,
1696 compositor_idle_cb, compositor,
1697 NULL((void*)0));
1698#endif
1699}
1700#endif
1701
1702static void
1703add_damage (MetaScreen *screen,
1704 XserverRegion damage)
1705{
1706 MetaDisplay *display = meta_screen_get_display (screen);
1707 Display *xdisplay = meta_display_get_xdisplay (display);
1708 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1709
1710 /* dump_xserver_region ("add_damage", display, damage); */
1711
1712 if (info != NULL((void*)0))
1713 {
1714 if (info->all_damage)
1715 {
1716 XFixesUnionRegion (xdisplay, info->all_damage, info->all_damage, damage);
1717 XFixesDestroyRegion (xdisplay, damage);
1718 }
1719 else
1720 {
1721 info->all_damage = damage;
1722 }
1723 }
1724
1725#ifdef USE_IDLE_REPAINT1
1726 add_repair (display);
1727#endif
1728}
1729
1730static void
1731damage_screen (MetaScreen *screen)
1732{
1733 MetaDisplay *display = meta_screen_get_display (screen);
1734 Display *xdisplay = meta_display_get_xdisplay (display);
1735 XserverRegion region;
1736 int width, height;
1737 XRectangle r;
1738
1739 r.x = 0;
1740 r.y = 0;
1741 meta_screen_get_size (screen, &width, &height);
1742 r.width = width;
1743 r.height = height;
1744
1745 region = XFixesCreateRegion (xdisplay, &r, 1);
1746 dump_xserver_region ("damage_screen", display, region);
1747 add_damage (screen, region);
1748}
1749
1750static void
1751repair_win (MetaCompWindow *cw)
1752{
1753 MetaScreen *screen = cw->screen;
1754 MetaDisplay *display = meta_screen_get_display (screen);
1755 Display *xdisplay = meta_display_get_xdisplay (display);
1756 XserverRegion parts;
1757
1758 meta_error_trap_push (display);
1759 if (!cw->damaged)
1760 {
1761 parts = win_extents (cw);
1762 XDamageSubtract (xdisplay, cw->damage, None0L, None0L);
1763 }
1764 else
1765 {
1766 parts = XFixesCreateRegion (xdisplay, 0, 0);
1767 XDamageSubtract (xdisplay, cw->damage, None0L, parts);
1768 XFixesTranslateRegion (xdisplay, parts,
1769 cw->attrs.x + cw->attrs.border_width,
1770 cw->attrs.y + cw->attrs.border_width);
1771 }
1772
1773 meta_error_trap_pop (display, FALSE(0));
1774
1775 dump_xserver_region ("repair_win", display, parts);
1776 add_damage (screen, parts);
1777 cw->damaged = TRUE(!(0));
1778}
1779
1780static void
1781free_win (MetaCompWindow *cw,
1782 gboolean destroy)
1783{
1784 MetaDisplay *display = meta_screen_get_display (cw->screen);
1785 Display *xdisplay = meta_display_get_xdisplay (display);
1786 MetaCompScreen *info = meta_screen_get_compositor_data (cw->screen);
1787
1788 /* See comment in map_win */
1789 if (cw->back_pixmap && destroy)
1790 {
1791 XFreePixmap (xdisplay, cw->back_pixmap);
1792 cw->back_pixmap = None0L;
1793 }
1794
1795 if (cw->shaded_back_pixmap && destroy)
1796 {
1797 XFreePixmap (xdisplay, cw->shaded_back_pixmap);
1798 cw->shaded_back_pixmap = None0L;
1799 }
1800
1801 if (cw->picture)
1802 {
1803 XRenderFreePicture (xdisplay, cw->picture);
1804 cw->picture = None0L;
1805 }
1806
1807 if (cw->shadow)
1808 {
1809 XRenderFreePicture (xdisplay, cw->shadow);
1810 cw->shadow = None0L;
1811 }
1812
1813 if (cw->alpha_pict)
1814 {
1815 XRenderFreePicture (xdisplay, cw->alpha_pict);
1816 cw->alpha_pict = None0L;
1817 }
1818
1819 if (cw->shadow_pict)
1820 {
1821 XRenderFreePicture (xdisplay, cw->shadow_pict);
1822 cw->shadow_pict = None0L;
1823 }
1824
1825 if (cw->border_size)
1826 {
1827 XFixesDestroyRegion (xdisplay, cw->border_size);
1828 cw->border_size = None0L;
1829 }
1830
1831 if (cw->border_clip)
1832 {
1833 XFixesDestroyRegion (xdisplay, cw->border_clip);
1834 cw->border_clip = None0L;
1835 }
1836
1837 if (cw->extents)
1838 {
1839 XFixesDestroyRegion (xdisplay, cw->extents);
1840 cw->extents = None0L;
1841 }
1842
1843 if (destroy)
1844 {
1845 if (cw->damage != None0L) {
1846 meta_error_trap_push (display);
1847 XDamageDestroy (xdisplay, cw->damage);
1848 meta_error_trap_pop (display, FALSE(0));
1849
1850 cw->damage = None0L;
1851 }
1852
1853 /* The window may not have been added to the list in this case,
1854 but we can check anyway */
1855 if (info!=NULL((void*)0) && cw->type == META_COMP_WINDOW_DOCK)
1856 info->dock_windows = g_slist_remove (info->dock_windows, cw);
1857
1858 g_free (cw);
1859 }
1860}
1861
1862static void
1863map_win (MetaDisplay *display,
1864 MetaScreen *screen,
1865 Window id)
1866{
1867 MetaCompWindow *cw = find_window_for_screen (screen, id);
1868 Display *xdisplay = meta_display_get_xdisplay (display);
1869
1870 if (cw == NULL((void*)0))
1871 return;
1872
1873 /* The reason we deallocate this here and not in unmap
1874 is so that we will still have a valid pixmap for
1875 whenever the window is unmapped */
1876 if (cw->back_pixmap)
1877 {
1878 XFreePixmap (xdisplay, cw->back_pixmap);
1879 cw->back_pixmap = None0L;
1880 }
1881
1882 if (cw->shaded_back_pixmap)
1883 {
1884 XFreePixmap (xdisplay, cw->shaded_back_pixmap);
1885 cw->shaded_back_pixmap = None0L;
1886 }
1887
1888 cw->attrs.map_state = IsViewable2;
1889 cw->damaged = FALSE(0);
1890}
1891
1892static void
1893unmap_win (MetaDisplay *display,
1894 MetaScreen *screen,
1895 Window id)
1896{
1897 MetaCompWindow *cw = find_window_for_screen (screen, id);
1898 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
1899
1900 if (cw == NULL((void*)0) || info == NULL((void*)0))
1901 {
1902 return;
1903 }
1904
1905 if (cw->window && cw->window == info->focus_window)
1906 info->focus_window = NULL((void*)0);
1907
1908 cw->attrs.map_state = IsUnmapped0;
1909 cw->damaged = FALSE(0);
1910
1911 if (cw->extents != None0L)
1912 {
1913 dump_xserver_region ("unmap_win", display, cw->extents);
1914 add_damage (screen, cw->extents);
1915 cw->extents = None0L;
1916 }
1917
1918 free_win (cw, FALSE(0));
1919 info->clip_changed = TRUE(!(0));
1920}
1921
1922static void
1923determine_mode (MetaDisplay *display,
1924 MetaScreen *screen,
1925 MetaCompWindow *cw)
1926{
1927 XRenderPictFormat *format;
1928 Display *xdisplay = meta_display_get_xdisplay (display);
1929
1930 if (cw->alpha_pict)
1931 {
1932 XRenderFreePicture (xdisplay, cw->alpha_pict);
1933 cw->alpha_pict = None0L;
1934 }
1935
1936 if (cw->shadow_pict)
1937 {
1938 XRenderFreePicture (xdisplay, cw->shadow_pict);
1939 cw->shadow_pict = None0L;
1940 }
1941
1942 if (cw->attrs.class == InputOnly2)
1943 format = NULL((void*)0);
1944 else
1945 format = XRenderFindVisualFormat (xdisplay, cw->attrs.visual);
1946
1947 if ((format && format->type == PictTypeDirect1 && format->direct.alphaMask)
1948 || cw->opacity != (guint) OPAQUE0xffffffff)
1949 cw->mode = WINDOW_ARGB1;
1950 else
1951 cw->mode = WINDOW_SOLID0;
1952
1953 if (cw->extents)
1954 {
1955 XserverRegion damage;
1956 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
1957 XFixesCopyRegion (xdisplay, damage, cw->extents);
1958
1959 dump_xserver_region ("determine_mode", display, damage);
1960 add_damage (screen, damage);
1961 }
1962}
1963
1964static gboolean
1965is_shaped (MetaDisplay *display,
1966 Window xwindow)
1967{
1968 Display *xdisplay = meta_display_get_xdisplay (display);
1969 int xws, yws, xbs, ybs;
1970 unsigned wws, hws, wbs, hbs;
1971 int bounding_shaped, clip_shaped;
1972
1973 if (meta_display_has_shape (display))
1974 {
1975 XShapeQueryExtents (xdisplay, xwindow, &bounding_shaped,
1976 &xws, &yws, &wws, &hws, &clip_shaped,
1977 &xbs, &ybs, &wbs, &hbs);
1978 return (bounding_shaped != 0);
1979 }
1980
1981 return FALSE(0);
1982}
1983
1984static void
1985get_window_type (MetaDisplay *display,
1986 MetaCompWindow *cw)
1987{
1988 MetaCompositorXRender *compositor = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
;
1989 int n_atoms;
1990 Atom *atoms, type_atom;
1991 int i;
1992
1993 type_atom = None0L;
1994 n_atoms = 0;
1995 atoms = NULL((void*)0);
1996
1997 meta_prop_get_atom_list (display, cw->id,
1998 compositor->atom_net_wm_window_type,
1999 &atoms, &n_atoms);
2000
2001 for (i = 0; i < n_atoms; i++)
2002 {
2003 if (atoms[i] == compositor->atom_net_wm_window_type_dnd ||
2004 atoms[i] == compositor->atom_net_wm_window_type_desktop ||
2005 atoms[i] == compositor->atom_net_wm_window_type_dock ||
2006 atoms[i] == compositor->atom_net_wm_window_type_toolbar ||
2007 atoms[i] == compositor->atom_net_wm_window_type_menu ||
2008 atoms[i] == compositor->atom_net_wm_window_type_dialog ||
2009 atoms[i] == compositor->atom_net_wm_window_type_normal ||
2010 atoms[i] == compositor->atom_net_wm_window_type_utility ||
2011 atoms[i] == compositor->atom_net_wm_window_type_splash ||
2012 atoms[i] == compositor->atom_net_wm_window_type_dropdown_menu ||
2013 atoms[i] == compositor->atom_net_wm_window_type_tooltip)
2014 {
2015 type_atom = atoms[i];
2016 break;
2017 }
2018 }
2019
2020 meta_XFree (atoms)do { if ((atoms)) XFree ((atoms)); } while (0);
2021
2022 if (type_atom == compositor->atom_net_wm_window_type_dnd)
2023 cw->type = META_COMP_WINDOW_DND;
2024 else if (type_atom == compositor->atom_net_wm_window_type_desktop)
2025 cw->type = META_COMP_WINDOW_DESKTOP;
2026 else if (type_atom == compositor->atom_net_wm_window_type_dock)
2027 cw->type = META_COMP_WINDOW_DOCK;
2028 else if (type_atom == compositor->atom_net_wm_window_type_menu)
2029 cw->type = META_COMP_WINDOW_MENU;
2030 else if (type_atom == compositor->atom_net_wm_window_type_dropdown_menu)
2031 cw->type = META_COMP_WINDOW_DROP_DOWN_MENU;
2032 else if (type_atom == compositor->atom_net_wm_window_type_tooltip)
2033 cw->type = META_COMP_WINDOW_TOOLTIP;
2034 else
2035 cw->type = META_COMP_WINDOW_NORMAL;
2036
2037/* meta_verbose ("Window is %d\n", cw->type); */
2038}
2039
2040/* Must be called with an error trap in place */
2041static void
2042add_win (MetaScreen *screen,
2043 MetaWindow *window,
2044 Window xwindow)
2045{
2046 MetaDisplay *display = meta_screen_get_display (screen);
2047 Display *xdisplay = meta_display_get_xdisplay (display);
2048 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
2049 MetaCompWindow *cw;
2050 gulong event_mask;
2051
2052 if (info == NULL((void*)0))
2053 return;
2054
2055 if (xwindow == info->output)
2056 return;
2057
2058 /* If already added, ignore */
2059 if (find_window_for_screen (screen, xwindow) != NULL((void*)0))
2060 return;
2061
2062 cw = g_new0 (MetaCompWindow, 1)((MetaCompWindow *) g_malloc0_n ((1), sizeof (MetaCompWindow)
))
;
2063 cw->screen = screen;
2064 cw->window = window;
2065 cw->id = xwindow;
2066
2067 if (!XGetWindowAttributes (xdisplay, xwindow, &cw->attrs))
2068 {
2069 g_free (cw);
2070 return;
2071 }
2072 get_window_type (display, cw);
2073
2074 /* If Croma has decided not to manage this window then the input events
2075 won't have been set on the window */
2076 event_mask = cw->attrs.your_event_mask | PropertyChangeMask(1L<<22);
2077
2078 XSelectInput (xdisplay, xwindow, event_mask);
2079
2080 cw->back_pixmap = None0L;
2081 cw->shaded_back_pixmap = None0L;
2082
2083 cw->damaged = FALSE(0);
2084 cw->shaped = is_shaped (display, xwindow);
2085
2086 cw->shape_bounds.x = cw->attrs.x;
2087 cw->shape_bounds.y = cw->attrs.y;
2088 cw->shape_bounds.width = cw->attrs.width;
2089 cw->shape_bounds.height = cw->attrs.height;
2090
2091 if (cw->attrs.class == InputOnly2)
2092 cw->damage = None0L;
2093 else
2094 cw->damage = XDamageCreate (xdisplay, xwindow, XDamageReportNonEmpty3);
2095
2096 cw->alpha_pict = None0L;
2097 cw->shadow_pict = None0L;
2098 cw->border_size = None0L;
2099 cw->extents = None0L;
2100 cw->shadow = None0L;
2101 cw->shadow_dx = 0;
2102 cw->shadow_dy = 0;
2103 cw->shadow_width = 0;
2104 cw->shadow_height = 0;
2105
2106 if (window && meta_window_has_focus (window))
2107 cw->shadow_type = META_SHADOW_LARGE;
2108 else
2109 cw->shadow_type = META_SHADOW_MEDIUM;
2110
2111 cw->opacity = OPAQUE0xffffffff;
2112
2113 cw->border_clip = None0L;
2114
2115 determine_mode (display, screen, cw);
2116 cw->needs_shadow = window_has_shadow (cw);
2117
2118 /* Only add the window to the list of docks if it needs a shadow */
2119 if (cw->type == META_COMP_WINDOW_DOCK && cw->needs_shadow)
2120 {
2121 meta_verbosemeta_verbose_real ("Appending %p to dock windows\n", cw);
2122 info->dock_windows = g_slist_append (info->dock_windows, cw);
2123 }
2124
2125 /* Add this to the list at the top of the stack
2126 before it is mapped so that map_win can find it again */
2127 info->windows = g_list_prepend (info->windows, cw);
2128 g_hash_table_insert (info->windows_by_xid, (gpointer) xwindow, cw);
2129
2130 if (cw->attrs.map_state == IsViewable2)
2131 map_win (display, screen, xwindow);
2132}
2133
2134static void
2135destroy_win (MetaDisplay *display,
2136 Window xwindow,
2137 gboolean gone)
2138{
2139 MetaScreen *screen;
2140 MetaCompScreen *info;
2141 MetaCompWindow *cw;
2142
2143 cw = find_window_in_display (display, xwindow);
2144
2145 if (cw == NULL((void*)0))
2146 return;
2147
2148 screen = cw->screen;
2149
2150 if (cw->extents != None0L)
2151 {
2152 dump_xserver_region ("destroy_win", display, cw->extents);
2153 add_damage (screen, cw->extents);
2154 cw->extents = None0L;
2155 }
2156
2157 info = meta_screen_get_compositor_data (screen);
2158 if (info != NULL((void*)0))
2159 {
2160 info->windows = g_list_remove (info->windows, (gconstpointer) cw);
2161 g_hash_table_remove (info->windows_by_xid, (gpointer) xwindow);
2162 }
2163
2164 free_win (cw, TRUE(!(0)));
2165}
2166
2167static void
2168restack_win (MetaCompWindow *cw,
2169 Window above)
2170{
2171 MetaScreen *screen;
2172 MetaCompScreen *info;
2173 Window previous_above;
2174 GList *sibling, *next;
2175
2176 screen = cw->screen;
2177 info = meta_screen_get_compositor_data (screen);
2178
2179 if (info == NULL((void*)0))
2180 {
2181 return;
2182 }
2183
2184 sibling = g_list_find (info->windows, (gconstpointer) cw);
2185 next = g_list_next (sibling)((sibling) ? (((GList *)(sibling))->next) : ((void*)0));
2186 previous_above = None0L;
2187
2188 if (next)
2189 {
2190 MetaCompWindow *ncw = (MetaCompWindow *) next->data;
2191 previous_above = ncw->id;
2192 }
2193
2194 /* If above is set to None, the window whose state was changed is on
2195 * the bottom of the stack with respect to sibling.
2196 */
2197 if (above == None0L)
2198 {
2199 /* Insert at bottom of window stack */
2200 info->windows = g_list_delete_link (info->windows, sibling);
2201 info->windows = g_list_append (info->windows, cw);
2202 }
2203 else if (previous_above != above)
2204 {
2205 GList *index;
2206
2207 for (index = info->windows; index; index = index->next) {
2208 MetaCompWindow *cw2 = (MetaCompWindow *) index->data;
2209 if (cw2->id == above)
2210 break;
2211 }
2212
2213 if (index != NULL((void*)0))
2214 {
2215 info->windows = g_list_delete_link (info->windows, sibling);
2216 info->windows = g_list_insert_before (info->windows, index, cw);
2217 }
2218 }
2219}
2220
2221static void
2222resize_win (MetaCompWindow *cw,
2223 int x,
2224 int y,
2225 int width,
2226 int height,
2227 int border_width,
2228 gboolean override_redirect)
2229{
2230 MetaScreen *screen = cw->screen;
2231 MetaDisplay *display = meta_screen_get_display (screen);
2232 Display *xdisplay = meta_display_get_xdisplay (display);
2233 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
2234 XserverRegion damage;
2235 XserverRegion shape;
2236 gboolean debug;
2237
2238 debug = DISPLAY_COMPOSITOR (display)((MetaCompositorXRender *) meta_display_get_compositor (display
))
->debug;
2239
2240 if (cw->extents)
2241 {
2242 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
2243 XFixesCopyRegion (xdisplay, damage, cw->extents);
2244 }
2245 else
2246 {
2247 damage = None0L;
2248 if (debug)
2249 fprintf (stderrstderr, "no extents to damage !\n");
2250 }
2251
2252 /* { // Damage whole screen each time ! ;-)
2253 XRectangle r;
2254
2255 r.x = 0;
2256 r.y = 0;
2257 meta_screen_get_size (screen, &r.width, &r.height);
2258 fprintf (stderr, "Damage whole screen %d,%d (%d %d)\n",
2259 r.x, r.y, r.width, r.height);
2260
2261 damage = XFixesCreateRegion (xdisplay, &r, 1);
2262 } */
2263
2264 cw->attrs.x = x;
2265 cw->attrs.y = y;
2266
2267 if (cw->attrs.width != width || cw->attrs.height != height)
2268 {
2269 if (cw->shaded_back_pixmap)
2270 {
2271 XFreePixmap (xdisplay, cw->shaded_back_pixmap);
2272 cw->shaded_back_pixmap = None0L;
2273 }
2274
2275 if (cw->back_pixmap)
2276 {
2277 /* If the window is shaded, we store the old backing pixmap
2278 so we can return a proper image of the window */
2279 if (cw->window && meta_window_is_shaded (cw->window))
2280 {
2281 cw->shaded_back_pixmap = cw->back_pixmap;
2282 cw->back_pixmap = None0L;
2283 }
2284 else
2285 {
2286 XFreePixmap (xdisplay, cw->back_pixmap);
2287 cw->back_pixmap = None0L;
2288 }
2289 }
2290
2291 if (cw->picture)
2292 {
2293 XRenderFreePicture (xdisplay, cw->picture);
2294 cw->picture = None0L;
2295 }
2296
2297 if (cw->shadow)
2298 {
2299 XRenderFreePicture (xdisplay, cw->shadow);
2300 cw->shadow = None0L;
2301 }
2302 }
2303
2304 cw->attrs.width = width;
2305 cw->attrs.height = height;
2306 cw->attrs.border_width = border_width;
2307 cw->attrs.override_redirect = override_redirect;
2308
2309 if (cw->extents)
2310 XFixesDestroyRegion (xdisplay, cw->extents);
2311
2312 cw->extents = win_extents (cw);
2313
2314 if (damage)
2315 {
2316 if (debug)
2317 fprintf (stderrstderr, "Inexplicable intersection with new extents!\n");
2318
2319 XFixesUnionRegion (xdisplay, damage, damage, cw->extents);
2320 }
2321 else
2322 {
2323 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
2324 XFixesCopyRegion (xdisplay, damage, cw->extents);
2325 }
2326
2327 shape = XFixesCreateRegion (xdisplay, &cw->shape_bounds, 1);
2328 XFixesUnionRegion (xdisplay, damage, damage, shape);
2329 XFixesDestroyRegion (xdisplay, shape);
2330
2331 dump_xserver_region ("resize_win", display, damage);
2332 add_damage (screen, damage);
2333
2334 if (info != NULL((void*)0))
2335 {
2336 info->clip_changed = TRUE(!(0));
2337 }
2338}
2339
2340/* event processors must all be called with an error trap in place */
2341static void
2342process_circulate_notify (MetaCompositorXRender *compositor,
2343 XCirculateEvent *event)
2344{
2345 MetaCompWindow *cw = find_window_in_display (compositor->display,
2346 event->window);
2347 MetaCompWindow *top;
2348 MetaCompScreen *info;
2349 MetaScreen *screen;
2350 GList *first;
2351 Window above;
2352
2353 if (!cw)
2354 return;
2355
2356 screen = cw->screen;
2357 info = meta_screen_get_compositor_data (screen);
2358 first = info->windows;
2359 top = (MetaCompWindow *) first->data;
2360
2361 if ((event->place == PlaceOnTop0) && top)
2362 above = top->id;
2363 else
2364 above = None0L;
2365 restack_win (cw, above);
2366
2367 if (info != NULL((void*)0))
2368 {
2369 info->clip_changed = TRUE(!(0));
2370 }
2371
2372#ifdef USE_IDLE_REPAINT1
2373 add_repair (compositor->display);
2374#endif
2375}
2376
2377static void
2378process_configure_notify (MetaCompositorXRender *compositor,
2379 XConfigureEvent *event)
2380{
2381 MetaDisplay *display = compositor->display;
2382 Display *xdisplay = meta_display_get_xdisplay (display);
2383 MetaCompWindow *cw = find_window_in_display (display, event->window);
2384
2385 if (cw)
2386 {
2387#if 0
2388 int x = -1, y = -1, width = -1, height = -1;
2389 int ex = -1, ey = -1, ewidth = -1, eheight = -1;
2390 MetaRectangle *rect;
2391
2392 if (cw->window) {
2393 rect = meta_window_get_rect (cw->window);
2394 x = rect->x;
2395 y = rect->y;
2396 width = rect->width;
2397 height = rect->height;
2398 }
2399 fprintf (stderrstderr, "configure notify xy (%d %d) -> (%d %d), wh (%d %d) -> (%d %d)\n",
2400 x, y, event->x, event->y,
2401 width, height, event->width, event->height);
2402#endif
2403
2404 if (compositor->debug)
2405 {
2406 fprintf (stderrstderr, "configure notify %d %d %d\n", cw->damaged,
2407 cw->shaped, cw->needs_shadow);
2408 dump_xserver_region ("\textents", display, cw->extents);
2409 fprintf (stderrstderr, "\txy (%d %d), wh (%d %d)\n",
2410 event->x, event->y, event->width, event->height);
2411 }
2412
2413 restack_win (cw, event->above);
2414 resize_win (cw, event->x, event->y, event->width, event->height,
2415 event->border_width, event->override_redirect);
2416 }
2417 else
2418 {
2419 MetaScreen *screen;
2420 MetaCompScreen *info;
2421
2422 /* Might be the root window? */
2423 screen = meta_display_screen_for_root (display, event->window);
2424 if (screen == NULL((void*)0))
2425 return;
2426
2427 info = meta_screen_get_compositor_data (screen);
2428 if (info != NULL((void*)0))
2429 {
2430 int b;
2431 for (b = 0; b < NUM_BUFFER2; b++)
2432 {
2433 if (info->root_buffers[b]) {
2434 XRenderFreePicture (xdisplay, info->root_buffers[b]);
2435 XFreePixmap (xdisplay, info->root_pixmaps[b]);
2436 info->root_buffers[b] = None0L;
2437 info->root_pixmaps[b] = None0L;
2438 }
2439 }
2440 }
2441
2442 damage_screen (screen);
2443 }
2444}
2445
2446static void
2447process_property_notify (MetaCompositorXRender *compositor,
2448 XPropertyEvent *event)
2449{
2450 MetaDisplay *display = compositor->display;
2451 Display *xdisplay = meta_display_get_xdisplay (display);
2452 MetaScreen *screen;
2453 int p;
2454 Atom background_atoms[2];
2455
2456 /* Check for the background property changing */
2457 background_atoms[0] = compositor->atom_x_root_pixmap;
2458 background_atoms[1] = compositor->atom_x_set_root;
2459
2460 for (p = 0; p < 2; p++)
2461 {
2462 if (event->atom == background_atoms[p])
2463 {
2464 screen = meta_display_screen_for_root (display, event->window);
2465 if (screen)
2466 {
2467 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
2468 Window xroot = meta_screen_get_xroot (screen);
2469
2470 if (info != NULL((void*)0) && info->root_tile)
2471 {
2472 XClearArea (xdisplay, xroot, 0, 0, 0, 0, TRUE(!(0)));
2473 XRenderFreePicture (xdisplay, info->root_tile);
2474 info->root_tile = None0L;
2475
2476 /* Damage the whole screen as we may need to redraw the
2477 background ourselves */
2478 damage_screen (screen);
2479#ifdef USE_IDLE_REPAINT1
2480 add_repair (display);
2481#endif
2482
2483 return;
2484 }
2485 }
2486 }
2487 }
2488
2489 /* Check for the opacity changing */
2490 if (event->atom == compositor->atom_net_wm_window_opacity)
2491 {
2492 MetaCompWindow *cw = find_window_in_display (display, event->window);
2493 gulong value;
2494
2495 if (!cw)
2496 {
2497 /* Applications can set this for their toplevel windows, so
2498 * this must be propagated to the window managed by the compositor
2499 */
2500 cw = find_window_for_child_window_in_display (display, event->window);
2501 }
2502
2503 if (!cw)
2504 return;
2505
2506 if (meta_prop_get_cardinal (display, event->window,
2507 compositor->atom_net_wm_window_opacity,
2508 &value) == FALSE(0))
2509 value = OPAQUE0xffffffff;
2510
2511 cw->opacity = (guint)value;
2512 determine_mode (display, cw->screen, cw);
2513 cw->needs_shadow = window_has_shadow (cw);
2514
2515 if (cw->shadow)
2516 {
2517 XRenderFreePicture (xdisplay, cw->shadow);
2518 cw->shadow = None0L;
2519 }
2520
2521 if (cw->extents)
2522 XFixesDestroyRegion (xdisplay, cw->extents);
2523 cw->extents = win_extents (cw);
2524
2525 cw->damaged = TRUE(!(0));
2526#ifdef USE_IDLE_REPAINT1
2527 add_repair (display);
2528#endif
2529
2530 return;
2531 }
2532
2533 if (event->atom == compositor->atom_net_wm_window_type) {
2534 MetaCompWindow *cw = find_window_in_display (display, event->window);
2535
2536 if (!cw)
2537 return;
2538
2539 get_window_type (display, cw);
2540 cw->needs_shadow = window_has_shadow (cw);
2541 return;
2542 }
2543}
2544
2545static void
2546expose_area (MetaScreen *screen,
2547 XRectangle *rects,
2548 int nrects)
2549{
2550 MetaDisplay *display = meta_screen_get_display (screen);
2551 Display *xdisplay = meta_display_get_xdisplay (display);
2552 XserverRegion region;
2553
2554 region = XFixesCreateRegion (xdisplay, rects, nrects);
2555
2556 dump_xserver_region ("expose_area", display, region);
2557 add_damage (screen, region);
2558}
2559
2560static void
2561process_expose (MetaCompositorXRender *compositor,
2562 XExposeEvent *event)
2563{
2564 MetaCompWindow *cw = find_window_in_display (compositor->display,
2565 event->window);
2566 MetaScreen *screen = NULL((void*)0);
2567 XRectangle rect[1];
2568 int origin_x = 0, origin_y = 0;
2569
2570 if (cw != NULL((void*)0))
2571 {
2572 screen = cw->screen;
2573 origin_x = cw->attrs.x; /* + cw->attrs.border_width; ? */
2574 origin_y = cw->attrs.y; /* + cw->attrs.border_width; ? */
2575 }
2576 else
2577 {
2578 screen = meta_display_screen_for_root (compositor->display,
2579 event->window);
2580 if (screen == NULL((void*)0))
2581 return;
2582 }
2583
2584 rect[0].x = event->x + origin_x;
2585 rect[0].y = event->y + origin_y;
2586 rect[0].width = event->width;
2587 rect[0].height = event->height;
2588
2589 expose_area (screen, rect, 1);
2590}
2591
2592static void
2593process_unmap (MetaCompositorXRender *compositor,
2594 XUnmapEvent *event)
2595{
2596 MetaCompWindow *cw;
2597
2598 if (event->from_configure)
2599 {
2600 /* Ignore unmap caused by parent's resize */
2601 return;
2602 }
2603
2604
2605 cw = find_window_in_display (compositor->display, event->window);
2606 if (cw)
2607 unmap_win (compositor->display, cw->screen, event->window);
2608}
2609
2610static void
2611process_map (MetaCompositorXRender *compositor,
2612 XMapEvent *event)
2613{
2614 MetaCompWindow *cw = find_window_in_display (compositor->display,
2615 event->window);
2616
2617 if (cw)
2618 map_win (compositor->display, cw->screen, event->window);
2619}
2620
2621static void
2622process_reparent (MetaCompositorXRender *compositor,
2623 XReparentEvent *event,
2624 MetaWindow *window)
2625{
2626 MetaScreen *screen;
2627
2628 screen = meta_display_screen_for_root (compositor->display, event->parent);
2629 if (screen != NULL((void*)0))
2630 add_win (screen, window, event->window);
2631 else
2632 destroy_win (compositor->display, event->window, FALSE(0));
2633}
2634
2635static void
2636process_create (MetaCompositorXRender *compositor,
2637 XCreateWindowEvent *event,
2638 MetaWindow *window)
2639{
2640 MetaScreen *screen;
2641 /* We are only interested in top level windows, others will
2642 be caught by normal croma functions */
2643
2644 screen = meta_display_screen_for_root (compositor->display, event->parent);
2645 if (screen == NULL((void*)0))
2646 return;
2647
2648 if (!find_window_in_display (compositor->display, event->window))
2649 add_win (screen, window, event->window);
2650}
2651
2652static void
2653process_destroy (MetaCompositorXRender *compositor,
2654 XDestroyWindowEvent *event)
2655{
2656 destroy_win (compositor->display, event->window, FALSE(0));
2657}
2658
2659static void
2660process_damage (MetaCompositorXRender *compositor,
2661 XDamageNotifyEvent *event)
2662{
2663 MetaCompWindow *cw = find_window_in_display (compositor->display,
2664 event->drawable);
2665 if (cw == NULL((void*)0))
2666 return;
2667
2668 repair_win (cw);
2669
2670#ifdef USE_IDLE_REPAINT1
2671 if (event->more == FALSE(0))
2672 add_repair (compositor->display);
2673#endif
2674}
2675
2676static void
2677process_shape (MetaCompositorXRender *compositor,
2678 XShapeEvent *event)
2679{
2680 MetaCompWindow *cw = find_window_in_display (compositor->display,
2681 event->window);
2682
2683 if (cw == NULL((void*)0))
2684 return;
2685
2686 if (event->kind == ShapeBounding0)
2687 {
2688 if (!event->shaped && cw->shaped)
2689 cw->shaped = FALSE(0);
2690
2691 resize_win (cw, cw->attrs.x, cw->attrs.y,
2692 event->width + event->x, event->height + event->y,
2693 cw->attrs.border_width, cw->attrs.override_redirect);
2694
2695 if (event->shaped && !cw->shaped)
2696 cw->shaped = TRUE(!(0));
2697
2698 if (event->shaped == True1)
2699 {
2700 cw->shape_bounds.x = cw->attrs.x + event->x;
2701 cw->shape_bounds.y = cw->attrs.y + event->y;
2702 cw->shape_bounds.width = event->width;
2703 cw->shape_bounds.height = event->height;
2704 }
2705 else
2706 {
2707 cw->shape_bounds.x = cw->attrs.x;
2708 cw->shape_bounds.y = cw->attrs.y;
2709 cw->shape_bounds.width = cw->attrs.width;
2710 cw->shape_bounds.height = cw->attrs.height;
2711 }
2712 }
2713}
2714
2715#ifdef HAVE_PRESENT
2716static void
2717xrender_present_complete(MetaScreen *screen,
2718 XPresentCompleteNotifyEvent *ce)
2719{
2720 MetaCompScreen *info = meta_screen_get_compositor_data (screen);
2721
2722 info->present_pending = False0;
2723 repair_screen(screen);
2724}
2725#endif /* HAVE_PRESENT */
2726
2727static void
2728process_generic(MetaCompositorXRender *compositor,
2729 XGenericEvent *event)
2730{
2731 XGenericEventCookie *ge = (XGenericEventCookie *) event;
2732 Display *xdisplay = meta_display_get_xdisplay (compositor->display);
2733 XGetEventData(xdisplay, ge);
2734
2735 switch (ge->evtype)
2736 {
2737#ifdef HAVE_PRESENT
2738 case PresentConfigureNotify0:
2739 break;
2740 case PresentCompleteNotify1:
2741 {
2742 if (ge->extension == compositor->present_major)
2743 {
2744 XPresentCompleteNotifyEvent *ce = ge->data;
2745 MetaScreen *screen = find_screen_from_output(compositor->display, ce->window);
2746 if (screen)
2747 xrender_present_complete(screen, ce);
2748 }
2749 }
2750 break;
2751#endif /* HAVE_PRESENT */
2752 }
2753 XFreeEventData(xdisplay, ge);
2754}
2755
2756static int
2757timeout_debug (MetaCompositorXRender *compositor)
2758{
2759 compositor->show_redraw = (g_getenv ("CROMA_DEBUG_REDRAWS") != NULL((void*)0));
2760 compositor->debug = (g_getenv ("CROMA_DEBUG_COMPOSITOR") != NULL((void*)0));
2761
2762 return FALSE(0);
2763}
2764
2765static void
2766xrender_add_window (MetaCompositor *compositor,
2767 MetaWindow *window,
2768 Window xwindow,
2769 XWindowAttributes *attrs)
2770{
2771#ifdef HAVE_COMPOSITE_EXTENSIONS1
2772 MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
2773 MetaScreen *screen = meta_screen_for_x_screen (attrs->screen);
2774
2775 meta_error_trap_push (xrc->display);
2776 add_win (screen, window, xwindow);
2777 meta_error_trap_pop (xrc->display, FALSE(0));
2778#endif
2779}
2780
2781static void
2782xrender_remove_window (MetaCompositor *compositor,
2783 Window xwindow)
2784{
2785#ifdef HAVE_COMPOSITE_EXTENSIONS1
2786#endif
2787}
2788
2789static void
2790show_overlay_window (MetaScreen *screen,
2791 Window cow)
2792{
2793 MetaDisplay *display = meta_screen_get_display (screen);
2794 Display *xdisplay = meta_display_get_xdisplay (display);
2795 XserverRegion region;
2796
2797 region = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
2798
2799 XFixesSetWindowShapeRegion (xdisplay, cow, ShapeBounding0, 0, 0, 0);
2800 XFixesSetWindowShapeRegion (xdisplay, cow, ShapeInput2, 0, 0, region);
2801
2802 XFixesDestroyRegion (xdisplay, region);
2803
2804 damage_screen (screen);
2805}
2806
2807static void
2808hide_overlay_window (MetaScreen *screen,
2809 Window cow)
2810{
2811 MetaDisplay *display = meta_screen_get_display (screen);
2812 Display *xdisplay = meta_display_get_xdisplay (display);
2813 XserverRegion region;
2814
2815 region = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
2816 XFixesSetWindowShapeRegion (xdisplay, cow, ShapeBounding0, 0, 0, region);
2817 XFixesDestroyRegion (xdisplay, region);
2818}
2819
2820static Window
2821get_output_window (MetaScreen *screen)
2822{
2823 MetaDisplay *display = meta_screen_get_display (screen);
2824 Display *xdisplay = meta_display_get_xdisplay (display);
2825 Window output, xroot;
2826
2827 xroot = meta_screen_get_xroot (screen);
2828
2829 output = XCompositeGetOverlayWindow (xdisplay, xroot);
2830 XSelectInput (xdisplay, output, ExposureMask(1L<<15));
2831
2832 return output;
2833}
2834
2835static void
2836xrender_manage_screen (MetaCompositor *compositor,
2837 MetaScreen *screen)
2838{
2839#ifdef HAVE_COMPOSITE_EXTENSIONS1
2840 MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
2841 MetaCompScreen *info;
2842 MetaDisplay *display = meta_screen_get_display (screen);
2843 Display *xdisplay = meta_display_get_xdisplay (display);
2844 CdkDisplay *cdk_display = cdk_x11_lookup_xdisplay (xdisplay);
2845 XRenderPictureAttributes pa;
2846 XRenderPictFormat *visual_format;
2847 int screen_number = meta_screen_get_screen_number (screen);
2848 Window xroot = meta_screen_get_xroot (screen);
2849 int b;
2850
2851 /* Check if the screen is already managed */
2852 if (meta_screen_get_compositor_data (screen))
2853 return;
2854
2855 cdk_x11_display_error_trap_push (cdk_display);
2856 XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual1);
2857 XSync (xdisplay, FALSE(0));
2858
2859 if (cdk_x11_display_error_trap_pop (cdk_display))
2860 {
2861 g_warning ("Another compositing manager is running on screen %i",
2862 screen_number);
2863 return;
2864 }
2865
2866 info = g_new0 (MetaCompScreen, 1)((MetaCompScreen *) g_malloc0_n ((1), sizeof (MetaCompScreen)
))
;
2867 info->screen = screen;
2868
2869 meta_screen_set_compositor_data (screen, info);
2870
2871 visual_format = XRenderFindVisualFormat (xdisplay, DefaultVisual (xdisplay,((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
2872 screen_number)((&((_XPrivDisplay)(xdisplay))->screens[screen_number]
)->root_visual)
);
2873 if (!visual_format)
2874 {
2875 g_warning ("Cannot find visual format on screen %i", screen_number);
2876 return;
2877 }
2878
2879 info->output = get_output_window (screen);
2880
2881 pa.subwindow_mode = IncludeInferiors1;
2882 info->root_picture = XRenderCreatePicture (xdisplay, info->output,
2883 visual_format,
2884 CPSubwindowMode(1 << 8), &pa);
2885 if (info->root_picture == None0L)
2886 {
2887 g_warning ("Cannot create root picture on screen %i", screen_number);
2888 return;
2889 }
2890
2891 for (b = 0; b < NUM_BUFFER2; b++) {
2892 info->root_buffers[b] = None0L;
2893 info->root_pixmaps[b] = None0L;
2894 }
2895 info->black_picture = solid_picture (display, screen, TRUE(!(0)), 1, 0, 0, 0);
2896
2897 info->root_tile = None0L;
2898 info->all_damage = None0L;
2899
2900 info->windows = NULL((void*)0);
2901 info->windows_by_xid = g_hash_table_new (g_direct_hash, g_direct_equal);
2902
2903 info->focus_window = meta_display_get_focus_window (display);
2904
2905 info->compositor_active = TRUE(!(0));
2906 info->overlays = 0;
2907 info->clip_changed = TRUE(!(0));
2908
2909 info->have_shadows = (g_getenv("META_DEBUG_NO_SHADOW") == NULL((void*)0));
2910 if (info->have_shadows)
2911 {
2912 meta_verbosemeta_verbose_real ("Enabling shadows\n");
2913 generate_shadows (info);
2914 }
2915 else
2916 meta_verbosemeta_verbose_real ("Disabling shadows\n");
2917
2918#ifdef HAVE_PRESENT
2919 if (xrc->has_present)
2920 {
2921 info->present_eid = XPresentSelectInput(xdisplay, info->output,
2922 PresentCompleteNotifyMask2);
2923 info->use_present = TRUE(!(0));
2924 info->present_pending = FALSE(0);
2925 }
2926 else
2927 {
2928 info->use_present = FALSE(0);
2929 g_warning ("XPresent not available");
2930 }
2931#endif /* HAVE_PRESENT */
2932
2933 XClearArea (xdisplay, info->output, 0, 0, 0, 0, TRUE(!(0)));
2934
2935 meta_screen_set_cm_selection (screen);
2936
2937 /* Now we're up and running we can show the output if needed */
2938 show_overlay_window (screen, info->output);
2939#endif
2940}
2941
2942static void
2943xrender_unmanage_screen (MetaCompositor *compositor,
2944 MetaScreen *screen)
2945{
2946#ifdef HAVE_COMPOSITE_EXTENSIONS1
2947 MetaDisplay *display = meta_screen_get_display (screen);
2948 Display *xdisplay = meta_display_get_xdisplay (display);
2949 MetaCompScreen *info;
2950 Window xroot = meta_screen_get_xroot (screen);
2951 GList *index;
2952
2953 info = meta_screen_get_compositor_data (screen);
2954
2955 /* This screen isn't managed */
2956 if (info == NULL((void*)0))
2957 return;
2958
2959 hide_overlay_window (screen, info->output);
2960
2961 /* Destroy the windows */
2962 for (index = info->windows; index; index = index->next)
2963 {
2964 MetaCompWindow *cw = (MetaCompWindow *) index->data;
2965 free_win (cw, TRUE(!(0)));
2966 }
2967 g_list_free (info->windows);
2968 g_hash_table_destroy (info->windows_by_xid);
2969
2970 if (info->root_picture)
2971 XRenderFreePicture (xdisplay, info->root_picture);
2972
2973 if (info->black_picture)
2974 XRenderFreePicture (xdisplay, info->black_picture);
2975
2976 if (info->have_shadows)
2977 {
2978 int i;
2979
2980 for (i = 0; i < LAST_SHADOW_TYPE; i++)
2981 g_free (info->shadows[i]->gaussian_map);
2982 }
2983
2984 XCompositeUnredirectSubwindows (xdisplay, xroot,
2985 CompositeRedirectManual1);
2986 meta_screen_unset_cm_selection (screen);
2987
2988 XCompositeReleaseOverlayWindow (xdisplay, info->output);
2989
2990 g_free (info);
2991
2992 meta_screen_set_compositor_data (screen, NULL((void*)0));
2993#endif
2994}
2995
2996static void
2997xrender_set_updates (MetaCompositor *compositor,
2998 MetaWindow *window,
2999 gboolean updates)
3000{
3001#ifdef HAVE_COMPOSITE_EXTENSIONS1
3002
3003#endif
3004}
3005
3006static void
3007xrender_destroy (MetaCompositor *compositor)
3008{
3009#ifdef HAVE_COMPOSITE_EXTENSIONS1
3010 g_free (compositor);
3011#endif
3012}
3013
3014#if 0
3015/* Taking these out because they're empty and never called, and the
3016 * compiler complains -- tthurman
3017 */
3018
3019static void
3020xrender_begin_move (MetaCompositor *compositor,
3021 MetaWindow *window,
3022 MetaRectangle *initial,
3023 int grab_x,
3024 int grab_y)
3025{
3026#ifdef HAVE_COMPOSITE_EXTENSIONS1
3027#endif
3028}
3029
3030static void
3031xrender_update_move (MetaCompositor *compositor,
3032 MetaWindow *window,
3033 int x,
3034 int y)
3035{
3036#ifdef HAVE_COMPOSITE_EXTENSIONS1
3037#endif
3038}
3039
3040static void
3041xrender_end_move (MetaCompositor *compositor,
3042 MetaWindow *window)
3043{
3044#ifdef HAVE_COMPOSITE_EXTENSIONS1
3045#endif
3046}
3047
3048#endif /* 0 */
3049
3050static void
3051xrender_free_window (MetaCompositor *compositor,
3052 MetaWindow *window)
3053{
3054#ifdef HAVE_COMPOSITE_EXTENSIONS1
3055 MetaCompositorXRender *xrc;
3056 MetaFrame *frame;
3057 Window xwindow;
3058
3059 xrc = (MetaCompositorXRender *) compositor;
3060 frame = meta_window_get_frame (window);
3061 xwindow = None0L;
3062
3063 if (frame)
3064 {
3065 xwindow = meta_frame_get_xwindow (frame);
3066 }
3067 else
3068 {
3069 /* FIXME: When an undecorated window is hidden this is called, but the
3070 * window does not get readded if it is subsequentally shown again. See:
3071 * http://bugzilla.gnome.org/show_bug.cgi?id=504876
3072 */
3073 /* xwindow = meta_window_get_xwindow (window); */
3074 }
3075
3076 if (xwindow != None0L)
3077 destroy_win (xrc->display, xwindow, FALSE(0));
3078#endif
3079}
3080
3081
3082static void
3083xrender_process_event (MetaCompositor *compositor,
3084 XEvent *event,
3085 MetaWindow *window)
3086{
3087#ifdef HAVE_COMPOSITE_EXTENSIONS1
3088 MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
3089 /*
3090 * This trap is so that none of the compositor functions cause
3091 * X errors. This is really a hack, but I'm afraid I don't understand
3092 * enough about Croma/X to know how else you are supposed to do it
3093 */
3094 meta_error_trap_push (xrc->display);
3095 switch (event->type)
3096 {
3097 case CirculateNotify26:
3098 process_circulate_notify (xrc, (XCirculateEvent *) event);
3099 break;
3100
3101 case ConfigureNotify22:
3102 process_configure_notify (xrc, (XConfigureEvent *) event);
3103 break;
3104
3105 case PropertyNotify28:
3106 process_property_notify (xrc, (XPropertyEvent *) event);
3107 break;
3108
3109 case Expose12:
3110 process_expose (xrc, (XExposeEvent *) event);
3111 break;
3112
3113 case UnmapNotify18:
3114 process_unmap (xrc, (XUnmapEvent *) event);
3115 break;
3116
3117 case MapNotify19:
3118 process_map (xrc, (XMapEvent *) event);
3119 break;
3120
3121 case ReparentNotify21:
3122 process_reparent (xrc, (XReparentEvent *) event, window);
3123 break;
3124
3125 case CreateNotify16:
3126 process_create (xrc, (XCreateWindowEvent *) event, window);
3127 break;
3128
3129 case DestroyNotify17:
3130 process_destroy (xrc, (XDestroyWindowEvent *) event);
3131 break;
3132
3133 case GenericEvent35:
3134 process_generic (xrc, (XGenericEvent *) event);
3135 break;
3136
3137 default:
3138 if (event->type == meta_display_get_damage_event_base (xrc->display) + XDamageNotify0)
3139 process_damage (xrc, (XDamageNotifyEvent *) event);
3140#ifdef HAVE_SHAPE
3141 else if (event->type == meta_display_get_shape_event_base (xrc->display) + ShapeNotify0)
3142 process_shape (xrc, (XShapeEvent *) event);
3143#endif /* HAVE_SHAPE */
3144 else
3145 {
3146 meta_error_trap_pop (xrc->display, FALSE(0));
3147 return;
3148 }
3149 break;
3150 }
3151
3152 meta_error_trap_pop (xrc->display, FALSE(0));
3153#ifndef USE_IDLE_REPAINT1
3154 repair_display (xrc->display);
3155#endif
3156
3157 return;
3158#endif
3159}
3160
3161static cairo_surface_t *
3162xrender_get_window_surface (MetaCompositor *compositor,
3163 MetaWindow *window)
3164{
3165#ifdef HAVE_COMPOSITE_EXTENSIONS1
3166 MetaFrame *frame;
3167 Window xwindow;
3168 MetaScreen *screen;
3169 MetaCompWindow *cw;
3170 MetaCompositorXRender *xrc;
3171 Display *display;
3172 Pixmap pixmap;
3173
3174 frame = meta_window_get_frame (window);
3175
3176 if (frame)
3177 xwindow = meta_frame_get_xwindow (frame);
3178 else
3179 xwindow = meta_window_get_xwindow (window);
3180
3181 screen = meta_window_get_screen (window);
3182 cw = find_window_for_screen (screen, xwindow);
3183
3184 if (cw == NULL((void*)0))
3185 return NULL((void*)0);
3186
3187 xrc = (MetaCompositorXRender *) compositor;
3188 display = meta_display_get_xdisplay (xrc->display);
3189
3190 if (meta_window_is_shaded (window))
3191 pixmap = cw->shaded_back_pixmap;
3192 else
3193 pixmap = cw->back_pixmap;
3194
3195 return cairo_xlib_surface_create (display, pixmap, cw->attrs.visual,
3196 cw->attrs.width, cw->attrs.height);
3197#endif
3198}
3199
3200static void
3201xrender_set_active_window (MetaCompositor *compositor,
3202 MetaScreen *screen,
3203 MetaWindow *window)
3204{
3205#ifdef HAVE_COMPOSITE_EXTENSIONS1
3206 MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
3207 MetaDisplay *display;
3208 Display *xdisplay;
3209 MetaCompWindow *old_focus = NULL((void*)0), *new_focus = NULL((void*)0);
3210 MetaCompScreen *info = NULL((void*)0);
3211 MetaWindow *old_focus_win = NULL((void*)0);
3212
3213 if (compositor == NULL((void*)0))
1
Assuming 'compositor' is not equal to NULL
2
Taking false branch
3214 return;
3215
3216 display = xrc->display;
3217 xdisplay = meta_display_get_xdisplay (display);
3218 info = meta_screen_get_compositor_data (screen);
3219
3220 if (info != NULL((void*)0))
3
Assuming 'info' is equal to NULL
4
Taking false branch
3221 {
3222 old_focus_win = info->focus_window;
3223 }
3224
3225 if (old_focus_win
4.1
'old_focus_win' is null
)
5
Taking false branch
3226 {
3227 MetaFrame *f = meta_window_get_frame (old_focus_win);
3228
3229 old_focus = find_window_for_screen (screen,
3230 f ? meta_frame_get_xwindow (f) :
3231 meta_window_get_xwindow (old_focus_win));
3232 }
3233
3234 if (window)
6
Assuming 'window' is non-null
7
Taking true branch
3235 {
3236 MetaFrame *f = meta_window_get_frame (window);
3237 new_focus = find_window_for_screen (screen,
3238 f ? meta_frame_get_xwindow (f) :
8
Assuming 'f' is null
9
'?' condition is false
3239 meta_window_get_xwindow (window));
3240 }
3241
3242 if (info
9.1
'info' is equal to NULL
!= NULL((void*)0))
10
Taking false branch
3243 {
3244 info->focus_window = window;
3245 }
3246
3247 if (old_focus
10.1
'old_focus' is null
)
11
Taking false branch
3248 {
3249 XserverRegion damage;
3250
3251 /* Tear down old shadows */
3252 old_focus->shadow_type = META_SHADOW_MEDIUM;
3253 determine_mode (display, screen, old_focus);
3254 old_focus->needs_shadow = window_has_shadow (old_focus);
3255
3256 if (old_focus->attrs.map_state == IsViewable2)
3257 {
3258 if (old_focus->shadow)
3259 {
3260 XRenderFreePicture (xdisplay, old_focus->shadow);
3261 old_focus->shadow = None0L;
3262 }
3263
3264 if (old_focus->extents)
3265 {
3266 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
3267 XFixesCopyRegion (xdisplay, damage, old_focus->extents);
3268 XFixesDestroyRegion (xdisplay, old_focus->extents);
3269 }
3270 else
3271 damage = None0L;
3272
3273 /* Build new extents */
3274 old_focus->extents = win_extents (old_focus);
3275
3276 if (damage)
3277 XFixesUnionRegion (xdisplay, damage, damage, old_focus->extents);
3278 else
3279 {
3280 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
3281 XFixesCopyRegion (xdisplay, damage, old_focus->extents);
3282 }
3283
3284 dump_xserver_region ("resize_win", display, damage);
3285 add_damage (screen, damage);
3286
3287 if (info != NULL((void*)0))
3288 {
3289 info->clip_changed = TRUE(!(0));
3290 }
3291 }
3292 }
3293
3294 if (new_focus)
12
Assuming 'new_focus' is non-null
13
Taking true branch
3295 {
3296 XserverRegion damage;
3297
3298 new_focus->shadow_type = META_SHADOW_LARGE;
3299 determine_mode (display, screen, new_focus);
3300 new_focus->needs_shadow = window_has_shadow (new_focus);
3301
3302 if (new_focus->shadow)
14
Assuming field 'shadow' is 0
15
Taking false branch
3303 {
3304 XRenderFreePicture (xdisplay, new_focus->shadow);
3305 new_focus->shadow = None0L;
3306 }
3307
3308 if (new_focus->extents
15.1
Field 'extents' is 0
)
16
Taking false branch
3309 {
3310 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
3311 XFixesCopyRegion (xdisplay, damage, new_focus->extents);
3312 XFixesDestroyRegion (xdisplay, new_focus->extents);
3313 }
3314 else
3315 damage = None0L;
3316
3317 /* Build new extents */
3318 new_focus->extents = win_extents (new_focus);
17
Calling 'win_extents'
3319
3320 if (damage)
3321 XFixesUnionRegion (xdisplay, damage, damage, new_focus->extents);
3322 else
3323 {
3324 damage = XFixesCreateRegion (xdisplay, NULL((void*)0), 0);
3325 XFixesCopyRegion (xdisplay, damage, new_focus->extents);
3326 }
3327
3328 dump_xserver_region ("resize_win", display, damage);
3329 add_damage (screen, damage);
3330
3331 if (info != NULL((void*)0))
3332 {
3333 info->clip_changed = TRUE(!(0));
3334 }
3335 }
3336#ifdef USE_IDLE_REPAINT1
3337 add_repair (display);
3338#endif
3339#endif
3340}
3341
3342static void
3343xrender_maximize_window (MetaCompositor *compositor,
3344 MetaWindow *window)
3345{
3346#ifdef HAVE_COMPOSITE_EXTENSIONS1
3347 MetaFrame *frame = meta_window_get_frame (window);
3348 Window xid = frame ? meta_frame_get_xwindow (frame) : meta_window_get_xwindow (window);
3349 MetaCompWindow *cw = find_window_in_display (meta_window_get_display (window), xid);
3350
3351 if (!cw)
3352 return;
3353
3354 cw->needs_shadow = window_has_shadow (cw);
3355#endif
3356}
3357
3358static void
3359xrender_unmaximize_window (MetaCompositor *compositor,
3360 MetaWindow *window)
3361{
3362#ifdef HAVE_COMPOSITE_EXTENSIONS1
3363 MetaFrame *frame = meta_window_get_frame (window);
3364 Window xid = frame ? meta_frame_get_xwindow (frame) : meta_window_get_xwindow (window);
3365 MetaCompWindow *cw = find_window_in_display (meta_window_get_display (window), xid);
3366
3367 if (!cw)
3368 return;
3369
3370 cw->needs_shadow = window_has_shadow (cw);
3371#endif
3372}
3373
3374static MetaCompositor comp_info = {
3375 xrender_destroy,
3376 xrender_manage_screen,
3377 xrender_unmanage_screen,
3378 xrender_add_window,
3379 xrender_remove_window,
3380 xrender_set_updates,
3381 xrender_process_event,
3382 xrender_get_window_surface,
3383 xrender_set_active_window,
3384 xrender_free_window,
3385 xrender_maximize_window,
3386 xrender_unmaximize_window,
3387};
3388
3389MetaCompositor *
3390meta_compositor_xrender_new (MetaDisplay *display)
3391{
3392#ifdef HAVE_COMPOSITE_EXTENSIONS1
3393 char *atom_names[] = {
3394 "_XROOTPMAP_ID",
3395 "_XSETROOT_ID",
3396 "_NET_WM_WINDOW_OPACITY",
3397 "_NET_WM_WINDOW_TYPE_DND",
3398 "_NET_WM_WINDOW_TYPE",
3399 "_NET_WM_WINDOW_TYPE_DESKTOP",
3400 "_NET_WM_WINDOW_TYPE_DOCK",
3401 "_NET_WM_WINDOW_TYPE_MENU",
3402 "_NET_WM_WINDOW_TYPE_DIALOG",
3403 "_NET_WM_WINDOW_TYPE_NORMAL",
3404 "_NET_WM_WINDOW_TYPE_UTILITY",
3405 "_NET_WM_WINDOW_TYPE_SPLASH",
3406 "_NET_WM_WINDOW_TYPE_TOOLBAR",
3407 "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
3408 "_NET_WM_WINDOW_TYPE_TOOLTIP"
3409 };
3410 Atom atoms[G_N_ELEMENTS(atom_names)(sizeof (atom_names) / sizeof ((atom_names)[0]))];
3411 MetaCompositorXRender *xrc;
3412 MetaCompositor *compositor;
3413 Display *xdisplay = meta_display_get_xdisplay (display);
3414
3415 xrc = g_new (MetaCompositorXRender, 1)((MetaCompositorXRender *) g_malloc_n ((1), sizeof (MetaCompositorXRender
)))
;
3416 xrc->compositor = comp_info;
3417
3418 compositor = (MetaCompositor *) xrc;
3419
3420 xrc->display = display;
3421
3422 meta_verbosemeta_verbose_real ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names)(sizeof (atom_names) / sizeof ((atom_names)[0])));
3423 XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names)(sizeof (atom_names) / sizeof ((atom_names)[0])),
3424 False0, atoms);
3425
3426 xrc->atom_x_root_pixmap = atoms[0];
3427 xrc->atom_x_set_root = atoms[1];
3428 xrc->atom_net_wm_window_opacity = atoms[2];
3429 xrc->atom_net_wm_window_type_dnd = atoms[3];
3430 xrc->atom_net_wm_window_type = atoms[4];
3431 xrc->atom_net_wm_window_type_desktop = atoms[5];
3432 xrc->atom_net_wm_window_type_dock = atoms[6];
3433 xrc->atom_net_wm_window_type_menu = atoms[7];
3434 xrc->atom_net_wm_window_type_dialog = atoms[8];
3435 xrc->atom_net_wm_window_type_normal = atoms[9];
3436 xrc->atom_net_wm_window_type_utility = atoms[10];
3437 xrc->atom_net_wm_window_type_splash = atoms[11];
3438 xrc->atom_net_wm_window_type_toolbar = atoms[12];
3439 xrc->atom_net_wm_window_type_dropdown_menu = atoms[13];
3440 xrc->atom_net_wm_window_type_tooltip = atoms[14];
3441 xrc->show_redraw = FALSE(0);
3442 xrc->debug = FALSE(0);
3443#ifdef HAVE_PRESENT
3444 xrc->has_present = XPresentQueryExtension(xdisplay, &xrc->present_major, NULL((void*)0), NULL((void*)0));
3445#endif /* HAVE_PRESENT */
3446
3447#ifdef USE_IDLE_REPAINT1
3448 meta_verbosemeta_verbose_real ("Using idle repaint\n");
3449 xrc->repaint_id = 0;
3450#endif
3451
3452 xrc->enabled = TRUE(!(0));
3453 g_timeout_add (2000, (GSourceFunc) timeout_debug, xrc);
3454
3455 return compositor;
3456#else
3457 return NULL((void*)0);
3458#endif
3459}
3460
3461#endif /* HAVE_COMPOSITE_EXTENSIONS */
3462