Index: beryl-plugins/src/cube.c =================================================================== --- beryl-plugins/src/cube.c (Revision 1234) +++ beryl-plugins/src/cube.c (Arbeitskopie) @@ -181,6 +181,7 @@ DonePaintScreenProc donePaintScreen; PaintScreenProc paintScreen; PaintTransformedScreenProc paintTransformedScreen; + ApplyScreenTransformProc applyScreenTransform; PaintBackgroundProc paintBackground; SetScreenOptionProc setScreenOption; OutputChangeNotifyProc outputChangeNotify; @@ -223,6 +224,9 @@ int output[64]; int outputMask[64]; + float outputXScale, outputYScale; + float outputXOffset, outputYOffset; + Bool fullscreenOutput; } CubeScreen; @@ -1432,39 +1436,49 @@ unsigned int mask, int dx) { - int cubeOutput, dView; CUBE_SCREEN (s); - /* translate to cube output */ - cubeOutput = cs->outputMask[output]; + if (cs->nOutput > 1) + { + int cubeOutput, dView; - /* convert from window movement to viewport movement */ - dView = -dx; + /* translate to cube output */ + cubeOutput = cs->outputMask[output]; - cubeOutput += dView; + /* convert from window movement to viewport movement */ + dView = -dx; - dView = cubeOutput / cs->nOutput; - cubeOutput = cubeOutput % cs->nOutput; + cubeOutput += dView; - if (cubeOutput < 0) + dView = cubeOutput / cs->nOutput; + cubeOutput = cubeOutput % cs->nOutput; + + if (cubeOutput < 0) + { + cubeOutput += cs->nOutput; + dView--; + } + + /* translate back to beryl output */ + output = cs->output[cubeOutput]; + + moveScreenViewport (s, -dView, 0, FALSE); + (*s->paintTransformedScreen) (s, sAttrib, output, TRUE, mask); + moveScreenViewport (s, dView, 0, FALSE); + } + else { - cubeOutput += cs->nOutput; - dView--; + moveScreenViewport (s, dx, 0, FALSE); + (*s->paintTransformedScreen)(s, sAttrib, output, FALSE, mask); + moveScreenViewport (s, -dx, 0, FALSE); } - - /* translate back to beryl output */ - output = cs->output[cubeOutput]; - - moveScreenViewport (s, -dView, 0, FALSE); - (*s->paintTransformedScreen) (s, sAttrib, output, clipToOutput, mask); - moveScreenViewport (s, dView, 0, FALSE); } static void cubePaintTransformedScreen (CompScreen * s, const ScreenPaintAttrib * sAttrib, int output, - Bool clipToOutput, + Bool clipToOutput, unsigned int mask) { ScreenPaintAttrib sa = *sAttrib; @@ -1477,20 +1491,37 @@ hsize = s->hsize * cs->nOutput; size = hsize; - if ((cs->outputMask[output] < 0) && (sAttrib->xScale!=1.0f || sAttrib->yScale!=1.0f)) + if ((cs->nOutput != s->nOutputDev) && (sAttrib->xScale!=1.0f || sAttrib->yScale!=1.0f)) { - UNWRAP (cs, s, paintTransformedScreen); - (*s->paintTransformedScreen) (s, sAttrib, output, clipToOutput, mask); - WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen); - return; + cs->outputXScale = (float) s->width / s->outputDev[output].width; + cs->outputYScale = (float) s->height / s->outputDev[output].height; + + cs->outputXOffset = + (s->width / 2.0f - + (s->outputDev[output].region.extents.x1 + + s->outputDev[output].region.extents.x2) / 2.0f) / + (float) s->outputDev[output].width; + + cs->outputYOffset = + (s->height / 2.0f - + (s->outputDev[output].region.extents.y1 + + s->outputDev[output].region.extents.y2) / 2.0f) / + (float) s->outputDev[output].height; } - + else + { + cs->outputXScale = 1.0f; + cs->outputYScale = 1.0f; + cs->outputXOffset = 0.0f; + cs->outputYOffset = 0.0f; + } + cubeUpdateGeometry(s, s->hsize, cs->invert); if (cs->sky.name) { - if ((mask & PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK) && !output) - glClear (GL_STENCIL_BUFFER_BIT); + if (mask & PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK) + clearTargetOutput (s->display, GL_STENCIL_BUFFER_BIT); screenLighting (s, FALSE); @@ -1512,12 +1543,12 @@ glCallList (cs->skyListId); glPopMatrix (); } - else if (!output) + else { if (mask & PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK) - glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + clearTargetOutput (s->display, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); else - glClear (GL_COLOR_BUFFER_BIT); + clearTargetOutput (s->display, GL_COLOR_BUFFER_BIT); } mask &= ~PAINT_SCREEN_CLEAR_MASK; @@ -1621,11 +1652,17 @@ if (sAttrib->xRotate > 0.0f) { sa.yRotate += 360.0f / size; - translateRotateScreen (&sa); + (s->applyScreenTransform) (s, &sa, output); + glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f); + glScalef (cs->outputXScale, cs->outputYScale, 1.0f); sa.yRotate -= 360.0f / size; } else - translateRotateScreen (&sa); + { + (s->applyScreenTransform) (s, &sa, output); + glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f); + glScalef (cs->outputXScale, cs->outputYScale, 1.0f); + } glVertexPointer (3, GL_FLOAT, 0, cs->vertices); @@ -1849,7 +1886,26 @@ WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen); } + static void +cubeApplyScreenTransform (CompScreen *s, + const ScreenPaintAttrib *sAttrib, + int output) +{ + CUBE_SCREEN (s); + + glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f); + glScalef (cs->outputXScale, cs->outputYScale, 1.0f); + + UNWRAP (cs, s, applyScreenTransform); + (*s->applyScreenTransform) (s, sAttrib, output); + WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform); + + glScalef (1.0f / cs->outputXScale, 1.0f / cs->outputYScale, 1.0f); + glTranslatef (-cs->outputXOffset, cs->outputYOffset, 0.0f); +} + +static void cubePaintBackground (CompScreen * s, Region region, unsigned int mask) { CUBE_SCREEN (s); @@ -2271,6 +2327,7 @@ WRAP (cs, s, donePaintScreen, cubeDonePaintScreen); WRAP (cs, s, paintScreen, cubePaintScreen); WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen); + WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform); WRAP (cs, s, paintBackground, cubePaintBackground); WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption); WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify); @@ -2307,6 +2364,7 @@ UNWRAP (cs, s, donePaintScreen); UNWRAP (cs, s, paintScreen); UNWRAP (cs, s, paintTransformedScreen); + UNWRAP (cs, s, applyScreenTransform); UNWRAP (cs, s, paintBackground); UNWRAP (cs, s, setScreenOption); UNWRAP (cs, s, outputChangeNotify); Index: beryl-plugins/src/plane.c =================================================================== --- beryl-plugins/src/plane.c (Revision 1233) +++ beryl-plugins/src/plane.c (Arbeitskopie) @@ -298,8 +298,7 @@ double dx, dy, tx, ty; int vx, vy; - glClearColor (0.0, 0.0, 0.0, 1.0); - glClear (GL_COLOR_BUFFER_BIT); + clearTargetOutput (screen->display, GL_COLOR_BUFFER_BIT); compute_translation (ps, &dx, &dy); Index: beryl-core/include/beryl.h =================================================================== --- beryl-core/include/beryl.h (Revision 1234) +++ beryl-core/include/beryl.h (Arbeitskopie) @@ -26,7 +26,7 @@ #ifndef _BERYL_H #define _BERYL_H -#define BERYL_VERSION 23 +#define BERYL_VERSION 24 #define BERYL_ABI_INFO \ BERYL_VERSION, \ @@ -936,6 +936,10 @@ XEvent *event, CompOption *option); +void +clearTargetOutput (CompDisplay *display, + unsigned int mask); + /* paint.c */ #define MULTIPLY_USHORT(us1, us2) \ @@ -1003,6 +1007,9 @@ Bool clipToOutput, unsigned int mask); +typedef void (*ApplyScreenTransformProc) (CompScreen *screen, + const ScreenPaintAttrib *sAttrib, + int output); #define PAINT_WINDOW_SOLID_MASK (1 << 0) #define PAINT_WINDOW_TRANSLUCENT_MASK (1 << 1) @@ -1045,9 +1052,6 @@ donePaintScreen (CompScreen *screen); void -translateRotateScreen (const ScreenPaintAttrib *sa); - -void prepareXCoords (CompScreen *screen, int output, float z); @@ -1059,6 +1063,11 @@ Bool clipToOutput, unsigned int mask); +void +applyScreenTransform (CompScreen *screen, + const ScreenPaintAttrib *sAttrib, + int output); + Bool paintScreen (CompScreen *screen, const ScreenPaintAttrib *sAttrib, @@ -1566,6 +1575,8 @@ GLint stencilRef; + Bool cleared; + Bool lighting; Bool slowAnimations; @@ -1627,6 +1638,7 @@ DonePaintScreenProc donePaintScreen; PaintScreenProc paintScreen; PaintTransformedScreenProc paintTransformedScreen; + ApplyScreenTransformProc applyScreenTransform; PaintBackgroundProc paintBackground; PaintWindowProc paintWindow; AddWindowGeometryProc addWindowGeometry; @@ -1892,6 +1904,9 @@ int *x2, int *y2); +void clearScreenOutput (CompScreen *s, + int output, + unsigned int mask); /* window.c */ Index: beryl-core/src/display.c =================================================================== --- beryl-core/src/display.c (Revision 1234) +++ beryl-core/src/display.c (Arbeitskopie) @@ -89,6 +89,9 @@ static struct pollfd *watchPollFds = 0; static int nWatchFds = 0; +static CompScreen *targetScreen = NULL; +static int targetOutput = 0; + static Bool inHandleEvent = FALSE; static Bool shutDown = FALSE; @@ -1489,6 +1492,8 @@ if (!s->damageMask || s->timeLeft > timeToNextRedraw) continue; + targetScreen = s; + timeDiff = TIMEVALDIFF (&tv, &s->lastRedraw); /* handle clock rollback */ @@ -1552,6 +1557,9 @@ for (i = 0; i < s->nOutputDev; i++) { + targetScreen = s; + targetOutput = i; + if (s->nOutputDev > 1) { glViewport (s->outputDev[i].region.extents.x1, @@ -1645,6 +1653,9 @@ } } + targetScreen = NULL; + targetOutput = 0; + s->lastRedraw = tv; IPCS_lock = FALSE; @@ -2986,3 +2997,14 @@ return FALSE; } + +void +clearTargetOutput (CompDisplay *display, + unsigned int mask) +{ + if (targetScreen) + clearScreenOutput (targetScreen, + targetOutput, + mask); +} + Index: beryl-core/src/paint.c =================================================================== --- beryl-core/src/paint.c (Revision 1233) +++ beryl-core/src/paint.c (Arbeitskopie) @@ -49,19 +49,22 @@ } void -translateRotateScreen (const ScreenPaintAttrib * sa) +applyScreenTransform (CompScreen *screen, + const ScreenPaintAttrib *sAttrib, + int output) { - glTranslatef (sa->xTranslate, - sa->yTranslate, sa->zTranslate + sa->zCamera); + glTranslatef (sAttrib->xTranslate, + sAttrib->yTranslate, + sAttrib->zTranslate + sAttrib->zCamera); - glRotatef (sa->xRotate, 0.0f, 1.0f, 0.0f); - glRotatef (sa->vRotate, - 1.0f - sa->xRotate / 90.0f, 0.0f, sa->xRotate / 90.0f); - glRotatef (sa->yRotate, 0.0f, 1.0f, 0.0f); - glScalef(sa->xScale,sa->yScale,1.0f); + glRotatef (sAttrib->xRotate, 0.0f, 1.0f, 0.0f); + glRotatef (sAttrib->vRotate, + 1.0f - sAttrib->xRotate / 90.0f, + 0.0f, + sAttrib->xRotate / 90.0f); + glRotatef (sAttrib->yRotate, 0.0f, 1.0f, 0.0f); +} -} - void prepareXCoords (CompScreen *screen, int output, @@ -72,8 +75,7 @@ -1.0f / screen->outputDev[output].height, 1.0f); glTranslatef (-screen->outputDev[output].region.extents.x1, - -screen->outputDev[output].height - -screen->outputDev[output].region.extents.y1, + -screen->outputDev[output].region.extents.y2, 0.0f); } @@ -94,14 +96,14 @@ else clip = &screen->region; - if ((mask & PAINT_SCREEN_CLEAR_MASK) && !output) - glClear (GL_COLOR_BUFFER_BIT); + if (mask & PAINT_SCREEN_CLEAR_MASK) + clearTargetOutput (screen->display, GL_COLOR_BUFFER_BIT); screenLighting (screen, TRUE); glPushMatrix (); - translateRotateScreen (sAttrib); + (screen->applyScreenTransform) (screen, sAttrib, output); prepareXCoords (screen, output, -sAttrib->zTranslate); Index: beryl-core/src/screen.c =================================================================== --- beryl-core/src/screen.c (Revision 1234) +++ beryl-core/src/screen.c (Arbeitskopie) @@ -1220,6 +1220,7 @@ s->donePaintScreen = donePaintScreen; s->paintScreen = paintScreen; s->paintTransformedScreen = paintTransformedScreen; + s->applyScreenTransform = applyScreenTransform; s->paintBackground = paintBackground; s->paintWindow = paintWindow; s->addWindowGeometry = addWindowGeometry; @@ -3535,3 +3536,36 @@ { } +void +clearScreenOutput (CompScreen *s, + int output, + unsigned int mask) +{ + BoxPtr pBox = &s->outputDev[output].region.extents; + + if (pBox->x1 != 0 || + pBox->y1 != 0 || + pBox->x2 != s->width || + pBox->y2 != s->height) + { + glPushAttrib (GL_SCISSOR_BIT); + + glEnable (GL_SCISSOR_TEST); + glScissor (pBox->x1, + s->height - pBox->y2, + pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1); + glClear (mask); + + glPopAttrib (); + } + else + { + glClear (mask); + } +} +