All pastes #425707 Raw Edit

Something

public text v1 · immutable
·published 2007-04-05 17:41 UTC
rendered paste body
diff --git a/include/compiz.h b/include/compiz.h
index 027a0e3..415e409 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -1150,6 +1150,12 @@ typedef void (*DonePaintScreenProc) (CompScreen *screen);
 #define PAINT_SCREEN_TRANSFORMED_MASK		   (1 << 2)
 #define PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK (1 << 3)
 #define PAINT_SCREEN_CLEAR_MASK			   (1 << 4)
+#define PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK	   (1 << 5)
+#define PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK	   (1 << 6)
+/* A plugin that sets PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK will get reversed painting.
+   A plugin that sets  both PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK and PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK
+   will get both normal and reversed painting one after the other,
+   and will check paint window mask to avoid painting the window twice. This allows more complex drawing order.*/
 
 typedef Bool (*PaintScreenProc) (CompScreen		 *screen,
 				 const ScreenPaintAttrib *sAttrib,
@@ -1215,6 +1221,13 @@ typedef void (*ApplyScreenTransformProc) (CompScreen		  *screen,
 */
 #define PAINT_WINDOW_BLEND_MASK			(1 << 19)
 
+/*
+ flags that indicate the painting order which is used
+ in paintScreen when drawing the window.
+*/
+#define PAINT_WINDOW_BACK_TO_FRONT_MASK		(1 << 20)
+#define PAINT_WINDOW_FRONT_TO_BACK_MASK		(1 << 21)
+
 
 typedef Bool (*PaintWindowProc) (CompWindow		 *window,
 				 const WindowPaintAttrib *attrib,
@@ -1252,6 +1265,10 @@ typedef void (*PaintBackgroundProc) (CompScreen   *screen,
 				     Region	  region,
 				     unsigned int mask);
 
+typedef void (*SetClipPlanesProc) (CompScreen *screen, Region region, int output);
+
+void setClipPlanes (CompScreen *screen, Region region, int output);
+
 void
 preparePaintScreen (CompScreen *screen,
 		    int	       msSinceLastPaint);
@@ -1922,6 +1939,7 @@ struct _CompScreen {
     GetOutputExtentsForWindowProc  getOutputExtentsForWindow;
     GetAllowedActionsForWindowProc getAllowedActionsForWindow;
     FocusWindowProc		   focusWindow;
+    SetClipPlanesProc		   setClipPlanes;
 
     PaintCursorProc      paintCursor;
     DamageCursorRectProc damageCursorRect;
diff --git a/plugins/cube.c b/plugins/cube.c
index 6784a45..bbe13fc 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -133,6 +133,7 @@ typedef struct _CubeScreen {
     ApplyScreenTransformProc   applyScreenTransform;
     SetScreenOptionProc	       setScreenOption;
     OutputChangeNotifyProc     outputChangeNotify;
+    SetClipPlanesProc          setClipPlanes;
 
     CompOption opt[CUBE_SCREEN_OPTION_NUM];
 
@@ -1563,6 +1564,42 @@ cubePaintTransformedScreen (CompScreen		    *s,
     WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
 }
 
+static void cubeSetClipPlanes (CompScreen *s, Region region, int output)
+{
+    CUBE_SCREEN(s);
+
+    glTranslatef(cs->outputXOffset, -cs->outputYOffset, 0.0f);
+    glScalef( cs->outputXScale, cs->outputYScale, 1.0f);
+
+    UNWRAP(cs, s, setClipPlanes);
+    (*s->setClipPlanes) (s, region, output);
+    WRAP(cs, s, setClipPlanes, cubeSetClipPlanes);
+
+	
+    if (cs->invert == 1)
+    {
+	GLdouble clipPlane0[] = { 1.0, 0.0, 0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane1[] = { -1.0,  0.0, 0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane2[] = { 0.0,  -1.0, 0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane3[] = { 0.0,  1.0, 0.5 / cs->distance, 0.0 };
+	glClipPlane (GL_CLIP_PLANE0, clipPlane0);
+	glClipPlane (GL_CLIP_PLANE1, clipPlane1);
+	glClipPlane (GL_CLIP_PLANE2, clipPlane2);
+	glClipPlane (GL_CLIP_PLANE3, clipPlane3);
+    }
+    else
+    {
+	GLdouble clipPlane0[] = { -1.0, 0.0, -0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane1[] = { 1.0,  0.0, -0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane2[] = { 0.0,  1.0, -0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane3[] = { 0.0,  -1.0, -0.5 / cs->distance, 0.0 };
+	glClipPlane (GL_CLIP_PLANE0, clipPlane0);
+	glClipPlane (GL_CLIP_PLANE1, clipPlane1);
+	glClipPlane (GL_CLIP_PLANE2, clipPlane2);
+	glClipPlane (GL_CLIP_PLANE3, clipPlane3);
+    }
+}
+
 static void
 cubeApplyScreenTransform (CompScreen		  *s,
 			  const ScreenPaintAttrib *sAttrib,
@@ -1583,6 +1620,25 @@ cubeApplyScreenTransform (CompScreen		  *s,
     matrixTranslate (transform, -cs->outputXOffset, cs->outputYOffset, 0.0f);
 }
 
+static void
+cubeFoldEvent(CompScreen *s, Bool unfolded)
+{
+    CompOption o[2];
+
+    o[0].type = CompOptionTypeInt;
+    o[0].name = "root";
+    o[0].value.i = s->root;
+
+    o[1].type = CompOptionTypeBool;
+    o[1].name = "unfolded";
+    o[1].value.b = unfolded;
+
+    (*s->display->handleCompizEvent) (s->display, 
+				      "cube", 
+				      "unfoldEvent", 
+				      o, 2);
+}
+
 static Bool
 cubeUnfold (CompDisplay     *d,
 	    CompAction      *action,
@@ -1611,6 +1667,7 @@ cubeUnfold (CompDisplay     *d,
 
 	if (cs->grabIndex)
 	{
+	    cubeFoldEvent (s, TRUE);
 	    cs->unfolded = TRUE;
 	    damageScreen (s);
 	}
@@ -1646,6 +1703,7 @@ cubeFold (CompDisplay     *d,
 
 	if (cs->grabIndex)
 	{
+	    cubeFoldEvent (s, FALSE);
 	    cs->unfolded = FALSE;
 	    damageScreen (s);
 	}
@@ -1958,6 +2016,7 @@ cubeInitScreen (CompPlugin *p,
     WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
     WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption);
     WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
+    WRAP (cs, s, setClipPlanes, cubeSetClipPlanes);
 
     cubeUpdateOutputs (s);
 
@@ -1992,6 +2051,7 @@ cubeFiniScreen (CompPlugin *p,
     UNWRAP (cs, s, applyScreenTransform);
     UNWRAP (cs, s, setScreenOption);
     UNWRAP (cs, s, outputChangeNotify);
+    UNWRAP (cs, s, setClipPlanes);
 
     finiTexture (s, &cs->texture);
     finiTexture (s, &cs->sky);
diff --git a/plugins/rotate.c b/plugins/rotate.c
index c19030b..b74c40c 100644
--- a/plugins/rotate.c
+++ b/plugins/rotate.c
@@ -400,6 +400,30 @@ rotateReleaseMoveWindow (CompScreen *s)
     rs->moveWindow = None;
 }
 
+static void rotateEvent(CompScreen *s, 
+			Bool       rotating, 
+			Bool       manual)
+{
+    CompOption o[3];
+
+    o[0].type = CompOptionTypeInt;
+    o[0].name = "root";
+    o[0].value.i = s->root;
+
+    o[1].type = CompOptionTypeBool;
+    o[1].name = "rotating";
+    o[1].value.b = rotating;
+
+    o[2].type = CompOptionTypeBool;
+    o[2].name = "manual";
+    o[2].value.b = manual;
+
+    (*s->display->handleCompizEvent)(s->display, 
+				     "rotate", 
+				     "rotateEvent", 
+				     o, 3);
+}
+
 static void
 rotatePreparePaintScreen (CompScreen *s,
 			  int	     msSinceLastPaint)
@@ -485,6 +509,8 @@ rotatePreparePaintScreen (CompScreen *s,
 		    else
 			tx = (s->hsize * xrot / 360.0f) + 0.5f;
 
+		    rotateEvent (s, FALSE, FALSE);
+
 		    moveScreenViewport (s, tx, 0, TRUE);
 
 		    rs->xrot = 0.0f;
@@ -638,6 +664,10 @@ rotateInitiate (CompDisplay     *d,
 	rs->moving = FALSE;
 	rs->slow   = FALSE;
 
+	/* notify other plugins that rotation starts - if action is
+	   non-NULL, we are called from the 'Initiate rotate' binding */
+	rotateEvent (s, TRUE, (action != NULL));
+
 	if (!rs->grabIndex)
 	{
 	    rs->grabIndex = pushScreenGrab (s, s->invisibleCursor, "rotate");
diff --git a/src/paint.c b/src/paint.c
index a618328..713b2f5 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -157,7 +157,9 @@ paintScreenRegion (CompScreen	       *screen,
     static Region tmpRegion = NULL;
     CompWindow    *w;
     CompCursor	  *c;
-    int		  count, windowMask, backgroundMask;
+    int		  count, windowMask, backgroundMask, occlusionMask;
+    Bool ftb = (mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK) && 
+	      !(mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK);	// Do FTB drawing only if FTB flag is set and BTF flag isn't
 
     if (!tmpRegion)
     {
@@ -179,10 +181,29 @@ paintScreenRegion (CompScreen	       *screen,
 	count	       = 0;
     }
 
+    if (ftb)
+    {
+	windowMask |= PAINT_WINDOW_FRONT_TO_BACK_MASK;
+	occlusionMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK | 
+	               PAINT_WINDOW_FRONT_TO_BACK_MASK;
+    }
+    else
+    {
+	windowMask |= PAINT_WINDOW_BACK_TO_FRONT_MASK;
+	occlusionMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK | 
+	               PAINT_WINDOW_BACK_TO_FRONT_MASK;
+    }
+    
+
     XSubtractRegion (region, &emptyRegion, tmpRegion);
 
-    /* detect occlusions */
-    for (w = screen->reverseWindows; w; w = w->prev)
+    /* detect occlusions (order is reversed from true painting order). */
+    if (ftb)
+	w = screen->windows;
+    else
+	w = screen->reverseWindows;
+
+    for (; w; w = (ftb)? w->next: w->prev)
     {
 	if (w->destroyed)
 	    continue;
@@ -197,7 +218,7 @@ paintScreenRegion (CompScreen	       *screen,
 	XSubtractRegion (tmpRegion, &emptyRegion, w->clip);
 
 	if ((*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
-				    PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
+				   occlusionMask))
 	{
 	    /* unredirect top most fullscreen windows. */
 	    if (count == 0					      &&
@@ -216,8 +237,13 @@ paintScreenRegion (CompScreen	       *screen,
 
     (*screen->paintBackground) (screen, tmpRegion, backgroundMask);
 
-    /* paint all windows from bottom to top */
-    for (w = screen->windows; w; w = w->next)
+    /* paint all windows with the order specified by the masks. */
+    if (ftb)
+	w = screen->reverseWindows;
+    else
+	w = screen->windows;
+
+    for (; w; w = (ftb)? w->prev: w->next)
     {
 	if (w->destroyed)
 	    continue;
@@ -231,9 +257,22 @@ paintScreenRegion (CompScreen	       *screen,
 	(*screen->paintWindow) (w, &w->paint, transform, w->clip, windowMask);
     }
 
-    /* paint cursors */
-    for (c = screen->cursors; c; c = c->next)
-	(*screen->paintCursor) (c, transform, tmpRegion, 0);
+    if ((mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK) &&
+	(mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK))
+    {
+	/* when both modes are set, we first paint in Back-To-Front mode (already done), 
+           and after that we paint the screen in Front-To-Back mode, by removing the 
+           Back-To-Front mask. 
+           Painting the cursors will be done after the Front-To-Back drawing*/
+	paintScreenRegion (screen, transform, region, output, 
+	                   mask & (~PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK));	
+    }
+    else
+    {
+	/* paint cursors */
+	for (c = screen->cursors; c; c = c->next)
+	    (*screen->paintCursor) (c, transform, tmpRegion, 0);
+    }
 }
 
 
@@ -259,30 +298,11 @@ paintTransformedScreen (CompScreen		*screen,
 
     if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK)
     {
-	GLdouble h = screen->height;
-
-	GLdouble p1[2] = { region->extents.x1, h - region->extents.y2 };
-	GLdouble p2[2] = { region->extents.x2, h - region->extents.y1 };
-
-	GLdouble halfW = screen->outputDev[output].width / 2.0;
-	GLdouble halfH = screen->outputDev[output].height / 2.0;
-
-	GLdouble cx = screen->outputDev[output].region.extents.x1 + halfW;
-	GLdouble cy = (h - screen->outputDev[output].region.extents.y2) + halfH;
-
-	GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
-	GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
-	GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
-	GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
-
 	glPushMatrix ();
 	glLoadMatrixf (sTransform.m);
 
-	glClipPlane (GL_CLIP_PLANE0, top);
-	glClipPlane (GL_CLIP_PLANE1, bottom);
-	glClipPlane (GL_CLIP_PLANE2, left);
-	glClipPlane (GL_CLIP_PLANE3, right);
-
+	(*screen->setClipPlanes) (screen, region, output);
+	
 	glEnable (GL_CLIP_PLANE0);
 	glEnable (GL_CLIP_PLANE1);
 	glEnable (GL_CLIP_PLANE2);
@@ -1154,3 +1174,27 @@ paintBackground (CompScreen   *s,
 
     free (data);
 }
+
+void setClipPlanes (CompScreen *screen, Region region, int output)
+{
+    GLdouble h = screen->height;
+
+    GLdouble p1[2] = { region->extents.x1, h - region->extents.y2 };
+    GLdouble p2[2] = { region->extents.x2, h - region->extents.y1 };
+
+    GLdouble halfW = screen->outputDev[output].width / 2.0;
+    GLdouble halfH = screen->outputDev[output].height / 2.0;
+
+    GLdouble cx = screen->outputDev[output].region.extents.x1 + halfW;
+    GLdouble cy = (h - screen->outputDev[output].region.extents.y2) + halfH;
+
+    GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
+    GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
+    GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
+    GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
+
+    glClipPlane (GL_CLIP_PLANE0, top);
+    glClipPlane (GL_CLIP_PLANE1, bottom);
+    glClipPlane (GL_CLIP_PLANE2, left);
+    glClipPlane (GL_CLIP_PLANE3, right);
+}
diff --git a/src/screen.c b/src/screen.c
index 63d7189..482f0da 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1688,6 +1688,7 @@ addScreen (CompDisplay *display,
     s->getOutputExtentsForWindow  = getOutputExtentsForWindow;
     s->getAllowedActionsForWindow = getAllowedActionsForWindow;
     s->focusWindow		  = focusWindow;
+    s->setClipPlanes		  = setClipPlanes;
 
     s->paintCursor      = paintCursor;
     s->damageCursorRect	= damageCursorRect;