#ifndef _COMPIZ_H #define _COMPIZ_H -#define ABIVERSION 20070507 +#define ABIVERSION 20070508 #include #include @@ -1279,6 +1279,10 @@ typedef void (*PaintBackgroundProc) (CompScreen *screen, Region region, unsigned int mask); +typedef void (*SetClipPlanesProc) (CompScreen *screen, + Region region, + int output); + void preparePaintScreen (CompScreen *screen, int msSinceLastPaint); @@ -1379,6 +1383,10 @@ paintBackground (CompScreen *screen, Region region, unsigned int mask); +void setClipPlanes (CompScreen *screen, + Region region, + int output); + /* texture.c */ @@ -1958,6 +1966,7 @@ struct _CompScreen { PaintTransformedScreenProc paintTransformedScreen; ApplyScreenTransformProc applyScreenTransform; PaintBackgroundProc paintBackground; + SetClipPlanesProc setClipPlanes; PaintWindowProc paintWindow; DrawWindowProc drawWindow; AddWindowGeometryProc addWindowGeometry; diff --git a/plugins/cube.c b/plugins/cube.c index 833d33e..a4767ac 100644 --- a/plugins/cube.c +++ b/plugins/cube.c @@ -87,6 +87,7 @@ typedef struct _CubeScreen { ApplyScreenTransformProc applyScreenTransform; SetScreenOptionProc setScreenOption; OutputChangeNotifyProc outputChangeNotify; + SetClipPlanesProc setClipPlanes; CompOption opt[CUBE_SCREEN_OPTION_NUM]; @@ -1526,6 +1527,41 @@ cubePaintBackground (CompScreen *s, } } +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, @@ -1901,6 +1937,7 @@ cubeInitScreen (CompPlugin *p, WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform); WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption); WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify); + WRAP (cs, s, setClipPlanes, cubeSetClipPlanes); return TRUE; } @@ -1922,6 +1959,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/src/paint.c b/src/paint.c index b736cdf..a4679e0 100644 --- a/src/paint.c +++ b/src/paint.c @@ -266,29 +266,10 @@ 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); @@ -1185,3 +1166,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 469e437..0155bad 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1516,6 +1516,7 @@ addScreen (CompDisplay *display, s->paintTransformedScreen = paintTransformedScreen; s->applyScreenTransform = applyScreenTransform; s->paintBackground = paintBackground; + s->setClipPlanes = setClipPlanes; s->paintWindow = paintWindow; s->drawWindow = drawWindow; s->addWindowGeometry = addWindowGeometry;