diff -ruN a/files/usr/share/cinnamon/applets/calendar@cinnamon.org/applet.js b/files/usr/share/cinnamon/applets/calendar@cinnamon.org/applet.js --- a/files/usr/share/cinnamon/applets/calendar@cinnamon.org/applet.js 2012-08-04 23:40:06.000000000 -0300 +++ b/files/usr/share/cinnamon/applets/calendar@cinnamon.org/applet.js 2012-08-01 10:46:36.546118615 -0300 @@ -41,6 +41,8 @@ this._orientation = orientation; this._initContextMenu(); + fx = new St.BackgroundEffect(); + this.menu.actor.add_effect_with_name('blur',fx); this._calendarArea = new St.BoxLayout({name: 'calendarArea' }); this.menu.addActor(this._calendarArea); diff -ruN a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js --- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js 2012-08-04 23:40:06.000000000 -0300 +++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js 2012-08-05 06:18:51.048078727 -0300 @@ -641,7 +641,8 @@ this.menuManager = new PopupMenu.PopupMenuManager(this); this.menu = new Applet.AppletPopupMenu(this, orientation); this.menuManager.addMenu(this.menu); - + fx = new St.BackgroundEffect(); + this.menu.actor.add_effect_with_name('blur',fx); this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress)); this.showRecent = global.settings.get_boolean("menu-show-recent"); global.settings.connect("changed::menu-show-recent", Lang.bind(this, function() { diff -ruN a/src/Makefile.in b/src/Makefile.in --- a/src/Makefile.in 2012-08-04 23:41:01.000000000 -0300 +++ b/src/Makefile.in 2012-08-01 10:46:36.546118615 -0300 @@ -183,6 +183,7 @@ $(libgvc_la_LDFLAGS) $(LDFLAGS) -o $@ libst_1_0_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_7 = libst_1_0_la-st-adjustment.lo libst_1_0_la-st-bin.lo \ + libst_1_0_la-st-background-effect.lo \ libst_1_0_la-st-border-image.lo libst_1_0_la-st-box-layout.lo \ libst_1_0_la-st-box-layout-child.lo libst_1_0_la-st-button.lo \ libst_1_0_la-st-clipboard.lo libst_1_0_la-st-container.lo \ @@ -574,6 +575,7 @@ # please, keep this sorted alphabetically st_source_h = \ st/st-adjustment.h \ + st/st-background-effect.h \ st/st-bin.h \ st/st-border-image.h \ st/st-box-layout.h \ @@ -618,6 +620,7 @@ # please, keep this sorted alphabetically st_source_c = \ st/st-adjustment.c \ + st/st-background-effect.c \ st/st-bin.c \ st/st-border-image.c \ st/st-box-layout.c \ @@ -1162,6 +1165,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgvc_la-gvc-mixer-source.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgvc_la-gvc-mixer-stream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libst_1_0_la-st-adjustment.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libst_1_0_la-st-background-effect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libst_1_0_la-st-bin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libst_1_0_la-st-border-image.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libst_1_0_la-st-box-layout-child.Plo@am__quote@ @@ -1492,6 +1496,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libst_1_0_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libst_1_0_la-st-adjustment.lo `test -f 'st/st-adjustment.c' || echo '$(srcdir)/'`st/st-adjustment.c +libst_1_0_la-st-background-effect.lo: st/st-background-effect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libst_1_0_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libst_1_0_la-st-background-effect.lo -MD -MP -MF $(DEPDIR)/libst_1_0_la-st-background-effect.Tpo -c -o libst_1_0_la-st-background-effect.lo `test -f 'st/st-background-effect.c' || echo '$(srcdir)/'`st/st-background-effect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libst_1_0_la-st-background-effect.Tpo $(DEPDIR)/libst_1_0_la-st-background-effect.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/st-background-effect.c' object='libst_1_0_la-st-background-effect.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libst_1_0_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libst_1_0_la-st-background-effect.lo `test -f 'st/st-background-effect.c' || echo '$(srcdir)/'`st/st-background-effect.c + libst_1_0_la-st-bin.lo: st/st-bin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libst_1_0_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libst_1_0_la-st-bin.lo -MD -MP -MF $(DEPDIR)/libst_1_0_la-st-bin.Tpo -c -o libst_1_0_la-st-bin.lo `test -f 'st/st-bin.c' || echo '$(srcdir)/'`st/st-bin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libst_1_0_la-st-bin.Tpo $(DEPDIR)/libst_1_0_la-st-bin.Plo diff -ruN a/src/Makefile-st.am b/src/Makefile-st.am --- a/src/Makefile-st.am 2012-08-04 23:40:06.000000000 -0300 +++ b/src/Makefile-st.am 2012-08-01 10:46:36.550120546 -0300 @@ -67,6 +67,7 @@ # please, keep this sorted alphabetically st_source_h = \ st/st-adjustment.h \ + st/st-background-effect.h \ st/st-bin.h \ st/st-border-image.h \ st/st-box-layout.h \ @@ -124,6 +125,7 @@ # please, keep this sorted alphabetically st_source_c = \ st/st-adjustment.c \ + st/st-background-effect.c \ st/st-bin.c \ st/st-border-image.c \ st/st-box-layout.c \ diff -ruN a/src/st/st-background-effect.c b/src/st/st-background-effect.c --- a/src/st/st-background-effect.c 1969-12-31 21:00:00.000000000 -0300 +++ b/src/st/st-background-effect.c 2012-08-09 16:39:52.749610257 -0300 @@ -0,0 +1,340 @@ +#include "st-background-effect.h" +#define ST_BACKGROUND_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ST_TYPE_BACKGROUND_EFFECT, StBackgroundEffectClass)) +#define ST_IS_BACKGROUND_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ST_TYPE_BACKGROUND_EFFECT)) +#define ST_BACKGROUND_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ST_TYPE_BACKGROUND_EFFECT, StBackgroundEffectClass)) + +G_DEFINE_TYPE (StBackgroundEffect, st_background_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT); + +#define CLUTTER_ENABLE_EXPERIMENTAL_API + +#include "cogl/cogl.h" + +static const gchar *box_blur_glsl_declarations = + "uniform vec2 pixel_step;\n"; +#define SAMPLE(offx, offy) \ + "cogl_texel += texture2D (cogl_sampler, cogl_tex_coord.st + pixel_step * " \ + "vec2 (" G_STRINGIFY (offx) ", " G_STRINGIFY (offy) ") * 2.0);\n" +static const gchar *box_blur_glsl_shader = + " cogl_texel = texture2D (cogl_sampler, cogl_tex_coord.st);\n" + SAMPLE (-1.0, -1.0) + SAMPLE ( 0.0, -1.0) + SAMPLE (+1.0, -1.0) + SAMPLE (-1.0, 0.0) + SAMPLE ( 0.0, 0.0) + SAMPLE (+1.0, 0.0) + SAMPLE (-1.0, +1.0) + SAMPLE ( 0.0, +1.0) + SAMPLE (+1.0, +1.0) + " cogl_texel /= 10.0;\n"; +#undef SAMPLE + +typedef enum +{ + COGL_PIPELINE_CULL_FACE_MODE_NONE, + COGL_PIPELINE_CULL_FACE_MODE_FRONT, + COGL_PIPELINE_CULL_FACE_MODE_BACK, + COGL_PIPELINE_CULL_FACE_MODE_BOTH +} CoglPipelineCullFaceMode; + +typedef enum +{ + COGL_PIPELINE_FILTER_NEAREST = 0x2600, + COGL_PIPELINE_FILTER_LINEAR = 0x2601, + COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701, + COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703 +} CoglPipelineFilter; + +static gboolean +st_background_effect_pre_paint (ClutterEffect *effect) +{ + StBackgroundEffect *self = ST_BACKGROUND_EFFECT (effect); + ClutterEffectClass *parent_class; + gfloat width; + gfloat height; + gfloat posx; + gfloat posy; + guchar *data; + guint size; + guint rowstride; + gdouble new_time; + gdouble time_used; + + if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) + return FALSE; + + self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); + if (self->actor == NULL) + return FALSE; + + if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) + { + /* if we don't have support for GLSL shaders then we + * forcibly disable the ActorMeta + */ + g_warning ("Unable to use the ShaderEffect: the graphics hardware " + "or the current GL driver does not implement support " + "for the GLSL shading language."); + clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE); + return FALSE; + } + + new_time = clock(); + time_used = ((double) (new_time - self->old_time)*100) / CLOCKS_PER_SEC; + self->old_time = new_time; + + posx = 0.0f; + posy = 0.0f; + + width = 0.0f; + height = 0.0f; + + clutter_actor_get_transformed_position (self->actor, &posx, &posy); + clutter_actor_get_transformed_size (self->actor, &width, &height); + self->opacity = clutter_actor_get_paint_opacity (self->actor); + + if (( posx != self->posx_old) + || ( posy != self->posy_old) + || ( width != self->width_old) + || ( height != self->height_old) + || (time_used > 50)) + + { + self->posx_old = posx; + self->posy_old = posy; + self->width_old = width; + self->height_old = height; + + self->bg_posx_i = posx+2; + self->bg_posy_i = posy+2; + self->bg_width_i = width-4; + self->bg_height_i = height-4; + + size = (self->bg_width_i) * (self->bg_height_i) * 4; + + if ((size > 100) && (self->opacity > 0xe6)) + { + rowstride = (self->bg_width_i) * 4; + + data = g_malloc (size); + + cogl_read_pixels (self->bg_posx_i, + self->bg_posy_i, + self->bg_width_i, + self->bg_height_i, + COGL_READ_PIXELS_COLOR_BUFFER, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + data); + + if (data != NULL) + { + + if (self->bg_texture != NULL) + { + cogl_handle_unref (self->bg_texture); + self->bg_texture = NULL; + } + + self->bg_texture = cogl_texture_new_from_data (self->bg_width_i, + self->bg_height_i, + COGL_TEXTURE_NO_SLICING, + COGL_PIXEL_FORMAT_RGBA_8888, + COGL_PIXEL_FORMAT_ANY, + rowstride, + data); + + g_free (data); + } + } + } + + parent_class = CLUTTER_EFFECT_CLASS (st_background_effect_parent_class); + + if (parent_class->pre_paint (effect)) + { + ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect); + CoglHandle fg_texture; + + fg_texture = clutter_offscreen_effect_get_texture (offscreen_effect); + + if (fg_texture != COGL_INVALID_HANDLE) + { + self->fg_width_i = cogl_texture_get_width (fg_texture); + self->fg_height_i = cogl_texture_get_height (fg_texture); + + + if (self->bg_texture != NULL) + { + + if (self->pixel_step_uniform > -1) + { + gfloat pixel_step[2]; + + pixel_step[0] = 1.0f / (self->bg_width_i); + pixel_step[1] = 1.0f / (self->bg_height_i); + + cogl_pipeline_set_uniform_float (self->pipeline1, + self->pixel_step_uniform, + 2, + 1, + pixel_step); + } + + cogl_pipeline_set_layer_texture (self->pipeline1, 0, self->bg_texture); + + } + + cogl_pipeline_set_layer_texture (self->pipeline2, 0, fg_texture); + } + return TRUE; + } + else + { + return FALSE; + } + +} + +static void +st_background_effect_paint_target (ClutterOffscreenEffect *effect) +{ + StBackgroundEffect *self = ST_BACKGROUND_EFFECT (effect); + + cogl_pipeline_set_color4ub (self->pipeline1, + self->opacity, + self->opacity, + self->opacity, + self->opacity); + + cogl_pipeline_set_color4ub (self->pipeline2, + self->opacity, + self->opacity, + self->opacity, + self->opacity); + + cogl_push_source (self->pipeline1); + cogl_rectangle (4.0f, 4.0f, (self->bg_width_i) + 4.0f, (self->bg_height_i) + 4.0f); + cogl_pop_source (); + + cogl_push_source (self->pipeline2); + cogl_rectangle (0.0f, 0.0f, (self->fg_width_i), (self->fg_height_i)); + cogl_pop_source (); + + clutter_actor_queue_redraw (self->actor); + +} + +static void +st_background_effect_dispose (GObject *gobject) +{ + StBackgroundEffect *self = ST_BACKGROUND_EFFECT (gobject); + + if (self->pipeline1 != NULL) + { + cogl_object_unref (self->pipeline1); + self->pipeline1 = NULL; + } + + if (self->pipeline2 != NULL) + { + cogl_object_unref (self->pipeline2); + self->pipeline2 = NULL; + } + + if (self->bg_texture != NULL) + { + cogl_handle_unref (self->bg_texture); + self->bg_texture = NULL; + } + + G_OBJECT_CLASS (st_background_effect_parent_class)->dispose (gobject); +} + + +static void +st_background_effect_class_init (StBackgroundEffectClass *klass) +{ + ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterOffscreenEffectClass *offscreen_class; + + effect_class->pre_paint = st_background_effect_pre_paint; + gobject_class->dispose = st_background_effect_dispose; + + offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); + offscreen_class->paint_target = st_background_effect_paint_target; +} + +static void +st_background_effect_init (StBackgroundEffect *self) +{ + CoglContext *ctx; + StBackgroundEffectClass *klass = ST_BACKGROUND_EFFECT_GET_CLASS (self); + + if (G_UNLIKELY (klass->base_pipeline == NULL)) + { + ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + + klass->base_pipeline = cogl_pipeline_new (ctx); + } + + self->pipeline1 = cogl_pipeline_copy (klass->base_pipeline); + self->pipeline2 = cogl_pipeline_copy (klass->base_pipeline); + + CoglSnippet *snippet; + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, + box_blur_glsl_declarations, + NULL); + + cogl_snippet_set_replace (snippet, box_blur_glsl_shader); + cogl_pipeline_add_layer_snippet (self->pipeline1, 0, snippet); + cogl_object_unref (snippet); + + cogl_pipeline_set_layer_wrap_mode (self->pipeline1, 0, + COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); + + cogl_pipeline_set_layer_wrap_mode (self->pipeline2, 0, + COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); + + cogl_pipeline_set_cull_face_mode (self->pipeline1, + COGL_PIPELINE_CULL_FACE_MODE_NONE); + + cogl_pipeline_set_cull_face_mode (self->pipeline2, + COGL_PIPELINE_CULL_FACE_MODE_NONE); + + cogl_pipeline_set_layer_filters (self->pipeline1, 0, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR); + + cogl_pipeline_set_layer_filters (self->pipeline2, 0, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR); + + cogl_pipeline_set_layer_null_texture (self->pipeline1, + 0, + COGL_TEXTURE_TYPE_2D); + + cogl_pipeline_set_layer_null_texture (self->pipeline2, + 0, + COGL_TEXTURE_TYPE_2D); + + self->pixel_step_uniform = + cogl_pipeline_get_uniform_location (self->pipeline1, "pixel_step"); + + self->bg_texture = NULL; + + self->old_time = 0; + + self->opacity = 0; + +} + + +ClutterEffect * +st_background_effect_new () +{ + return g_object_new (ST_TYPE_BACKGROUND_EFFECT, + NULL); +} + diff -ruN a/src/st/st-background-effect.h b/src/st/st-background-effect.h --- a/src/st/st-background-effect.h 1969-12-31 21:00:00.000000000 -0300 +++ b/src/st/st-background-effect.h 2012-08-09 15:52:12.488792129 -0300 @@ -0,0 +1,60 @@ +#ifndef __ST_BACKGROUND_EFFECT_H__ +#define __ST_BACKGROUND_EFFECT_H__ + +#include +G_BEGIN_DECLS +#define ST_TYPE_BACKGROUND_EFFECT (st_background_effect_get_type ()) +#define ST_BACKGROUND_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ST_TYPE_BACKGROUND_EFFECT, StBackgroundEffect)) +#define ST_IS_BACKGROUND_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ST_TYPE_BACKGROUND_EFFECT)) + +typedef struct _StBackgroundEffect StBackgroundEffect; +typedef struct _StBackgroundEffectClass StBackgroundEffectClass; + +/* object */ + +struct _StBackgroundEffect +{ + ClutterOffscreenEffect parent_instance; + + ClutterActor *actor; + CoglHandle bg_texture; + CoglHandle bg_sub_texture; + + gint pixel_step_uniform; + + gint bg_posx_i; + gint bg_posy_i; + + gint bg_width_i; + gint bg_height_i; + + gint fg_width_i; + gint fg_height_i; + + gfloat posx_old; + gfloat posy_old; + gfloat width_old; + gfloat height_old; + + CoglPipeline *pipeline1; + CoglPipeline *pipeline2; + + gdouble old_time; + guint8 opacity; +}; + +/* class */ + +struct _StBackgroundEffectClass +{ + ClutterOffscreenEffectClass parent_class; + CoglPipeline *base_pipeline; + gboolean changed; +}; + +GType st_background_effect_get_type (void) G_GNUC_CONST; + +ClutterEffect *st_background_effect_new (); + +G_END_DECLS +#endif /* __ST_BACKGROUND_EFFECT_H__ */