[beryl-commits] compiz mirror: Changes to 'master' (bb7e30cca4fe4b385e45ea0967a8689bf8e11b93)

compiz at server.beryl-project.org compiz at server.beryl-project.org
Thu Jun 21 18:08:22 CEST 2007


New commits:
commit bb7e30cca4fe4b385e45ea0967a8689bf8e11b93
Merge: a2f6b00680d650ba230144b659e7960878de55de 4158e1647a7ead4418e7317f27a7a82bfa944ae7
Author: David Reveman <davidr at novell.com>
Date:   Thu Jun 21 11:37:15 2007 -0400

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/app/compiz

commit a2f6b00680d650ba230144b659e7960878de55de
Merge: fdfb32755d78ac421c391980f2286510d7f1fc61 4d5342048eff70ebb6a2f2b00b77b165809d4caa
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 20 16:25:12 2007 -0400

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/app/compiz

commit fdfb32755d78ac421c391980f2286510d7f1fc61
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 20 16:24:53 2007 -0400

    Don't allow transients to be stacked above dock windows
    unless they are dock windows themselves.

commit bc8fcabd2e1d9cea5d44fad4b35a5168ad425948
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 20 12:52:53 2007 -0400

    libdecoration is now useed by svg plugin.

commit 01c54eb57a38ed48becdc1699c4b5fa0dbee410f
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 20 12:52:12 2007 -0400

    Add experimental support for svg objects.

commit 5cd5d087be9dd62b7579ea1ad299942eb37f7861
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 20 12:50:23 2007 -0400

    Add some basic events that can be used by other plugins
    to track zoom region.

commit c2c386324bdc21dbe42535b825da20628141694f
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 20 12:27:20 2007 -0400

    Do not fall-through if path isn't long enough to be an
    option message.

commit 32a79e747390130fadb9f2d4fceac715ae06c2ed
Author: David Reveman <davidr at novell.com>
Date:   Fri Jun 15 17:15:42 2007 -0400

    Set hoveredWindow more properly.

commit 4b7ec83e3ed8b077ff1aa4a4c5902a5bdd3d41b1
Author: David Reveman <davidr at novell.com>
Date:   Tue Jun 12 16:34:18 2007 -0400

    Make sure we free the window private index.

commit b98c723a8781e550d276b56788bcc2044f71f65d
Merge: 90ed941f533a0a3acf72e0b356391a5c564bf783 64fbb40bc64208e5410582e3cd9f19aa0d52bcc4
Author: David Reveman <davidr at novell.com>
Date:   Tue Jun 12 12:46:05 2007 -0400

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/app/compiz

commit 90ed941f533a0a3acf72e0b356391a5c564bf783
Author: David Reveman <davidr at novell.com>
Date:   Fri Jun 8 11:54:57 2007 -0400

    Use pointerX and pointerY when initializing deltas.

commit 072b980bee3c236a59428a161a09d2e97cddb12e
Merge: e1ad529462615c9d5911269e04b38d1976cc4fd0 f5aae2667806553b1593f4a792da62c1f7d3bc89
Author: David Reveman <davidr at novell.com>
Date:   Fri Jun 8 10:54:03 2007 -0400

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/app/compiz

commit e1ad529462615c9d5911269e04b38d1976cc4fd0
Merge: 672ca9b0d9f090a53221947d66bd51144797eb95 7bdb04de807dc83b624b52c4e41f15aa9ce49285
Author: David Reveman <davidr at novell.com>
Date:   Thu Jun 7 10:51:43 2007 -0400

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/app/compiz

commit 672ca9b0d9f090a53221947d66bd51144797eb95
Author: David Reveman <davidr at novell.com>
Date:   Wed Jun 6 15:34:00 2007 -0400

    Use fleur cursor instead of plus cursor when moving
    windows.


 plugins/Makefile.am |    5 +-
 plugins/dbus.c      |    9 +
 plugins/resize.c    |    4 +-
 plugins/scale.c     |    4 +-
 plugins/svg.c       |  753 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 plugins/video.c     |    2 +
 plugins/zoom.c      |   61 ++++
 src/window.c        |   26 +-
 8 files changed, 839 insertions(+), 25 deletions(-)


Modified: compiz/plugins/Makefile.am
===================================================================
--- compiz/plugins/Makefile.am
+++ compiz/plugins/Makefile.am
@@ -65,8 +65,11 @@ libini_la_LDFLAGS = -module -avoid-version -no-undefined
 libini_la_SOURCES = ini.c
 
 if USE_LIBRSVG
+libsvg_la_DEPENDENCIES = $(top_builddir)/libdecoration/libdecoration.la
 libsvg_la_LDFLAGS = -module -avoid-version -no-undefined
-libsvg_la_LIBADD = @LIBRSVG_LIBS@
+libsvg_la_LIBADD =				       \
+	$(top_builddir)/libdecoration/libdecoration.la \
+	@LIBRSVG_LIBS@
 libsvg_la_SOURCES = svg.c
 libsvg_module = libsvg.la
 endif

Modified: compiz/plugins/dbus.c
===================================================================
--- compiz/plugins/dbus.c
+++ compiz/plugins/dbus.c
@@ -1905,6 +1905,9 @@ dbusHandleMessage (DBusConnection *connection,
 		return DBUS_HANDLER_RESULT_HANDLED;
 	    }
 	}
+
+	dbus_free_string_array (path);
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
     /* plugin message */
     else if (!path[4])
@@ -1919,6 +1922,9 @@ dbusHandleMessage (DBusConnection *connection,
 		return DBUS_HANDLER_RESULT_HANDLED;
 	    }
 	}
+
+	dbus_free_string_array (path);
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
     /* screen message */
     else if (!path[5])
@@ -1942,6 +1948,9 @@ dbusHandleMessage (DBusConnection *connection,
 		return DBUS_HANDLER_RESULT_HANDLED;
 	    }
 	}
+
+	dbus_free_string_array (path);
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
     /* option message */
     if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,

Modified: compiz/plugins/resize.c
===================================================================
--- compiz/plugins/resize.c
+++ compiz/plugins/resize.c
@@ -351,8 +351,8 @@ resizeInitiate (CompDisplay     *d,
 
 	rd->geometry = rd->savedGeometry;
 
-	rd->pointerDx = x - lastPointerX;
-	rd->pointerDy = y - lastPointerY;
+	rd->pointerDx = x - pointerX;
+	rd->pointerDy = y - pointerY;
 
 	rd->mode = rd->opt[RESIZE_DISPLAY_OPTION_MODE].value.i;
 	for (i = 0; i <= RESIZE_MODE_LAST; i++)

Modified: compiz/plugins/scale.c
===================================================================
--- compiz/plugins/scale.c
+++ compiz/plugins/scale.c
@@ -1332,8 +1332,6 @@ scaleSelectWindow (CompWindow *w)
 {
     SCALE_DISPLAY (w->screen->display);
 
-    sd->hoveredWindow = w->id;
-
     if (sd->selectedWindow != w->id)
     {
 	CompWindow *old, *new;
@@ -1374,6 +1372,8 @@ scaleSelectWindowAt (CompScreen *s,
 	    moveInputFocusToWindow (w);
 	}
 
+	sd->hoveredWindow = w->id;
+
 	return TRUE;
     }
 

Modified: compiz/plugins/svg.c
===================================================================
--- compiz/plugins/svg.c
+++ compiz/plugins/svg.c
@@ -26,25 +26,620 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <cairo/cairo-xlib.h>
 #include <librsvg/rsvg.h>
 #include <librsvg/rsvg-cairo.h>
 
+#include <X11/Xatom.h>
+#include <X11/extensions/shape.h>
+
 #include <compiz.h>
+#include <decoration.h>
 
 static CompMetadata svgMetadata;
 
+#define SVG_DISPLAY_OPTION_SET 0
+#define SVG_DISPLAY_OPTION_NUM 1
+
 static int displayPrivateIndex;
 
 typedef struct _SvgDisplay {
+    CompOption opt[SVG_DISPLAY_OPTION_NUM];
+
+    int	screenPrivateIndex;
+
+    HandleCompizEventProc handleCompizEvent;
+
     FileToImageProc fileToImage;
 } SvgDisplay;
 
+typedef struct _SvgScreen {
+    int	windowPrivateIndex;
+
+    DrawWindowProc drawWindow;
+
+    WindowMoveNotifyProc   windowMoveNotify;
+    WindowResizeNotifyProc windowResizeNotify;
+
+    BoxRec zoom;
+} SvgScreen;
+
+typedef struct _SvgSource {
+    decor_point_t p1;
+    decor_point_t p2;
+
+    RsvgHandle	      *svg;
+    RsvgDimensionData dimension;
+} SvgSource;
+
+typedef struct _SvgTexture {
+    CompTexture texture;
+    CompMatrix  matrix;
+    cairo_t     *cr;
+    Pixmap      pixmap;
+    int		width;
+    int	        height;
+} SvgTexture;
+
+typedef struct _SvgContext {
+    SvgSource  *source;
+    REGION     box;
+    SvgTexture texture[2];
+    BoxRec     rect;
+    int	       width, height;
+} SvgContext;
+
+typedef struct _SvgWindow {
+    SvgSource  *source;
+    SvgContext *context;
+} SvgWindow;
+
 #define GET_SVG_DISPLAY(d)				    \
     ((SvgDisplay *) (d)->privates[displayPrivateIndex].ptr)
 
 #define SVG_DISPLAY(d)			 \
     SvgDisplay *sd = GET_SVG_DISPLAY (d)
 
+#define GET_SVG_SCREEN(s, sd)					\
+    ((SvgScreen *) (s)->privates[(sd)->screenPrivateIndex].ptr)
+
+#define SVG_SCREEN(s)						     \
+    SvgScreen *ss = GET_SVG_SCREEN (s, GET_SVG_DISPLAY (s->display))
+
+#define GET_SVG_WINDOW(w, ss)					\
+    ((SvgWindow *) (w)->privates[(ss)->windowPrivateIndex].ptr)
+
+#define SVG_WINDOW(w)					   \
+    SvgWindow *sw = GET_SVG_WINDOW  (w,			   \
+		    GET_SVG_SCREEN  (w->screen,		   \
+		    GET_SVG_DISPLAY (w->screen->display)))
+
+#define NUM_OPTIONS(d) (sizeof ((d)->opt) / sizeof (CompOption))
+
+static void
+renderSvg (CompScreen *s,
+	   SvgSource  *source,
+	   SvgTexture *texture,
+	   float      x1,
+	   float      y1,
+	   float      x2,
+	   float      y2,
+	   int	      width,
+	   int	      height)
+{
+    float w = x2 - x1;
+    float h = y2 - y1;
+
+    cairo_save (texture->cr);
+
+    cairo_set_operator (texture->cr, CAIRO_OPERATOR_SOURCE);
+    cairo_set_source_rgb (texture->cr, 1.0, 1.0, 1.0);
+    cairo_paint (texture->cr);
+    cairo_set_operator (texture->cr, CAIRO_OPERATOR_OVER);
+
+    cairo_scale (texture->cr, 1.0 / w, 1.0 / h);
+
+    cairo_scale (texture->cr,
+		 (double) width / source->dimension.width,
+		 (double) height / source->dimension.height);
+
+    cairo_translate (texture->cr,
+		     -x1 * source->dimension.width,
+		     -y1 * source->dimension.height);
+
+    rsvg_handle_render_cairo (source->svg, texture->cr);
+
+    cairo_restore (texture->cr);
+}
+
+static Bool
+initSvgTexture (CompScreen *s,
+		SvgSource  *source,
+		SvgTexture *texture,
+		int	   width,
+		int	   height)
+{
+    cairo_surface_t *surface;
+    Visual	    *visual;
+    int		    depth;
+
+    initTexture (s, &texture->texture);
+
+    texture->width  = width;
+    texture->height = height;
+
+    texture->pixmap = None;
+    texture->cr     = NULL;
+
+    if (width && height)
+    {
+	depth = DefaultDepth (s->display->display, s->screenNum);
+	texture->pixmap = XCreatePixmap (s->display->display, s->root,
+					 width, height, depth);
+
+	if (!bindPixmapToTexture (s,
+				  &texture->texture,
+				  texture->pixmap,
+				  width, height, depth))
+	{
+	    fprintf (stderr, "%s: Couldn't bind pixmap 0x%x to "
+		     "texture\n", programName, (int) texture->pixmap);
+
+	    XFreePixmap (s->display->display, texture->pixmap);
+
+	    return FALSE;
+	}
+
+	visual = DefaultVisual (s->display->display, s->screenNum);
+
+	surface = cairo_xlib_surface_create (s->display->display,
+					     texture->pixmap, visual,
+					     width, height);
+	texture->cr = cairo_create (surface);
+	cairo_surface_destroy (surface);
+    }
+
+    return TRUE;
+}
+
+static void
+finiSvgTexture (CompScreen *s,
+		SvgTexture *texture)
+{
+    if (texture->cr)
+	cairo_destroy (texture->cr);
+
+    if (texture->pixmap)
+	XFreePixmap (s->display->display, texture->pixmap);
+
+    finiTexture (s, &texture->texture);
+}
+
+static void
+updateWindowSvgMatrix (CompWindow *w)
+{
+    CompMatrix *m;
+    int	       width, height;
+
+    SVG_WINDOW (w);
+
+    width  = sw->context->box.extents.x2 - sw->context->box.extents.x1;
+    height = sw->context->box.extents.y2 - sw->context->box.extents.y1;
+
+    m = &sw->context->texture[0].matrix;
+    *m = sw->context->texture[0].texture.matrix;
+
+    m->xx *= (float) sw->context->texture[0].width  / width;
+    m->yy *= (float) sw->context->texture[0].height / height;
+
+    m->x0 -= (sw->context->box.extents.x1 * m->xx);
+    m->y0 -= (sw->context->box.extents.y1 * m->yy);
+
+    m = &sw->context->texture[1].matrix;
+    *m = sw->context->texture[1].texture.matrix;
+
+    width  = sw->context->rect.x2 - sw->context->rect.x1;
+    height = sw->context->rect.y2 - sw->context->rect.y1;
+
+    m->xx *= (float) sw->context->texture[1].width  / width;
+    m->yy *= (float) sw->context->texture[1].height / height;
+
+    m->x0 -= (sw->context->rect.x1 * m->xx);
+    m->y0 -= (sw->context->rect.y1 * m->yy);
+}
+
+static Bool
+svgDrawWindow (CompWindow	      *w,
+		 const CompTransform  *transform,
+		 const FragmentAttrib *attrib,
+		 Region		      region,
+		 unsigned int	      mask)
+{
+    Bool status;
+
+    SVG_SCREEN (w->screen);
+
+    UNWRAP (ss, w->screen, drawWindow);
+    status = (*w->screen->drawWindow) (w, transform, attrib, region, mask);
+    WRAP (ss, w->screen, drawWindow, svgDrawWindow);
+
+    if (status)
+    {
+	SVG_WINDOW (w);
+
+	if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
+	    region = &infiniteRegion;
+
+	if (sw->context && region->numRects)
+	{
+	    CompTexture *texture = &sw->context->texture[0].texture;
+	    CompMatrix  *matrix = &sw->context->texture[0].matrix;
+	    REGION	r;
+
+	    r.rects    = &r.extents;
+	    r.numRects = 1;
+
+	    r.extents = sw->context->box.extents;
+
+	    if (r.extents.x1 < ss->zoom.x1)
+		r.extents.x1 = ss->zoom.x1;
+	    if (r.extents.y1 < ss->zoom.y1)
+		r.extents.y1 = ss->zoom.y1;
+	    if (r.extents.x2 > ss->zoom.x2)
+		r.extents.x2 = ss->zoom.x2;
+	    if (r.extents.y2 > ss->zoom.y2)
+		r.extents.y2 = ss->zoom.y2;
+
+	    w->vCount = w->indexCount = 0;
+
+	    (*w->screen->addWindowGeometry) (w,
+					     matrix, 1,
+					     &sw->context->box,
+					     region);
+
+	    if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
+		mask |= PAINT_WINDOW_BLEND_MASK;
+
+	    (*w->screen->drawWindowTexture) (w, texture, attrib, mask);
+
+	    if (r.extents.x1 < r.extents.x2 && r.extents.y1 < r.extents.y2)
+	    {
+		float xScale, yScale;
+		float dx, dy;
+		int   width, height;
+		int   saveFilter;
+
+		r.extents.x1--;
+		r.extents.y1--;
+		r.extents.x2++;
+		r.extents.y2++;
+
+		xScale = w->screen->width  / (float)
+		    (ss->zoom.x2 - ss->zoom.x1);
+		yScale = w->screen->height / (float)
+		    (ss->zoom.y2 - ss->zoom.y1);
+
+		dx = r.extents.x2 - r.extents.x1;
+		dy = r.extents.y2 - r.extents.y1;
+
+		width  = dx * xScale + 0.5f;
+		height = dy * yScale + 0.5f;
+
+		if (r.extents.x1 != sw->context->rect.x1 ||
+		    r.extents.y1 != sw->context->rect.y1 ||
+		    r.extents.x2 != sw->context->rect.x2 ||
+		    r.extents.y2 != sw->context->rect.y2 ||
+		    width	 != sw->context->width   ||
+		    height	 != sw->context->height)
+		{
+		    float x1, y1, x2, y2;
+
+		    sw->context->rect = r.extents;
+
+		    sw->context->width  = width;
+		    sw->context->height = height;
+
+		    dx = sw->context->box.extents.x2 -
+			sw->context->box.extents.x1;
+		    dy = sw->context->box.extents.y2 -
+			sw->context->box.extents.y1;
+
+		    x1 = (r.extents.x1 - sw->context->box.extents.x1) / dx;
+		    y1 = (r.extents.y1 - sw->context->box.extents.y1) / dy;
+		    x2 = (r.extents.x2 - sw->context->box.extents.x1) / dx;
+		    y2 = (r.extents.y2 - sw->context->box.extents.y1) / dy;
+
+		    finiSvgTexture (w->screen, &sw->context->texture[1]);
+
+		    if (initSvgTexture (w->screen, sw->context->source,
+					&sw->context->texture[1],
+					width, height))
+		    {
+			renderSvg (w->screen, sw->context->source,
+				   &sw->context->texture[1],
+				   x1, y1, x2, y2,
+				   width, height);
+
+			updateWindowSvgMatrix (w);
+		    }
+		}
+
+		texture = &sw->context->texture[1].texture;
+		matrix = &sw->context->texture[1].matrix;
+
+		w->vCount = w->indexCount = 0;
+
+		saveFilter = w->screen->filter[SCREEN_TRANS_FILTER];
+		w->screen->filter[SCREEN_TRANS_FILTER] =
+		    COMP_TEXTURE_FILTER_GOOD;
+
+		(*w->screen->addWindowGeometry) (w, matrix, 1, &r, region);
+		(*w->screen->drawWindowTexture) (w, texture, attrib, mask);
+
+		w->screen->filter[SCREEN_TRANS_FILTER] = saveFilter;
+	    }
+	    else if (sw->context->texture[1].width)
+	    {
+		finiSvgTexture (w->screen, &sw->context->texture[1]);
+		initSvgTexture (w->screen, sw->source,
+				&sw->context->texture[1],
+				0, 0);
+
+		memset (&sw->context->rect, 0, sizeof (BoxRec));
+
+		sw->context->width  = 0;
+		sw->context->height = 0;
+	    }
+	}
+    }
+
+    return status;
+}
+
+static void
+updateWindowSvgContext (CompWindow *w,
+			SvgSource  *source)
+{
+    int x1, y1, x2, y2;
+
+    SVG_WINDOW (w);
+
+    if (sw->context)
+    {
+	finiSvgTexture (w->screen, &sw->context->texture[0]);
+	finiSvgTexture (w->screen, &sw->context->texture[1]);
+    }
+    else
+    {
+	sw->context = malloc (sizeof (SvgContext));
+	if (!sw->context)
+	    return;
+    }
+
+    memset (&sw->context->rect, 0, sizeof (BoxRec));
+
+    sw->context->width  = 0;
+    sw->context->height = 0;
+
+    initSvgTexture (w->screen, source,
+		    &sw->context->texture[1],
+		    0, 0);
+
+    sw->context->source = source;
+
+    sw->context->box.rects    = &sw->context->box.extents;
+    sw->context->box.numRects = 1;
+
+    decor_apply_gravity (source->p1.gravity,
+			 source->p1.x, source->p1.y,
+			 w->width, w->height,
+			 &x1, &y1);
+
+    decor_apply_gravity (source->p2.gravity,
+			 source->p2.x, source->p2.y,
+			 w->width, w->height,
+			 &x2, &y2);
+
+    x1 = MAX (x1, 0);
+    y1 = MAX (y1, 0);
+    x2 = MIN (x2, w->width);
+    y2 = MIN (y2, w->height);
+
+    if (!initSvgTexture (w->screen, source,
+			 &sw->context->texture[0],
+			 w->width, w->height))
+    {
+	free (sw->context);
+	sw->context = NULL;
+    }
+    else
+    {
+	renderSvg (w->screen, source, &sw->context->texture[0],
+		   0.0f, 0.0f, 1.0f, 1.0f, w->width, w->height);
+
+	initSvgTexture (w->screen, source, &sw->context->texture[1], 0, 0);
+
+	sw->context->box.extents.x1 = x1;
+	sw->context->box.extents.y1 = y1;
+	sw->context->box.extents.x2 = x2;
+	sw->context->box.extents.y2 = y2;
+
+	sw->context->box.extents.x1 += w->attrib.x;
+	sw->context->box.extents.y1 += w->attrib.y;
+	sw->context->box.extents.x2 += w->attrib.x;
+	sw->context->box.extents.y2 += w->attrib.y;
+
+	updateWindowSvgMatrix (w);
+    }
+}
+
+static Bool
+svgSet (CompDisplay     *d,
+	CompAction      *action,
+	CompActionState state,
+	CompOption      *option,
+	int	        nOption)
+{
+    CompWindow *w;
+    Window     xid;
+
+    xid = getIntOptionNamed (option, nOption, "window", 0);
+
+    w = findWindowAtDisplay (d, xid);
+    if (w)
+    {
+	decor_point_t p[2];
+	char	      *data;
+	RsvgHandle    *svg = NULL;
+	GError	      *error = NULL;
+
+	SVG_WINDOW (w);
+
+	memset (p, 0, sizeof (p));
+
+	p[0].gravity = getIntOptionNamed (option, nOption, "gravity0",
+					  GRAVITY_NORTH | GRAVITY_WEST);
+
+	p[0].x = getIntOptionNamed (option, nOption, "x0", 0);
+	p[0].y = getIntOptionNamed (option, nOption, "y0", 0);
+
+	p[1].gravity = getIntOptionNamed (option, nOption, "gravity1",
+					  GRAVITY_SOUTH | GRAVITY_EAST);
+
+	p[1].x = getIntOptionNamed (option, nOption, "x1", 0);
+	p[1].y = getIntOptionNamed (option, nOption, "y1", 0);
+
+	data = getStringOptionNamed (option, nOption, "data", 0);
+	if (data)
+	    svg = rsvg_handle_new_from_data ((guint8 *) data, strlen (data),
+					     &error);
+
+	if (sw->source)
+	{
+	    rsvg_handle_free (sw->source->svg);
+	    sw->source->svg = svg;
+	}
+	else
+	{
+	    sw->source = malloc (sizeof (SvgSource));
+	    if (sw->source)
+		sw->source->svg = svg;
+	}
+
+	if (sw->source && sw->source->svg)
+	{
+	    sw->source->p1 = p[0];
+	    sw->source->p2 = p[1];
+
+	    sw->source->svg = svg;
+
+	    rsvg_handle_get_dimensions (svg, &sw->source->dimension);
+
+	    updateWindowSvgContext (w, sw->source);
+	}
+	else
+	{
+	    if (svg)
+		rsvg_handle_free (svg);
+
+	    if (sw->source)
+	    {
+		free (sw->source);
+		sw->source = NULL;
+	    }
+
+	    if (sw->context)
+	    {
+		finiSvgTexture (w->screen, &sw->context->texture[0]);
+		free (sw->context);
+		sw->context = NULL;
+	    }
+	}
+    }
+
+    return FALSE;
+}
+
+static void
+svgWindowMoveNotify (CompWindow *w,
+		       int	  dx,
+		       int	  dy,
+		       Bool	  immediate)
+{
+    SVG_SCREEN (w->screen);
+    SVG_WINDOW (w);
+
+    if (sw->context)
+    {
+	sw->context->box.extents.x1 += dx;
+	sw->context->box.extents.y1 += dy;
+	sw->context->box.extents.x2 += dx;
+	sw->context->box.extents.y2 += dy;
+
+	updateWindowSvgMatrix (w);
+    }
+
+    UNWRAP (ss, w->screen, windowMoveNotify);
+    (*w->screen->windowMoveNotify) (w, dx, dy, immediate);
+    WRAP (ss, w->screen, windowMoveNotify, svgWindowMoveNotify);
+}
+
+static void
+svgWindowResizeNotify (CompWindow *w,
+		       int        dx,
+		       int        dy,
+		       int        dwidth,
+		       int        dheight)
+{
+    SVG_SCREEN (w->screen);
+    SVG_WINDOW (w);
+
+    if (sw->source)
+	updateWindowSvgContext (w, sw->source);
+
+    UNWRAP (ss, w->screen, windowResizeNotify);
+    (*w->screen->windowResizeNotify) (w, dx, dy, dwidth, dheight);
+    WRAP (ss, w->screen, windowResizeNotify, svgWindowResizeNotify);
+}
+
+static void
+svgHandleCompizEvent (CompDisplay *d,
+		      char	  *pluginName,
+		      char	  *eventName,
+		      CompOption  *option,
+		      int	  nOption)
+{
+    SVG_DISPLAY (d);
+
+    UNWRAP (sd, d, handleCompizEvent);
+    (*d->handleCompizEvent) (d, pluginName, eventName, option, nOption);
+    WRAP (sd, d, handleCompizEvent, svgHandleCompizEvent);
+
+    if (strcmp (pluginName, "zoom") == 0)
+    {
+	CompScreen *s;
+	int	   output = getIntOptionNamed (option, nOption, "output", 0);
+
+	s = findScreenAtDisplay (d, getIntOptionNamed (option, nOption,
+						       "root", 0));
+	if (s && output == 0)
+	{
+	    SVG_SCREEN (s);
+
+	    if (strcmp (eventName, "in") == 0)
+	    {
+		ss->zoom.x1 = getIntOptionNamed (option, nOption, "x1", 0);
+		ss->zoom.y1 = getIntOptionNamed (option, nOption, "y1", 0);
+		ss->zoom.x2 = getIntOptionNamed (option, nOption, "x2", 0);
+		ss->zoom.y2 = getIntOptionNamed (option, nOption, "y2", 0);
+	    }
+	    else if (strcmp (eventName, "out") == 0)
+	    {
+		memset (&ss->zoom, 0, sizeof (BoxRec));
+	    }
+	}
+    }
+}
 
 static Bool
 readSvgFileToImage (char *file,
@@ -163,6 +758,38 @@ svgFileToImage (CompDisplay *d,
     return status;
 }
 
+static CompOption *
+svgGetDisplayOptions (CompPlugin  *plugin,
+		      CompDisplay *display,
+		      int	  *count)
+{
+    SVG_DISPLAY (display);
+
+    *count = NUM_OPTIONS (sd);
+    return sd->opt;
+}
+
+static Bool
+svgSetDisplayOption (CompPlugin      *plugin,
+		     CompDisplay     *display,
+		     char	     *name,
+		     CompOptionValue *value)
+{
+    CompOption *o;
+
+    SVG_DISPLAY (display);
+
+    o = compFindOption (sd->opt, NUM_OPTIONS (sd), name, NULL);
+    if (!o)
+	return FALSE;
+
+    return compSetDisplayOption (display, o, value);
+}
+
+static const CompMetadataOptionInfo svgDisplayOptionInfo[] = {
+    { "set", "action", 0, svgSet, NULL }
+};
+
 static Bool
 svgInitDisplay (CompPlugin  *p,
 		CompDisplay *d)
@@ -174,6 +801,25 @@ svgInitDisplay (CompPlugin  *p,
     if (!sd)
 	return FALSE;
 
+    if (!compInitDisplayOptionsFromMetadata (d,
+					     &svgMetadata,
+					     svgDisplayOptionInfo,
+					     sd->opt,
+					     SVG_DISPLAY_OPTION_NUM))
+    {
+	free (sd);
+	return FALSE;
+    }
+
+    sd->screenPrivateIndex = allocateScreenPrivateIndex (d);
+    if (sd->screenPrivateIndex < 0)
+    {
+	compFiniDisplayOptions (d, sd->opt, SVG_DISPLAY_OPTION_NUM);
+	free (sd);
+	return FALSE;
+    }
+
+    WRAP (sd, d, handleCompizEvent, svgHandleCompizEvent);
     WRAP (sd, d, fileToImage, svgFileToImage);
 
     d->privates[displayPrivateIndex].ptr = sd;
@@ -192,20 +838,113 @@ svgFiniDisplay (CompPlugin  *p,
 
     SVG_DISPLAY (d);
 
+    UNWRAP (sd, d, handleCompizEvent);
     UNWRAP (sd, d, fileToImage);
 
     for (s = d->screens; s; s = s->next)
 	updateDefaultIcon (s);
 
+    freeScreenPrivateIndex (d, sd->screenPrivateIndex);
+
+    compFiniDisplayOptions (d, sd->opt, SVG_DISPLAY_OPTION_NUM);
+
     free (sd);
 }
 
 static Bool
+svgInitScreen (CompPlugin *p,
+	       CompScreen *s)
+{
+    SvgScreen *ss;
+
+    SVG_DISPLAY (s->display);
+
+    ss = malloc (sizeof (SvgScreen));
+    if (!ss)
+	return FALSE;
+
+    ss->windowPrivateIndex = allocateWindowPrivateIndex (s);
+    if (ss->windowPrivateIndex < 0)
+    {
+	free (ss);
+	return FALSE;
+    }
+
+    memset (&ss->zoom, 0, sizeof (BoxRec));
+
+    WRAP (ss, s, drawWindow, svgDrawWindow);
+    WRAP (ss, s, windowMoveNotify, svgWindowMoveNotify);
+    WRAP (ss, s, windowResizeNotify, svgWindowResizeNotify);
+
+    s->privates[sd->screenPrivateIndex].ptr = ss;
+
+    return TRUE;
+}
+
+static void
+svgFiniScreen (CompPlugin *p,
+	       CompScreen *s)
+{
+    SVG_SCREEN (s);
+
+    freeWindowPrivateIndex (s, ss->windowPrivateIndex);
+
+    UNWRAP (ss, s, drawWindow);
+    UNWRAP (ss, s, windowMoveNotify);
+    UNWRAP (ss, s, windowResizeNotify);
+
+    free (ss);
+}
+
+static Bool
+svgInitWindow (CompPlugin *p,
+	       CompWindow *w)
+{
+    SvgWindow *sw;
+
+    SVG_SCREEN (w->screen);
+
+    sw = malloc (sizeof (SvgWindow));
+    if (!sw)
+	return FALSE;
+
+    sw->source  = NULL;
+    sw->context = NULL;
+
+    w->privates[ss->windowPrivateIndex].ptr = sw;
+
+    return TRUE;
+}
+
+static void
+svgFiniWindow (CompPlugin *p,
+	       CompWindow *w)
+{
+    SVG_WINDOW (w);
+
+    if (sw->source)
+    {
+	rsvg_handle_free (sw->source->svg);
+	free (sw->source);
+    }
+
+    if (sw->context)
+    {
+	finiSvgTexture (w->screen, &sw->context->texture[0]);
+	free (sw->context);
+    }
+
+    free (sw);
+}
+
+static Bool
 svgInit (CompPlugin *p)
 {
     if (!compInitPluginMetadataFromInfo (&svgMetadata,
 					 p->vTable->name,
-					 0, 0, 0, 0))
+					 svgDisplayOptionInfo,
+					 SVG_DISPLAY_OPTION_NUM,
+					 0, 0))
 	return FALSE;
 
     displayPrivateIndex = allocateDisplayPrivateIndex ();
@@ -248,12 +987,12 @@ CompPluginVTable svgVTable = {
     svgFini,
     svgInitDisplay,
     svgFiniDisplay,
-    0, /* InitScreen */
-    0, /* FiniScreen */
-    0, /* InitWindow */
-    0, /* FiniWindow */
-    0, /* GetDisplayOptions */
-    0, /* SetDisplayOption */
+    svgInitScreen,
+    svgFiniScreen,
+    svgInitWindow,
+    svgFiniWindow,
+    svgGetDisplayOptions,
+    svgSetDisplayOption,
     0, /* GetScreenOptions */
     0, /* SetScreenOption */
     0, /* Deps */

Modified: compiz/plugins/video.c
===================================================================
--- compiz/plugins/video.c
+++ compiz/plugins/video.c
@@ -1158,6 +1158,8 @@ videoFiniScreen (CompPlugin *p,
     VIDEO_DISPLAY (s->display);
     VIDEO_SCREEN (s);
 
+    freeWindowPrivateIndex (s, vs->windowPrivateIndex);
+
     XDeleteProperty (s->display->display, s->root, vd->videoSupportedAtom);
 
     videoDestroyFragmentFunctions (s, &vs->yv12Functions);

Modified: compiz/plugins/zoom.c
===================================================================
--- compiz/plugins/zoom.c
+++ compiz/plugins/zoom.c
@@ -155,6 +155,58 @@ adjustZoomVelocity (ZoomScreen *zs)
 }
 
 static void
+zoomInEvent (CompScreen *s)
+{
+    CompOption o[6];
+
+    ZOOM_SCREEN (s);
+
+    o[0].type    = CompOptionTypeInt;
+    o[0].name    = "root";
+    o[0].value.i = s->root;
+
+    o[1].type    = CompOptionTypeInt;
+    o[1].name    = "output";
+    o[1].value.i = zs->zoomOutput;
+
+    o[2].type    = CompOptionTypeInt;
+    o[2].name    = "x1";
+    o[2].value.i = zs->current[zs->zoomOutput].x1;
+
+    o[3].type    = CompOptionTypeInt;
+    o[3].name    = "y1";
+    o[3].value.i = zs->current[zs->zoomOutput].y1;
+
+    o[4].type    = CompOptionTypeInt;
+    o[4].name    = "x2";
+    o[4].value.i = zs->current[zs->zoomOutput].x2;
+
+    o[5].type    = CompOptionTypeInt;
+    o[5].name    = "y2";
+    o[5].value.i = zs->current[zs->zoomOutput].y2;
+
+    (*s->display->handleCompizEvent) (s->display, "zoom", "in", o, 6);
+}
+
+static void
+zoomOutEvent (CompScreen *s)
+{
+    CompOption o[2];
+
+    ZOOM_SCREEN (s);
+
+    o[0].type    = CompOptionTypeInt;
+    o[0].name    = "root";
+    o[0].value.i = s->root;
+
+    o[1].type    = CompOptionTypeInt;
+    o[1].name    = "output";
+    o[1].value.i = zs->zoomOutput;
+
+    (*s->display->handleCompizEvent) (s->display, "zoom", "out", o, 2);
+}
+
+static void
 zoomPreparePaintScreen (CompScreen *s,
 			int	   msSinceLastPaint)
 {
@@ -187,7 +239,14 @@ zoomPreparePaintScreen (CompScreen *s,
 		    zs->current[zs->zoomOutput].y2 == pBox->y2)
 		{
 		    zs->zoomed &= ~(1 << zs->zoomOutput);
+		    zoomOutEvent (s);
+		}
+		else
+		{
+		    zoomInEvent (s);
 		}
+
+		break;
 	    }
 	    else
 	    {
@@ -741,6 +800,8 @@ zoomTerminatePan (CompDisplay     *d,
 	{
 	    removeScreenGrab (s, zs->panGrabIndex, NULL);
 	    zs->panGrabIndex = 0;
+
+	    zoomInEvent (s);
 	}
 
 	return TRUE;

Modified: compiz/src/window.c
===================================================================
--- compiz/src/window.c
+++ compiz/src/window.c
@@ -2888,7 +2888,7 @@ stackLayerCheck (CompWindow *w,
 		 Window	    clientLeader,
 		 CompWindow *below)
 {
-    if (w->transientFor == below->id)
+    if (isAncestorTo (w, below))
 	return TRUE;
 
     if (isAncestorTo (below, w))
@@ -2964,10 +2964,6 @@ findSiblingBelow (CompWindow *w,
 	if (below->type & CompWindowTypeDesktopMask)
 	    return below;
 
-	/* always above ancestor */
-	if (isAncestorTo (w, below))
-	    return below;
-
 	switch (type) {
 	case CompWindowTypeDesktopMask:
 	    /* desktop window layer */
@@ -3026,10 +3022,6 @@ findLowestSiblingBelow (CompWindow *w)
 	if (below->type & CompWindowTypeDesktopMask)
 	    return below;
 
-	/* always above ancestor */
-	if (isAncestorTo (w, below))
-	    return below;
-
 	switch (type) {
 	case CompWindowTypeDesktopMask:
 	    /* desktop window layer */
@@ -3086,10 +3078,6 @@ validSiblingBelow (CompWindow *w,
     if (sibling->type & CompWindowTypeDesktopMask)
 	return TRUE;
 
-    /* always above ancestor */
-    if (isAncestorTo (w, sibling))
-	return FALSE;
-
     switch (type) {
     case CompWindowTypeDesktopMask:
 	/* desktop window layer */
@@ -3246,6 +3234,10 @@ stackTransients (CompWindow	*w,
 
 	if (t->transientFor == w->id || isGroupTransient (t, clientLeader))
 	{
+	    if (w->type & CompWindowTypeDockMask)
+		if (!(t->type & CompWindowTypeDockMask))
+		    return FALSE;
+
 	    if (!stackTransients (t, avoid, xwc))
 		return FALSE;
 
@@ -3277,6 +3269,10 @@ stackAncestors (CompWindow     *w,
 	    if (ancestor->type & CompWindowTypeDesktopMask)
 		return;
 
+	    if (ancestor->type & CompWindowTypeDockMask)
+		if (!(w->type & CompWindowTypeDockMask))
+		    return;
+
 	    if (ancestor->mapNum || ancestor->pendingMaps)
 		configureXWindow (ancestor,
 				  CWSibling | CWStackMode,
@@ -3304,6 +3300,10 @@ stackAncestors (CompWindow     *w,
 		if (a->type & CompWindowTypeDesktopMask)
 		    continue;
 
+		if (a->type & CompWindowTypeDockMask)
+		    if (!(w->type & CompWindowTypeDockMask))
+			break;
+
 		if (a->mapNum || a->pendingMaps)
 		    configureXWindow (a,
 				      CWSibling | CWStackMode,



More information about the commits mailing list