From f0d22e18c41e342d7a11232f3a820d9694506025 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 25 Jun 2009 18:56:15 -0400 Subject: [PATCH] Split shadow code into a separate file Separate code related to creating the gaussian-blurred shadow texture into a separate file. Move the definition of MetaCompositor into a compositor-private.h so that the shadow code can cache the source in the compositor structure. http://bugzilla.gnome.org/show_bug.cgi?id=587251 --- src/Makefile.am | 3 + src/compositor/compositor-private.h | 25 ++ src/compositor/compositor.c | 371 +--------------------------- src/compositor/shadow.c | 350 ++++++++++++++++++++++++++ src/compositor/shadow.h | 9 + 5 files changed, 391 insertions(+), 367 deletions(-) create mode 100644 src/compositor/compositor-private.h create mode 100644 src/compositor/shadow.c create mode 100644 src/compositor/shadow.h diff --git a/src/Makefile.am b/src/Makefile.am index 3bc356fbd..d46a73a26 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,12 +22,15 @@ mutter_SOURCES= \ core/boxes.c \ include/boxes.h \ compositor/compositor.c \ + compositor/compositor-private.h \ compositor/mutter-module.c \ compositor/mutter-module.h \ compositor/mutter-plugin.c \ compositor/mutter-plugin-manager.c \ compositor/mutter-plugin-manager.h \ compositor/mutter-shaped-texture.c \ + compositor/shadow.c \ + compositor/shadow.h \ compositor/mutter-shaped-texture.h \ compositor/tidy/tidy-texture-frame.c \ compositor/tidy/tidy-texture-frame.h \ diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h new file mode 100644 index 000000000..6611761af --- /dev/null +++ b/src/compositor/compositor-private.h @@ -0,0 +1,25 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_COMPOSITOR_PRIVATE_H +#define META_COMPOSITOR_PRIVATE_H + +#include "compositor.h" +#include "display.h" +#include + +struct _MetaCompositor +{ + MetaDisplay *display; + + Atom atom_x_root_pixmap; + Atom atom_x_set_root; + Atom atom_net_wm_window_opacity; + + ClutterActor *shadow_src; + + gboolean show_redraw : 1; + gboolean debug : 1; + gboolean no_mipmaps : 1; +}; + +#endif /* META_COMPOSITOR_PRIVATE_H */ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index e23a5c1ac..5a70bb9cc 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1,28 +1,23 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -#define _GNU_SOURCE - #include -#include #include -#include #include #include #include "../core/window-private.h" -#include "display.h" #include "screen.h" #include "frame.h" #include "errors.h" #include "window.h" -#include "compositor.h" +#include "compositor-private.h" #include "compositor-mutter.h" #include "mutter-plugin-manager.h" -#include "tidy/tidy-texture-frame.h" #include "xprops.h" #include "prefs.h" +#include "shadow.h" #include "mutter-shaped-texture.h" #include #include @@ -32,19 +27,8 @@ #include #include -#include #include -#include -#define SHADOW_RADIUS 8 -#define SHADOW_OPACITY 0.9 -#define SHADOW_OFFSET_X (SHADOW_RADIUS) -#define SHADOW_OFFSET_Y (SHADOW_RADIUS) - -#define MAX_TILE_SZ 8 /* Must be <= shaddow radius */ -#define TILE_WIDTH (3*MAX_TILE_SZ) -#define TILE_HEIGHT (3*MAX_TILE_SZ) - #define CHECK_LIST_INTEGRITY_START(list) \ {int len2__; int len__ = g_list_length(list); @@ -103,8 +87,6 @@ meta_xattrs_get_type (void) return our_type; } -static unsigned char* shadow_gaussian_make_tile (void); - static inline gboolean composite_at_least_version (MetaDisplay *display, int maj, int min) { @@ -117,21 +99,6 @@ composite_at_least_version (MetaDisplay *display, int maj, int min) return (major > maj || (major == maj && minor >= min)); } -struct _MetaCompositor -{ - MetaDisplay *display; - - Atom atom_x_root_pixmap; - Atom atom_x_set_root; - Atom atom_net_wm_window_opacity; - - ClutterActor *shadow_src; - - gboolean show_redraw : 1; - gboolean debug : 1; - gboolean no_mipmaps : 1; -}; - typedef struct _MetaCompScreen { MetaScreen *screen; @@ -443,15 +410,8 @@ mutter_window_constructed (GObject *object) if (mutter_window_has_shadow (self)) { - priv->shadow = - tidy_texture_frame_new (CLUTTER_TEXTURE (compositor->shadow_src), - MAX_TILE_SZ, - MAX_TILE_SZ, - MAX_TILE_SZ, - MAX_TILE_SZ); + priv->shadow = mutter_create_shadow_frame (compositor); - clutter_actor_set_position (priv->shadow, - SHADOW_OFFSET_X , SHADOW_OFFSET_Y); clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->shadow); } @@ -581,15 +541,7 @@ mutter_window_set_property (GObject *object, clutter_actor_get_size (CLUTTER_ACTOR (mw), &w, &h); - priv->shadow = - tidy_texture_frame_new (CLUTTER_TEXTURE (compositor->shadow_src), - MAX_TILE_SZ, - MAX_TILE_SZ, - MAX_TILE_SZ, - MAX_TILE_SZ); - - clutter_actor_set_position (priv->shadow, - SHADOW_OFFSET_X , SHADOW_OFFSET_Y); + priv->shadow = mutter_create_shadow_frame (compositor); clutter_actor_set_size (priv->shadow, w, h); @@ -2539,7 +2491,6 @@ meta_compositor_new (MetaDisplay *display) Atom atoms[G_N_ELEMENTS(atom_names)]; MetaCompositor *compositor; Display *xdisplay = meta_display_get_xdisplay (display); - guchar *data; if (!composite_at_least_version (display, 0, 3)) return NULL; @@ -2559,23 +2510,6 @@ meta_compositor_new (MetaDisplay *display) compositor->atom_x_set_root = atoms[1]; compositor->atom_net_wm_window_opacity = atoms[2]; - /* Shadow setup */ - - data = shadow_gaussian_make_tile (); - - compositor->shadow_src = clutter_texture_new (); - - clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (compositor->shadow_src), - data, - TRUE, - TILE_WIDTH, - TILE_HEIGHT, - TILE_WIDTH*4, - 4, - 0, - NULL); - free (data); - return compositor; } @@ -2586,300 +2520,3 @@ mutter_get_overlay_window (MetaScreen *screen) return info->output; } - - -/* ------------------------------- */ -/* Shadow Generation */ - -typedef struct GaussianMap -{ - int size; - double * data; -} 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 GaussianMap * -make_gaussian_map (double r) -{ - GaussianMap *c; - int size = ((int) ceil ((r * 3)) + 1) & ~1; - int center = size / 2; - int x, y; - double t = 0.0; - double g; - - c = malloc (sizeof (GaussianMap) + size * size * sizeof (double)); - c->size = size; - - c->data = (double *) (c + 1); - - 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; - } - - for (y = 0; y < size; y++) - for (x = 0; x < size; x++) - c->data[y*size + x] /= t; - - return c; -} - -static unsigned char -sum_gaussian (GaussianMap * 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; - unsigned int r; - - /* - * 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; - - v *= (opacity * 255.0); - - r = (unsigned int) v; - - return (unsigned char) r; -} - -static unsigned char * -shadow_gaussian_make_tile () -{ - unsigned char * data; - int size; - int center; - int x, y; - unsigned char d; - int pwidth, pheight; - double opacity = SHADOW_OPACITY; - static GaussianMap * gaussian_map = NULL; - - struct _mypixel - { - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - } * _d; - - - if (!gaussian_map) - gaussian_map = - make_gaussian_map (SHADOW_RADIUS); - - size = gaussian_map->size; - center = size / 2; - - /* Top & bottom */ - - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - data = g_malloc0 (4 * TILE_WIDTH * TILE_HEIGHT); - - _d = (struct _mypixel*) data; - - /* N */ - for (y = 0; y < pheight; y++) - { - d = sum_gaussian (gaussian_map, opacity, - center, y - center, - TILE_WIDTH, TILE_HEIGHT); - for (x = 0; x < pwidth; x++) - { - _d[y*3*pwidth + x + pwidth].r = 0; - _d[y*3*pwidth + x + pwidth].g = 0; - _d[y*3*pwidth + x + pwidth].b = 0; - _d[y*3*pwidth + x + pwidth].a = d; - } - - } - - /* S */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - for (y = 0; y < pheight; y++) - { - d = sum_gaussian (gaussian_map, opacity, - center, y - center, - TILE_WIDTH, TILE_HEIGHT); - for (x = 0; x < pwidth; x++) - { - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].r = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].g = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].b = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].a = d; - } - - } - - - /* w */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - for (x = 0; x < pwidth; x++) - { - d = sum_gaussian (gaussian_map, opacity, - x - center, center, - TILE_WIDTH, TILE_HEIGHT); - for (y = 0; y < pheight; y++) - { - _d[y*3*pwidth + 3*pwidth*pheight + x].r = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x].g = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x].b = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x].a = d; - } - - } - - /* E */ - for (x = 0; x < pwidth; x++) - { - d = sum_gaussian (gaussian_map, opacity, - x - center, center, - TILE_WIDTH, TILE_HEIGHT); - for (y = 0; y < pheight; y++) - { - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].r = 0; - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].g = 0; - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].b = 0; - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].a = d; - } - - } - - /* NW */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = sum_gaussian (gaussian_map, opacity, - x-center, y-center, - TILE_WIDTH, TILE_HEIGHT); - - _d[y*3*pwidth + x].r = 0; - _d[y*3*pwidth + x].g = 0; - _d[y*3*pwidth + x].b = 0; - _d[y*3*pwidth + x].a = d; - } - - /* SW */ - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = sum_gaussian (gaussian_map, opacity, - x-center, y-center, - TILE_WIDTH, TILE_HEIGHT); - - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].r = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].g = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].b = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].a = d; - } - - /* SE */ - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = sum_gaussian (gaussian_map, opacity, - x-center, y-center, - TILE_WIDTH, TILE_HEIGHT); - - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].r = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].g = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].b = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].a = d; - } - - /* NE */ - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = sum_gaussian (gaussian_map, opacity, - x-center, y-center, - TILE_WIDTH, TILE_HEIGHT); - - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].r = 0; - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].g = 0; - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].b = 0; - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].a = d; - } - - /* center */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - d = sum_gaussian (gaussian_map, opacity, - center, center, TILE_WIDTH, TILE_HEIGHT); - - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].r = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].g = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].b = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].a = 0; - } - - return data; -} diff --git a/src/compositor/shadow.c b/src/compositor/shadow.c new file mode 100644 index 000000000..b204440e5 --- /dev/null +++ b/src/compositor/shadow.c @@ -0,0 +1,350 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#define _GNU_SOURCE /* For M_PI */ + +#include + +#include "compositor-private.h" +#include "shadow.h" +#include "tidy/tidy-texture-frame.h" + +#define SHADOW_RADIUS 8 +#define SHADOW_OPACITY 0.9 +#define SHADOW_OFFSET_X (SHADOW_RADIUS) +#define SHADOW_OFFSET_Y (SHADOW_RADIUS) + +#define MAX_TILE_SZ 8 /* Must be <= shaddow radius */ +#define TILE_WIDTH (3*MAX_TILE_SZ) +#define TILE_HEIGHT (3*MAX_TILE_SZ) + +static unsigned char* shadow_gaussian_make_tile (void); + +ClutterActor * +mutter_create_shadow_frame (MetaCompositor *compositor) +{ + ClutterActor *frame; + + if (!compositor->shadow_src) + { + guchar *data; + + data = shadow_gaussian_make_tile (); + + compositor->shadow_src = clutter_texture_new (); + + clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (compositor->shadow_src), + data, + TRUE, + TILE_WIDTH, + TILE_HEIGHT, + TILE_WIDTH*4, + 4, + 0, + NULL); + g_free (data); + } + + frame = tidy_texture_frame_new (CLUTTER_TEXTURE (compositor->shadow_src), + MAX_TILE_SZ, + MAX_TILE_SZ, + MAX_TILE_SZ, + MAX_TILE_SZ); + + clutter_actor_set_position (frame, + SHADOW_OFFSET_X , SHADOW_OFFSET_Y); + + return frame; +} + +typedef struct GaussianMap +{ + int size; + double * data; +} 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 GaussianMap * +make_gaussian_map (double r) +{ + GaussianMap *c; + int size = ((int) ceil ((r * 3)) + 1) & ~1; + int center = size / 2; + int x, y; + double t = 0.0; + double g; + + c = g_malloc (sizeof (GaussianMap) + size * size * sizeof (double)); + c->size = size; + + c->data = (double *) (c + 1); + + 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; + } + + for (y = 0; y < size; y++) + for (x = 0; x < size; x++) + c->data[y*size + x] /= t; + + return c; +} + +static unsigned char +sum_gaussian (GaussianMap * 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; + unsigned int r; + + /* + * 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; + + v *= (opacity * 255.0); + + r = (unsigned int) v; + + return (unsigned char) r; +} + +static unsigned char * +shadow_gaussian_make_tile () +{ + unsigned char * data; + int size; + int center; + int x, y; + unsigned char d; + int pwidth, pheight; + double opacity = SHADOW_OPACITY; + static GaussianMap * gaussian_map = NULL; + + struct _mypixel + { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + } * _d; + + + if (!gaussian_map) + gaussian_map = + make_gaussian_map (SHADOW_RADIUS); + + size = gaussian_map->size; + center = size / 2; + + /* Top & bottom */ + + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + data = g_malloc0 (4 * TILE_WIDTH * TILE_HEIGHT); + + _d = (struct _mypixel*) data; + + /* N */ + for (y = 0; y < pheight; y++) + { + d = sum_gaussian (gaussian_map, opacity, + center, y - center, + TILE_WIDTH, TILE_HEIGHT); + for (x = 0; x < pwidth; x++) + { + _d[y*3*pwidth + x + pwidth].r = 0; + _d[y*3*pwidth + x + pwidth].g = 0; + _d[y*3*pwidth + x + pwidth].b = 0; + _d[y*3*pwidth + x + pwidth].a = d; + } + + } + + /* S */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + for (y = 0; y < pheight; y++) + { + d = sum_gaussian (gaussian_map, opacity, + center, y - center, + TILE_WIDTH, TILE_HEIGHT); + for (x = 0; x < pwidth; x++) + { + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].r = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].g = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].b = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].a = d; + } + + } + + + /* w */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + for (x = 0; x < pwidth; x++) + { + d = sum_gaussian (gaussian_map, opacity, + x - center, center, + TILE_WIDTH, TILE_HEIGHT); + for (y = 0; y < pheight; y++) + { + _d[y*3*pwidth + 3*pwidth*pheight + x].r = 0; + _d[y*3*pwidth + 3*pwidth*pheight + x].g = 0; + _d[y*3*pwidth + 3*pwidth*pheight + x].b = 0; + _d[y*3*pwidth + 3*pwidth*pheight + x].a = d; + } + + } + + /* E */ + for (x = 0; x < pwidth; x++) + { + d = sum_gaussian (gaussian_map, opacity, + x - center, center, + TILE_WIDTH, TILE_HEIGHT); + for (y = 0; y < pheight; y++) + { + _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].r = 0; + _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].g = 0; + _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].b = 0; + _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].a = d; + } + + } + + /* NW */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = sum_gaussian (gaussian_map, opacity, + x-center, y-center, + TILE_WIDTH, TILE_HEIGHT); + + _d[y*3*pwidth + x].r = 0; + _d[y*3*pwidth + x].g = 0; + _d[y*3*pwidth + x].b = 0; + _d[y*3*pwidth + x].a = d; + } + + /* SW */ + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = sum_gaussian (gaussian_map, opacity, + x-center, y-center, + TILE_WIDTH, TILE_HEIGHT); + + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].r = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].g = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].b = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].a = d; + } + + /* SE */ + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = sum_gaussian (gaussian_map, opacity, + x-center, y-center, + TILE_WIDTH, TILE_HEIGHT); + + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + + 2*pwidth].r = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + + 2*pwidth].g = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + + 2*pwidth].b = 0; + _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + + 2*pwidth].a = d; + } + + /* NE */ + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = sum_gaussian (gaussian_map, opacity, + x-center, y-center, + TILE_WIDTH, TILE_HEIGHT); + + _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].r = 0; + _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].g = 0; + _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].b = 0; + _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].a = d; + } + + /* center */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + d = sum_gaussian (gaussian_map, opacity, + center, center, TILE_WIDTH, TILE_HEIGHT); + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].r = 0; + _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].g = 0; + _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].b = 0; + _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].a = 0; + } + + return data; +} diff --git a/src/compositor/shadow.h b/src/compositor/shadow.h new file mode 100644 index 000000000..3a1f90209 --- /dev/null +++ b/src/compositor/shadow.h @@ -0,0 +1,9 @@ +#ifndef SHADOW_H +#define SHADOW_H + +#include +#include "compositor.h" + +ClutterActor *mutter_create_shadow_frame (MetaCompositor *compositor); + +#endif /* SHADOW_H */