summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--dummy0
-rw-r--r--src/vignetting.cpp238
-rw-r--r--src/vignetting.h81
-rw-r--r--vignetting.xml.in38
5 files changed, 363 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..5ae07f3
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,6 @@
+find_package (Compiz REQUIRED)
+
+include (CompizPlugin)
+
+compiz_plugin (vignetting PLUGINDEPS composite opengl PKGDEPS cairo cairo-xlib-xrender)
+
diff --git a/dummy b/dummy
deleted file mode 100644
index e69de29..0000000
--- a/dummy
+++ /dev/null
diff --git a/src/vignetting.cpp b/src/vignetting.cpp
new file mode 100644
index 0000000..be8d1d4
--- /dev/null
+++ b/src/vignetting.cpp
@@ -0,0 +1,238 @@
+#include "vignetting.h"
+
+COMPIZ_PLUGIN_20090315 (vignetting, VigPluginVTable);
+
+void
+VigScreen::cairoClear (cairo_t *cr)
+{
+ if (pixmap)
+ {
+ XFreePixmap (screen->dpy (), pixmap);
+ pixmap = None;
+ }
+ if (surface)
+ {
+ cairo_surface_destroy (surface);
+ surface = NULL;
+ }
+ if (cairo)
+ {
+ cairo_destroy (cairo);
+ cairo = NULL;
+ }
+
+ cairo = cairoContext ();
+
+ if (cairo)
+ {
+ cairo_save (cairo);
+ cairo_set_operator (cairo, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cairo);
+ cairo_restore (cairo);
+ }
+}
+
+cairo_t *
+VigScreen::cairoContext ()
+{
+ if (!cairo)
+ {
+ XRenderPictFormat *format;
+ Screen *xScreen;
+ int w, h;
+
+ xScreen = ScreenOfDisplay (screen->dpy (), screen->screenNum ());
+
+ w = optionGetQuality () * 50;
+ h = optionGetQuality () * 50;
+
+ format = XRenderFindStandardFormat (screen->dpy (),
+ PictStandardARGB32);
+
+ pixmap = XCreatePixmap (screen->dpy (), screen->root (), w, h, 32);
+
+ texture = GLTexture::bindPixmapToTexture (pixmap, w, h, 32);
+
+ if (texture.empty ())
+ {
+ compLogMessage ("annotate", CompLogLevelError,
+ "Couldn't bind pixmap 0x%x to texture",
+ (int) pixmap);
+
+ XFreePixmap (screen->dpy (), pixmap);
+
+ return NULL;
+ }
+
+ damage = XDamageCreate (screen->dpy (), pixmap,
+ XDamageReportRawRectangles);
+
+ surface =
+ cairo_xlib_surface_create_with_xrender_format (screen->dpy (),
+ pixmap, xScreen,
+ format, w, h);
+
+ cairo = cairo_create (surface);
+ }
+
+ return cairo;
+}
+
+void
+VigScreen::renderVignette ()
+{
+ cairo_pattern_t *pat;
+ cairoClear (cairo);
+
+ unsigned int size = optionGetQuality () * 50;
+
+ /* Radial gradient - transparent center, opaque black outside */
+ pat = cairo_pattern_create_radial (size / 2, size / 2, size / 20,
+ size / 2, size / 2, size / 2);
+
+ /* Transparent */
+ cairo_pattern_add_color_stop_rgba (pat, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+ /* Black */
+ cairo_pattern_add_color_stop_rgba (pat, 1.0f, 0.0f, 0.0f, 0.0f, 0.9f);
+ /* Drawing over whatever was there */
+ cairo_set_operator (cairo, CAIRO_OPERATOR_OVER);
+ /* Copy the size of the rectangle to the surface from the gradient
+ */
+ cairo_rectangle (cairo, 0, 0, (optionGetQuality () * 50),
+ (optionGetQuality () * 50));
+ cairo_set_source (cairo, pat);
+ cairo_fill (cairo);
+
+ cairo_pattern_destroy (pat);
+
+}
+
+/* Draw the window */
+
+bool
+VigWindow::glDraw (const GLMatrix &transform,
+ GLFragment::Attrib &fragment,
+ const CompRegion &region,
+ unsigned int mask)
+{
+ /* Save the brightness, we will be using it later */
+ float brightness = fragment.getBrightness ();
+
+ /* We want to set the geometry of the vignette to the window
+ * region */
+ CompRegion reg = CompRegion (window->inputRect ());
+
+ /* Draw the window on the bottom, we will be drawing the
+ * vignette render on top */
+ bool status = gWindow->glDraw (transform, fragment, region, mask);
+
+ VIG_SCREEN (screen);
+
+ foreach (GLTexture *tex, vs->texture)
+ {
+ GLTexture::MatrixList matl;
+ GLTexture::Matrix mat = tex->matrix ();
+
+ /* We can reset the window geometry since it will be
+ * re-added later */
+ gWindow->geometry ().reset ();
+
+ /* Scale the vignette render by the ratio of vignette size
+ * to window size */
+ mat.xx *= (vs->optionGetQuality () * 50.0f) / window->inputRect ().width ();
+ mat.yy *= (vs->optionGetQuality () * 50.0f) / window->inputRect ().height ();
+
+ /* Not sure what this does, but it is necessary
+ * (adjusts for scale?) */
+ mat.x0 -= mat.xx * reg.boundingRect ().x1 ();
+ mat.y0 -= mat.yy * reg.boundingRect ().y1 ();
+
+ matl.push_back (mat);
+
+ /* Now allow plugins to mess with the geometry of our
+ * vignette (so we get a nice render for things like
+ * wobbly etc etc */
+ gWindow->glAddGeometry (matl, reg, infiniteRegion);
+
+ /* Did it succeed? */
+ if (gWindow->geometry ().vertices)
+ {
+ /* Set the opacity of the vignette render to
+ * the opposite of the real brightness of the window */
+ fragment.setOpacity (OPAQUE - brightness);
+ /* Texture rendering set-up */
+ vs->gScreen->setTexEnvMode (GL_MODULATE);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* Draw the vignette texture with all of it's modified
+ * geometry glory */
+ gWindow->glDrawTexture (tex, fragment, mask | PAINT_WINDOW_BLEND_MASK
+ | PAINT_WINDOW_TRANSLUCENT_MASK |
+ PAINT_WINDOW_TRANSFORMED_MASK);
+ /* Texture rendering tear-down */
+ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ vs->gScreen->setTexEnvMode (GL_REPLACE);
+ }
+ }
+
+ return status;
+}
+
+void
+VigScreen::optionChanged (CompOption *opt,
+ Options num)
+{
+ switch (num)
+ {
+ case VignettingOptions::Quality:
+ renderVignette ();
+ default:
+ break;
+ }
+}
+
+
+
+/* Constructors */
+
+VigWindow::VigWindow (CompWindow *w) :
+ PluginClassHandler <VigWindow, CompWindow> (w),
+ window (w),
+ cWindow (CompositeWindow::get (w)),
+ gWindow (GLWindow::get (w))
+{
+ GLWindowInterface::setHandler (gWindow);
+}
+
+VigWindow::~VigWindow ()
+{
+}
+
+VigScreen::VigScreen (CompScreen *s) :
+ PluginClassHandler <VigScreen, CompScreen> (s),
+ cScreen (CompositeScreen::get (s)),
+ gScreen (GLScreen::get (s)),
+ pixmap (None),
+ surface (NULL),
+ cairo (NULL)
+{
+ renderVignette ();
+
+ optionSetQualityNotify (boost::bind (&VigScreen::optionChanged, this,
+ _1, _2));
+};
+
+VigScreen::~VigScreen ()
+{
+ cairoClear (cairo);
+}
+
+bool
+VigPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
+ !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
+ !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
+ return false;
+
+ return true;
+}
diff --git a/src/vignetting.h b/src/vignetting.h
new file mode 100644
index 0000000..15d46c3
--- /dev/null
+++ b/src/vignetting.h
@@ -0,0 +1,81 @@
+#include <core/core.h>
+#include <composite/composite.h>
+#include <opengl/opengl.h>
+
+#include <cairo-xlib-xrender.h>
+
+#include "vignetting_options.h"
+
+class VigScreen :
+ public PluginClassHandler <VigScreen, CompScreen>,
+ public VignettingOptions
+{
+ public:
+
+ VigScreen (CompScreen *);
+ ~VigScreen ();
+
+ void
+ cairoClear (cairo_t *cr);
+
+ cairo_t *
+ cairoContext ();
+
+ void
+ renderVignette ();
+
+ void
+ optionChanged (CompOption *opt,
+ Options num);
+
+ public:
+
+ CompositeScreen *cScreen;
+ GLScreen *gScreen;
+
+ public:
+
+ Pixmap pixmap;
+ GLTexture::List texture;
+ cairo_surface_t *surface;
+ cairo_t *cairo;
+ Damage damage;
+};
+
+#define VIG_SCREEN(s) \
+ VigScreen *vs = VigScreen::get (s);
+
+class VigWindow :
+ public PluginClassHandler <VigWindow, CompWindow>,
+ public GLWindowInterface
+{
+ public:
+
+ VigWindow (CompWindow *w);
+ ~VigWindow ();
+
+ public:
+
+ CompWindow *window;
+ CompositeWindow *cWindow;
+ GLWindow *gWindow;
+
+ public:
+
+ bool
+ glDraw (const GLMatrix &, GLFragment::Attrib &,
+ const CompRegion &, unsigned int);
+
+
+};
+
+#define VIG_WINDOW(w) \
+ VigWindow *vw = VigWindow::get (w);
+
+class VigPluginVTable :
+ public CompPlugin::VTableForScreenAndWindow <VigScreen, VigWindow>
+{
+ public:
+
+ bool init ();
+};
diff --git a/vignetting.xml.in b/vignetting.xml.in
new file mode 100644
index 0000000..469ee57
--- /dev/null
+++ b/vignetting.xml.in
@@ -0,0 +1,38 @@
+<compiz>
+ <plugin name="vignetting" useBcop="true">
+ <category>Effects</category>
+ <_short>Vignetting</_short>
+ <_long>Draw a vignette of brightness rather than continually dimming the whole window</_long>
+ <deps>
+ <requirement>
+ <plugin>composite</plugin>
+ <plugin>opengl</plugin>
+ </requirement>
+ <relation type="after">
+ <plugin>decor</plugin>
+ </relation>
+ <relation type="before">
+ <plugin>group</plugin>
+ <plugin>obs</plugin>
+ <plugin>shift</plugin>
+ <plugin>switcher</plugin>
+ <plugin>staticswitcher</plugin>
+ <plugin>stackswitch</plugin>
+ <plugin>dialog</plugin>
+ <plugin>fade</plugin>
+ <plugin>trailfocus</plugin>
+ <plugin>splash</plugin>
+ <plugin>loginout</plugin>
+ </relation>
+ </deps>
+ <options>
+ <option name="quality" type="int">
+ <_short>Quality</_short>
+ <_long>Quality of Vignette Rendering</_long>
+ <default>5</default>
+ <min>1</min>
+ <max>15</max>
+ </option>
+ </options>
+ </plugin>
+</compiz>