summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2005-02-01 21:26:19 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2005-02-01 21:26:19 +0000
commitb7fa1995e76f323ce233fc2d3d43aa74038ad17f (patch)
treee03cbe28cc400827ac70eb0e07130c691e656d52
parent2695f72ad01437bdd805f06419aa15605ef4ef99 (diff)
downloadmetacity-b7fa1995e76f323ce233fc2d3d43aa74038ad17f.tar.gz
new files
Tue Feb 1 16:21:40 2005 Søren Sandmann <sandmann@redhat.com> * src/snow.[ch]: new files * src/cwindow.c: Tweak the shadows a bit, remove unused code. Make sure we don't crash when we try to freeze a non-existing window. * src/compositor.c (update_world): Hook up the snow. * src/Makefile.am (metacity_SOURCES): Add snow.[ch] * README: Add a note about the branch
-rw-r--r--ChangeLog13
-rw-r--r--README31
-rw-r--r--src/Makefile.am2
-rw-r--r--src/compositor.c58
-rw-r--r--src/cwindow.c120
-rw-r--r--src/snow.c358
-rw-r--r--src/snow.h16
-rw-r--r--src/window.c2
8 files changed, 504 insertions, 96 deletions
diff --git a/ChangeLog b/ChangeLog
index d35fb45d..302af674 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Tue Feb 1 16:21:40 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * src/snow.[ch]: new files
+
+ * src/cwindow.c: Tweak the shadows a bit, remove unused code. Make
+ sure we don't crash when we try to freeze a non-existing window.
+
+ * src/compositor.c (update_world): Hook up the snow.
+
+ * src/Makefile.am (metacity_SOURCES): Add snow.[ch]
+
+ * README: Add a note about the branch
+
Wed Jan 26 18:00:35 2005 Søren Sandmann <sandmann@redhat.com>
* src/cwindow.c: Add Gaussian shadows, lifted from xcompmgr. Add
diff --git a/README b/README
index f2a206db..6d85d361 100644
--- a/README
+++ b/README
@@ -1,3 +1,34 @@
+This is the 'spifficity' branch of metacity. It is intended to take advantage of
+new X extensions such as composite, damage and fixes. Some brokenness should be
+expected.
+
+Somewhat surprisingly, the better the video card you have, the worse
+performance you should expect. The technical reason for this is that
+better video cards usually have more frame-buffer memory, so more
+windows will end up being put in the framebuffer. This casues
+software rendering to slow down because reading from the framebuffer
+is really slow.
+
+To get reasonable performance, try adding
+
+ Option "NoAccel"
+
+to the "Device" section of your /etc/X11/xorg.conf file. This will
+likely improve performance a lot when a compositing manager is
+running, but also hurt performance a lot when no compositing manager
+is running.
+
+Besides the drop-shadows which were lifted from Keith Packard's
+xcompmgr, you should also see gtk+ (> 2.6) applications applications
+resize a lot more smoothly. If someone adds support for the
+_NET_WM_SYNC_REQUEST protocol to Qt, you should see Qt applications
+resize smoothly too.
+
+
+
+Original README:
+
+
Metacity is not a meta-City as in an urban center, but rather
Meta-ness as in the state of being meta. i.e. metacity : meta as
opacity : opaque. Also it may have something to do with the Meta key
diff --git a/src/Makefile.am b/src/Makefile.am
index 4ad59658..2535656d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,6 +70,8 @@ metacity_SOURCES= \
screen.h \
session.c \
session.h \
+ snow.c \
+ snow.h \
stack.c \
stack.h \
tabpopup.c \
diff --git a/src/compositor.c b/src/compositor.c
index 4b87d5be..afd5c870 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -29,6 +29,7 @@
#include "matrix.h"
#include <math.h>
#include "cwindow.h"
+#include "snow.h"
#ifdef HAVE_COMPOSITE_EXTENSIONS
#include <X11/extensions/Xcomposite.h>
@@ -42,7 +43,9 @@
struct MetaCompositor
{
MetaDisplay *display;
-
+
+ World *world;
+
int composite_error_base;
int composite_event_base;
int damage_error_base;
@@ -88,6 +91,33 @@ print_region (Display *dpy, const char *name, XserverRegion region)
XFree (rects);
}
+static gboolean
+update_world (gpointer data)
+{
+ static double time;
+
+ MetaCompositor *compositor = data;
+ World *world = compositor->world;
+ MetaScreen *screen = world_get_screen (world);
+ XserverRegion region;
+
+ region = world_invalidate (world);
+ screen = world_get_screen (world);
+
+ meta_compositor_invalidate_region (compositor, screen, region);
+ XFixesDestroyRegion (compositor->display->xdisplay, region);
+
+ world_set_time (world, time); /* FIXME */
+
+ region = world_invalidate (world);
+ meta_compositor_invalidate_region (compositor, screen, region);
+ XFixesDestroyRegion (compositor->display->xdisplay, region);
+
+ time += 0.0005;
+
+ return TRUE;
+}
+
MetaCompositor*
meta_compositor_new (MetaDisplay *display)
{
@@ -173,7 +203,7 @@ meta_compositor_new (MetaDisplay *display)
free_window_hash_value);
compositor->enabled = TRUE;
-
+
return compositor;
#else /* HAVE_COMPOSITE_EXTENSIONS */
return (void*) 0xdeadbeef; /* non-NULL value */
@@ -273,10 +303,13 @@ create_root_buffer (MetaScreen *screen, Pixmap *pixmap)
value.function = GXcopy;
value.subwindow_mode = IncludeInferiors;
- gc = XCreateGC (display, buffer_pixmap, GCFunction | GCSubwindowMode, &value);
+ gc = XCreateGC (display, buffer_pixmap,
+ GCFunction | GCSubwindowMode, &value);
XSetForeground (display, gc, WhitePixel (display, screen->number));
XSetForeground (display, gc, 0x00ff0099);
+
+ XFillRectangle (display, buffer_pixmap, gc, 0, 0, screen->width, screen->height);
format = XRenderFindVisualFormat (display,
DefaultVisual (display,
@@ -390,7 +423,7 @@ paint_screen (MetaCompositor *compositor,
XFixesSetPictureClipRegion (xdisplay, buffer_picture, 0, 0, None);
- if (compositor->debug_updates)
+ if (compositor->debug_updates)
{
#define ALPHA 0.5
XRenderColor hilight = { ALPHA * 0xFFFF, ALPHA * 0xFFFF, ALPHA * 0x0000, ALPHA * 0xFFFF };
@@ -400,6 +433,8 @@ paint_screen (MetaCompositor *compositor,
XSync (xdisplay, False);
g_usleep (20000);
}
+
+ world_paint (compositor->world, buffer_picture);
paint_buffer (screen, pixmap, damage_region);
@@ -466,6 +501,19 @@ ensure_repair_idle (MetaCompositor *compositor)
if (compositor->repair_idle != 0)
return;
+ if (!compositor->world)
+ {
+ compositor->world = world_new (compositor->display->xdisplay,
+ meta_display_screen_for_x_screen (
+ compositor->display,
+ ScreenOfDisplay (compositor->display->xdisplay,
+ DefaultScreen (compositor->display->xdisplay))));
+
+ g_print ("screen %p\n", world_get_screen (compositor->world));
+
+ g_timeout_add_full (G_PRIORITY_LOW, 25, update_world, compositor, NULL);
+ }
+
compositor->repair_idle = g_idle_add_full (META_PRIORITY_COMPOSITE,
repair_now, compositor, NULL);
@@ -605,7 +653,7 @@ process_map (MetaCompositor *compositor,
/* See if window was mapped as child of root */
screen = meta_display_screen_for_root (compositor->display,
event->event);
-
+
if (screen == NULL || screen->root_picture == None)
{
meta_topic (META_DEBUG_COMPOSITOR,
diff --git a/src/cwindow.c b/src/cwindow.c
index 5698ef54..a8a45e6b 100644
--- a/src/cwindow.c
+++ b/src/cwindow.c
@@ -7,9 +7,9 @@
#include <math.h>
#include <string.h>
-#define SHADOW_RADIUS 14
-#define SHADOW_OPACITY (.75)
-#define SHADOW_OFFSET -17
+#define SHADOW_RADIUS 6
+#define SHADOW_OPACITY (.25)
+#define SHADOW_OFFSET -6
static Picture shadow_picture (Display *dpy, Window root,
double opacity, int width, int height, int *wp, int *hp);
@@ -62,7 +62,7 @@ struct CWindow
unsigned int viewable : 1;
unsigned int input_only : 1;
unsigned int translucent : 1;
-
+
unsigned int screen_index : 8;
Visual *visual;
@@ -146,7 +146,7 @@ cwindow_extents (CWindow *cwindow)
if (cwindow->shadow)
{
r.x = geometry->x + SHADOW_OFFSET;
- r.y = geometry->y + SHADOW_OFFSET;
+ r.y = geometry->y;
r.width = cwindow->shadow_width;
r.height = cwindow->shadow_height;
}
@@ -424,9 +424,13 @@ cwindow_set_height (CWindow *cwindow, int height)
void
cwindow_set_viewable (CWindow *cwindow, gboolean viewable)
{
- cwindow->viewable = viewable;
-}
-
+ viewable = !!viewable;
+ if (cwindow->viewable != viewable)
+ {
+ cwindow_queue_paint (cwindow);
+ cwindow->viewable = viewable;
+ }
+}
void
cwindow_set_border_width (CWindow *cwindow, int border_width)
@@ -539,11 +543,13 @@ compute_transform (int x, int y,
matrix3_translate (&matrix, (gdouble)-x, (gdouble)-y);
#endif
+#if 0
g_print ("mapping from %d %d %d %d to (%d %d) (%d %d) (%d %d) (%d %d)\n", x, y, width, height,
tmp.points[0].x, tmp.points[0].y,
tmp.points[1].x, tmp.points[1].y,
tmp.points[2].x, tmp.points[2].y,
tmp.points[3].x, tmp.points[3].y);
+#endif
transform_matrix_perspective (x, y,
x + width - 1,
@@ -562,86 +568,19 @@ compute_transform (int x, int y,
convert_matrix (&matrix, transform);
}
-#if 0
-void
-cwindow_draw_warped (CWindow *cwindow,
- MetaScreen *screen,
- Picture picture,
- Quad *destination)
-{
- MetaCompositor *compositor;
- Display *display;
-
- Picture wpicture;
- XRenderPictureAttributes pa;
- XRenderPictFormat *format;
-
- XTransform transform;
-
- if (!cwindow)
- return;
-
- if (cwindow_get_input_only (cwindow))
- return;
-
- if (!cwindow_get_viewable (cwindow))
- return;
-
- compositor = cwindow_get_compositor (cwindow);
- display = meta_compositor_get_display (compositor)->xdisplay;
-
-
- format = XRenderFindVisualFormat (meta_compositor_get_display (compositor)->xdisplay,
- cwindow_get_visual (cwindow));
- pa.subwindow_mode = IncludeInferiors;
- g_assert (meta_compositor_get_display (compositor));
-
- wpicture = XRenderCreatePicture (display, cwindow_get_drawable (cwindow), format, CPSubwindowMode, &pa);
-
- g_assert (wpicture);
-
- compute_transform (0, 0, cwindow_get_width (cwindow), cwindow_get_height (cwindow),
- destination, &transform);
-
- XRenderSetPictureTransform (display, wpicture, &transform);
- XRenderSetPictureFilter (meta_compositor_get_display (compositor)->xdisplay, wpicture, "bilinear", 0, 0);
-
- XRenderComposite (meta_compositor_get_display (compositor)->xdisplay,
- PictOpOver, /* PictOpOver for alpha, PictOpSrc without */
- wpicture,
- screen->trans_picture,
- picture,
- 0, 0,
- 0, 0,
- bbox (destination).x, bbox (destination).y,
- bbox (destination).width, bbox (destination).height + 100);
-
- XRenderFreePicture (display, wpicture);
-}
-#endif
-
-#if 0
static void
-compute_transformation (int x, int y, int w, int h, Quad *dest, XTransform *trans)
+print_region (Display *dpy, const char *name, XserverRegion region)
{
- Matrix3 tmp;
+ XRectangle *rects;
+ int i, n_rects;
- matrix3_identity (&tmp);
+ rects = XFixesFetchRegion (dpy, region, &n_rects);
- transform_matrix_perspective (x, y, w, h,
-
- dest->points[0].x, dest->points[0].y,
- dest->points[1].x, dest->points[1].y,
- dest->points[2].x, dest->points[2].y,
- dest->points[3].x, dest->points[3].y,
-
- &tmp);
-
- matrix3_invert (&tmp);
-
- convert_matrix (&tmp, trans);
+ g_print ("region \"%s\":\n", name);
+ for (i = 0; i < n_rects; ++i)
+ g_print (" %d %d %d %d\n", rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+ XFree (rects);
}
-#endif
void
cwindow_process_damage_notify (CWindow *cwindow, XDamageNotifyEvent *event)
@@ -658,7 +597,7 @@ cwindow_process_damage_notify (CWindow *cwindow, XDamageNotifyEvent *event)
else
g_print ("damage on unknown window\n");
#endif
-
+
region = XFixesCreateRegion (cwindow_get_xdisplay (cwindow), NULL, 0);
/* translate region to screen; can error if window of damage is
@@ -676,9 +615,9 @@ cwindow_process_damage_notify (CWindow *cwindow, XDamageNotifyEvent *event)
screen = cwindow_get_screen (cwindow);
+ /* ignore damage on frozen window */
if (!cwindow->freeze_info)
{
- /* ignore damage on frozen window */
meta_compositor_invalidate_region (cwindow->compositor, screen, region);
}
@@ -745,6 +684,9 @@ cwindow_set_transformation (CWindow *cwindow,
void
cwindow_freeze (CWindow *cwindow)
{
+ if (!cwindow)
+ return;
+
if (cwindow->freeze_info)
{
meta_print_backtrace();
@@ -766,7 +708,6 @@ cwindow_freeze (CWindow *cwindow)
void
cwindow_thaw (CWindow *cwindow)
{
- XserverRegion region;
if (!cwindow->freeze_info)
return;
@@ -803,7 +744,7 @@ cwindow_draw (CWindow *cwindow, Picture destination)
if (!cwindow_get_viewable (cwindow))
return;
-
+
format = XRenderFindVisualFormat (cwindow_get_xdisplay (cwindow),
cwindow_get_visual (cwindow));
@@ -848,7 +789,6 @@ cwindow_draw (CWindow *cwindow, Picture destination)
&cwindow->freeze_info->geometry :
&cwindow->geometry;
- XRenderColor shadow_color = { 0x0000, 0x000, 0x0000, 0x70c0 };
XserverRegion shadow_clip;
XserverRegion old_clip = XFixesCreateRegionFromPicture (dpy, destination);
@@ -858,17 +798,15 @@ cwindow_draw (CWindow *cwindow, Picture destination)
XFixesSetPictureClipRegion (dpy, destination, 0, 0, shadow_clip);
- /* super drop shadow */
if (!cwindow->translucent)
{
- int hp, wp;
create_shadow (cwindow);
XRenderComposite (cwindow_get_xdisplay (cwindow), PictOpOver,
cwindow->shadow, None, destination,
0, 0,
0, 0,
- geometry->x + SHADOW_OFFSET, geometry->y + SHADOW_OFFSET,
+ geometry->x + SHADOW_OFFSET, geometry->y,
cwindow->shadow_width, cwindow->shadow_height);
}
diff --git a/src/snow.c b/src/snow.c
new file mode 100644
index 00000000..b8ae68d5
--- /dev/null
+++ b/src/snow.c
@@ -0,0 +1,358 @@
+#include <X11/Xlib.h>
+#include <glib.h>
+#include <X11/extensions/Xfixes.h>
+#include "config.h"
+#include "snow.h"
+#include "screen.h"
+#include <math.h>
+
+typedef struct Flake Flake;
+
+/*
+ * Diana:
+ * Snowflakes are two concentric circles
+ * outer radius: 8.2 * s
+ * inner radius: 5.2 * s
+ * alpha of both circles: 60 %
+ *
+ */
+
+#define MAX_RADIUS 6.2
+#define MIN_RADIUS 4.5
+#define MIN_ALPHA 40.0
+#define MAX_ALPHA 70.0
+
+struct Flake
+{
+ World * world;
+ double x;
+ double y;
+ int alpha;
+ int radius;
+ double y_speed;
+ double increment;
+ double angle;
+ XRenderColor color;
+};
+
+struct World
+{
+ Display *dpy;
+ MetaScreen *screen;
+ GList *flakes;
+ gdouble time;
+};
+
+static void
+flake_renew (Flake *flake, gboolean first)
+{
+ flake->x = g_random_double () * flake->world->screen->width;
+
+ if (first)
+ flake->y = g_random_double () * flake->world->screen->height;
+ else
+ flake->y = 0.0;
+
+ flake->y_speed = (g_random_double () * 1.8 + 0.2) * flake->world->screen->height;
+ flake->alpha = g_random_double_range (MIN_ALPHA, MAX_ALPHA);
+ flake->radius = MIN_RADIUS + ((flake->alpha - MIN_ALPHA) / (MAX_ALPHA - MIN_ALPHA)) * (MAX_RADIUS - MIN_RADIUS);
+ flake->increment = -0.025 + g_random_double() * 0.05;
+ flake->angle = 0.0;
+
+#define BORING
+
+#define GRAYNESS 0xffff
+
+#ifdef BORING
+ flake->color.red = (flake->alpha / 100.0) * GRAYNESS;
+ flake->color.green = (flake->alpha / 100.0) * GRAYNESS;
+ flake->color.blue = (flake->alpha / 100.0) * GRAYNESS;
+ flake->color.alpha = (flake->alpha / 100.0) * 0xffff;
+#else
+ flake->color.red = (flake->alpha / 100.0) * g_random_int_range (2 << 14, GRAYNESS);
+ flake->color.green = (flake->alpha / 100.0) * 0xEE00;
+ flake->color.blue = (flake->alpha / 100.0) * GRAYNESS;
+ flake->color.alpha = (flake->alpha / 100.0) * 0xFFFF;
+#endif
+}
+
+static Flake *
+flake_new (World *world,
+ gdouble time,
+ int radius)
+{
+ Flake *flake = g_new (Flake, 1);
+
+ flake->world = world;
+
+ flake_renew (flake, TRUE);
+
+ return flake;
+}
+
+static void
+flake_move (Flake *flake,
+ gdouble delta)
+{
+ flake->angle += delta * flake->increment;
+
+ flake->x += flake->radius * 100000 * delta * sin (flake->angle);
+ flake->y += delta * flake->y_speed;
+
+ if ((flake->x > flake->world->screen->width || flake->x < 0) ||
+ (flake->y > flake->world->screen->height || flake->y < 0))
+ {
+ flake_renew (flake, FALSE);
+ }
+}
+
+static void
+flake_get_position (Flake *flake,
+ int *x,
+ int *y)
+{
+ if (x)
+ {
+ *x = flake->x;
+ *x = *x % flake->world->screen->width;
+ }
+
+ if (y)
+ {
+ *y = flake->y;
+ *y = *y % flake->world->screen->height;
+ }
+}
+
+static void
+flake_get_rectangle (Flake *flake, double time, XRectangle *rect)
+{
+ int x, y;
+
+ flake_get_position (flake, &x, &y);
+
+ rect->x = x - flake->radius;
+ rect->y = y - flake->radius;
+ rect->width = 2 * flake->radius;
+ rect->height = 2 * flake->radius;
+}
+
+static void
+flake_destroy (Flake *flake)
+{
+ g_free (flake);
+}
+
+static void
+flake_invalidate (Flake *flake,
+ gdouble time,
+ XserverRegion region)
+{
+ XRectangle rect;
+ XserverRegion flake_region;
+
+ g_return_if_fail (region != None);
+
+ flake_get_rectangle (flake, time, &rect);
+
+ flake_region = XFixesCreateRegion (flake->world->dpy, &rect, 1);
+
+ XFixesUnionRegion (flake->world->dpy, region, region, flake_region);
+
+ XFixesDestroyRegion (flake->world->dpy, flake_region);
+}
+
+void
+XRenderCompositeTrapezoids (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XTrapezoid *traps,
+ int ntrap);
+
+static double
+integral (int r, int x)
+{
+ g_return_val_if_fail (x <= r, -1.0);
+
+ if (x == r)
+ return 0.25 * M_PI * r * r;
+
+ return 0.5 * (x * sqrt (r * r - x * x) + r * r * atan ( x / sqrt (r * r - x * x)));
+}
+
+static void
+fill_circle (Display *dpy, Picture destination, int x, int y, int radius, XRenderColor *color)
+{
+ int i;
+ for (i = 0; i < radius; ++i)
+ {
+ XRenderColor antialias;
+
+ double value = integral (radius, i + 1) - integral (radius, i);
+ int intpart = value;
+ double fract = value - intpart;
+
+ static int j;
+
+#if 0
+ if (j++ % 5000 == 0)
+ g_print ("%d (r: %d, i: %d)\n", intpart, radius, i);
+#endif
+
+ XRenderFillRectangle (dpy, PictOpOver, destination, color,
+ i + x, y - intpart,
+ 1, 2 * intpart);
+ XRenderFillRectangle (dpy, PictOpOver, destination, color,
+ x - i - 1, y - intpart,
+ 1, 2 * intpart);
+
+ antialias = *color;
+ antialias.red *= fract;
+ antialias.green *= fract;
+ antialias.blue *= fract;
+ antialias.alpha *= fract;
+
+ XRenderFillRectangle (dpy, PictOpOver, destination, &antialias,
+ i + x, y - intpart - 1,
+ 1, 1);
+ XRenderFillRectangle (dpy, PictOpOver, destination, &antialias,
+ i + x, y + intpart,
+ 1, 1);
+ XRenderFillRectangle (dpy, PictOpOver, destination, &antialias,
+ x - i - 1, y - intpart - 1,
+ 1, 1);
+ XRenderFillRectangle (dpy, PictOpOver, destination, &antialias,
+ x - i - 1, y + intpart,
+ 1, 1);
+ }
+}
+
+static void
+flake_paint (Flake *flake, Picture destination)
+{
+ int x, y;
+
+ flake_get_position (flake, &x, &y);
+
+ double radius = flake->radius;
+
+#if 0
+ g_print (" %d %d %d %d \n", color.red, color.green, color.blue, color.alpha);
+#endif
+
+ fill_circle (flake->world->dpy, destination, x, y, radius, &flake->color);
+
+#if 0
+ XRenderFillRectangle (flake->world->dpy, PictOpOver, destination, &flake->color,
+ x - radius, y - radius,
+ 2 * radius, 2 * radius);
+#endif
+
+ radius = 0.63 * radius;
+
+ fill_circle (flake->world->dpy, destination, x, y, radius, &flake->color);
+
+#if 0
+ XRenderFillRectangle (flake->world->dpy, PictOpOver, destination, &flake->color,
+ x - radius, y - radius,
+ 2 * radius, 2 * radius);
+#endif
+}
+
+/*
+ * World
+ */
+
+World *
+world_new (Display *dpy,
+ MetaScreen *screen)
+{
+#define N_FLAKES (screen->width / 40)
+#if 0
+#define N_FLAKES 10
+#endif
+ int i;
+ World *world = g_new (World, 1);
+
+ world->dpy = dpy;
+ world->flakes = NULL;
+ world->screen = screen;
+
+ for (i = 0; i < N_FLAKES; ++i)
+ {
+ Flake *flake = flake_new (world, 0.0, 2);
+
+ world->flakes = g_list_prepend (world->flakes, flake);
+ }
+
+ return world;
+}
+
+void
+world_set_time (World *world, double time)
+{
+ GList *list;
+ gdouble delta = time - world->time;
+ world->time = time;
+
+ for (list = world->flakes; list; list = list->next)
+ {
+ Flake *flake = list->data;
+
+ flake_move (flake, delta);
+ }
+}
+
+#if 0
+void
+world_start (World *world, gdouble time)
+{
+ g_timeout_add (25, update_world, world);
+}
+#endif
+
+MetaScreen *
+world_get_screen (World *world)
+{
+ return world->screen;
+}
+
+XserverRegion
+world_invalidate (World *world)
+{
+ GList *list;
+
+ XserverRegion region;
+
+ region = XFixesCreateRegion (world->dpy, NULL, 0);
+
+ for (list = world->flakes; list != NULL; list = list->next)
+ {
+ Flake *flake = list->data;
+
+ flake_invalidate (flake, world->time, region);
+ }
+
+ return region;
+}
+
+void
+world_paint (World *world, Picture destination)
+{
+ GList *list;
+
+ list = world->flakes;
+ while (list)
+ {
+ GList *next = list->next;
+ Flake *flake = list->data;
+
+ flake_paint (flake, destination);
+
+ list = next;
+ }
+}
diff --git a/src/snow.h b/src/snow.h
new file mode 100644
index 00000000..2e294df3
--- /dev/null
+++ b/src/snow.h
@@ -0,0 +1,16 @@
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xrender.h>
+#include "display.h"
+
+typedef struct World World;
+
+World *
+world_new (Display *display, MetaScreen *screen);
+XserverRegion
+world_invalidate (World *world);
+void
+world_set_time (World *world, gdouble time);
+void
+world_paint (World *world, Picture destination);
+MetaScreen *
+world_get_screen (World *world);
diff --git a/src/window.c b/src/window.c
index 3a0daed1..f30da357 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2771,8 +2771,10 @@ meta_window_move_resize_internal (MetaWindow *window,
#endif
send_sync_request (window);
}
+#if 0
else
meta_print_backtrace ();
+#endif
#if 0
g_print ("not sending request\n");
#endif