[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

X Strike Force X.Org X11 SVN commit: r3541 - in trunk/app/compiz: . debian include plugins src



Author: beatle
Date: 2006-09-29 00:02:32 -0400 (Fri, 29 Sep 2006)
New Revision: 3541

Added:
   trunk/app/compiz/plugins/plane.c
Modified:
   trunk/app/compiz/configure.ac
   trunk/app/compiz/debian/changelog
   trunk/app/compiz/debian/control
   trunk/app/compiz/include/compiz.h
   trunk/app/compiz/plugins/Makefile.am
   trunk/app/compiz/plugins/compiz.schemas.in
   trunk/app/compiz/plugins/cube.c
   trunk/app/compiz/plugins/minimize.c
   trunk/app/compiz/plugins/place.c
   trunk/app/compiz/plugins/rotate.c
   trunk/app/compiz/plugins/scale.c
   trunk/app/compiz/plugins/screenshot.c
   trunk/app/compiz/plugins/switcher.c
   trunk/app/compiz/plugins/wobbly.c
   trunk/app/compiz/plugins/zoom.c
   trunk/app/compiz/src/display.c
   trunk/app/compiz/src/event.c
   trunk/app/compiz/src/paint.c
   trunk/app/compiz/src/screen.c
   trunk/app/compiz/src/window.c
Log:
Update to latest upstream checkout.

Revise the changelog to make entries consistent.


Modified: trunk/app/compiz/configure.ac
===================================================================
--- trunk/app/compiz/configure.ac	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/configure.ac	2006-09-29 04:02:32 UTC (rev 3541)
@@ -85,6 +85,7 @@
 		 xfixes	    \
 		 xdamage    \
 		 xrandr	    \
+		 xinerama   \
 		 ice	    \
 		 sm	    \
 		 libstartup-notification-1.0 >= 0.7"
@@ -118,10 +119,10 @@
   if test x"$GCONFTOOL" = xno; then
     AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
   fi
-
-  AM_GCONF_SOURCE_2
 fi
 
+AM_GCONF_SOURCE_2
+
 AM_CONDITIONAL(GCONF_PLUGIN, test "x$use_gconf" = "xyes")
 if test "$use_gconf" = yes; then
   AC_DEFINE(USE_GCONF, 1, [Build gconf plugin])
@@ -229,6 +230,9 @@
 
     windowsettingsdatadir=`pkg-config --variable=prefix gnome-window-settings-2.0`/share
     windowsettingslibdir=`pkg-config --variable=libdir gnome-window-settings-2.0`
+  else
+    use_metacity="no"
+    use_gnome="no"
   fi
 fi
 

Modified: trunk/app/compiz/debian/changelog
===================================================================
--- trunk/app/compiz/debian/changelog	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/debian/changelog	2006-09-29 04:02:32 UTC (rev 3541)
@@ -1,28 +1,30 @@
-compiz (0.0.13-1) experimental; urgency=low
+compiz (0.0.13-1) unstable; urgency=low
 
   * Initial release. (Closes: #352151)
-  * Now installs the compiz schema during postinst and removes it during
-    prerm.
-  * Added patches by Kristian Høgsberg to make compiz work on AIGLX:
+  * Install the compiz schema during postinst and removes it during prerm
+    (using dh_gconf).
+  * Add patches by Kristian Høgsberg to make compiz work on AIGLX:
     + 002_tfp-server-extension.patch
     + 005_glfinish.patch
   * No longer build the compiz-kde package, because it is unusable.
-  * Now installs the window settings configuration plugin into the right
-    location (/usr/lib/libgnome-window-settings1/libcompiz.so).
+  * Add gtk-window-decorator.1 manpage.
+  * Install the window settings configuration plugin into the right location
+    (/usr/lib/libgnome-window-settings1/libcompiz.so).
   * Bump build-dependency on libxcomposite-dev (>= 0.3) because it provides
     the XComposite{Get,Release}OverlayWindow functions.
   * Install a compiz wrapper as /usr/bin/compiz to call compiz.real with
     required arguments (load gconf plugin).
   * Add 010_snap-by-default.patch to turn snapping on by default.
-  * Revised the gnome-window-decorator manpage.
-  * Added a versioned build-dependency on x11proto-gl-dev (>= 1.4.7-1) to make
+  * Add a versioned build-dependency on x11proto-gl-dev (>= 1.4.8-1) to make
     sure compiz gets built with the correct opcodes for the GLX_EXT_tfp
     extension.
-  * Added build-dependency on libmetacity-dev, which is needed for metacity
+  * Add build-dependency on libmetacity-dev, which is needed for metacity
     theme support.
-  * Added the compiz-gtk package containing the former gnome-window-decorator.
+  * Add the compiz-gtk package containing the former gnome-window-decorator.
     The compiz-gnome package provides the files necessary to integrate compiz
     and compiz-gtk with the GNOME desktop environment.
+  * Add a build-dependency on libxinerama-dev, needed to build compiz with
+    support for the xinerama extension.
 
- -- Thierry Reding <thierry@gilfi.de>  Mon, 25 Sep 2006 17:46:58 +0200
+ -- Thierry Reding <thierry@gilfi.de>  Wed, 27 Sep 2006 12:36:21 +0200
 

Modified: trunk/app/compiz/debian/control
===================================================================
--- trunk/app/compiz/debian/control	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/debian/control	2006-09-29 04:02:32 UTC (rev 3541)
@@ -2,7 +2,7 @@
 Section: x11
 Priority: optional
 Maintainer: Thierry Reding <thierry@gilfi.de>
-Build-Depends: debhelper (>= 5), quilt (>= 0.40), automake1.9, libtool, libglib2.0-dev, libgconf2-dev, libpng12-dev | libpng-dev, libxcomposite-dev (>= 0.3), libxfixes-dev (>= 4.0.1), libxdamage-dev (>= 1.0.3), libxrandr-dev (>= 1.1.0.2), libxrender-dev (>= 0.9.1), libice-dev (>= 1.0.1), libsm-dev (>= 1.0.1), libgl1-mesa-dev (>= 6.5.1) | libgl-dev, libcairo-dev, librsvg2-dev, libgnome-desktop-dev, libgnome-window-settings-dev, libdbus-1-dev, libwnck-dev, libgtk2.0-dev, libpango1.0-dev, x11proto-gl-dev (>= 1.4.7-1), libmetacity-dev
+Build-Depends: debhelper (>= 5), quilt (>= 0.40), automake1.9, libtool, libglib2.0-dev, libgconf2-dev, libpng12-dev | libpng-dev, libxcomposite-dev (>= 0.3), libxfixes-dev (>= 4.0.1), libxdamage-dev (>= 1.0.3), libxrandr-dev (>= 1.1.0.2), libxrender-dev (>= 0.9.1), libice-dev (>= 1.0.1), libsm-dev (>= 1.0.1), libgl1-mesa-dev (>= 6.5.1) | libgl-dev, libcairo-dev, librsvg2-dev, libgnome-desktop-dev, libgnome-window-settings-dev, libdbus-1-dev, libwnck-dev, libgtk2.0-dev, libpango1.0-dev, x11proto-gl-dev (>= 1.4.8-1), libmetacity-dev, libxinerama-dev
 Standards-Version: 3.7.2
 
 Package: compiz

Modified: trunk/app/compiz/include/compiz.h
===================================================================
--- trunk/app/compiz/include/compiz.h	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/include/compiz.h	2006-09-29 04:02:32 UTC (rev 3541)
@@ -26,7 +26,7 @@
 #ifndef _COMPIZ_H
 #define _COMPIZ_H
 
-#define ABIVERSION 20060919
+#define ABIVERSION 20060927
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -35,6 +35,7 @@
 #include <X11/Xutil.h>
 #include <X11/extensions/Xdamage.h>
 #include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xinerama.h>
 #include <X11/extensions/sync.h>
 #include <X11/Xregion.h>
 #include <X11/XKBlib.h>
@@ -560,6 +561,12 @@
     Bool xkbExtension;
     int  xkbEvent, xkbError;
 
+    Bool xineramaExtension;
+    int  xineramaEvent, xineramaError;
+
+    XineramaScreenInfo *screenInfo;
+    int		       nScreenInfo;
+
     SnDisplay *snDisplay;
 
     Atom supportedAtom;
@@ -888,10 +895,12 @@
 typedef Bool (*PaintScreenProc) (CompScreen		 *screen,
 				 const ScreenPaintAttrib *sAttrib,
 				 Region			 region,
+				 int		         output,
 				 unsigned int		 mask);
 
 typedef void (*PaintTransformedScreenProc) (CompScreen		    *screen,
 					    const ScreenPaintAttrib *sAttrib,
+					    int			    output,
 					    unsigned int	    mask);
 
 
@@ -939,12 +948,14 @@
 void
 paintTransformedScreen (CompScreen		*screen,
 			const ScreenPaintAttrib *sAttrib,
+			int			output,
 			unsigned int	        mask);
 
 Bool
 paintScreen (CompScreen		     *screen,
 	     const ScreenPaintAttrib *sAttrib,
 	     Region		     region,
+	     int		     output,
 	     unsigned int	     mask);
 
 Bool
@@ -1067,12 +1078,13 @@
 #define COMP_SCREEN_OPTION_DETECT_REFRESH_RATE 0
 #define COMP_SCREEN_OPTION_LIGHTING	       1
 #define COMP_SCREEN_OPTION_REFRESH_RATE	       2
-#define COMP_SCREEN_OPTION_SIZE		       3
-#define COMP_SCREEN_OPTION_OPACITY_STEP        4
-#define COMP_SCREEN_OPTION_UNREDIRECT_FS       5
-#define COMP_SCREEN_OPTION_DEFAULT_ICON        6
-#define COMP_SCREEN_OPTION_SYNC_TO_VBLANK      7
-#define COMP_SCREEN_OPTION_NUM		       8
+#define COMP_SCREEN_OPTION_HSIZE	       3
+#define COMP_SCREEN_OPTION_VSIZE	       4
+#define COMP_SCREEN_OPTION_OPACITY_STEP        5
+#define COMP_SCREEN_OPTION_UNREDIRECT_FS       6
+#define COMP_SCREEN_OPTION_DEFAULT_ICON        7
+#define COMP_SCREEN_OPTION_SYNC_TO_VBLANK      8
+#define COMP_SCREEN_OPTION_NUM		       9
 
 #ifndef GLX_EXT_texture_from_pixmap
 #define GLX_BIND_TO_TEXTURE_RGB_EXT        0x20D0
@@ -1254,7 +1266,8 @@
 typedef struct _CompStartupSequence {
     struct _CompStartupSequence *next;
     SnStartupSequence		*sequence;
-    unsigned int		viewport;
+    unsigned int		viewportX;
+    unsigned int		viewportY;
 } CompStartupSequence;
 
 typedef struct _CompFBConfig {
@@ -1289,6 +1302,11 @@
     int		height;
 };
 
+typedef struct _CompOutput {
+    char   *name;
+    REGION region;
+} CompOutput;
+
 struct _CompScreen {
     CompScreen  *next;
     CompDisplay *display;
@@ -1303,7 +1321,9 @@
     int		      width;
     int		      height;
     int		      x;
-    int		      size;
+    int		      y;
+    int		      hsize;		/* Number of horizontal viewports */
+    int		      vsize;		/* Number of vertical viewports */
     REGION	      region;
     Region	      damage;
     unsigned long     damageMask;
@@ -1332,6 +1352,10 @@
     unsigned int      mapNum;
     unsigned int      activeNum;
 
+    CompOutput *outputDev;
+    int	       nOutputDev;
+    int	       currentOutputDev;
+
     int overlayWindowCount;
 
     CompScreenEdge screenEdge[SCREEN_EDGE_NUM];
@@ -1465,6 +1489,10 @@
 		 XConfigureEvent *ce);
 
 void
+setCurrentOutput (CompScreen *s,
+		  int	     outputNum);
+
+void
 updateScreenBackground (CompScreen  *screen,
 			CompTexture *texture);
 
@@ -1565,6 +1593,7 @@
 void
 moveScreenViewport (CompScreen *s,
 		    int	       tx,
+		    int	       ty,
 		    Bool       sync);
 
 void
@@ -1623,7 +1652,12 @@
 void
 finishScreenDrawing (CompScreen *s);
 
+int
+outputDeviceForPoint (CompScreen *s,
+		      int	 x,
+		      int	 y);
 
+
 /* window.c */
 
 #define WINDOW_INVISIBLE(w)				       \
@@ -1694,7 +1728,8 @@
     int		      destroyRefCnt;
     int		      unmapRefCnt;
 
-    unsigned int initialViewport;
+    unsigned int initialViewportX;
+    unsigned int initialViewportY;
 
     Bool placed;
     Bool minimized;
@@ -2034,8 +2069,10 @@
 void
 redirectWindow (CompWindow *w);
 
-int
-defaultViewportForWindow (CompWindow *w);
+void
+defaultViewportForWindow (CompWindow *w,
+			  int	     *vx,
+			  int        *vy);
 
 CompIcon *
 getWindowIcon (CompWindow *w,
@@ -2045,7 +2082,10 @@
 void
 freeWindowIcons (CompWindow *w);
 
+int
+outputDeviceForWindow (CompWindow *w);
 
+
 /* plugin.c */
 
 typedef int (*GetVersionProc) (CompPlugin *plugin,

Modified: trunk/app/compiz/plugins/Makefile.am
===================================================================
--- trunk/app/compiz/plugins/Makefile.am	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/Makefile.am	2006-09-29 04:02:32 UTC (rev 3541)
@@ -50,6 +50,10 @@
 libscreenshot_la_LIBADD = @COMPIZ_LIBS@
 libscreenshot_la_SOURCES = screenshot.c
 
+libplane_la_LDFLAGS = -module -avoid-version -no-undefined
+libplane_la_LIBADD = @COMPIZ_LIBS@
+libplane_la_SOURCES = plane.c
+
 if GCONF_PLUGIN
 libgconf_la_LDFLAGS = -module -avoid-version -no-undefined
 libgconf_la_LIBADD = @COMPIZ_LIBS@ @GCONF_LIBS@
@@ -135,6 +139,7 @@
 	libswitcher.la		\
 	libwater.la		\
 	libscreenshot.la	\
+	libplane.la		\
 	$(libgconf_dump_module)
 
 EXTRA_DIST = $(schema_in_files)

Modified: trunk/app/compiz/plugins/compiz.schemas.in
===================================================================
--- trunk/app/compiz/plugins/compiz.schemas.in	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/compiz.schemas.in	2006-09-29 04:02:32 UTC (rev 3541)
@@ -10409,7 +10409,7 @@
             <owner>compiz</owner>
             <type>list</type>
             <list_type>string</list_type>
-            <default>[novell.png]</default>
+            <default>[freedektop.png]</default>
             <locale name="C">
                 <short>Image files</short>
                 <long>List of PNG and SVG files that should be rendered on top face of cube</long>

Modified: trunk/app/compiz/plugins/cube.c
===================================================================
--- trunk/app/compiz/plugins/cube.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/cube.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -747,7 +747,7 @@
     case CUBE_SCREEN_OPTION_IN:
 	if (compSetBoolOption (o, value))
 	{
-	    if (cubeUpdateGeometry (screen, screen->size, o->value.b ? -1 : 1))
+	    if (cubeUpdateGeometry (screen, screen->hsize, o->value.b ? -1 : 1))
 		return TRUE;
 	}
 	break;
@@ -1009,6 +1009,7 @@
 cubePaintScreen (CompScreen		 *s,
 		 const ScreenPaintAttrib *sAttrib,
 		 Region			 region,
+		 int			 output,
 		 unsigned int		 mask)
 {
     Bool status;
@@ -1022,7 +1023,7 @@
     }
 
     UNWRAP (cs, s, paintScreen);
-    status = (*s->paintScreen) (s, sAttrib, region, mask);
+    status = (*s->paintScreen) (s, sAttrib, region, output, mask);
     WRAP (cs, s, paintScreen, cubePaintScreen);
 
     return status;
@@ -1044,11 +1045,12 @@
 static void
 cubePaintTransformedScreen (CompScreen		    *s,
 			    const ScreenPaintAttrib *sAttrib,
+			    int			    output,
 			    unsigned int	    mask)
 {
     ScreenPaintAttrib sa = *sAttrib;
     int		      xMove = 0;
-    float	      size = s->size;
+    float	      size = s->hsize;
 
     CUBE_SCREEN (s);
 
@@ -1106,18 +1108,18 @@
 	sa.xRotate = sAttrib->xRotate * cs->invert;
 	if (sa.xRotate > 0.0f)
 	{
-	    cs->xrotations = (int) (s->size * sa.xRotate) / 360;
-	    sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / s->size;
+	    cs->xrotations = (int) (s->hsize * sa.xRotate) / 360;
+	    sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / s->hsize;
 	}
 	else
 	{
-	    cs->xrotations = (int) (s->size * sa.xRotate) / 360;
+	    cs->xrotations = (int) (s->hsize * sa.xRotate) / 360;
 	    sa.xRotate = sa.xRotate -
-		(360.0f * cs->xrotations) / s->size + 360.0f / s->size;
+		(360.0f * cs->xrotations) / s->hsize + 360.0f / s->hsize;
 	    cs->xrotations--;
 	}
 
-	sa.xRotate = sa.xRotate / size * s->size;
+	sa.xRotate = sa.xRotate / size * s->hsize;
     }
     else
     {
@@ -1166,7 +1168,7 @@
 
 	glNormal3f (0.0f, -1.0f, 0.0f);
 
-	if (cs->invert == 1 && s->size == 4 && cs->texture.name)
+	if (cs->invert == 1 && s->hsize == 4 && cs->texture.name)
 	{
 	    enableTexture (s, &cs->texture, COMP_TEXTURE_FILTER_GOOD);
 	    glTexCoordPointer (2, GL_FLOAT, 0, cs->tc);
@@ -1196,23 +1198,23 @@
     /* outside cube */
     if (cs->invert == 1)
     {
-	if (cs->grabIndex || s->size > 4)
+	if (cs->grabIndex || s->hsize > 4)
 	{
 	    GLenum filter;
 	    int    i;
 
-	    xMove = cs->xrotations - ((s->size >> 1) - 1);
-	    sa.yRotate += (360.0f / size) * ((s->size >> 1) - 1);
+	    xMove = cs->xrotations - ((s->hsize >> 1) - 1);
+	    sa.yRotate += (360.0f / size) * ((s->hsize >> 1) - 1);
 
 	    filter = s->display->textureFilter;
 	    if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
 		s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
 
-	    for (i = 0; i < s->size; i++)
+	    for (i = 0; i < s->hsize; i++)
 	    {
-		moveScreenViewport (s, xMove, FALSE);
-		(*s->paintTransformedScreen) (s, &sa, mask);
-		moveScreenViewport (s, -xMove, FALSE);
+		moveScreenViewport (s, xMove, 0, FALSE);
+		(*s->paintTransformedScreen) (s, &sa, output, mask);
+		moveScreenViewport (s, -xMove, 0, FALSE);
 
 		sa.yRotate -= 360.0f / size;
 		xMove++;
@@ -1226,19 +1228,19 @@
 	    {
 		xMove = cs->xrotations;
 
-		moveScreenViewport (s, xMove, FALSE);
-		(*s->paintTransformedScreen) (s, &sa, mask);
-		moveScreenViewport (s, -xMove, FALSE);
+		moveScreenViewport (s, xMove, 0, FALSE);
+		(*s->paintTransformedScreen) (s, &sa, output, mask);
+		moveScreenViewport (s, -xMove, 0, FALSE);
 
 		xMove++;
 
-		moveScreenViewport (s, xMove, FALSE);
+		moveScreenViewport (s, xMove, 0, FALSE);
 	    }
 
 	    sa.yRotate -= 360.0f / size;
 
-	    (*s->paintTransformedScreen) (s, &sa, mask);
-	    moveScreenViewport (s, -xMove, FALSE);
+	    (*s->paintTransformedScreen) (s, &sa, output, mask);
+	    moveScreenViewport (s, -xMove, 0, FALSE);
 	}
     }
     else
@@ -1263,20 +1265,20 @@
 
 	    if (sa.xRotate > 180.0f / size)
 	    {
-		xMove -= ((s->size >> 1) - 2);
-		sa.yRotate -= (360.0f / size) * ((s->size >> 1) - 2);
+		xMove -= ((s->hsize >> 1) - 2);
+		sa.yRotate -= (360.0f / size) * ((s->hsize >> 1) - 2);
 	    }
 	    else
 	    {
-		xMove -= ((s->size >> 1) - 1);
-		sa.yRotate -= (360.0f / size) * ((s->size >> 1) - 1);
+		xMove -= ((s->hsize >> 1) - 1);
+		sa.yRotate -= (360.0f / size) * ((s->hsize >> 1) - 1);
 	    }
 
-	    for (i = 0; i < s->size; i++)
+	    for (i = 0; i < s->hsize; i++)
 	    {
-		moveScreenViewport (s, xMove, FALSE);
-		(*s->paintTransformedScreen) (s, &sa, mask);
-		moveScreenViewport (s, -xMove, FALSE);
+		moveScreenViewport (s, xMove, 0, FALSE);
+		(*s->paintTransformedScreen) (s, &sa, output, mask);
+		moveScreenViewport (s, -xMove, 0, FALSE);
 
 		sa.yRotate += 360.0f / size;
 		xMove++;
@@ -1286,23 +1288,23 @@
 	}
 	else
 	{
-	    moveScreenViewport (s, xMove, FALSE);
-	    (*s->paintTransformedScreen) (s, &sa, mask);
-	    moveScreenViewport (s, -xMove, FALSE);
+	    moveScreenViewport (s, xMove, 0, FALSE);
+	    (*s->paintTransformedScreen) (s, &sa, output, mask);
+	    moveScreenViewport (s, -xMove, 0, FALSE);
 
 	    sa.yRotate += 360.0f / size;
 	    xMove = -cs->xrotations;
 
-	    moveScreenViewport (s, xMove, FALSE);
-	    (*s->paintTransformedScreen) (s, &sa, mask);
-	    moveScreenViewport (s, -xMove, FALSE);
+	    moveScreenViewport (s, xMove, 0, FALSE);
+	    (*s->paintTransformedScreen) (s, &sa, output, mask);
+	    moveScreenViewport (s, -xMove, 0, FALSE);
 
 	    sa.yRotate += 360.0f / size;
 	    xMove = 1 - cs->xrotations;
 
-	    moveScreenViewport (s, xMove, FALSE);
-	    (*s->paintTransformedScreen) (s, &sa, mask);
-	    moveScreenViewport (s, -xMove, FALSE);
+	    moveScreenViewport (s, xMove, 0, FALSE);
+	    (*s->paintTransformedScreen) (s, &sa, output, mask);
+	    moveScreenViewport (s, -xMove, 0, FALSE);
 	}
     }
 
@@ -1461,7 +1463,7 @@
     WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption);
 
     if (status && strcmp (name, "size") == 0)
-	cubeUpdateGeometry (s, s->size, cs->invert);
+	cubeUpdateGeometry (s, s->hsize, cs->invert);
 
     return status;
 }
@@ -1673,7 +1675,7 @@
     WRAP (cs, s, paintBackground, cubePaintBackground);
     WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption);
 
-    if (!cubeUpdateGeometry (s, s->size, cs->invert))
+    if (!cubeUpdateGeometry (s, s->hsize, cs->invert))
 	return FALSE;
 
     if (cs->imgNFile)

Modified: trunk/app/compiz/plugins/minimize.c
===================================================================
--- trunk/app/compiz/plugins/minimize.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/minimize.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -598,6 +598,7 @@
 minPaintScreen (CompScreen		*s,
 		const ScreenPaintAttrib *sAttrib,
 		Region		        region,
+		int			output,
 		unsigned int		mask)
 {
     Bool status;
@@ -608,7 +609,7 @@
 	mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
 
     UNWRAP (ms, s, paintScreen);
-    status = (*s->paintScreen) (s, sAttrib, region, mask);
+    status = (*s->paintScreen) (s, sAttrib, region, output, mask);
     WRAP (ms, s, paintScreen, minPaintScreen);
 
     return status;

Modified: trunk/app/compiz/plugins/place.c
===================================================================
--- trunk/app/compiz/plugins/place.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/place.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -179,7 +179,40 @@
 	return 0;
 }
 
+
 static void
+get_workarea_of_current_output_device (CompScreen *s,
+				       XRectangle *area)
+{
+    int x1, y1, x2, y2;
+    int oX1, oY1, oX2, oY2;
+
+    x1 = s->workArea.x;
+    y1 = s->workArea.y;
+    x2 = x1 + s->workArea.width;
+    y2 = y1 + s->workArea.height;
+
+    oX1 = s->outputDev[s->currentOutputDev].region.extents.x1;
+    oY1 = s->outputDev[s->currentOutputDev].region.extents.y1;
+    oX2 = s->outputDev[s->currentOutputDev].region.extents.x2;
+    oY2 = s->outputDev[s->currentOutputDev].region.extents.y2;
+
+    if (x1 < oX1)
+	x1 = oX1;
+    if (y1 < oY1)
+	y1 = oY1;
+    if (x2 > oX2)
+	x2 = oX2;
+    if (y2 > oY2)
+	y2 = oY2;
+
+    area->x      = x1;
+    area->y      = y1;
+    area->width  = x2 - x1;
+    area->height = y2 - y1;
+}
+
+static void
 find_next_cascade (CompWindow *window,
 		   GList      *windows,
 		   int        x,
@@ -217,7 +250,7 @@
      * of NW corner of window frame.
      */
 
-    work_area = window->screen->workArea;
+    get_workarea_of_current_output_device (window->screen, &work_area);
 
     cascade_x = MAX (0, work_area.x);
     cascade_y = MAX (0, work_area.y);
@@ -325,7 +358,7 @@
     frame_size_left = window->input.left;
     frame_size_top  = window->input.top;
 
-    work_area = window->screen->workArea;
+    get_workarea_of_current_output_device (window->screen, &work_area);
 
     getOuterRectOfWindow (focus_window, &avoid);
     getOuterRectOfWindow (window, &outer);
@@ -592,9 +625,12 @@
 
     getOuterRectOfWindow (window, &rect);
 
-    work_area = window->screen->workArea;
-    work_area.x += (window->initialViewport - window->screen->x) *
+    get_workarea_of_current_output_device (window->screen, &work_area);
+
+    work_area.x += (window->initialViewportX - window->screen->x) *
 	window->screen->width;
+    work_area.y += (window->initialViewportY - window->screen->y) *
+	window->screen->height;
 
     center_tile_rect_in_area (&rect, &work_area);
 
@@ -678,13 +714,17 @@
     CompWindow *wi;
     GList      *windows;
     XRectangle work_area;
-    int	       x0 = (window->initialViewport - window->screen->x) *
+    int	       x0 = (window->initialViewportX - window->screen->x) *
 	window->screen->width;
+    int	       y0 = (window->initialViewportY - window->screen->y) *
+	window->screen->height;
 
     PLACE_SCREEN (window->screen);
 
-    work_area = window->screen->workArea;
+    get_workarea_of_current_output_device (window->screen, &work_area);
+
     work_area.x += x0;
+    work_area.y += y0;
 
     windows = NULL;
 
@@ -718,7 +758,7 @@
     if (window->type & CompWindowTypeFullscreenMask)
     {
 	x = x0;
-	y = 0;
+	y = y0;
 	goto done_no_constraints;
     }
 
@@ -816,8 +856,10 @@
 	    if (parent->attrib.x < parent->screen->width &&
 		parent->attrib.x + parent->screen->width > 0)
 	    {
-		XRectangle area = parent->screen->workArea;
+		XRectangle area;
 
+		get_workarea_of_current_output_device (window->screen, &area);
+
 		if (x + window->width > area.x + area.width)
 		    x = area.x + area.width - window->width;
 		if (y + window->height > area.y + area.height)
@@ -878,7 +920,7 @@
 
     /* "Origin" placement algorithm */
     x = x0;
-    y = 0;
+    y = y0;
 
     if (find_first_fit (window, windows, x, y, &x, &y))
 	goto done_check_denied_focus;

Added: trunk/app/compiz/plugins/plane.c
===================================================================
--- trunk/app/compiz/plugins/plane.c	                        (rev 0)
+++ trunk/app/compiz/plugins/plane.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -0,0 +1,904 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Red Hat, Inc. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Søren Sandmann <sandmann@redhat.com>
+ */
+
+#define _GNU_SOURCE /* for asprintf */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/time.h>
+
+#include <X11/Xatom.h>
+#include <X11/Xproto.h>
+
+#include <compiz.h>
+
+static int displayPrivateIndex;
+
+#define PLANE_LEFT_KEY_DEFAULT        "Left"
+#define PLANE_LEFT_MODIFIERS_DEFAULT  (ControlMask | CompAltMask)
+
+#define PLANE_RIGHT_KEY_DEFAULT       "Right"
+#define PLANE_RIGHT_MODIFIERS_DEFAULT (ControlMask | CompAltMask)
+
+#define PLANE_UP_KEY_DEFAULT          "Up"
+#define PLANE_UP_MODIFIERS_DEFAULT    (ControlMask | CompAltMask)
+
+#define PLANE_DOWN_KEY_DEFAULT        "Down"
+#define PLANE_DOWN_MODIFIERS_DEFAULT  (ControlMask | CompAltMask)
+
+enum
+{
+    PLANE_DISPLAY_OPTION_LEFT,
+    PLANE_DISPLAY_OPTION_RIGHT,
+    PLANE_DISPLAY_OPTION_DOWN,
+    PLANE_DISPLAY_OPTION_UP,
+    PLANE_DISPLAY_OPTION_TO_1,
+    PLANE_DISPLAY_OPTION_TO_2,
+    PLANE_DISPLAY_OPTION_TO_3,
+    PLANE_DISPLAY_OPTION_TO_4,
+    PLANE_DISPLAY_OPTION_TO_5,
+    PLANE_DISPLAY_OPTION_TO_6,
+    PLANE_DISPLAY_OPTION_TO_7,
+    PLANE_DISPLAY_OPTION_TO_8,
+    PLANE_DISPLAY_OPTION_TO_9,
+    PLANE_DISPLAY_OPTION_TO_10,
+    PLANE_DISPLAY_OPTION_TO_11,
+    PLANE_DISPLAY_OPTION_TO_12,
+    PLANE_N_DISPLAY_OPTIONS
+};
+
+typedef struct _PlaneDisplay {
+    int			screenPrivateIndex;
+    HandleEventProc	handleEvent;
+
+    CompOption		opt[PLANE_N_DISPLAY_OPTIONS];
+
+    int			flipTime;
+} PlaneDisplay;
+
+typedef struct _PlaneScreen {
+    PaintTransformedScreenProc		paintTransformedScreen;
+    PreparePaintScreenProc		preparePaintScreen;
+    DonePaintScreenProc			donePaintScreen;
+    PaintScreenProc			paintScreen;
+
+    SetScreenOptionForPluginProc	setScreenOptionForPlugin;
+    WindowGrabNotifyProc		windowGrabNotify;
+    WindowUngrabNotifyProc		windowUngrabNotify;
+
+    CompTimeoutHandle			timeoutHandle;
+    int					timer;
+
+    double				cur_x;
+    double				cur_y;
+    double				dest_x;
+    double				dest_y;
+} PlaneScreen;
+
+#define GET_PLANE_DISPLAY(d)				       \
+    ((PlaneDisplay *) (d)->privates[displayPrivateIndex].ptr)
+
+#define PLANE_DISPLAY(d)		       \
+    PlaneDisplay *pd = GET_PLANE_DISPLAY (d)
+
+#define GET_PLANE_SCREEN(s, pd)				   \
+    ((PlaneScreen *) (s)->privates[(pd)->screenPrivateIndex].ptr)
+
+#define PLANE_SCREEN(s)						      \
+    PlaneScreen *ps = GET_PLANE_SCREEN (s, GET_PLANE_DISPLAY (s->display))
+
+#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
+
+static Bool
+endMove (void *data)
+{
+    CompScreen *screen = data;
+    PLANE_SCREEN (screen);
+
+    moveScreenViewport (screen, -ps->dest_x, -ps->dest_y, TRUE);
+
+    ps->dest_x = 0;
+    ps->dest_y = 0;
+
+    ps->timeoutHandle = 0;
+    return FALSE;
+}
+
+#define SCROLL_TIME	250
+
+static void
+computeTranslation (PlaneScreen *ps,
+		    double	*x,
+		    double      *y)
+{
+    double dx, dy;
+    double elapsed = 1 - (ps->timer / (double)SCROLL_TIME);
+
+    if (elapsed < 0.0)
+	elapsed = 0.0;
+    if (elapsed > 1.0)
+	elapsed = 1.0;
+
+    /* Use temporary variables to you can pass in &ps->cur_x */
+    dx = (ps->dest_x - ps->cur_x) * elapsed + ps->cur_x;
+    dy = (ps->dest_y - ps->cur_y) * elapsed + ps->cur_y;
+
+    *x = dx;
+    *y = dy;
+}
+
+static void
+moveViewport (CompScreen *screen,
+	      int	 dx,
+	      int	 dy)
+{
+    PLANE_SCREEN (screen);
+
+    if (dx == 0 && dy == 0)
+	return;
+
+    if (ps->timeoutHandle)
+    {
+	computeTranslation (ps, &ps->cur_x, &ps->cur_y);
+
+	ps->dest_x += dx;
+	ps->dest_y += dy;
+
+	compRemoveTimeout (ps->timeoutHandle);
+    }
+    else
+    {
+	ps->cur_x = 0.0;
+	ps->cur_y = 0.0;
+	ps->dest_x = dx;
+	ps->dest_y = dy;
+    }
+
+    if (ps->dest_x + screen->x > screen->hsize - 1)
+	ps->dest_x = screen->hsize - screen->x - 1;
+
+    if (ps->dest_x + screen->x < 0)
+	ps->dest_x = -screen->x;
+
+    if (ps->dest_y + screen->y > screen->vsize - 1)
+	ps->dest_y = screen->vsize - screen->y - 1;
+
+    if (ps->dest_y + screen->y < 0)
+	ps->dest_y = -screen->y;
+
+    ps->timer = SCROLL_TIME;
+    ps->timeoutHandle = compAddTimeout (SCROLL_TIME, endMove, screen);
+
+    damageScreen (screen);
+}
+
+static void
+planePreparePaintScreen (CompScreen *s,
+			 int	    msSinceLastPaint)
+{
+    PLANE_SCREEN (s);
+
+    ps->timer -= msSinceLastPaint;
+
+    UNWRAP (ps, s, preparePaintScreen);
+
+    (* s->preparePaintScreen) (s, msSinceLastPaint);
+
+    WRAP (ps, s, preparePaintScreen, planePreparePaintScreen);
+}
+
+static void
+planePaintTransformedScreen (CompScreen		     *screen,
+			     const ScreenPaintAttrib *sAttrib,
+			     int                     output,
+			     unsigned int	     mask)
+{
+    PLANE_SCREEN (screen);
+
+    glPushMatrix ();
+    UNWRAP (ps, screen, paintTransformedScreen);
+
+    if (ps->timeoutHandle)
+    {
+	double dx, dy, tx, ty;
+	int vx, vy;
+
+	glClearColor (0.0, 0.0, 0.0, 1.0);
+	glClear (GL_COLOR_BUFFER_BIT);
+
+	computeTranslation (ps, &dx, &dy);
+
+	dx *= -1;
+	dy *= -1;
+
+	tx = dy;
+	ty = dy;
+	vx = 0;
+	vy = 0;
+
+	while (dx > 1)
+	{
+	    dx -= 1.0;
+	    moveScreenViewport (screen, 1, 0, FALSE);
+	    vx++;
+	}
+
+	while (dx < -1)
+	{
+	    dx += 1.0;
+	    moveScreenViewport (screen, -1, 0, FALSE);
+	    vx--;
+	}
+
+	while (dy > 1)
+	{
+	    dy -= 1.0;
+	    moveScreenViewport (screen, 0, 1, FALSE);
+	    vy++;
+	}
+
+	while (dy < -1)
+	{
+	    dy += 1.0;
+	    moveScreenViewport (screen, 0, -1, FALSE);
+	    vy--;
+	}
+
+	glPushMatrix ();
+
+	glTranslatef (dx, -dy, 0.0);
+	(*screen->paintTransformedScreen) (screen, sAttrib, output, mask);
+	if (dx > 0)
+	{
+	    glTranslatef (-1.0, 0.0, 0.0);
+	    moveScreenViewport (screen, 1, 0, FALSE);
+	}
+	else
+	{
+	    glTranslatef (1.0, 0.0, 0.0);
+	    moveScreenViewport (screen, -1, 0, FALSE);
+	}
+	(*screen->paintTransformedScreen) (screen, sAttrib, output, mask);
+	if (dy > 0)
+	{
+	    glTranslatef (0.0, 1.0, 0.0);
+	    moveScreenViewport (screen, 0, 1, FALSE);
+	}
+	else
+	{
+	    glTranslatef (0.0, -1.0, 0.0);
+	    moveScreenViewport (screen, 0, -1, FALSE);
+	}
+	(*screen->paintTransformedScreen) (screen, sAttrib, output, mask);
+	if (dx > 0)
+	{
+	    glTranslatef (1.0, 0.0, 0.0);
+	    moveScreenViewport (screen, -1, 0, FALSE);
+	}
+	else
+	{
+	    glTranslatef (-1.0, 0.0, 0.0);
+	    moveScreenViewport (screen, 1, 0, FALSE);
+	}
+	(*screen->paintTransformedScreen) (screen, sAttrib, output, mask);
+	if (dy > 0)
+	{
+	    glTranslatef (0.0, -1.0, 0.0);
+	    moveScreenViewport (screen, 0, -1, FALSE);
+	}
+	else
+	{
+	    glTranslatef (0.0, 1.0, 0.0);
+	    moveScreenViewport (screen, 0, 1, FALSE);
+	}
+	glTranslatef (-dx, -dy, 0.0);
+	glPopMatrix ();
+
+	moveScreenViewport (screen, -vx, -vy, FALSE);
+    }
+    else
+    {
+	(*screen->paintTransformedScreen) (screen, sAttrib, output, mask);
+    }
+
+    WRAP (ps, screen, paintTransformedScreen, planePaintTransformedScreen);
+    glPopMatrix ();
+
+}
+
+static void
+planeDonePaintScreen (CompScreen *s)
+{
+    PLANE_SCREEN (s);
+
+    if (ps->timeoutHandle)
+	damageScreen (s);
+
+    UNWRAP (ps, s, donePaintScreen);
+
+    (*s->donePaintScreen) (s);
+
+    WRAP (ps, s, donePaintScreen, planeDonePaintScreen);
+}
+
+static Bool
+planePaintScreen (CompScreen		  *s,
+		  const ScreenPaintAttrib *sAttrib,
+		  Region		  region,
+		  int			  output,
+		  unsigned int		  mask)
+{
+    Bool status;
+
+    PLANE_SCREEN (s);
+
+    if (ps->timeoutHandle)
+    {
+	mask &= ~PAINT_SCREEN_REGION_MASK;
+	mask |= PAINT_SCREEN_TRANSFORMED_MASK;
+    }
+
+    UNWRAP (ps, s, paintScreen);
+    status = (*s->paintScreen) (s, sAttrib, region, output, mask);
+    WRAP (ps, s, paintScreen, planePaintScreen);
+
+    return status;
+}
+
+static void
+planeHandleEvent (CompDisplay *d,
+		  XEvent      *event)
+{
+    CompScreen *s;
+
+    PLANE_DISPLAY (d);
+
+    switch (event->type) {
+    case ClientMessage:
+	if (event->xclient.message_type == d->winActiveAtom)
+	{
+	    CompWindow *w;
+
+	    w = findWindowAtDisplay (d, event->xclient.window);
+	    if (w)
+	    {
+		int dx, dy;
+
+		s = w->screen;
+
+		/* window must be placed */
+		if (!w->placed)
+		    break;
+
+		if (otherScreenGrabExist (s, "plane", "switcher", "cube", 0))
+		    break;
+
+		defaultViewportForWindow (w, &dx, &dy);
+		dx -= s->x;
+		dy -= s->y;
+
+		moveViewport (s, dx, dy);
+	    }
+	}
+	else if (event->xclient.message_type == d->desktopViewportAtom)
+	{
+	    int dx, dy;
+
+	    s = findScreenAtDisplay (d, event->xclient.window);
+	    if (!s)
+		break;
+
+	    if (otherScreenGrabExist (s, "plane", "switcher", "cube", 0))
+		break;
+
+	    dx = event->xclient.data.l[0] / s->width - s->x;
+	    dy = event->xclient.data.l[1] / s->height - s->y;
+
+	    if (!dx && !dy)
+		break;
+
+	    moveViewport (s, dx, dy);
+	}
+	break;
+
+    default:
+	break;
+    }
+
+    UNWRAP (pd, d, handleEvent);
+    (*d->handleEvent) (d, event);
+    WRAP (pd, d, handleEvent, planeHandleEvent);
+}
+
+static void
+planeWindowGrabNotify (CompWindow   *w,
+		       int	    x,
+		       int	    y,
+		       unsigned int state,
+		       unsigned int mask)
+{
+    PLANE_SCREEN (w->screen);
+
+    UNWRAP (ps, w->screen, windowGrabNotify);
+    (*w->screen->windowGrabNotify) (w, x, y, state, mask);
+    WRAP (ps, w->screen, windowGrabNotify, planeWindowGrabNotify);
+}
+
+static void
+planeWindowUngrabNotify (CompWindow *w)
+{
+    PLANE_SCREEN (w->screen);
+
+    UNWRAP (ps, w->screen, windowUngrabNotify);
+    (*w->screen->windowUngrabNotify) (w);
+    WRAP (ps, w->screen, windowUngrabNotify, planeWindowUngrabNotify);
+}
+
+static Bool
+planeSetScreenOptionForPlugin (CompScreen      *s,
+			       char	       *plugin,
+			       char	       *name,
+			       CompOptionValue *value)
+{
+    PLANE_SCREEN (s);
+    Bool status;
+
+    UNWRAP (ps, s, setScreenOptionForPlugin);
+    status = (*s->setScreenOptionForPlugin) (s, plugin, name, value);
+    WRAP (ps, s, setScreenOptionForPlugin, planeSetScreenOptionForPlugin);
+
+    return status;
+}
+
+static CompOption *
+planeGetDisplayOptions (CompDisplay *display,
+			int	    *count)
+{
+    PLANE_DISPLAY (display);
+
+    *count = NUM_OPTIONS (pd);
+    return pd->opt;
+}
+
+static Bool
+planeSetDisplayOption (CompDisplay     *display,
+		       char	       *name,
+		       CompOptionValue *value)
+{
+    CompOption *o;
+    int	       index;
+
+    PLANE_DISPLAY (display);
+
+    o = compFindOption (pd->opt, NUM_OPTIONS (pd), name, &index);
+    if (!o)
+	return FALSE;
+
+    switch (index) {
+    case PLANE_DISPLAY_OPTION_LEFT:
+    case PLANE_DISPLAY_OPTION_RIGHT:
+    case PLANE_DISPLAY_OPTION_UP:
+    case PLANE_DISPLAY_OPTION_DOWN:
+
+    case PLANE_DISPLAY_OPTION_TO_1:
+    case PLANE_DISPLAY_OPTION_TO_2:
+    case PLANE_DISPLAY_OPTION_TO_3:
+    case PLANE_DISPLAY_OPTION_TO_4:
+    case PLANE_DISPLAY_OPTION_TO_5:
+    case PLANE_DISPLAY_OPTION_TO_6:
+    case PLANE_DISPLAY_OPTION_TO_7:
+    case PLANE_DISPLAY_OPTION_TO_8:
+    case PLANE_DISPLAY_OPTION_TO_9:
+    case PLANE_DISPLAY_OPTION_TO_10:
+    case PLANE_DISPLAY_OPTION_TO_11:
+    case PLANE_DISPLAY_OPTION_TO_12:
+	if (setDisplayAction (display, o, value))
+	    return TRUE;
+	break;
+    default:
+	break;
+    }
+
+    return FALSE;
+}
+
+static CompScreen *
+getScreen (CompDisplay *d,
+	   CompOption  *option,
+	   int	       n_options)
+{
+    XID rootWindow = getIntOptionNamed (option, n_options, "root", 0);
+
+    return findScreenAtDisplay (d, rootWindow);
+}
+
+static Bool
+planeLeft (CompDisplay		*d,
+	    CompAction		*action,
+	    CompActionState	state,
+	    CompOption		*option,
+	    int			n_options)
+{
+    CompScreen *screen = getScreen (d, option, n_options);
+
+    moveViewport (screen, -1, 0);
+    return FALSE;
+}
+
+static Bool
+planeRight (CompDisplay	    *d,
+	    CompAction	    *action,
+	    CompActionState state,
+	    CompOption	    *option,
+	    int		    n_options)
+{
+    CompScreen *screen = getScreen (d, option, n_options);
+
+    moveViewport (screen, 1, 0);
+    return FALSE;
+}
+
+static Bool
+planeUp (CompDisplay	 *d,
+	 CompAction	 *action,
+	 CompActionState state,
+	 CompOption	 *option,
+	 int		 n_options)
+{
+    CompScreen *screen = getScreen (d, option, n_options);
+
+    moveViewport (screen, 0, -1);
+    return FALSE;
+}
+
+static Bool
+planeDown (CompDisplay	   *d,
+	   CompAction	   *action,
+	   CompActionState state,
+	   CompOption	   *option,
+	   int		   n_options)
+{
+    CompScreen *screen = getScreen (d, option, n_options);
+
+    moveViewport (screen, 0, 1);
+    return FALSE;
+}
+
+static Bool
+planeTo (CompDisplay     *d,
+	 CompAction      *action,
+	 CompActionState state,
+	 CompOption      *option,
+	 int		  n_options)
+{
+    int i, new_x, new_y, cur_x, cur_y;
+    CompScreen *screen = getScreen (d, option, n_options);
+    PLANE_DISPLAY (d);
+
+    new_x = new_y = -1;
+    for (i = PLANE_DISPLAY_OPTION_TO_1; i <= PLANE_DISPLAY_OPTION_TO_12; ++i)
+    {
+	if (action == &pd->opt[i].value.action)
+	{
+	    int viewport_no = i - PLANE_DISPLAY_OPTION_TO_1;
+
+	    new_x = viewport_no % screen->hsize;
+	    new_y = viewport_no / screen->hsize;
+
+	    break;
+	}
+    }
+
+    if (new_x == -1 || new_y == -1)
+	return FALSE;
+
+    cur_x = screen->x;
+    cur_y = screen->y;
+
+    moveViewport (screen, new_x - cur_x, new_y - cur_y);
+
+    return FALSE;
+}
+
+static void
+planeDisplayInitOptions (PlaneDisplay *pd,
+			 Display      *display)
+{
+    CompOption *o;
+    char *str;
+
+    o = &pd->opt[PLANE_DISPLAY_OPTION_LEFT];
+    o->name			  = "plane_left";
+    o->shortDesc		  = N_("Plane Left");
+    o->longDesc			  = N_("Plane left");
+    o->type			  = CompOptionTypeAction;
+    o->value.action.initiate	  = planeLeft;
+    o->value.action.terminate	  = 0;
+    o->value.action.bell	  = FALSE;
+    o->value.action.edgeMask	  = 0;
+    o->value.action.state	  = CompActionStateInitEdge;
+    o->value.action.state	 |= CompActionStateInitEdgeDnd;
+    o->value.action.state	 |= CompActionStateInitKey;
+    o->value.action.state	 |= CompActionStateInitButton;
+    o->value.action.type	  = CompBindingTypeKey;
+    o->value.action.key.modifiers = PLANE_LEFT_MODIFIERS_DEFAULT;
+    o->value.action.key.keycode   =
+	XKeysymToKeycode (display,
+			  XStringToKeysym (PLANE_LEFT_KEY_DEFAULT));
+
+    o = &pd->opt[PLANE_DISPLAY_OPTION_RIGHT];
+    o->name			  = "plane_right";
+    o->shortDesc		  = N_("Plane Right");
+    o->longDesc			  = N_("Plane right");
+    o->type			  = CompOptionTypeAction;
+    o->value.action.initiate	  = planeRight;
+    o->value.action.terminate	  = 0;
+    o->value.action.bell	  = FALSE;
+    o->value.action.edgeMask	  = 0;
+    o->value.action.state	  = CompActionStateInitEdge;
+    o->value.action.state	 |= CompActionStateInitEdgeDnd;
+    o->value.action.state	 |= CompActionStateInitKey;
+    o->value.action.state	 |= CompActionStateInitButton;
+    o->value.action.type	  = CompBindingTypeKey;
+    o->value.action.key.modifiers = PLANE_RIGHT_MODIFIERS_DEFAULT;
+    o->value.action.key.keycode   =
+	XKeysymToKeycode (display,
+			  XStringToKeysym (PLANE_RIGHT_KEY_DEFAULT));
+
+    o = &pd->opt[PLANE_DISPLAY_OPTION_DOWN];
+    o->name			  = "plane_down";
+    o->shortDesc		  = N_("Plane Down");
+    o->longDesc			  = N_("Plane down");
+    o->type			  = CompOptionTypeAction;
+    o->value.action.initiate	  = planeDown;
+    o->value.action.terminate	  = 0;
+    o->value.action.bell	  = FALSE;
+    o->value.action.edgeMask	  = 0;
+    o->value.action.state	  = CompActionStateInitEdge;
+    o->value.action.state	 |= CompActionStateInitEdgeDnd;
+    o->value.action.state	 |= CompActionStateInitKey;
+    o->value.action.state	 |= CompActionStateInitButton;
+    o->value.action.type	  = CompBindingTypeKey;
+    o->value.action.key.modifiers = PLANE_DOWN_MODIFIERS_DEFAULT;
+    o->value.action.key.keycode   =
+	XKeysymToKeycode (display,
+			  XStringToKeysym (PLANE_DOWN_KEY_DEFAULT));
+
+    o = &pd->opt[PLANE_DISPLAY_OPTION_UP];
+    o->name			  = "plane_up";
+    o->shortDesc		  = N_("Plane Up");
+    o->longDesc			  = N_("Plane up");
+    o->type			  = CompOptionTypeAction;
+    o->value.action.initiate	  = planeUp;
+    o->value.action.terminate	  = 0;
+    o->value.action.bell	  = FALSE;
+    o->value.action.edgeMask	  = 0;
+    o->value.action.state	  = CompActionStateInitEdge;
+    o->value.action.state	 |= CompActionStateInitEdgeDnd;
+    o->value.action.state	 |= CompActionStateInitKey;
+    o->value.action.state	 |= CompActionStateInitButton;
+    o->value.action.type	  = CompBindingTypeKey;
+    o->value.action.key.modifiers = PLANE_UP_MODIFIERS_DEFAULT;
+    o->value.action.key.keycode   =
+	XKeysymToKeycode (display,
+			  XStringToKeysym (PLANE_UP_KEY_DEFAULT));
+
+#define PLANE_TO_SHORT        N_("Plane To Face %d")
+#define PLANE_TO_LONG         N_("Plane to face %d")
+#define PLANE_TO_WINDOW_SHORT N_("Plane To Face %d with Window")
+#define PLANE_TO_WINDOW_LONG  N_("Plane to face %d and bring active " \
+				  "window along")
+
+#define PLANE_TO_OPTION(n)						 \
+    o = &pd->opt[PLANE_DISPLAY_OPTION_TO_ ## n];			 \
+    o->name			  = "plane_to_" #n;			 \
+    asprintf (&str, PLANE_TO_SHORT, n);				 \
+    o->shortDesc		  = str;				 \
+    asprintf (&str, PLANE_TO_LONG, n);					 \
+    o->longDesc			  = str;				 \
+    o->type			  = CompOptionTypeAction;		 \
+    o->value.action.initiate	  = planeTo;				 \
+    o->value.action.terminate	  = 0;					 \
+    o->value.action.bell	  = FALSE;				 \
+    o->value.action.edgeMask	  = 0;					 \
+    o->value.action.state	  = CompActionStateInitKey;		 \
+    o->value.action.state	 |= CompActionStateInitButton;		 \
+    o->value.action.type	  = CompBindingTypeNone;
+
+    PLANE_TO_OPTION (1);
+    PLANE_TO_OPTION (2);
+    PLANE_TO_OPTION (3);
+    PLANE_TO_OPTION (4);
+    PLANE_TO_OPTION (5);
+    PLANE_TO_OPTION (6);
+    PLANE_TO_OPTION (7);
+    PLANE_TO_OPTION (8);
+    PLANE_TO_OPTION (9);
+    PLANE_TO_OPTION (10);
+    PLANE_TO_OPTION (11);
+    PLANE_TO_OPTION (12);
+}
+
+static Bool
+planeInitDisplay (CompPlugin  *p,
+		  CompDisplay *d)
+{
+    PlaneDisplay *pd;
+
+    pd = malloc (sizeof (PlaneDisplay));
+    if (!pd)
+	return FALSE;
+
+    pd->screenPrivateIndex = allocateScreenPrivateIndex (d);
+    if (pd->screenPrivateIndex < 0)
+    {
+	free (pd);
+	return FALSE;
+    }
+
+    planeDisplayInitOptions (pd, d->display);
+
+    WRAP (pd, d, handleEvent, planeHandleEvent);
+
+    d->privates[displayPrivateIndex].ptr = pd;
+
+    return TRUE;
+}
+
+static void
+planeFiniDisplay (CompPlugin  *p,
+		  CompDisplay *d)
+{
+    PLANE_DISPLAY (d);
+
+    freeScreenPrivateIndex (d, pd->screenPrivateIndex);
+
+    UNWRAP (pd, d, handleEvent);
+
+    free (pd);
+}
+
+static Bool
+planeInitScreen (CompPlugin *p,
+		 CompScreen *s)
+{
+    PlaneScreen *ps;
+
+    PLANE_DISPLAY (s->display);
+
+    ps = malloc (sizeof (PlaneScreen));
+    if (!ps)
+	return FALSE;
+
+    ps->timeoutHandle = 0;
+
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_LEFT].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_RIGHT].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_DOWN].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_UP].value.action);
+
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_1].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_2].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_3].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_4].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_5].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_6].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_7].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_8].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_9].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_10].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_11].value.action);
+    addScreenAction (s, &pd->opt[PLANE_DISPLAY_OPTION_TO_12].value.action);
+
+    WRAP (ps, s, paintTransformedScreen, planePaintTransformedScreen);
+    WRAP (ps, s, preparePaintScreen, planePreparePaintScreen);
+    WRAP (ps, s, donePaintScreen, planeDonePaintScreen);
+    WRAP (ps, s, paintScreen, planePaintScreen);
+    WRAP (ps, s, setScreenOptionForPlugin, planeSetScreenOptionForPlugin);
+    WRAP (ps, s, windowGrabNotify, planeWindowGrabNotify);
+    WRAP (ps, s, windowUngrabNotify, planeWindowUngrabNotify);
+
+    s->privates[pd->screenPrivateIndex].ptr = ps;
+
+    return TRUE;
+}
+
+static void
+planeFiniScreen (CompPlugin *p,
+		 CompScreen *s)
+{
+    PLANE_SCREEN (s);
+
+    UNWRAP (ps, s, paintTransformedScreen);
+    UNWRAP (ps, s, preparePaintScreen);
+    UNWRAP (ps, s, donePaintScreen);
+    UNWRAP (ps, s, paintScreen);
+    UNWRAP (ps, s, setScreenOptionForPlugin);
+    UNWRAP (ps, s, windowGrabNotify);
+    UNWRAP (ps, s, windowUngrabNotify);
+
+    free (ps);
+}
+
+static Bool
+planeInit (CompPlugin *p)
+{
+    displayPrivateIndex = allocateDisplayPrivateIndex ();
+    if (displayPrivateIndex < 0)
+	return FALSE;
+
+    return TRUE;
+}
+
+static void
+planeFini (CompPlugin *p)
+{
+    if (displayPrivateIndex >= 0)
+	freeDisplayPrivateIndex (displayPrivateIndex);
+}
+
+CompPluginDep planeDeps[] = {
+#if 0
+    /* We need a new CompPluginRuleConflicts */
+    { CompPluginRuleConflicts, "rotate" },
+    { CompPluginRuleConflicts, "cube" },
+#endif
+};
+
+static int
+planeGetVersion (CompPlugin *plugin,
+		 int	    version)
+{
+    return ABIVERSION;
+}
+
+CompPluginVTable planeVTable = {
+    "plane",
+    N_("Desktop Plane"),
+    N_("Place windows on a plane"),
+    planeGetVersion,
+    planeInit,
+    planeFini,
+    planeInitDisplay,
+    planeFiniDisplay,
+    planeInitScreen,
+    planeFiniScreen,
+    0, /* InitWindow */
+    0, /* FiniWindow */
+    planeGetDisplayOptions,
+    planeSetDisplayOption,
+    NULL, /* planeGetScreenOptions, */
+    NULL, /* planeSetScreenOption, */
+    planeDeps,
+    sizeof (planeDeps) / sizeof (planeDeps[0])
+};
+
+CompPluginVTable *
+getCompPluginInfo (void)
+{
+    return &planeVTable;
+}

