Index: beryl-plugins/src/cube.c =================================================================== --- beryl-plugins/src/cube.c (Revision 1227) +++ beryl-plugins/src/cube.c (Arbeitskopie) @@ -183,6 +183,7 @@ PaintTransformedScreenProc paintTransformedScreen; PaintBackgroundProc paintBackground; SetScreenOptionProc setScreenOption; + OutputChangeNotifyProc outputChangeNotify; CompOption opt[CUBE_SCREEN_OPTION_NUM]; @@ -217,7 +218,13 @@ CubeCapInfo cubeCapBottom; CompTexture sky; + + int nOutput; + int output[64]; + int outputMask[64]; + Bool fullscreenOutput; + } CubeScreen; #define GET_CUBE_DISPLAY(d) \ @@ -291,8 +298,8 @@ height = svgDimension.height; if (scale) { - pw = s->width; - ph = s->height; + pw = (cs->nOutput > 1) ? s->outputDev[0].width : s->width; + ph = (cs->nOutput > 1) ? s->outputDev[0].height : s->height; } else { pw = width; ph = height; @@ -441,14 +448,26 @@ cubeLoadImg (CompScreen * s, CubeCapInfo *cubeCap, int n) { unsigned int width, height; + int pw, ph; CUBE_SCREEN (s); if (!cubeCap) return; - if (!cubeCap->imgNFile || cubeCap->pw != s->width || cubeCap->ph != s->height) + if (cs->nOutput != s->nOutputDev) { + pw = s->width; + ph = s->height; + } + else + { + pw = s->outputDev[0].width; + ph = s->outputDev[0].height; + } + + if (!cubeCap->imgNFile || cubeCap->pw != pw || cubeCap->ph != ph) + { finiTexture (s, &cubeCap->texture); initTexture (s, &cubeCap->texture); cubeFiniSvg (cubeCap, s); @@ -492,6 +511,8 @@ CUBE_SCREEN (s); + sides *= cs->nOutput; + distance = 0.5f / tanf (M_PI / sides); radius = 0.5f / sinf (M_PI / sides); @@ -537,7 +558,91 @@ return TRUE; } + static void +cubeUpdateOutputs (CompScreen *s) +{ + BoxPtr pBox0, pBox1; + int i, j, k, x; + + CUBE_SCREEN (s); + + k = 0; + + cs->fullscreenOutput = TRUE; + + for (i = 0; i < s->nOutputDev; i++) + { + cs->outputMask[i] = -1; + + if (s->outputDev[i].width != s->width && + s->outputDev[i].height != s->height) + cs->fullscreenOutput = FALSE; + + /* dimensions must match first output */ + if (s->outputDev[i].width != s->outputDev[0].width && + s->outputDev[i].height != s->outputDev[0].height) + continue; + + pBox0 = &s->outputDev[0].region.extents; + pBox1 = &s->outputDev[i].region.extents; + + /* top and bottom line must match first output */ + if (pBox0->y1 != pBox1->y1 || pBox0->y2 != pBox1->y2) + continue; + + k++; + + for (j = 0; j < s->nOutputDev; j++) + { + pBox0 = &s->outputDev[j].region.extents; + + /* must not intersect other output region */ + if (i != j && pBox0->x2 > pBox1->x1 && pBox0->x1 < pBox1->x2) + { + k--; + break; + } + } + } + + if (k != s->nOutputDev) + { + cs->nOutput = 1; + return; + } + + /* add output indices from left to right */ + j = 0; + for (;;) + { + x = MAXSHORT; + k = -1; + + for (i = 0; i < s->nOutputDev; i++) + { + if (cs->outputMask[i] != -1) + continue; + + if (s->outputDev[i].region.extents.x1 < x) + { + x = s->outputDev[i].region.extents.x1; + k = i; + } + } + + if (k < 0) + break; + + cs->outputMask[k] = j; + cs->output[j] = k; + + j++; + } + cs->nOutput = j; +} + +static void cubeUpdateSkyDomeTexture (CompScreen * screen) { CUBE_SCREEN (screen); @@ -1320,6 +1425,42 @@ } static void +cubeMoveViewportAndPaint (CompScreen *s, + const ScreenPaintAttrib *sAttrib, + int output, + Bool clipToOutput, + unsigned int mask, + int dx) +{ + int cubeOutput, dView; + CUBE_SCREEN (s); + + /* translate to cube output */ + cubeOutput = cs->outputMask[output]; + + /* convert from window movement to viewport movement */ + dView = -dx; + + cubeOutput += dView; + + 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, clipToOutput, mask); + moveScreenViewport (s, dView, 0, FALSE); +} + +static void cubePaintTransformedScreen (CompScreen * s, const ScreenPaintAttrib * sAttrib, int output, @@ -1327,12 +1468,15 @@ unsigned int mask) { ScreenPaintAttrib sa = *sAttrib; - int xMove = 0; - float size = s->hsize; + int hsize, xMove = 0; + float size; CUBE_SCREEN (s); - if (sAttrib->xScale!=1.0f || sAttrib->yScale!=1.0f) + hsize = s->hsize * cs->nOutput; + size = hsize; + + if ((cs->outputMask[output] < 0) && (sAttrib->xScale!=1.0f || sAttrib->yScale!=1.0f)) { UNWRAP (cs, s, paintTransformedScreen); (*s->paintTransformedScreen) (s, sAttrib, output, clipToOutput, mask); @@ -1401,18 +1545,18 @@ sa.xRotate = sAttrib->xRotate * cs->invert; if (sa.xRotate > 0.0f) { - cs->xrotations = (int)(s->hsize * sa.xRotate) / 360; - sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / s->hsize; + cs->xrotations = (int)(hsize * sa.xRotate) / 360; + sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / hsize; } else { - cs->xrotations = (int)(s->hsize * sa.xRotate) / 360; + cs->xrotations = (int)(hsize * sa.xRotate) / 360; sa.xRotate = sa.xRotate - - (360.0f * cs->xrotations) / s->hsize + 360.0f / s->hsize; + (360.0f * cs->xrotations) / s->hsize + 360.0f / hsize; cs->xrotations--; } - sa.xRotate = sa.xRotate / size * s->hsize; + sa.xRotate = sa.xRotate / size * hsize; } else if (cs->opt[CUBE_SCREEN_OPTION_VIEWPORT_SLIDE].value.b && (sa.vRotate == 0.0f @@ -1426,17 +1570,17 @@ sa.xRotate = sAttrib->xRotate * cs->invert; if (sa.xRotate > 0.0f) { - cs->xrotations = (int)(s->hsize * sa.xRotate) / 360; - sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / s->hsize; + cs->xrotations = (int)(hsize * sa.xRotate) / 360; + sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / hsize; } else { - cs->xrotations = (int)(s->hsize * sa.xRotate) / 360; + cs->xrotations = (int)(hsize * sa.xRotate) / 360; sa.xRotate = sa.xRotate - - (360.0f * cs->xrotations) / s->hsize + 360.0f / s->hsize; + (360.0f * cs->xrotations) / hsize + 360.0f / hsize; cs->xrotations--; } - sa.xRotate = sa.xRotate / size * s->hsize; + sa.xRotate = sa.xRotate / size * hsize; } else { @@ -1463,7 +1607,7 @@ } } - if (cs->grabIndex == 0 && + if (cs->grabIndex == 0 && (hsize > 2) && (cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f) && cs->opt[CUBE_SCREEN_OPTION_DRAW_CAPS].value.b) { @@ -1486,10 +1630,10 @@ glNormal3f (0.0f, -1.0f, 0.0f); - if (s->hsize != 4 && cs->invert != 1) + if (hsize != 4 && cs->invert != 1) glRotatef (180.0f, 0.0f, 1.0f, 0.0f); - if (s->hsize == 4) + if (hsize == 4) { // change to stop the old, buggy rotation int alpha = ((int)(4 * oldRotate) / 360); @@ -1529,7 +1673,7 @@ } } - if (s->hsize == 4 && cs->invert == 1 && cs->cubeCapTop.texture.name) + if (hsize == 4 && cs->invert == 1 && cs->cubeCapTop.texture.name) { enableTexture (s, &cs->cubeCapTop.texture, COMP_TEXTURE_FILTER_GOOD); glTexCoordPointer (2, GL_FLOAT, 0, (cs->invert == 1) ? cs->tc : cs->tc_in); @@ -1537,7 +1681,7 @@ glDisableClientState (GL_TEXTURE_COORD_ARRAY); disableTexture (s, &cs->cubeCapTop.texture); } - else if (s->hsize == 4 && cs->invert != 1 && cs->cubeCapBottom.texture.name) + else if (hsize == 4 && cs->invert != 1 && cs->cubeCapBottom.texture.name) { enableTexture (s, &cs->cubeCapBottom.texture, COMP_TEXTURE_FILTER_GOOD); glTexCoordPointer (2, GL_FLOAT, 0, (cs->invert == 1) ? cs->tc : cs->tc_in); @@ -1552,10 +1696,10 @@ glNormal3f (0.0f, 1.0f, 0.0f); - if (s->hsize == 4) + if (hsize == 4) glRotatef (270.0f, 0.0f, 1.0f, 0.0f); - if (s->hsize == 4 && cs->invert == 1 && cs->cubeCapBottom.texture.name) + if (hsize == 4 && cs->invert == 1 && cs->cubeCapBottom.texture.name) { enableTexture (s, &cs->cubeCapBottom.texture, COMP_TEXTURE_FILTER_GOOD); glEnableClientState (GL_TEXTURE_COORD_ARRAY); @@ -1565,7 +1709,7 @@ glDisableClientState (GL_TEXTURE_COORD_ARRAY); disableTexture (s, &cs->cubeCapBottom.texture); } - else if (s->hsize == 4 && cs->invert != 1 && cs->cubeCapTop.texture.name) + else if (hsize == 4 && cs->invert != 1 && cs->cubeCapTop.texture.name) { enableTexture (s, &cs->cubeCapTop.texture, COMP_TEXTURE_FILTER_GOOD); glEnableClientState (GL_TEXTURE_COORD_ARRAY); @@ -1592,20 +1736,20 @@ /* outside cube */ if (cs->invert == 1) { - if (cs->grabIndex || s->hsize > 4) + if (cs->grabIndex || hsize > 4) { GLenum filter; int i; float yRot = sa.yRotate; - xMove = cs->xrotations - ((s->hsize >> 1) - 1); - sa.yRotate += (360.0f / size) * ((s->hsize >> 1) - 1); + xMove = cs->xrotations - ((hsize >> 1) - 1); + sa.yRotate += (360.0f / size) * ((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->hsize; i++) + for (i = 0; i < hsize; i++) { if (xMove != cs->xrotations + 1) { @@ -1669,20 +1813,18 @@ if (sa.xRotate > 180.0f / size) { - xMove -= ((s->hsize >> 1) - 2); - sa.yRotate -= (360.0f / size) * ((s->hsize >> 1) - 2); + xMove -= ((hsize >> 1) - 2); + sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 2); } else { - xMove -= ((s->hsize >> 1) - 1); - sa.yRotate -= (360.0f / size) * ((s->hsize >> 1) - 1); + xMove -= ((hsize >> 1) - 1); + sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 1); } - for (i = 0; i < s->hsize; i++) + for (i = 0; i < hsize; i++) { - moveScreenViewport (s, xMove, 0, FALSE); - (*s->paintTransformedScreen) (s, &sa, output, clipToOutput, mask); - moveScreenViewport (s, -xMove, 0, FALSE); + cubeMoveViewportAndPaint (s, &sa, output, clipToOutput, mask, xMove); sa.yRotate += 360.0f / size; xMove++; @@ -1692,23 +1834,18 @@ } else { - moveScreenViewport (s, xMove, 0, FALSE); - (*s->paintTransformedScreen) (s, &sa, output, clipToOutput, mask); - moveScreenViewport (s, -xMove, 0, FALSE); + cubeMoveViewportAndPaint (s, &sa, output, clipToOutput, mask, xMove); sa.yRotate += 360.0f / size; xMove = -cs->xrotations; - moveScreenViewport (s, xMove, 0, FALSE); - (*s->paintTransformedScreen) (s, &sa, output, clipToOutput, mask); + cubeMoveViewportAndPaint (s, &sa, output, clipToOutput, mask, xMove); moveScreenViewport (s, -xMove, 0, FALSE); sa.yRotate += 360.0f / size; xMove = 1 - cs->xrotations; - moveScreenViewport (s, xMove, 0, FALSE); - (*s->paintTransformedScreen) (s, &sa, output, clipToOutput, mask); - moveScreenViewport (s, -xMove, 0, FALSE); + cubeMoveViewportAndPaint (s, &sa, output, clipToOutput, mask, xMove); } } @@ -1742,7 +1879,7 @@ { CUBE_SCREEN (s); - if (s->hsize < 4) + if (s->hsize * cs->nOutput < 4) return FALSE; if (otherScreenGrabExist (s, "rotate", "switcher", "cube", 0)) @@ -1861,6 +1998,19 @@ return FALSE; } +static void +cubeOutputChangeNotify (CompScreen *s) +{ + CUBE_SCREEN (s); + + cubeUpdateOutputs (s); + cubeUpdateGeometry (s, s->hsize, cs->invert); + + UNWRAP (cs, s, outputChangeNotify); + (*s->outputChangeNotify) (s); + WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify); +} + static Bool cubeSetGlobalScreenOption (CompScreen * s, char *name, CompOptionValue * value) @@ -2126,7 +2276,10 @@ WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen); WRAP (cs, s, paintBackground, cubePaintBackground); WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption); + WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify); + cubeUpdateOutputs (s); + if (!cubeUpdateGeometry (s, s->hsize, cs->invert)) return FALSE; @@ -2159,6 +2312,7 @@ UNWRAP (cs, s, paintTransformedScreen); UNWRAP (cs, s, paintBackground); UNWRAP (cs, s, setScreenOption); + UNWRAP (cs, s, outputChangeNotify); finiTexture (s, &cs->cubeCapTop.texture); finiTexture (s, &cs->cubeCapBottom.texture); Index: beryl-plugins/src/water.c =================================================================== --- beryl-plugins/src/water.c (Revision 1227) +++ beryl-plugins/src/water.c (Arbeitskopie) @@ -446,7 +446,7 @@ s->rasterX = s->rasterY = 0; - glViewport (0, 0, s->width, s->height); + setDefaultViewport (s); glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); Index: beryl-core/include/beryl.h =================================================================== --- beryl-core/include/beryl.h (Revision 1227) +++ beryl-core/include/beryl.h (Arbeitskopie) @@ -26,7 +26,7 @@ #ifndef _BERYL_H #define _BERYL_H -#define BERYL_VERSION 22 +#define BERYL_VERSION 23 #define BERYL_ABI_INFO \ BERYL_VERSION, \ @@ -1388,6 +1388,8 @@ typedef void (*WindowStateChangeNotifyProc) (CompWindow *window); +typedef void (*OutputChangeNotifyProc) (CompScreen *s); + #define COMP_SCREEN_DAMAGE_PENDING_MASK (1 << 0) #define COMP_SCREEN_DAMAGE_REGION_MASK (1 << 1) #define COMP_SCREEN_DAMAGE_ALL_MASK (1 << 2) @@ -1641,6 +1643,8 @@ WindowStateChangeNotifyProc windowStateChangeNotify; + OutputChangeNotifyProc outputChangeNotify; + CompPrivate *privates; Window overlay; @@ -1692,6 +1696,8 @@ void screenGetOutputDevWorkArea (CompScreen *s, int outputDev, XRectangle *workArea); +void setDefaultViewport (CompScreen *s); + Bool addScreen (CompDisplay *display, int screenNum, @@ -2271,6 +2277,9 @@ void windowStateChangeNotify (CompWindow *w); +void +outputChangeNotify (CompScreen *s); + void moveInputFocusToWindow (CompWindow *w); Index: beryl-core/src/display.c =================================================================== --- beryl-core/src/display.c (Revision 1227) +++ beryl-core/src/display.c (Arbeitskopie) @@ -1568,102 +1568,83 @@ &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) { XIntersectRegion (tmpRegion, &s->outputDev[i].region, outputRegion); - - if ((*s->paintScreen) (s, + if (!(*s->paintScreen) (s, &defaultScreenPaintAttrib, + outputRegion, i, PAINT_SCREEN_REGION_MASK)) + { + (*s->paintScreen) (s, &defaultScreenPaintAttrib, - outputRegion, i, - PAINT_SCREEN_REGION_MASK)) - { - BoxPtr pBox; - int nBox, y; + &s->outputDev[i].region, i, + PAINT_SCREEN_FULL_MASK); - pBox = outputRegion->rects; - nBox = outputRegion->numRects; + XUnionRegion (tmpRegion, &s->outputDev[i].region, + tmpRegion); + } + } + } - waitForVideoSync (s); + waitForVideoSync (s); - if (s->copySubBuffer) - { - while (nBox--) - { - y = s->height - pBox->y2; + if (mask & COMP_SCREEN_DAMAGE_ALL_MASK) + { + glXSwapBuffers (display->display, s->output); + } + else + { + BoxPtr pBox; + int nBox, y; - (*s->copySubBuffer) (display->display, - s->output, - pBox->x1, y, - pBox->x2 - - pBox->x1, - pBox->y2 - - pBox->y1); + pBox = tmpRegion->rects; + nBox = tmpRegion->numRects; - pBox++; - } - } - else - { - glEnable (GL_SCISSOR_TEST); - glDrawBuffer (GL_FRONT); + if (s->copySubBuffer) + { + while (nBox--) + { + y = s->height - pBox->y2; - while (nBox--) - { - y = s->height - pBox->y2; + (*s->copySubBuffer) (display->display, s->output, + pBox->x1, y, pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1); - glBitmap (0, 0, 0, 0, - pBox->x1 - s->rasterX, - y - s->rasterY, - NULL); + pBox++; + } + } + else + { + glEnable (GL_SCISSOR_TEST); + glDrawBuffer (GL_FRONT); - s->rasterX = pBox->x1; - s->rasterY = y; + while (nBox--) + { + y = s->height - pBox->y2; - glScissor (pBox->x1, y, - pBox->x2 - pBox->x1, - pBox->y2 - pBox->y1); + glBitmap (0, 0, 0, 0, pBox->x1 - s->rasterX, + y - s->rasterY, NULL); - glCopyPixels (pBox->x1, y, - pBox->x2 - pBox->x1, - pBox->y2 - pBox->y1, - GL_COLOR); + s->rasterX = pBox->x1; + s->rasterY = y; - pBox++; - } + glScissor (pBox->x1, y, pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1); - glDrawBuffer (GL_BACK); - glDisable (GL_SCISSOR_TEST); - glFlush (); - } - } - else - { - (*s->paintScreen) (s, - &defaultScreenPaintAttrib, - &s->outputDev[i].region, i, - PAINT_SCREEN_FULL_MASK); + glCopyPixels (pBox->x1, y, pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1, GL_COLOR); - if (i + 1 == s->nOutputDev) - { - waitForVideoSync (s); - glXSwapBuffers (display->display, - s->output); - } + pBox++; } + + glDrawBuffer (GL_BACK); + glDisable (GL_SCISSOR_TEST); + glFlush (); } } - glDisable(GL_SCISSOR_TEST); - s->lastRedraw = tv; IPCS_lock = FALSE; Index: beryl-core/src/screen.c =================================================================== --- beryl-core/src/screen.c (Revision 1227) +++ beryl-core/src/screen.c (Arbeitskopie) @@ -633,6 +633,11 @@ s->outputDev = output; s->nOutputDev = nOutput; + + setDefaultViewport (s); + damageScreen (s); + + (*s->outputChangeNotify) (s); } void @@ -1231,6 +1236,8 @@ s->windowStateChangeNotify = windowStateChangeNotify; + s->outputChangeNotify = outputChangeNotify; + s->getProcAddress = 0; if (!XGetWindowAttributes (dpy, s->root, &s->attrib)) @@ -3516,3 +3523,15 @@ if (y2) *y2 = s->outputDev[s->currentOutputDev].region.extents.y2; } + +void setDefaultViewport (CompScreen *s) +{ + glViewport (s->outputDev[0].region.extents.x1, + s->height - s->outputDev[0].region.extents.y2, + s->outputDev[0].width, s->outputDev[0].height); +} + +void outputChangeNotify (CompScreen *s) +{ +} +