summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2005-01-27 00:55:24 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2005-01-27 00:55:24 +0000
commit2695f72ad01437bdd805f06419aa15605ef4ef99 (patch)
treecf9f8e4ba81ed19d0219052f6cef9bafb3de6578
parent92688a3fb93e789bed078cd1502e8c05c1a491dd (diff)
downloadmetacity-2695f72ad01437bdd805f06419aa15605ef4ef99.tar.gz
Add Gaussian shadows, lifted from xcompmgr. Add support for translucent
Wed Jan 26 18:00:35 2005 Søren Sandmann <sandmann@redhat.com> * src/cwindow.c: Add Gaussian shadows, lifted from xcompmgr. Add support for translucent windows. * src/compositor.c: Support translucent windows. * src/window.c: Make unfocused windows translucent.
-rw-r--r--ChangeLog9
-rw-r--r--src/compositor.c18
-rw-r--r--src/compositor.h5
-rw-r--r--src/cwindow.c649
-rw-r--r--src/cwindow.h1
-rw-r--r--src/frame.c1
-rw-r--r--src/window.c21
7 files changed, 504 insertions, 200 deletions
diff --git a/ChangeLog b/ChangeLog
index 3b34f43c..d35fb45d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Wed Jan 26 18:00:35 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * src/cwindow.c: Add Gaussian shadows, lifted from xcompmgr. Add
+ support for translucent windows.
+
+ * src/compositor.c: Support translucent windows.
+
+ * src/window.c: Make unfocused windows translucent.
+
Mon Jan 24 20:27:53 2005 Søren Sandmann <sandmann@redhat.com>
* src/window.c: start compositing after ending grap op
diff --git a/src/compositor.c b/src/compositor.c
index 498f0865..4b87d5be 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -37,7 +37,6 @@
#endif /* HAVE_COMPOSITE_EXTENSIONS */
-#define SHADOW_OFFSET 10
#define FRAME_INTERVAL_MILLISECONDS ((int)(1000.0/40.0))
struct MetaCompositor
@@ -917,7 +916,7 @@ meta_compositor_add_window (MetaCompositor *compositor,
"mapped" : "unmapped");
cwindow = cwindow_new (compositor, xwindow, attrs);
-
+
/* FIXME this assertion can fail somehow... */
g_assert (attrs->map_state != IsUnviewable);
@@ -1056,7 +1055,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
&pa);
c.red = c.green = c.blue = 0;
- c.alpha = 0xb0b0;
+ c.alpha = 0xd0d0;
XRenderFillRectangle (compositor->display->xdisplay,
PictOpSrc,
screen->trans_picture, &c, 0, 0, 1, 1);
@@ -1321,3 +1320,16 @@ meta_compositor_get_display (MetaCompositor *compositor)
{
return compositor->display;
}
+
+void
+meta_compositor_set_translucent (MetaCompositor *compositor,
+ MetaWindow *window,
+ gboolean translucent)
+{
+ CWindow *cwindow = window_to_cwindow (compositor, window);
+
+ if (cwindow)
+ {
+ cwindow_set_translucent (cwindow, translucent);
+ }
+}
diff --git a/src/compositor.h b/src/compositor.h
index f8ab4fe3..8cfffcc3 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -62,4 +62,9 @@ meta_compositor_invalidate_region (MetaCompositor *compositor,
MetaScreen *screen,
XserverRegion invalid_area);
+void
+meta_compositor_set_translucent (MetaCompositor *compositor,
+ MetaWindow *window,
+ gboolean translucent);
+
#endif /* META_COMPOSITOR_H */
diff --git a/src/cwindow.c b/src/cwindow.c
index 9d7470c5..5698ef54 100644
--- a/src/cwindow.c
+++ b/src/cwindow.c
@@ -4,8 +4,15 @@
#include "compositor.h"
#include "matrix.h"
#include <X11/extensions/Xcomposite.h>
+#include <math.h>
+#include <string.h>
-#define SHADOW_OFFSET 3
+#define SHADOW_RADIUS 14
+#define SHADOW_OPACITY (.75)
+#define SHADOW_OFFSET -17
+
+static Picture shadow_picture (Display *dpy, Window root,
+ double opacity, int width, int height, int *wp, int *hp);
typedef struct Geometry Geometry;
typedef struct FreezeInfo FreezeInfo;
@@ -46,12 +53,15 @@ struct CWindow
XserverRegion border_size;
+ Picture shadow;
+
FreezeInfo *freeze_info;
unsigned int managed : 1;
unsigned int damaged : 1;
unsigned int viewable : 1;
unsigned int input_only : 1;
+ unsigned int translucent : 1;
unsigned int screen_index : 8;
@@ -59,6 +69,9 @@ struct CWindow
Distortion *distortions;
int n_distortions;
+
+ int shadow_width;
+ int shadow_height;
#endif
};
@@ -87,6 +100,30 @@ cwindow_free (CWindow *cwindow)
}
#endif /* HAVE_COMPOSITE_EXTENSIONS */
+static void
+create_shadow (CWindow *cwindow)
+{
+ if (!cwindow->shadow)
+ {
+ cwindow->shadow = shadow_picture (cwindow_get_xdisplay (cwindow),
+ cwindow_get_screen (cwindow)->xroot,
+ SHADOW_OPACITY,
+ cwindow_get_width (cwindow),
+ cwindow_get_height (cwindow),
+ &cwindow->shadow_width, &cwindow->shadow_height);
+ }
+}
+
+static void
+delete_shadow (CWindow *cwindow)
+{
+ if (cwindow->shadow)
+ {
+ XRenderFreePicture (cwindow_get_xdisplay (cwindow), cwindow->shadow);
+ cwindow->shadow = None;
+ }
+}
+
#ifdef HAVE_COMPOSITE_EXTENSIONS
XserverRegion
cwindow_extents (CWindow *cwindow)
@@ -103,9 +140,16 @@ cwindow_extents (CWindow *cwindow)
r.y = geometry->y;
r.width = geometry->width;
r.height = geometry->height;
-
- r.width += SHADOW_OFFSET;
- r.height += SHADOW_OFFSET;
+
+ create_shadow (cwindow);
+
+ if (cwindow->shadow)
+ {
+ r.x = geometry->x + SHADOW_OFFSET;
+ r.y = geometry->y + SHADOW_OFFSET;
+ r.width = cwindow->shadow_width;
+ r.height = cwindow->shadow_height;
+ }
return XFixesCreateRegion (cwindow_get_xdisplay (cwindow), &r, 1);
}
@@ -117,17 +161,53 @@ cwindow_get_opaque_region (CWindow *cwindow)
XRectangle rect;
Geometry *geometry;
- if (cwindow->freeze_info)
- geometry = &cwindow->freeze_info->geometry;
+ if (cwindow->translucent)
+ {
+ return XFixesCreateRegion (cwindow_get_xdisplay (cwindow), NULL, 0);
+ }
else
- geometry = &cwindow->geometry;
+ {
+
+ if (cwindow->freeze_info)
+ geometry = &cwindow->freeze_info->geometry;
+ else
+ geometry = &cwindow->geometry;
+
+ rect.x = geometry->x;
+ rect.y = geometry->y;
+ rect.width = geometry->width;
+ rect.height = geometry->height;
+
+ return XFixesCreateRegion (cwindow_get_xdisplay (cwindow), &rect, 1);
+ }
+}
+
+static void
+cwindow_queue_paint (CWindow *cwindow)
+{
+ XserverRegion region;
+ MetaScreen *screen;
- rect.x = geometry->x;
- rect.y = geometry->y;
- rect.width = geometry->width;
- rect.height = geometry->height;
+ create_shadow (cwindow);
+
+ region = cwindow_extents (cwindow);
+ screen = cwindow_get_screen (cwindow);
+
+ meta_compositor_invalidate_region (cwindow->compositor,
+ screen,
+ region);
+
+ XFixesDestroyRegion (cwindow_get_xdisplay (cwindow), region);
+}
+
+void
+cwindow_set_translucent (CWindow *cwindow, gboolean translucent)
+{
+#if 0
+ cwindow->translucent = !!translucent;
+#endif
- return XFixesCreateRegion (cwindow_get_xdisplay (cwindow), &rect, 1);
+ cwindow_queue_paint (cwindow);
}
Drawable
@@ -377,169 +457,16 @@ convert_matrix (Matrix3 *matrix, XTransform *trans)
trans->matrix[2][2] = double_to_fixed (matrix->coeff[2][2]);
}
-#if 0
-static void
-get_transform (XTransform *trans, int x, int y, int w, int h)
-{
- Matrix3 tmp;
-
- matrix3_identity (&tmp);
-
- transform_matrix_perspective (0, 0, w, h,
- 0, 0, w - 1 - 0.1 * w, 0,
- 0, 0 + h - 1 - 0.1 * h, 0 + w - 1, 0 + h - 1,
-
- &tmp);
-
-#if 0
- matrix3_translate (&tmp, 50, 50);
-#endif
-
- matrix3_invert (&tmp);
-
- convert_matrix (&tmp, trans);
-}
-#endif
-
-#if 0
-void
-cwindow_draw (CWindow *cwindow, Picture picture)
-{
- /* Actually draw the window */
- XRenderPictFormat *format;
- Picture wpicture;
- XRenderPictureAttributes pa;
- XTransform trans;
- int x, y, w, h;
-
- if (cwindow_get_input_only (cwindow))
- return;
-
- if (!cwindow_get_viewable (cwindow))
- return;
-
- cwindow_get_paint_bounds (cwindow, &x, &y, &w, &h);
-
- format = XRenderFindVisualFormat (cwindow_get_xdisplay (cwindow),
- cwindow_get_visual (cwindow));
- pa.subwindow_mode = IncludeInferiors;
- wpicture = XRenderCreatePicture (cwindow_get_xdisplay (cwindow),
- cwindow_get_drawable (cwindow),
- format,
- CPSubwindowMode,
- &pa);
-
- get_transform (&trans, x, y, w, h);
-
- if (cwindow_get_last_painted_extents (cwindow))
- cwindow_destroy_last_painted_extents (cwindow);
-
- cwindow_set_last_painted_extents (cwindow, cwindow_extents (cwindow));
-
-#if 0
- meta_topic (META_DEBUG_COMPOSITOR, " Compositing window 0x%lx %d,%d %dx%d\n",
- cwindow_get_xwindow (cwindow),
- cwindow->x, cwindow->y,
- cwindow->width, cwindow->height);
-#endif
-
-#if 0
- {
- XGCValues value;
- GC gc;
-
- value.function = GXcopy;
- value.subwindow_mode = IncludeInferiors;
-
- gc = XCreateGC (dpy, screen->xroot, GCFunction | GCSubwindowMode, &value);
- XSetForeground (dpy, gc, rand());
- XFixesSetGCClipRegion (dpy, gc, 0, 0, damaged_region);
- XFillRectangle (dpy, screen->xroot, gc, 0, 0,
- screen->width, screen->height);
- XFreeGC (dpy, gc);
- XSync (dpy, False);
- g_usleep (70000);
- }
-#endif
-
- if (cwindow_is_translucent (cwindow))
- {
- XRenderColor shadow_color = { 0x0000, 0, 0x0000, 0x70c0 };
- XFixesSetPictureClipRegion (cwindow_get_xdisplay (cwindow),
- picture, 0, 0,
- damaged_region);
-
-
-
- XRenderFillRectangle (cwindow_get_xdisplay (cwindow), PictOpOver,
- picture,
- &shadow_color,
- cwindow_get_x (cwindow) + SHADOW_OFFSET,
- cwindow_get_y (cwindow) + SHADOW_OFFSET,
- cwindow_get_width (cwindow),
- cwindow_get_height (cwindow));
- /* Draw window transparent while resizing */
- XRenderComposite (cwindow_get_xdisplay (cwindow), PictOpOver, /* PictOpOver for alpha, PictOpSrc without */
- wpicture,
- cwindow_get_screen (cwindow)->trans_picture,
- picture,
- 0, 0, 0, 0,
- x, y, w, h);
- }
- else
- {
-#if 0
- XRenderSetPictureTransform (cwindow_get_xdisplay (cwindow),
- wpicture,
- &trans);
- XRenderSetPictureFilter (cwindow_get_xdisplay (cwindow), wpicture, "bilinear", 0, 0);
-#endif
-
- /* Draw window normally */
- XRenderColor shadow_color = { 0x0000, 0, 0x0000, 0x70c0 };
-
-#if 0
- XFixesSetPictureClipRegion (dpy,
- picture, 0, 0,
- region_below);
-#endif
-
- XFixesSetPictureClipRegion (cwindow_get_xdisplay (cwindow),
- picture, 0, 0,
- damaged_region);
-
- /* superlame drop shadow */
- XRenderFillRectangle (cwindow_get_xdisplay (cwindow), PictOpOver,
- picture,
- &shadow_color,
- cwindow_get_x (cwindow) + SHADOW_OFFSET,
- cwindow_get_y (cwindow) + SHADOW_OFFSET,
- cwindow_get_width (cwindow),
- cwindow_get_height (cwindow));
-
- XRenderComposite (cwindow_get_xdisplay (cwindow),
- PictOpOver, /* PictOpOver for alpha, PictOpSrc without */
- wpicture,
- None,
- picture,
- 0, 0, 0, 0,
- x, y, w, h);
-
- }
- XRenderFreePicture (cwindow_get_xdisplay (cwindow), wpicture);
-}
-#endif
-
gboolean
cwindow_is_translucent (CWindow *cwindow)
{
return FALSE;
- MetaCompositor *compositor = cwindow_get_compositor (cwindow);
- MetaWindow *window = meta_display_lookup_x_window (meta_compositor_get_display (compositor), cwindow_get_xwindow (cwindow));
- return (window != NULL &&
- window == meta_compositor_get_display (compositor)->grab_window &&
- (meta_grab_op_is_resizing (meta_compositor_get_display (compositor)->grab_op) ||
- meta_grab_op_is_moving (meta_compositor_get_display (compositor)->grab_op)));
+ MetaCompositor *compositor = cwindow_get_compositor (cwindow);
+ MetaWindow *window = meta_display_lookup_x_window (meta_compositor_get_display (compositor), cwindow_get_xwindow (cwindow));
+ return (window != NULL &&
+ window == meta_compositor_get_display (compositor)->grab_window &&
+ (meta_grab_op_is_resizing (meta_compositor_get_display (compositor)->grab_op) ||
+ meta_grab_op_is_moving (meta_compositor_get_display (compositor)->grab_op)));
}
@@ -761,8 +688,8 @@ cwindow_process_damage_notify (CWindow *cwindow, XDamageNotifyEvent *event)
void
cwindow_process_configure_notify (CWindow *cwindow, XConfigureEvent *event)
{
- XserverRegion region;
MetaScreen *screen;
+ int old_width, old_height;
screen = cwindow_get_screen (cwindow);
@@ -774,20 +701,26 @@ cwindow_process_configure_notify (CWindow *cwindow, XConfigureEvent *event)
cwindow_set_x (cwindow, event->x);
cwindow_set_y (cwindow, event->y);
+ old_width = cwindow_get_width (cwindow);
cwindow_set_width (cwindow, event->width);
+ old_height = cwindow_get_height (cwindow);
cwindow_set_height (cwindow, event->height);
cwindow_set_border_width (cwindow, event->border_width);
if (cwindow->freeze_info)
- return;
-
- region = cwindow_extents (cwindow);
-
- meta_compositor_invalidate_region (cwindow->compositor,
- screen,
- region);
-
- XFixesDestroyRegion (cwindow_get_xdisplay (cwindow), region);
+ {
+ return;
+ }
+ else
+ {
+ if (old_width != cwindow_get_width (cwindow) ||
+ old_height != cwindow_get_height (cwindow))
+ {
+ delete_shadow (cwindow);
+ }
+
+ cwindow_queue_paint (cwindow);
+ }
}
void
@@ -852,14 +785,9 @@ cwindow_thaw (CWindow *cwindow)
g_free (cwindow->freeze_info);
cwindow->freeze_info = NULL;
- region = cwindow_extents (cwindow);
-
- meta_compositor_invalidate_region (cwindow->compositor,
- cwindow_get_screen (cwindow),
- region);
+ delete_shadow (cwindow);
- XFixesDestroyRegion (cwindow_get_xdisplay (cwindow), region);
-
+ cwindow_queue_paint (cwindow);
}
void
@@ -930,20 +858,26 @@ cwindow_draw (CWindow *cwindow, Picture destination)
XFixesSetPictureClipRegion (dpy, destination, 0, 0, shadow_clip);
- /* superlame drop shadow */
- XRenderFillRectangle (cwindow_get_xdisplay (cwindow),
- PictOpOver,
- destination,
- &shadow_color,
+ /* 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->width, geometry->height);
-
+ cwindow->shadow_width, cwindow->shadow_height);
+ }
+
XFixesSetPictureClipRegion (dpy, destination, 0, 0, old_clip);
XRenderComposite (cwindow_get_xdisplay (cwindow),
PictOpOver, /* PictOpOver for alpha, PictOpSrc without */
picture,
- None,
+ cwindow->translucent? cwindow_get_screen (cwindow)->trans_picture : None,
destination,
0, 0, 0, 0,
geometry->x,
@@ -962,3 +896,326 @@ cwindow_draw (CWindow *cwindow, Picture destination)
XRenderFreePicture (cwindow_get_xdisplay (cwindow), picture);
}
+
+
+/*
+ * Gaussian shadows
+ */
+
+/*
+ * FIXME: move these into MetaDisplay
+ */
+
+/* For shadow precomputation */
+typedef struct _conv {
+ int size;
+ double *data;
+} conv;
+
+int Gsize = -1;
+unsigned char *shadowCorner = NULL;
+unsigned char *shadowTop = NULL;
+conv *gaussianMap;
+
+static double
+gaussian (double r, double x, double y)
+{
+ return ((1 / (sqrt (2 * M_PI * r))) *
+ exp ((- (x * x + y * y)) / (2 * r * r)));
+}
+
+static conv *
+make_gaussian_map (Display *dpy, double r)
+{
+ conv *c;
+ int size = ((int) ceil ((r * 3)) + 1) & ~1;
+ int center = size / 2;
+ int x, y;
+ double t;
+ double g;
+
+ c = g_malloc (sizeof (conv) + size * size * sizeof (double));
+ c->size = size;
+ c->data = (double *) (c + 1);
+ t = 0.0;
+ for (y = 0; y < size; y++)
+ for (x = 0; x < size; x++)
+ {
+ g = gaussian (r, (double) (x - center), (double) (y - center));
+ t += g;
+ c->data[y * size + x] = g;
+ }
+/* printf ("gaussian total %f\n", t); */
+ for (y = 0; y < size; y++)
+ for (x = 0; x < size; x++)
+ {
+ c->data[y*size + x] /= t;
+ }
+ return c;
+}
+
+/*
+ * A picture will help
+ *
+ * -center 0 width width+center
+ * -center +-----+-------------------+-----+
+ * | | | |
+ * | | | |
+ * 0 +-----+-------------------+-----+
+ * | | | |
+ * | | | |
+ * | | | |
+ * height +-----+-------------------+-----+
+ * | | | |
+ * height+ | | | |
+ * center +-----+-------------------+-----+
+ */
+
+static unsigned char
+sum_gaussian (conv *map, double opacity, int x, int y, int width, int height)
+{
+ int fx, fy;
+ double *g_data;
+ double *g_line = map->data;
+ int g_size = map->size;
+ int center = g_size / 2;
+ int fx_start, fx_end;
+ int fy_start, fy_end;
+ double v;
+
+ /*
+ * Compute set of filter values which are "in range",
+ * that's the set with:
+ * 0 <= x + (fx-center) && x + (fx-center) < width &&
+ * 0 <= y + (fy-center) && y + (fy-center) < height
+ *
+ * 0 <= x + (fx - center) x + fx - center < width
+ * center - x <= fx fx < width + center - x
+ */
+
+ fx_start = center - x;
+ if (fx_start < 0)
+ fx_start = 0;
+ fx_end = width + center - x;
+ if (fx_end > g_size)
+ fx_end = g_size;
+
+ fy_start = center - y;
+ if (fy_start < 0)
+ fy_start = 0;
+ fy_end = height + center - y;
+ if (fy_end > g_size)
+ fy_end = g_size;
+
+ g_line = g_line + fy_start * g_size + fx_start;
+
+ v = 0;
+ for (fy = fy_start; fy < fy_end; fy++)
+ {
+ g_data = g_line;
+ g_line += g_size;
+
+ for (fx = fx_start; fx < fx_end; fx++)
+ v += *g_data++;
+ }
+ if (v > 1)
+ v = 1;
+
+ return ((unsigned char) (v * opacity * 255.0));
+}
+
+/* precompute shadow corners and sides to save time for large windows */
+static void
+presum_gaussian (conv *map)
+{
+ int center = map->size/2;
+ int opacity, x, y;
+
+ Gsize = map->size;
+
+ if (shadowCorner)
+ g_free ((void *)shadowCorner);
+ if (shadowTop)
+ g_free ((void *)shadowTop);
+
+ shadowCorner = (unsigned char *)(g_malloc ((Gsize + 1) * (Gsize + 1) * 26));
+ shadowTop = (unsigned char *)(g_malloc ((Gsize + 1) * 26));
+
+ for (x = 0; x <= Gsize; x++)
+ {
+ shadowTop[25 * (Gsize + 1) + x] = sum_gaussian (map, 1, x - center, center, Gsize * 2, Gsize * 2);
+ for(opacity = 0; opacity < 25; opacity++)
+ shadowTop[opacity * (Gsize + 1) + x] = shadowTop[25 * (Gsize + 1) + x] * opacity / 25;
+ for(y = 0; y <= x; y++)
+ {
+ shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
+ = sum_gaussian (map, 1, x - center, y - center, Gsize * 2, Gsize * 2);
+ shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
+ = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
+ for(opacity = 0; opacity < 25; opacity++)
+ shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
+ = shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
+ = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] * opacity / 25;
+ }
+ }
+}
+
+static XImage *
+make_shadow (Display *dpy, double opacity, int width, int height)
+{
+ XImage *ximage;
+ unsigned char *data;
+ int gsize = gaussianMap->size;
+ int ylimit, xlimit;
+ int swidth = width + gsize;
+ int sheight = height + gsize;
+ int center = gsize / 2;
+ int x, y;
+ unsigned char d;
+ int x_diff;
+ int opacity_int = (int)(opacity * 25);
+ data = g_malloc (swidth * sheight * sizeof (unsigned char));
+ if (!data)
+ return 0;
+ ximage = XCreateImage (dpy,
+ DefaultVisual(dpy, DefaultScreen(dpy)),
+ 8,
+ ZPixmap,
+ 0,
+ (char *) data,
+ swidth, sheight, 8, swidth * sizeof (unsigned char));
+ if (!ximage)
+ {
+ g_free (data);
+ return 0;
+ }
+ /*
+ * Build the gaussian in sections
+ */
+
+ /*
+ * center (fill the complete data array)
+ */
+ if (Gsize > 0)
+ d = shadowTop[opacity_int * (Gsize + 1) + Gsize];
+ else
+ d = sum_gaussian (gaussianMap, opacity, center, center, width, height);
+ memset(data, d, sheight * swidth);
+
+ /*
+ * corners
+ */
+ ylimit = gsize;
+ if (ylimit > sheight / 2)
+ ylimit = (sheight + 1) / 2;
+ xlimit = gsize;
+ if (xlimit > swidth / 2)
+ xlimit = (swidth + 1) / 2;
+
+ for (y = 0; y < ylimit; y++)
+ for (x = 0; x < xlimit; x++)
+ {
+ if (xlimit == Gsize && ylimit == Gsize)
+ d = shadowCorner[opacity_int * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
+ else
+ d = sum_gaussian (gaussianMap, opacity, x - center, y - center, width, height);
+ data[y * swidth + x] = d;
+ data[(sheight - y - 1) * swidth + x] = d;
+ data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
+ data[y * swidth + (swidth - x - 1)] = d;
+ }
+
+ /*
+ * top/bottom
+ */
+ x_diff = swidth - (gsize * 2);
+ if (x_diff > 0 && ylimit > 0)
+ {
+ for (y = 0; y < ylimit; y++)
+ {
+ if (ylimit == Gsize)
+ d = shadowTop[opacity_int * (Gsize + 1) + y];
+ else
+ d = sum_gaussian (gaussianMap, opacity, center, y - center, width, height);
+ memset (&data[y * swidth + gsize], d, x_diff);
+ memset (&data[(sheight - y - 1) * swidth + gsize], d, x_diff);
+ }
+ }
+
+ /*
+ * sides
+ */
+
+ for (x = 0; x < xlimit; x++)
+ {
+ if (xlimit == Gsize)
+ d = shadowTop[opacity_int * (Gsize + 1) + x];
+ else
+ d = sum_gaussian (gaussianMap, opacity, x - center, center, width, height);
+ for (y = gsize; y < sheight - gsize; y++)
+ {
+ data[y * swidth + x] = d;
+ data[y * swidth + (swidth - x - 1)] = d;
+ }
+ }
+
+ return ximage;
+}
+
+static Picture
+shadow_picture (Display *dpy, Window root,
+ double opacity, int width, int height, int *wp, int *hp)
+{
+ XImage *shadowImage;
+ Pixmap shadowPixmap;
+ Picture shadowPicture;
+ GC gc;
+
+ if (!gaussianMap)
+ {
+ gaussianMap = make_gaussian_map(dpy, SHADOW_RADIUS);
+ presum_gaussian (gaussianMap);
+ }
+
+ shadowImage = make_shadow (dpy, opacity, width, height);
+ if (!shadowImage)
+ return None;
+ shadowPixmap = XCreatePixmap (dpy, root,
+ shadowImage->width,
+ shadowImage->height,
+ 8);
+ if (!shadowPixmap)
+ {
+ XDestroyImage (shadowImage);
+ return None;
+ }
+
+ shadowPicture = XRenderCreatePicture (dpy, shadowPixmap,
+ XRenderFindStandardFormat (dpy, PictStandardA8),
+ 0, 0);
+ if (!shadowPicture)
+ {
+ XDestroyImage (shadowImage);
+ XFreePixmap (dpy, shadowPixmap);
+ return None;
+ }
+
+ gc = XCreateGC (dpy, shadowPixmap, 0, 0);
+ if (!gc)
+ {
+ XDestroyImage (shadowImage);
+ XFreePixmap (dpy, shadowPixmap);
+ XRenderFreePicture (dpy, shadowPicture);
+ return None;
+ }
+
+ XPutImage (dpy, shadowPixmap, gc, shadowImage, 0, 0, 0, 0,
+ shadowImage->width,
+ shadowImage->height);
+ *wp = shadowImage->width;
+ *hp = shadowImage->height;
+ XFreeGC (dpy, gc);
+ XDestroyImage (shadowImage);
+ XFreePixmap (dpy, shadowPixmap);
+ return shadowPicture;
+}
diff --git a/src/cwindow.h b/src/cwindow.h
index fdb7f165..a31e213c 100644
--- a/src/cwindow.h
+++ b/src/cwindow.h
@@ -101,3 +101,4 @@ void cwindow_draw (CWindow *cwindo
Picture destination);
void cwindow_freeze (CWindow *cwindow);
void cwindow_thaw (CWindow *cwindow);
+void cwindow_set_translucent (CWindow *cwindow, gboolean translucent);
diff --git a/src/frame.c b/src/frame.c
index a2022a91..2e8da667 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -395,4 +395,3 @@ meta_frame_set_screen_cursor (MetaFrame *frame,
XFreeCursor (frame->window->display->xdisplay, xcursor);
}
}
-
diff --git a/src/window.c b/src/window.c
index f64bad12..3a0daed1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -727,6 +727,12 @@ meta_window_new_with_attrs (MetaDisplay *display,
meta_error_trap_pop (display, FALSE); /* pop the XSync()-reducing trap */
meta_display_ungrab (display);
+
+ if (window->frame)
+ {
+ meta_compositor_add_window (window->display->compositor, window->frame->xwindow, attrs);
+ meta_compositor_set_translucent (window->display->compositor, window, TRUE);
+ }
return window;
}
@@ -2771,6 +2777,9 @@ meta_window_move_resize_internal (MetaWindow *window,
g_print ("not sending request\n");
#endif
#endif
+
+
+
#if 0
g_print ("configuring client\n");
#endif
@@ -3287,6 +3296,12 @@ meta_window_focus (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"Setting input focus to window %s, input: %d take_focus: %d\n",
window->desc, window->input, window->take_focus);
+
+ if (window->display->expected_focus_window)
+ {
+ meta_compositor_set_translucent (window->display->compositor,
+ window->display->expected_focus_window, TRUE);
+ }
if (window->display->grab_window &&
window->display->grab_window->all_keys_grabbed)
@@ -3361,6 +3376,12 @@ meta_window_focus (MetaWindow *window,
window->wm_state_demands_attention = FALSE;
set_net_wm_state (window);
}
+
+ if (window->display->expected_focus_window)
+ {
+ meta_compositor_set_translucent (window->display->compositor,
+ window->display->expected_focus_window, FALSE);
+ }
}
static void