Modified: trunk/app/compiz/plugins/rotate.c
===================================================================
--- trunk/app/compiz/plugins/rotate.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/rotate.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -419,15 +419,15 @@
 	    rs->xrot += rs->xVelocity * chunk;
 	    rs->yrot += rs->yVelocity * chunk;
 
-	    if (rs->xrot > 360.0f / s->size)
+	    if (rs->xrot > 360.0f / s->hsize)
 	    {
-		rs->baseXrot += 360.0f / s->size;
-		rs->xrot -= 360.0f / s->size;
+		rs->baseXrot += 360.0f / s->hsize;
+		rs->xrot -= 360.0f / s->hsize;
 	    }
 	    else if (rs->xrot < 0.0f)
 	    {
-		rs->baseXrot -= 360.0f / s->size;
-		rs->xrot += 360.0f / s->size;
+		rs->baseXrot -= 360.0f / s->hsize;
+		rs->xrot += 360.0f / s->hsize;
 	    }
 
 	    if (rs->invert == -1)
@@ -467,7 +467,7 @@
 		if (fabs (rs->yVelocity) < 0.01f)
 		    rs->yVelocity = 0.0f;
 	    }
-	    else if (adjustVelocity (rs, s->size))
+	    else if (adjustVelocity (rs, s->hsize))
 	    {
 		rs->xVelocity = 0.0f;
 		rs->yVelocity = 0.0f;
@@ -479,11 +479,11 @@
 
 		    xrot = rs->baseXrot + rs->xrot;
 		    if (xrot < 0.0f)
-			tx = (s->size * xrot / 360.0f) - 0.5f;
+			tx = (s->hsize * xrot / 360.0f) - 0.5f;
 		    else
-			tx = (s->size * xrot / 360.0f) + 0.5f;
+			tx = (s->hsize * xrot / 360.0f) + 0.5f;
 
-		    moveScreenViewport (s, tx, TRUE);
+		    moveScreenViewport (s, tx, 0, TRUE);
 
 		    rs->xrot = 0.0f;
 		    rs->yrot = 0.0f;
@@ -524,7 +524,7 @@
 	    w = findWindowAtScreen (s, rs->moveWindow);
 	    if (w)
 	    {
-		float xrot = (s->size * (rs->baseXrot + rs->xrot)) / 360.0f;
+		float xrot = (s->hsize * (rs->baseXrot + rs->xrot)) / 360.0f;
 
 		moveWindowToViewportPosition (w,
 					      rs->moveWindowX - xrot * s->width,
@@ -558,6 +558,7 @@
 rotatePaintScreen (CompScreen		   *s,
 		   const ScreenPaintAttrib *sAttrib,
 		   Region		   region,
+		   int			   output,
 		   unsigned int		   mask)
 {
     Bool status;
@@ -575,13 +576,13 @@
 	mask |= PAINT_SCREEN_TRANSFORMED_MASK;
 
 	UNWRAP (rs, s, paintScreen);
-	status = (*s->paintScreen) (s, &sa, region, mask);
+	status = (*s->paintScreen) (s, &sa, region, output, mask);
 	WRAP (rs, s, paintScreen, rotatePaintScreen);
     }
     else
     {
 	UNWRAP (rs, s, paintScreen);
-	status = (*s->paintScreen) (s, sAttrib, region, mask);
+	status = (*s->paintScreen) (s, sAttrib, region, output, mask);
 	WRAP (rs, s, paintScreen, rotatePaintScreen);
     }
 
@@ -737,7 +738,7 @@
 	}
 
 	rs->moving  = TRUE;
-	rs->moveTo += (360.0f / s->size) * direction;
+	rs->moveTo += (360.0f / s->hsize) * direction;
 	rs->grabbed = FALSE;
 
 	damageScreen (s);
@@ -814,7 +815,7 @@
 	if (rs->grabIndex)
 	{
 	    rs->moving  = TRUE;
-	    rs->moveTo += (360.0f / s->size) * direction;
+	    rs->moveTo += (360.0f / s->hsize) * direction;
 	    rs->grabbed = FALSE;
 
 	    damageScreen (s);
@@ -1130,7 +1131,7 @@
 		    compAddTimeout (rd->flipTime, rotateFlipLeft, s);
 
 	    rs->moving  = TRUE;
-	    rs->moveTo -= 360.0f / s->size;
+	    rs->moveTo -= 360.0f / s->hsize;
 	    rs->slow    = TRUE;
 
 	    if (state & CompActionStateInitEdge)
@@ -1170,7 +1171,7 @@
 		    compAddTimeout (rd->flipTime, rotateFlipRight, s);
 
 	    rs->moving  = TRUE;
-	    rs->moveTo += 360.0f / s->size;
+	    rs->moveTo += 360.0f / s->hsize;
 	    rs->slow    = TRUE;
 
 	    if (state & CompActionStateInitEdge)
@@ -1270,11 +1271,11 @@
 
     ROTATE_SCREEN (s);
 
-    delta = face - s->x - (rs->moveTo / (360.0f / s->size));
-    if (delta > s->size / 2)
-	delta -= s->size;
-    else if (delta < -(s->size / 2))
-	delta += s->size;
+    delta = face - s->x - (rs->moveTo / (360.0f / s->hsize));
+    if (delta > s->hsize / 2)
+	delta -= s->hsize;
+    else if (delta < -(s->hsize / 2))
+	delta += s->hsize;
 
     return delta;
 }
@@ -1473,7 +1474,8 @@
 		rs->moving = FALSE;
 		rs->moveTo = 0.0f;
 
-		dx = defaultViewportForWindow (w) - s->x;
+		defaultViewportForWindow (w, &dx, NULL);
+		dx -= s->x;
 		if (dx)
 		{
 		    Window	 win;
@@ -1484,10 +1486,10 @@
 		    XQueryPointer (d->display, s->root,
 				   &win, &win, &x, &y, &i, &i, &ui);
 
-		    if (dx > (s->size + 1) / 2)
-			dx -= s->size;
-		    else if (dx < -(s->size + 1) / 2)
-			dx += s->size;
+		    if (dx > (s->hsize + 1) / 2)
+			dx -= s->hsize;
+		    else if (dx < -(s->hsize + 1) / 2)
+			dx += s->hsize;
 
 		    o[0].type    = CompOptionTypeInt;
 		    o[0].name    = "x";
@@ -1530,10 +1532,10 @@
 		    XQueryPointer (d->display, s->root,
 				   &win, &win, &x, &y, &i, &i, &ui);
 
-		    if (dx > (s->size + 1) / 2)
-			dx -= s->size;
-		    else if (dx < -(s->size + 1) / 2)
-			dx += s->size;
+		    if (dx > (s->hsize + 1) / 2)
+			dx -= s->hsize;
+		    else if (dx < -(s->hsize + 1) / 2)
+			dx += s->hsize;
 
 		    o[0].type    = CompOptionTypeInt;
 		    o[0].name    = "x";

Modified: trunk/app/compiz/plugins/scale.c
===================================================================
--- trunk/app/compiz/plugins/scale.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/scale.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -852,6 +852,7 @@
 scalePaintScreen (CompScreen		  *s,
 		  const ScreenPaintAttrib *sAttrib,
 		  Region		  region,
+		  int			  output,
 		  unsigned int		  mask)
 {
     Bool status;
@@ -862,7 +863,7 @@
 	mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
 
     UNWRAP (ss, s, paintScreen);
-    status = (*s->paintScreen) (s, sAttrib, region, mask);
+    status = (*s->paintScreen) (s, sAttrib, region, output, mask);
     WRAP (ss, s, paintScreen, scalePaintScreen);
 
     return status;

Modified: trunk/app/compiz/plugins/screenshot.c
===================================================================
--- trunk/app/compiz/plugins/screenshot.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/screenshot.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -169,6 +169,7 @@
 shotPaintScreen (CompScreen		 *s,
 		 const ScreenPaintAttrib *sAttrib,
 		 Region			 region,
+		 int			 output,
 		 unsigned int		 mask)
 {
     Bool status;
@@ -176,7 +177,7 @@
     SHOT_SCREEN (s);
 
     UNWRAP (ss, s, paintScreen);
-    status = (*s->paintScreen) (s, sAttrib, region, mask);
+    status = (*s->paintScreen) (s, sAttrib, region, output, mask);
     WRAP (ss, s, paintScreen, shotPaintScreen);
 
     if (status && ss->grab)

Modified: trunk/app/compiz/plugins/switcher.c
===================================================================
--- trunk/app/compiz/plugins/switcher.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/switcher.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -1339,6 +1339,7 @@
 switchPaintScreen (CompScreen		   *s,
 		   const ScreenPaintAttrib *sAttrib,
 		   Region		   region,
+		   int			   output,
 		   unsigned int		   mask)
 {
     Bool status;
@@ -1388,7 +1389,7 @@
 	}
 
 	UNWRAP (ss, s, paintScreen);
-	status = (*s->paintScreen) (s, &sa, region, mask);
+	status = (*s->paintScreen) (s, &sa, region, output, mask);
 	WRAP (ss, s, paintScreen, switchPaintScreen);
 
 	if (zoomed)
@@ -1420,7 +1421,7 @@
     else
     {
 	UNWRAP (ss, s, paintScreen);
-	status = (*s->paintScreen) (s, sAttrib, region, mask);
+	status = (*s->paintScreen) (s, sAttrib, region, output, mask);
 	WRAP (ss, s, paintScreen, switchPaintScreen);
     }
 

Modified: trunk/app/compiz/plugins/wobbly.c
===================================================================
--- trunk/app/compiz/plugins/wobbly.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/wobbly.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -2802,6 +2802,7 @@
 wobblyPaintScreen (CompScreen		   *s,
 		   const ScreenPaintAttrib *sAttrib,
 		   Region		   region,
+		   int			   output,
 		   unsigned int		   mask)
 {
     Bool status;
@@ -2812,7 +2813,7 @@
 	mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
 
     UNWRAP (ws, s, paintScreen);
-    status = (*s->paintScreen) (s, sAttrib, region, mask);
+    status = (*s->paintScreen) (s, sAttrib, region, output, mask);
     WRAP (ws, s, paintScreen, wobblyPaintScreen);
 
     return status;

Modified: trunk/app/compiz/plugins/zoom.c
===================================================================
--- trunk/app/compiz/plugins/zoom.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/plugins/zoom.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -376,6 +376,7 @@
 zoomPaintScreen (CompScreen		 *s,
 		 const ScreenPaintAttrib *sAttrib,
 		 Region		         region,
+		 int			 output,
 		 unsigned int		 mask)
 {
     Bool status;
@@ -410,7 +411,7 @@
 	    s->filter[SCREEN_TRANS_FILTER] = COMP_TEXTURE_FILTER_FAST;
 
 	UNWRAP (zs, s, paintScreen);
-	status = (*s->paintScreen) (s, &sa, region, mask);
+	status = (*s->paintScreen) (s, &sa, region, output, mask);
 	WRAP (zs, s, paintScreen, zoomPaintScreen);
 
 	s->filter[SCREEN_TRANS_FILTER] = saveFilter;
@@ -418,7 +419,7 @@
     else
     {
 	UNWRAP (zs, s, paintScreen);
-	status = (*s->paintScreen) (s, sAttrib, region, mask);
+	status = (*s->paintScreen) (s, sAttrib, region, output, mask);
 	WRAP (zs, s, paintScreen, zoomPaintScreen);
     }
 

Modified: trunk/app/compiz/src/display.c
===================================================================
--- trunk/app/compiz/src/display.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/src/display.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -1808,6 +1808,11 @@
     if (!s->opt[COMP_SCREEN_OPTION_SYNC_TO_VBLANK].value.b)
 	return;
 
+    /* we currently can't handle sync to vblank when we have more than one
+       output device */
+    if (s->nOutputDev > 1)
+	return;
+
     if (s->getVideoSync)
     {
 	glFlush ();
@@ -1821,19 +1826,21 @@
 eventLoop (void)
 {
     XEvent	   event;
-    int		   timeDiff;
+    int		   timeDiff, i;
     struct timeval tv;
-    Region	   tmpRegion;
+    Region	   tmpRegion, outputRegion;
     CompDisplay    *display = compDisplays;
     CompScreen	   *s;
     int		   time, timeToNextRedraw = 0;
     CompWindow	   *w;
-    unsigned int   damageMask;
+    unsigned int   damageMask, mask;
 
     tmpRegion = XCreateRegion ();
-    if (!tmpRegion)
+    outputRegion = XCreateRegion ();
+    if (!tmpRegion || !outputRegion)
     {
-	fprintf (stderr, "%s: Couldn't create region\n", programName);
+	fprintf (stderr, "%s: Couldn't create temporary regions\n",
+		 programName);
 	return;
     }
 
@@ -1996,9 +2003,9 @@
 		    {
 			XIntersectRegion (s->damage, &s->region, tmpRegion);
 
-			if (tmpRegion->numRects  == 1	 &&
-			    tmpRegion->rects->x1 == 0	 &&
-			    tmpRegion->rects->y1 == 0	 &&
+			if (tmpRegion->numRects  == 1	     &&
+			    tmpRegion->rects->x1 == 0	     &&
+			    tmpRegion->rects->y1 == 0	     &&
 			    tmpRegion->rects->x2 == s->width &&
 			    tmpRegion->rects->y2 == s->height)
 			    damageScreen (s);
@@ -2006,97 +2013,118 @@
 
 		    EMPTY_REGION (s->damage);
 
-		    if (s->damageMask & COMP_SCREEN_DAMAGE_ALL_MASK)
-		    {
-			s->damageMask = 0;
+		    mask = s->damageMask;
+		    s->damageMask = 0;
 
-			(*s->paintScreen) (s,
-					   &defaultScreenPaintAttrib,
-					   &s->region,
-					   PAINT_SCREEN_REGION_MASK |
-					   PAINT_SCREEN_FULL_MASK);
-
-			waitForVideoSync (s);
-
-			glXSwapBuffers (s->display->display, s->output);
-		    }
-		    else if (s->damageMask & COMP_SCREEN_DAMAGE_REGION_MASK)
+		    for (i = 0; i < s->nOutputDev; i++)
 		    {
-			s->damageMask = 0;
+			if (s->nOutputDev > 1)
+			    glScissor (s->outputDev[i].region.extents.x1,
+				       s->outputDev[i].region.extents.y1,
+				       s->outputDev[i].region.extents.x2 -
+				       s->outputDev[i].region.extents.x1,
+				       s->outputDev[i].region.extents.y2 -
+				       s->outputDev[i].region.extents.y1);
 
-			if ((*s->paintScreen) (s,
+			if (mask & COMP_SCREEN_DAMAGE_ALL_MASK)
+			{
+			    (*s->paintScreen) (s,
 					       &defaultScreenPaintAttrib,
-					       tmpRegion,
-					       PAINT_SCREEN_REGION_MASK))
+					       &s->outputDev[i].region, i,
+					       PAINT_SCREEN_REGION_MASK |
+					       PAINT_SCREEN_FULL_MASK);
+
+			    if (i + 1 == s->nOutputDev)
+			    {
+				waitForVideoSync (s);
+				glXSwapBuffers (s->display->display, s->output);
+			    }
+			}
+			else if (mask & COMP_SCREEN_DAMAGE_REGION_MASK)
 			{
-			    BoxPtr pBox;
-			    int    nBox, y;
+			    XIntersectRegion (tmpRegion,
+					      &s->outputDev[i].region,
+					      outputRegion);
 
-			    pBox = tmpRegion->rects;
-			    nBox = tmpRegion->numRects;
+			    if ((*s->paintScreen) (s,
+						   &defaultScreenPaintAttrib,
+						   outputRegion, i,
+						   PAINT_SCREEN_REGION_MASK))
+			    {
+				BoxPtr pBox;
+				int    nBox, y;
 
-			    waitForVideoSync (s);
+				pBox = outputRegion->rects;
+				nBox = outputRegion->numRects;
 
-			    if (s->copySubBuffer)
-			    {
-				while (nBox--)
+				waitForVideoSync (s);
+
+				if (s->copySubBuffer)
 				{
-				    y = s->height - pBox->y2;
+				    while (nBox--)
+				    {
+					y = s->height - pBox->y2;
 
-				    (*s->copySubBuffer) (s->display->display,
-							 s->output,
-							 pBox->x1, y,
-							 pBox->x2 - pBox->x1,
-							 pBox->y2 - pBox->y1);
+					(*s->copySubBuffer) (display->display,
+							     s->output,
+							     pBox->x1, y,
+							     pBox->x2 -
+							     pBox->x1,
+							     pBox->y2 -
+							     pBox->y1);
 
-				    pBox++;
+					pBox++;
+				    }
 				}
-			    }
-			    else
-			    {
-				glEnable (GL_SCISSOR_TEST);
-				glDrawBuffer (GL_FRONT);
-
-				while (nBox--)
+				else
 				{
-				    y = s->height - pBox->y2;
+				    glEnable (GL_SCISSOR_TEST);
+				    glDrawBuffer (GL_FRONT);
 
-				    glBitmap (0, 0, 0, 0,
-					      pBox->x1 - s->rasterX,
-					      y - s->rasterY,
-					      NULL);
+				    while (nBox--)
+				    {
+					y = s->height - pBox->y2;
 
-				    s->rasterX = pBox->x1;
-				    s->rasterY = y;
+					glBitmap (0, 0, 0, 0,
+						  pBox->x1 - s->rasterX,
+						  y - s->rasterY,
+						  NULL);
 
-				    glScissor (pBox->x1, y,
-					       pBox->x2 - pBox->x1,
-					       pBox->y2 - pBox->y1);
+					s->rasterX = pBox->x1;
+					s->rasterY = y;
 
-				    glCopyPixels (pBox->x1, y,
-						  pBox->x2 - pBox->x1,
-						  pBox->y2 - pBox->y1,
-						  GL_COLOR);
+					glScissor (pBox->x1, y,
+						   pBox->x2 - pBox->x1,
+						   pBox->y2 - pBox->y1);
 
-				    pBox++;
+					glCopyPixels (pBox->x1, y,
+						      pBox->x2 - pBox->x1,
+						      pBox->y2 - pBox->y1,
+						      GL_COLOR);
+
+					pBox++;
+				    }
+
+				    glDrawBuffer (GL_BACK);
+				    glDisable (GL_SCISSOR_TEST);
+				    glFlush ();
 				}
+			    }
+			    else
+			    {
+				(*s->paintScreen) (s,
+						   &defaultScreenPaintAttrib,
+						   &s->outputDev[i].region, i,
+						   PAINT_SCREEN_FULL_MASK);
 
-				glDrawBuffer (GL_BACK);
-				glDisable (GL_SCISSOR_TEST);
-				glFlush ();
+				if (i + 1 == s->nOutputDev)
+				{
+				    waitForVideoSync (s);
+				    glXSwapBuffers (display->display,
+						    s->output);
+				}
 			    }
 			}
-			else
-			{
-			    (*s->paintScreen) (s,
-					       &defaultScreenPaintAttrib,
-					       &s->region,
-					       PAINT_SCREEN_FULL_MASK);
-
-			    waitForVideoSync (s);
-
-			    glXSwapBuffers (s->display->display, s->output);
-			}
 		    }
 
 		    s->lastRedraw = tv;
@@ -2651,6 +2679,19 @@
 	d->xkbEvent = d->xkbError = -1;
     }
 
+    d->xineramaExtension = XineramaQueryExtension (dpy,
+						   &d->xineramaEvent,
+						   &d->xineramaError);
+    if (d->xineramaExtension)
+    {
+	d->screenInfo = XineramaQueryScreens (dpy, &d->nScreenInfo);
+    }
+    else
+    {
+	d->screenInfo  = NULL;
+	d->nScreenInfo = 0;
+    }
+
     compDisplays = d;
 
     d->escapeKeyCode = XKeysymToKeycode (dpy, XStringToKeysym ("Escape"));

Modified: trunk/app/compiz/src/event.c
===================================================================
--- trunk/app/compiz/src/event.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/src/event.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -1066,6 +1066,22 @@
     CompScreen *s;
     CompWindow *w;
 
+    switch (event->type) {
+    case ButtonPress:
+	s = findScreenAtDisplay (d, event->xbutton.root);
+	if (s)
+	    setCurrentOutput (s, outputDeviceForPoint (s,
+						       event->xbutton.x_root,
+						       event->xbutton.y_root));
+	break;
+    case KeyPress:
+	w = findWindowAtDisplay (d, d->activeWindow);
+	if (w)
+	    setCurrentOutput (w->screen, outputDeviceForWindow (w));
+    default:
+	break;
+    }
+
     if (handleActionEvent (d, event))
     {
 	if (!d->screens->maxGrab)
@@ -1766,7 +1782,8 @@
 
 	    if (!(w->state & CompWindowStateHiddenMask))
 	    {
-		w->initialViewport = w->screen->x;
+		w->initialViewportX = w->screen->x;
+		w->initialViewportY = w->screen->y;
 
 		applyStartupProperties (w->screen, w);
 

Modified: trunk/app/compiz/src/paint.c
===================================================================
--- trunk/app/compiz/src/paint.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/src/paint.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -62,6 +62,7 @@
 void
 paintTransformedScreen (CompScreen		*screen,
 			const ScreenPaintAttrib *sAttrib,
+			int			output,
 			unsigned int		mask)
 {
     CompWindow *w;
@@ -143,6 +144,7 @@
 paintScreen (CompScreen		     *screen,
 	     const ScreenPaintAttrib *sAttrib,
 	     Region		     region,
+	     int		     output,
 	     unsigned int	     mask)
 {
     static Region tmpRegion = NULL;
@@ -154,7 +156,8 @@
 	{
 	    if (mask & PAINT_SCREEN_FULL_MASK)
 	    {
-		(*screen->paintTransformedScreen) (screen, sAttrib, mask);
+		(*screen->paintTransformedScreen) (screen, sAttrib, output,
+						   mask);
 
 		return TRUE;
 	    }
@@ -166,7 +169,7 @@
     }
     else if (mask & PAINT_SCREEN_FULL_MASK)
     {
-	(*screen->paintTransformedScreen) (screen, sAttrib, mask);
+	(*screen->paintTransformedScreen) (screen, sAttrib, output, mask);
 
 	return TRUE;
     }

Modified: trunk/app/compiz/src/screen.c
===================================================================
--- trunk/app/compiz/src/screen.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/src/screen.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -47,10 +47,14 @@
 
 #define DETECT_REFRESH_RATE_DEFAULT TRUE
 
-#define SCREEN_SIZE_DEFAULT 4
-#define SCREEN_SIZE_MIN	    4
-#define SCREEN_SIZE_MAX	    32
+#define SCREEN_HSIZE_DEFAULT 4
+#define SCREEN_HSIZE_MIN     1
+#define SCREEN_HSIZE_MAX     32
 
+#define SCREEN_VSIZE_DEFAULT 1
+#define SCREEN_VSIZE_MIN     1
+#define SCREEN_VSIZE_MAX     32
+
 #define LIGHTING_DEFAULT TRUE
 
 #define OPACITY_STEP_DEFAULT 10
@@ -105,19 +109,21 @@
 
 static void
 setVirtualScreenSize (CompScreen *screen,
-		      int	 size)
+		      int	 hsize,
+		      int	 vsize)
 {
     unsigned long data[2];
 
-    data[0] = screen->width * size;
-    data[1] = screen->height;
+    data[0] = screen->width * hsize;
+    data[1] = screen->height * vsize;
 
     XChangeProperty (screen->display->display, screen->root,
 		     screen->display->desktopGeometryAtom,
 		     XA_CARDINAL, 32, PropModeReplace,
 		     (unsigned char *) data, 2);
 
-    screen->size = size;
+    screen->hsize = hsize;
+    screen->vsize = vsize;
 }
 
 static Bool
@@ -197,16 +203,30 @@
 	    return TRUE;
 	}
 	break;
-    case COMP_SCREEN_OPTION_SIZE:
+    case COMP_SCREEN_OPTION_HSIZE:
 	if (compSetIntOption (o, value))
 	{
+	    CompOption *vsize = compFindOption (screen->opt, NUM_OPTIONS (screen), "vsize", NULL);
+	    
 	    if (o->value.i * screen->width > MAXSHORT)
 		return FALSE;
 
-	    setVirtualScreenSize (screen, o->value.i);
+	    setVirtualScreenSize (screen, o->value.i, vsize->value.i);
 	    return TRUE;
 	}
 	break;
+    case COMP_SCREEN_OPTION_VSIZE:
+	if (compSetIntOption (o, value))
+	{
+	    CompOption *hsize = compFindOption (screen->opt, NUM_OPTIONS (screen), "hsize", NULL);
+
+	    if (o->value.i * screen->height > MAXSHORT)
+		return FALSE;
+
+	    setVirtualScreenSize (screen, hsize->value.i, o->value.i);
+	    return TRUE;
+	}
+	break;
     case COMP_SCREEN_OPTION_OPACITY_STEP:
 	if (compSetIntOption (o, value))
 	{
@@ -267,15 +287,24 @@
     o->rest.i.min = 1;
     o->rest.i.max = 200;
 
-    o = &screen->opt[COMP_SCREEN_OPTION_SIZE];
-    o->name	  = "size";
-    o->shortDesc  = N_("Virtual Size");
-    o->longDesc	  = N_("Screen size multiplier for virtual size");
+    o = &screen->opt[COMP_SCREEN_OPTION_HSIZE];
+    o->name	  = "hsize";
+    o->shortDesc  = N_("Horizontal Virtual Size");
+    o->longDesc	  = N_("Screen size multiplier for horizontal virtual size");
     o->type	  = CompOptionTypeInt;
-    o->value.i    = SCREEN_SIZE_DEFAULT;
-    o->rest.i.min = SCREEN_SIZE_MIN;
-    o->rest.i.max = SCREEN_SIZE_MAX;
+    o->value.i    = SCREEN_HSIZE_DEFAULT;
+    o->rest.i.min = SCREEN_HSIZE_MIN;
+    o->rest.i.max = SCREEN_HSIZE_MAX;
 
+    o = &(screen->opt[COMP_SCREEN_OPTION_VSIZE]);
+    o->name	      = "vsize";
+    o->shortDesc      = N_("Vertical Virtual Size");
+    o->longDesc	      = N_("Screen size multiplier for vertical virtual size");
+    o->type	      = CompOptionTypeInt;
+    o->value.i	      = SCREEN_VSIZE_DEFAULT;
+    o->rest.i.min     = SCREEN_VSIZE_MIN;
+    o->rest.i.max     = SCREEN_VSIZE_MAX;
+
     o = &screen->opt[COMP_SCREEN_OPTION_OPACITY_STEP];
     o->name		= "opacity_step";
     o->shortDesc	= N_("Opacity Step");
@@ -362,7 +391,8 @@
 
     s->next     = screen->startupSequences;
     s->sequence = sequence;
-    s->viewport = screen->x;
+    s->viewportX = screen->x;
+    s->viewportY = screen->y;
 
     screen->startupSequences = s;
 
@@ -507,13 +537,86 @@
 }
 
 static void
+updateOutputDevices (CompScreen *s)
+{
+    CompOutput *output;
+    int	       nOutput, i;
+
+    if (s->display->screenInfo)
+    {
+	XineramaScreenInfo *screenInfo = s->display->screenInfo;
+	int		   nScreenInfo = s->display->nScreenInfo;
+
+	output = malloc (sizeof (CompOutput) * nScreenInfo);
+	if (!output)
+	    return;
+
+	for (i = 0; i < nScreenInfo; i++)
+	{
+	    output->name = malloc (sizeof (char) * 10);
+	    if (output->name)
+		snprintf (output->name, 10, "Output %d", i);
+
+	    output[i].region.rects    = &output[i].region.extents;
+	    output[i].region.numRects = 1;
+
+	    output[i].region.extents.x1 = screenInfo[i].x_org;
+	    output[i].region.extents.y1 = screenInfo[i].y_org;
+	    output[i].region.extents.x2 = screenInfo[i].x_org +
+		screenInfo[i].width;
+	    output[i].region.extents.y2 = screenInfo[i].y_org +
+		screenInfo[i].height;
+	}
+
+	nOutput = nScreenInfo;
+    }
+    else
+    {
+	output = malloc (sizeof (CompOutput));
+	if (!output)
+	    return;
+
+	output->name   = strdup ("Output 0");
+
+	output->region.rects    = &output->region.extents;
+	output->region.numRects = 1;
+
+	output->region.extents.x1 = 0;
+	output->region.extents.y1 = 0;
+	output->region.extents.x2 = s->attrib.width;
+	output->region.extents.y2 = s->attrib.height;
+
+	nOutput = 1;
+    }
+
+    if (s->outputDev)
+    {
+	for (i = 0; i < s->nOutputDev; i++)
+	    if (s->outputDev->name)
+		free (s->outputDev->name);
+
+	free (s->outputDev);
+    }
+
+    s->outputDev  = output;
+    s->nOutputDev = nOutput;
+}
+
+void
+setCurrentOutput (CompScreen *s,
+		  int	     outputNum)
+{
+    if (outputNum >= s->nOutputDev)
+	outputNum = 0;
+
+    s->currentOutputDev = outputNum;
+}
+
+static void
 reshape (CompScreen *s,
 	 int	    w,
 	 int	    h)
 {
-    s->width  = w;
-    s->height = h;
-
     glMatrixMode (GL_PROJECTION);
     glLoadIdentity ();
     glMatrixMode (GL_MODELVIEW);
@@ -538,6 +641,13 @@
     s->region.extents.y2 = h;
     s->region.size = 1;
 
+    s->width  = w;
+    s->height = h;
+
+    updateOutputDevices (s);
+
+    setCurrentOutput (s, s->currentOutputDev);
+
     updateScreenEdges (s);
     updateWorkareaForScreen (s);
 }
@@ -836,22 +946,25 @@
 	{
 	    memcpy (data, propData, sizeof (unsigned long));
 
-	    if (data[0] / s->width < s->size - 1)
+	    if (data[0] / s->width < s->hsize - 1)
 		s->x = data[0] / s->width;
+
+	    if (data[1] / s->height < s->vsize - 1)
+		s->y = data[1] / s->height;
 	}
 
 	XFree (propData);
     }
 
     data[0] = s->x * s->width;
-    data[1] = 0;
+    data[1] = s->y * s->height;
 
     XChangeProperty (d->display, s->root, d->desktopViewportAtom,
 		     XA_CARDINAL, 32, PropModeReplace,
 		     (unsigned char *) data, 2);
 
-    data[0] = s->width * s->size;
-    data[1] = s->height;
+    data[0] = s->width * s->hsize;
+    data[1] = s->height * s->vsize;
 
     XChangeProperty (d->display, s->root, d->desktopGeometryAtom,
 		     XA_CARDINAL, 32, PropModeReplace,
@@ -875,7 +988,7 @@
 				 d->showingDesktopAtom, 0L, 1L, FALSE,
 				 XA_CARDINAL, &actual, &format,
 				 &n, &left, &propData);
-
+    
     if (result == Success && n && propData)
     {
 	memcpy (data, propData, sizeof (unsigned long));
@@ -968,8 +1081,10 @@
     if (!s->damage)
 	return FALSE;
 
-    s->x    = 0;
-    s->size = 4;
+    s->x     = 0;
+    s->y     = 0;
+    s->hsize = SCREEN_HSIZE_DEFAULT;
+    s->vsize = SCREEN_VSIZE_DEFAULT;
 
     for (i = 0; i < SCREEN_EDGE_NUM; i++)
     {
@@ -1021,6 +1136,10 @@
     s->rasterX = 0;
     s->rasterY = 0;
 
+    s->outputDev	= NULL;
+    s->nOutputDev	= 0;
+    s->currentOutputDev = 0;
+
     s->windows = 0;
     s->reverseWindows = 0;
 
@@ -2522,32 +2641,50 @@
 void
 moveScreenViewport (CompScreen *s,
 		    int	       tx,
+		    int	       ty,
 		    Bool       sync)
 {
+    CompWindow *w;
+    int         m, wx, wy, vWidth, vHeight;
+
     tx = s->x - tx;
-    tx = MOD (tx, s->size);
+    tx = MOD (tx, s->hsize);
     tx -= s->x;
 
-    if (tx)
-    {
-	CompWindow *w;
-	int	   m, wx, vWidth = s->width * s->size;
+    ty = s->y - ty;
+    ty = MOD (ty, s->vsize);
+    ty -= s->y;
 
-	s->x += tx;
+    if (!tx && !ty)
+	return;
 
-	tx *= -s->width;
+    s->x += tx;
+    s->y += ty;
 
-	for (w = s->windows; w; w = w->next)
-	{
-	    if (w->attrib.override_redirect)
-		continue;
+    tx *= -s->width;
+    ty *= -s->height;
 
-	    if (w->type & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
-		continue;
+    vWidth = s->width * s->hsize;
+    vHeight = s->height * s->vsize;
 
-	    if (w->state & CompWindowStateStickyMask)
-		continue;
+    for (w = s->windows; w; w = w->next)
+    {
+	if (w->attrib.override_redirect)
+	    continue;
 
+	if (w->type & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
+	    continue;
+
+	if (w->state & CompWindowStateStickyMask)
+	    continue;
+
+	/* x */
+	if (s->hsize == 1)
+	{
+	    wx = tx;
+	}
+	else
+	{
 	    m = w->attrib.x + tx;
 	    if (m - w->output.left < s->width - vWidth)
 		wx = tx + vWidth;
@@ -2555,28 +2692,48 @@
 		wx = tx - vWidth;
 	    else
 		wx = tx;
+	}
 
-	    if (w->saveMask & CWX)
-		w->saveWc.x += wx;
+	if (w->saveMask & CWX)
+	    w->saveWc.x += wx;
 
-	    moveWindow (w, wx, 0, sync, TRUE);
-
-	    if (sync)
-		syncWindowPosition (w);
+	/* y */
+	if (s->vsize == 1)
+	{
+	    wy = ty;
 	}
+	else
+	{
+	    m = w->attrib.y + ty;
+	    if (m - w->output.top < s->height - vHeight)
+		wy = ty + vHeight;
+	    else if (m + w->height + w->output.bottom > vHeight)
+		wy = ty - vHeight;
+	    else
+		wy = ty;
+	}
 
+	if (w->saveMask & CWY)
+	    w->saveWc.y += wy;
+
+	/* move */
+	moveWindow (w, wx, wy, sync, TRUE);
+
 	if (sync)
-	{
-	    unsigned long data[2];
+	    syncWindowPosition (w);
+    }
 
-	    data[0] = s->x * s->width;
-	    data[1] = 0;
+    if (sync)
+    {
+	unsigned long data[2];
 
-	    XChangeProperty (s->display->display, s->root,
-			     s->display->desktopViewportAtom,
-			     XA_CARDINAL, 32, PropModeReplace,
-			     (unsigned char *) data, 2);
-	}
+	data[0] = s->x * s->width;
+	data[1] = s->y * s->height;
+
+	XChangeProperty (s->display->display, s->root,
+			 s->display->desktopViewportAtom,
+			 XA_CARDINAL, 32, PropModeReplace,
+			 (unsigned char *) data, 2);
     }
 }
 
@@ -2585,7 +2742,7 @@
 			      int	 x,
 			      Bool       sync)
 {
-    int	tx, vWidth = w->screen->width * w->screen->size;
+    int	tx, vWidth = w->screen->width * w->screen->hsize;
 
     x += w->screen->x * w->screen->width;
     x = MOD (x, vWidth);
@@ -2713,7 +2870,10 @@
     }
 
     if (s)
-	window->initialViewport = s->viewport;
+    {
+	window->initialViewportX = s->viewportX;
+	window->initialViewportY = s->viewportY;
+    }
 }
 
 void
@@ -2914,3 +3074,24 @@
 	s->pendingCommands = FALSE;
     }
 }
+
+int
+outputDeviceForPoint (CompScreen *s,
+		      int	 x,
+		      int	 y)
+{
+    int i, x1, y1, x2, y2;
+
+    for (i = 0; i < s->nOutputDev; i++)
+    {
+	x1 = s->outputDev[i].region.extents.x1;
+	y1 = s->outputDev[i].region.extents.y1;
+	x2 = s->outputDev[i].region.extents.x2;
+	y2 = s->outputDev[i].region.extents.y2;
+
+	if (x1 < x && x2 >= x && y1 < y && y2 >= y)
+	    return i;
+    }
+
+    return s->currentOutputDev;
+}

Modified: trunk/app/compiz/src/window.c
===================================================================
--- trunk/app/compiz/src/window.c	2006-09-29 03:59:58 UTC (rev 3540)
+++ trunk/app/compiz/src/window.c	2006-09-29 04:02:32 UTC (rev 3541)
@@ -1501,7 +1501,8 @@
     w->shaded		 = FALSE;
     w->hidden		 = FALSE;
 
-    w->initialViewport = screen->x;
+    w->initialViewportX = screen->x;
+    w->initialViewportY = screen->y;
 
     w->pendingUnmaps = 0;
 
@@ -2898,10 +2899,14 @@
 		      int	     oldBorderWidth)
 {
     int mask = 0;
-    int x;
+    int x, y;
+    int vx, vy;
 
-    x = (defaultViewportForWindow (w) - w->screen->x) * w->screen->width;
+    defaultViewportForWindow (w, &vx, &vy);
 
+    x = (vx - w->screen->x) * w->screen->width;
+    y = (vy - w->screen->y) * w->screen->height;
+
     if (w->type & CompWindowTypeFullscreenMask)
     {
 	saveWindowGeometry (w, CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
@@ -2964,7 +2969,7 @@
 	if (w->type & CompWindowTypeFullscreenMask)
 	{
 	    xwc->x = x;
-	    xwc->y = 0;
+	    xwc->y = y;
 
 	    mask |= CWX | CWY;
 	}
@@ -2988,16 +2993,16 @@
 
 	    if (w->state & CompWindowStateMaximizedVertMask)
 	    {
-		if (oldY < w->screen->workArea.y + w->input.top)
+		if (oldY < y + w->screen->workArea.y + w->input.top)
 		{
-		    xwc->y = w->screen->workArea.y + w->input.top;
+		    xwc->y = y + w->screen->workArea.y + w->input.top;
 		    mask |= CWY;
 		}
 		else
 		{
 		    height = xwc->height + oldBorderWidth * 2;
 
-		    max = w->screen->workArea.y + w->screen->workArea.height;
+		    max = y + w->screen->workArea.y + w->screen->workArea.height;
 		    if (oldY + oldHeight + w->input.bottom > max)
 		    {
 			xwc->y = max - height - w->input.bottom;
@@ -3393,9 +3398,9 @@
 	return;
 
     x1 = w->screen->workArea.x - w->screen->width * w->screen->x;
-    y1 = w->screen->workArea.y;
-    x2 = x1 + w->screen->workArea.width + w->screen->size * w->screen->width;
-    y2 = y1 + w->screen->workArea.height;
+    y1 = w->screen->workArea.y - w->screen->height * w->screen->y;
+    x2 = x1 + w->screen->workArea.width + w->screen->hsize * w->screen->width;
+    y2 = y1 + w->screen->workArea.height + w->screen->vsize * w->screen->height;
 
     if (w->attrib.x - w->input.left >= x2)
 	dx = (x2 - 25) - w->attrib.x;
@@ -3833,9 +3838,12 @@
 		   CompWindowTypeDockMask))
 	return FALSE;
 
-    if (w->initialViewport != w->screen->x)
+    if (w->initialViewportX != w->screen->x)
 	return FALSE;
 
+    if (w->initialViewportY != w->screen->y)
+	return FALSE;
+
     if (!w->inputHint &&
 	!(w->protocols & CompWindowProtocolTakeFocusMask))
 	return FALSE;
@@ -3880,20 +3888,44 @@
    currently computed as the viewport where the center of the window is
    located, except for when the window is visible in the current viewport as
    the current viewport is then always returned. */
-int
-defaultViewportForWindow (CompWindow *w)
+void
+defaultViewportForWindow (CompWindow *w,
+			  int	     *vx,
+			  int	     *vy)
 {
     CompScreen *s = w->screen;
     int	       x;
+    int	       y;
 
-    if (w->attrib.x < s->width && w->attrib.x + w->width > 0)
-	return s->x;
+    if ((w->attrib.x < s->width && w->attrib.x + w->width > 0)	&&
+	(w->attrib.y < s->height && w->attrib.y + w->height > 0))
+    {
+	if (vx)
+	    *vx = s->x;
 
-    x = w->attrib.x + (w->width >> 1);
-    if (x < 0)
-	return s->x + ((x / s->width) - 1) % s->size;
-    else
-	return s->x + (x / s->width) % s->size;
+	if (vy)
+	    *vy = s->y;
+
+	return;
+    }
+
+    if (vx)
+    {
+	x = w->attrib.x + (w->width >> 1);
+	if (x < 0)
+	    *vx = s->x + ((x / s->width) - 1) % s->hsize;
+	else
+	    *vx = s->x + (x / s->width) % s->hsize;
+    }
+
+    if (vy)
+    {
+	y = w->attrib.y + (w->height >> 1);
+	if (y < 0)
+	    *vy = s->y + ((y / s->height) - 1) % s->vsize;
+	else
+	    *vy = s->y + (y / s->height) % s->vsize;
+    }
 }
 
 
@@ -4040,3 +4072,27 @@
 
     w->nIcon = 0;
 }
+
+int
+outputDeviceForWindow (CompWindow *w)
+{
+    int output = w->screen->currentOutputDev;
+    int x1, y1, x2, y2;
+
+    x1 = w->screen->outputDev[output].region.extents.x1;
+    y1 = w->screen->outputDev[output].region.extents.y1;
+    x2 = w->screen->outputDev[output].region.extents.x2;
+    y2 = w->screen->outputDev[output].region.extents.y2;
+
+    if (x1 > w->attrib.x + w->width  ||
+	y1 > w->attrib.y + w->height ||
+	x2 < w->attrib.x	     ||
+	y2 < w->attrib.y)
+    {
+	output = outputDeviceForPoint (w->screen,
+				       w->attrib.x + w->width  / 2,
+				       w->attrib.y + w->height / 2);
+    }
+
+    return output;
+}



Reply to: