You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2234 lines
53 KiB
2234 lines
53 KiB
/*
|
|
* Copyright © 2005 Novell, 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
|
|
* Novell, Inc. not be used in advertising or publicity pertaining to
|
|
* distribution of the software without specific, written prior permission.
|
|
* Novell, Inc. makes no representations about the suitability of this
|
|
* software for any purpose. It is provided "as is" without express or
|
|
* implied warranty.
|
|
*
|
|
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
|
* NO EVENT SHALL NOVELL, 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: David Reveman <davidr@novell.com>
|
|
* Mirco Müller <macslow@bangang.de> (Skydome support)
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Xproto.h>
|
|
|
|
#include <compiz-cube.h>
|
|
|
|
static CompMetadata cubeMetadata;
|
|
|
|
static int cubeCorePrivateIndex;
|
|
static int cubeDisplayPrivateIndex;
|
|
|
|
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
|
|
|
|
static void
|
|
cubeLoadImg (CompScreen *s,
|
|
int n)
|
|
{
|
|
unsigned int width, height;
|
|
int pw, ph;
|
|
CompOptionValue *imgFiles;
|
|
int imgNFile;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
imgFiles = cs->opt[CUBE_SCREEN_OPTION_IMAGES].value.list.value;
|
|
imgNFile = cs->opt[CUBE_SCREEN_OPTION_IMAGES].value.list.nValue;
|
|
|
|
if (!cs->fullscreenOutput)
|
|
{
|
|
pw = s->width;
|
|
ph = s->height;
|
|
}
|
|
else
|
|
{
|
|
pw = s->outputDev[0].width;
|
|
ph = s->outputDev[0].height;
|
|
}
|
|
|
|
if (!imgNFile || cs->pw != pw || cs->ph != ph)
|
|
{
|
|
finiTexture (s, &cs->texture);
|
|
initTexture (s, &cs->texture);
|
|
|
|
if (!imgNFile)
|
|
return;
|
|
}
|
|
|
|
cs->imgCurFile = n % imgNFile;
|
|
|
|
if (!readImageToTexture (s, &cs->texture,
|
|
imgFiles[cs->imgCurFile].s,
|
|
&width, &height))
|
|
{
|
|
compLogMessage ("cube", CompLogLevelWarn,
|
|
"Failed to load slide: %s",
|
|
imgFiles[cs->imgCurFile].s);
|
|
|
|
finiTexture (s, &cs->texture);
|
|
initTexture (s, &cs->texture);
|
|
|
|
return;
|
|
}
|
|
|
|
cs->tc[0] = COMP_TEX_COORD_X (&cs->texture.matrix, width / 2.0f);
|
|
cs->tc[1] = COMP_TEX_COORD_Y (&cs->texture.matrix, height / 2.0f);
|
|
|
|
if (cs->opt[CUBE_SCREEN_OPTION_SCALE_IMAGE].value.b)
|
|
{
|
|
cs->tc[2] = COMP_TEX_COORD_X (&cs->texture.matrix, width);
|
|
cs->tc[3] = COMP_TEX_COORD_Y (&cs->texture.matrix, 0.0f);
|
|
|
|
cs->tc[4] = COMP_TEX_COORD_X (&cs->texture.matrix, 0.0f);
|
|
cs->tc[5] = COMP_TEX_COORD_Y (&cs->texture.matrix, 0.0f);
|
|
|
|
cs->tc[6] = COMP_TEX_COORD_X (&cs->texture.matrix, 0.0f);
|
|
cs->tc[7] = COMP_TEX_COORD_Y (&cs->texture.matrix, height);
|
|
|
|
cs->tc[8] = COMP_TEX_COORD_X (&cs->texture.matrix, width);
|
|
cs->tc[9] = COMP_TEX_COORD_Y (&cs->texture.matrix, height);
|
|
|
|
cs->tc[10] = COMP_TEX_COORD_X (&cs->texture.matrix, width);
|
|
cs->tc[11] = COMP_TEX_COORD_Y (&cs->texture.matrix, 0.0f);
|
|
}
|
|
else
|
|
{
|
|
float x1 = width / 2.0f - pw / 2.0f;
|
|
float y1 = height / 2.0f - ph / 2.0f;
|
|
float x2 = width / 2.0f + pw / 2.0f;
|
|
float y2 = height / 2.0f + ph / 2.0f;
|
|
|
|
cs->tc[2] = COMP_TEX_COORD_X (&cs->texture.matrix, x2);
|
|
cs->tc[3] = COMP_TEX_COORD_Y (&cs->texture.matrix, y1);
|
|
|
|
cs->tc[4] = COMP_TEX_COORD_X (&cs->texture.matrix, x1);
|
|
cs->tc[5] = COMP_TEX_COORD_Y (&cs->texture.matrix, y1);
|
|
|
|
cs->tc[6] = COMP_TEX_COORD_X (&cs->texture.matrix, x1);
|
|
cs->tc[7] = COMP_TEX_COORD_Y (&cs->texture.matrix, y2);
|
|
|
|
cs->tc[8] = COMP_TEX_COORD_X (&cs->texture.matrix, x2);
|
|
cs->tc[9] = COMP_TEX_COORD_Y (&cs->texture.matrix, y2);
|
|
|
|
cs->tc[10] = COMP_TEX_COORD_X (&cs->texture.matrix, x2);
|
|
cs->tc[11] = COMP_TEX_COORD_Y (&cs->texture.matrix, y1);
|
|
}
|
|
}
|
|
|
|
static Bool
|
|
cubeUpdateGeometry (CompScreen *s,
|
|
int sides,
|
|
Bool invert)
|
|
{
|
|
GLfloat radius, distance;
|
|
GLfloat *v;
|
|
int i, n;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
sides *= cs->nOutput;
|
|
|
|
distance = 0.5f / tanf (M_PI / sides);
|
|
radius = 0.5f / sinf (M_PI / sides);
|
|
|
|
n = (sides + 2) * 2;
|
|
|
|
if (cs->nVertices != n)
|
|
{
|
|
v = realloc (cs->vertices, sizeof (GLfloat) * n * 3);
|
|
if (!v)
|
|
return FALSE;
|
|
|
|
cs->nVertices = n;
|
|
cs->vertices = v;
|
|
}
|
|
else
|
|
v = cs->vertices;
|
|
|
|
*v++ = 0.0f;
|
|
*v++ = 0.5 * invert;
|
|
*v++ = 0.0f;
|
|
|
|
for (i = 0; i <= sides; i++)
|
|
{
|
|
*v++ = radius * sinf (i * 2 * M_PI / sides + M_PI / sides);
|
|
*v++ = 0.5 * invert;
|
|
*v++ = radius * cosf (i * 2 * M_PI / sides + M_PI / sides);
|
|
}
|
|
|
|
*v++ = 0.0f;
|
|
*v++ = -0.5 * invert;
|
|
*v++ = 0.0f;
|
|
|
|
for (i = sides; i >= 0; i--)
|
|
{
|
|
*v++ = radius * sinf (i * 2 * M_PI / sides + M_PI / sides);
|
|
*v++ = -0.5 * invert;
|
|
*v++ = radius * cosf (i * 2 * M_PI / sides + M_PI / sides);
|
|
}
|
|
|
|
cs->invert = invert;
|
|
cs->distance = distance;
|
|
|
|
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;
|
|
|
|
/* 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 (cs->moMode == CUBE_MOMODE_ONE)
|
|
{
|
|
cs->fullscreenOutput = FALSE;
|
|
cs->nOutput = 1;
|
|
return;
|
|
}
|
|
|
|
if (cs->moMode == CUBE_MOMODE_MULTI)
|
|
{
|
|
cs->fullscreenOutput = TRUE;
|
|
cs->nOutput = 1;
|
|
return;
|
|
}
|
|
|
|
if (k != s->nOutputDev)
|
|
{
|
|
cs->fullscreenOutput = FALSE;
|
|
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;
|
|
|
|
if (cs->nOutput == 1)
|
|
{
|
|
if (s->outputDev[0].width != s->width ||
|
|
s->outputDev[0].height != s->height)
|
|
cs->fullscreenOutput = FALSE;
|
|
}
|
|
}
|
|
|
|
static CompOption *
|
|
cubeGetScreenOptions (CompPlugin *plugin,
|
|
CompScreen *screen,
|
|
int *count)
|
|
{
|
|
CUBE_SCREEN (screen);
|
|
|
|
*count = NUM_OPTIONS (cs);
|
|
return cs->opt;
|
|
}
|
|
|
|
static void
|
|
cubeUpdateSkyDomeTexture (CompScreen *screen)
|
|
{
|
|
CUBE_SCREEN (screen);
|
|
|
|
finiTexture (screen, &cs->sky);
|
|
initTexture (screen, &cs->sky);
|
|
|
|
if (!cs->opt[CUBE_SCREEN_OPTION_SKYDOME].value.b)
|
|
return;
|
|
|
|
if (strlen (cs->opt[CUBE_SCREEN_OPTION_SKYDOME_IMG].value.s) == 0 ||
|
|
!readImageToTexture (screen,
|
|
&cs->sky,
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_IMG].value.s,
|
|
&cs->skyW,
|
|
&cs->skyH))
|
|
{
|
|
GLfloat aaafTextureData[128][128][3];
|
|
GLfloat fRStart = (GLfloat)
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_GRAD_START].value.c[0] / 0xffff;
|
|
GLfloat fGStart = (GLfloat)
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_GRAD_START].value.c[1] / 0xffff;
|
|
GLfloat fBStart = (GLfloat)
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_GRAD_START].value.c[2] / 0xffff;
|
|
GLfloat fREnd = (GLfloat)
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_GRAD_END].value.c[0] / 0xffff;
|
|
GLfloat fGEnd = (GLfloat)
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_GRAD_END].value.c[1] / 0xffff;
|
|
GLfloat fBEnd = (GLfloat)
|
|
cs->opt[CUBE_SCREEN_OPTION_SKYDOME_GRAD_END].value.c[2] / 0xffff;
|
|
GLfloat fRStep = (fREnd - fRStart) / 128.0f;
|
|
GLfloat fGStep = (fGEnd - fGStart) / 128.0f;
|
|
GLfloat fBStep = (fBStart - fBEnd) / 128.0f;
|
|
GLfloat fR = fRStart;
|
|
GLfloat fG = fGStart;
|
|
GLfloat fB = fBStart;
|
|
|
|
int iX, iY;
|
|
|
|
for (iX = 127; iX >= 0; iX--)
|
|
{
|
|
fR += fRStep;
|
|
fG += fGStep;
|
|
fB -= fBStep;
|
|
|
|
for (iY = 0; iY < 128; iY++)
|
|
{
|
|
aaafTextureData[iX][iY][0] = fR;
|
|
aaafTextureData[iX][iY][1] = fG;
|
|
aaafTextureData[iX][iY][2] = fB;
|
|
}
|
|
}
|
|
|
|
cs->sky.target = GL_TEXTURE_2D;
|
|
cs->sky.filter = GL_LINEAR;
|
|
cs->sky.wrap = GL_CLAMP_TO_EDGE;
|
|
|
|
cs->sky.matrix.xx = 1.0 / 128.0;
|
|
cs->sky.matrix.yy = -1.0 / 128.0;
|
|
cs->sky.matrix.xy = 0;
|
|
cs->sky.matrix.yx = 0;
|
|
cs->sky.matrix.x0 = 0;
|
|
cs->sky.matrix.y0 = 1.0;
|
|
|
|
cs->skyW = 128;
|
|
cs->skyH = 128;
|
|
|
|
glGenTextures (1, &cs->sky.name);
|
|
glBindTexture (cs->sky.target, cs->sky.name);
|
|
|
|
glTexParameteri (cs->sky.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri (cs->sky.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri (cs->sky.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri (cs->sky.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexImage2D (cs->sky.target,
|
|
0,
|
|
GL_RGB,
|
|
128,
|
|
128,
|
|
0,
|
|
GL_RGB,
|
|
GL_FLOAT,
|
|
aaafTextureData);
|
|
|
|
glBindTexture (cs->sky.target, 0);
|
|
}
|
|
}
|
|
|
|
static Bool
|
|
fillCircleTable (GLfloat **ppSint,
|
|
GLfloat **ppCost,
|
|
const int n)
|
|
{
|
|
const GLfloat angle = 2 * M_PI / (GLfloat) ((n == 0) ? 1 : n);
|
|
const int size = abs (n);
|
|
int i;
|
|
|
|
*ppSint = (GLfloat *) calloc (sizeof (GLfloat), size + 1);
|
|
*ppCost = (GLfloat *) calloc (sizeof (GLfloat), size + 1);
|
|
|
|
if (!(*ppSint) || !(*ppCost))
|
|
{
|
|
free (*ppSint);
|
|
free (*ppCost);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
(*ppSint)[0] = 0.0;
|
|
(*ppCost)[0] = 1.0;
|
|
|
|
for (i = 1; i < size; i++)
|
|
{
|
|
(*ppSint)[i] = sin (angle * i);
|
|
(*ppCost)[i] = cos (angle * i);
|
|
}
|
|
|
|
(*ppSint)[size] = (*ppSint)[0];
|
|
(*ppCost)[size] = (*ppCost)[0];
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
cubeUpdateSkyDomeList (CompScreen *s,
|
|
GLfloat fRadius)
|
|
{
|
|
GLint iSlices = 128;
|
|
GLint iStacks = 64;
|
|
GLfloat afTexCoordX[4];
|
|
GLfloat afTexCoordY[4];
|
|
GLfloat *sint1;
|
|
GLfloat *cost1;
|
|
GLfloat *sint2;
|
|
GLfloat *cost2;
|
|
GLfloat r;
|
|
GLfloat x;
|
|
GLfloat y;
|
|
GLfloat z;
|
|
int i;
|
|
int j;
|
|
int iStacksStart;
|
|
int iStacksEnd;
|
|
int iSlicesStart;
|
|
int iSlicesEnd;
|
|
GLfloat fStepX;
|
|
GLfloat fStepY;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->opt[CUBE_SCREEN_OPTION_SKYDOME_ANIM].value.b)
|
|
{
|
|
iStacksStart = 11; /* min. 0 */
|
|
iStacksEnd = 53; /* max. 64 */
|
|
iSlicesStart = 0; /* min. 0 */
|
|
iSlicesEnd = 128; /* max. 128 */
|
|
}
|
|
else
|
|
{
|
|
iStacksStart = 21; /* min. 0 */
|
|
iStacksEnd = 43; /* max. 64 */
|
|
iSlicesStart = 21; /* min. 0 */
|
|
iSlicesEnd = 44; /* max. 128 */
|
|
}
|
|
|
|
fStepX = 1.0 / (GLfloat) (iSlicesEnd - iSlicesStart);
|
|
fStepY = 1.0 / (GLfloat) (iStacksEnd - iStacksStart);
|
|
|
|
if (!fillCircleTable (&sint1, &cost1, -iSlices))
|
|
return;
|
|
|
|
if (!fillCircleTable (&sint2, &cost2, iStacks * 2))
|
|
{
|
|
free (sint1);
|
|
free (cost1);
|
|
return;
|
|
}
|
|
|
|
afTexCoordX[0] = 1.0f;
|
|
afTexCoordY[0] = 1.0f - fStepY;
|
|
afTexCoordX[1] = 1.0f - fStepX;
|
|
afTexCoordY[1] = 1.0f - fStepY;
|
|
afTexCoordX[2] = 1.0f - fStepX;
|
|
afTexCoordY[2] = 1.0f;
|
|
afTexCoordX[3] = 1.0f;
|
|
afTexCoordY[3] = 1.0f;
|
|
|
|
if (!cs->skyListId)
|
|
cs->skyListId = glGenLists (1);
|
|
|
|
glNewList (cs->skyListId, GL_COMPILE);
|
|
|
|
enableTexture (s, &cs->sky, COMP_TEXTURE_FILTER_GOOD);
|
|
|
|
glBegin (GL_QUADS);
|
|
|
|
for (i = iStacksStart; i < iStacksEnd; i++)
|
|
{
|
|
afTexCoordX[0] = 1.0f;
|
|
afTexCoordX[1] = 1.0f - fStepX;
|
|
afTexCoordX[2] = 1.0f - fStepX;
|
|
afTexCoordX[3] = 1.0f;
|
|
|
|
for (j = iSlicesStart; j < iSlicesEnd; j++)
|
|
{
|
|
/* bottom-right */
|
|
z = cost2[i];
|
|
r = sint2[i];
|
|
x = cost1[j];
|
|
y = sint1[j];
|
|
|
|
glTexCoord2f (
|
|
COMP_TEX_COORD_X (&cs->sky.matrix, afTexCoordX[3] * cs->skyW),
|
|
COMP_TEX_COORD_Y (&cs->sky.matrix, afTexCoordY[3] * cs->skyH));
|
|
glVertex3f (x * r * fRadius, y * r * fRadius, z * fRadius);
|
|
|
|
/* top-right */
|
|
z = cost2[i + 1];
|
|
r = sint2[i + 1];
|
|
x = cost1[j];
|
|
y = sint1[j];
|
|
|
|
glTexCoord2f (
|
|
COMP_TEX_COORD_X (&cs->sky.matrix, afTexCoordX[0] * cs->skyW),
|
|
COMP_TEX_COORD_Y (&cs->sky.matrix, afTexCoordY[0] * cs->skyH));
|
|
glVertex3f (x * r * fRadius, y * r * fRadius, z * fRadius);
|
|
|
|
/* top-left */
|
|
z = cost2[i + 1];
|
|
r = sint2[i + 1];
|
|
x = cost1[j + 1];
|
|
y = sint1[j + 1];
|
|
|
|
glTexCoord2f (
|
|
COMP_TEX_COORD_X (&cs->sky.matrix, afTexCoordX[1] * cs->skyW),
|
|
COMP_TEX_COORD_Y (&cs->sky.matrix, afTexCoordY[1] * cs->skyH));
|
|
glVertex3f (x * r * fRadius, y * r * fRadius, z * fRadius);
|
|
|
|
/* bottom-left */
|
|
z = cost2[i];
|
|
r = sint2[i];
|
|
x = cost1[j + 1];
|
|
y = sint1[j + 1];
|
|
|
|
glTexCoord2f (
|
|
COMP_TEX_COORD_X (&cs->sky.matrix, afTexCoordX[2] * cs->skyW),
|
|
COMP_TEX_COORD_Y (&cs->sky.matrix, afTexCoordY[2] * cs->skyH));
|
|
glVertex3f (x * r * fRadius, y * r * fRadius, z * fRadius);
|
|
|
|
afTexCoordX[0] -= fStepX;
|
|
afTexCoordX[1] -= fStepX;
|
|
afTexCoordX[2] -= fStepX;
|
|
afTexCoordX[3] -= fStepX;
|
|
}
|
|
|
|
afTexCoordY[0] -= fStepY;
|
|
afTexCoordY[1] -= fStepY;
|
|
afTexCoordY[2] -= fStepY;
|
|
afTexCoordY[3] -= fStepY;
|
|
}
|
|
|
|
glEnd ();
|
|
|
|
disableTexture (s, &cs->sky);
|
|
|
|
glEndList ();
|
|
|
|
free (sint1);
|
|
free (cost1);
|
|
free (sint2);
|
|
free (cost2);
|
|
}
|
|
|
|
static Bool
|
|
cubeSetScreenOption (CompPlugin *plugin,
|
|
CompScreen *screen,
|
|
const char *name,
|
|
CompOptionValue *value)
|
|
{
|
|
CompOption *o;
|
|
int index;
|
|
|
|
CUBE_SCREEN (screen);
|
|
|
|
o = compFindOption (cs->opt, NUM_OPTIONS (cs), name, &index);
|
|
if (!o)
|
|
return FALSE;
|
|
|
|
switch (index) {
|
|
case CUBE_SCREEN_OPTION_COLOR:
|
|
if (compSetColorOption (o, value))
|
|
{
|
|
memcpy (cs->color, o->value.c, sizeof (cs->color));
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_IN:
|
|
if (compSetBoolOption (o, value))
|
|
{
|
|
if (cubeUpdateGeometry (screen, screen->hsize, o->value.b ? -1 : 1))
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_SCALE_IMAGE:
|
|
if (compSetBoolOption (o, value))
|
|
{
|
|
cubeLoadImg (screen, cs->imgCurFile);
|
|
damageScreen (screen);
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_IMAGES:
|
|
if (compSetOptionList (o, value))
|
|
{
|
|
cubeLoadImg (screen, cs->imgCurFile);
|
|
damageScreen (screen);
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_SKYDOME:
|
|
if (compSetBoolOption (o, value))
|
|
{
|
|
cubeUpdateSkyDomeTexture (screen);
|
|
cubeUpdateSkyDomeList (screen, 1.0f);
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_SKYDOME_IMG:
|
|
if (compSetStringOption (o, value))
|
|
{
|
|
cubeUpdateSkyDomeTexture (screen);
|
|
cubeUpdateSkyDomeList (screen, 1.0f);
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_SKYDOME_ANIM:
|
|
if (compSetBoolOption (o, value))
|
|
{
|
|
cubeUpdateSkyDomeTexture (screen);
|
|
cubeUpdateSkyDomeList (screen, 1.0f);
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_SKYDOME_GRAD_START:
|
|
if (compSetColorOption (o, value))
|
|
{
|
|
cubeUpdateSkyDomeTexture (screen);
|
|
cubeUpdateSkyDomeList (screen, 1.0f);
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_SKYDOME_GRAD_END:
|
|
if (compSetColorOption (o, value))
|
|
{
|
|
cubeUpdateSkyDomeTexture (screen);
|
|
cubeUpdateSkyDomeList (screen, 1.0f);
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case CUBE_SCREEN_OPTION_MULTIOUTPUT_MODE:
|
|
if (compSetIntOption (o, value))
|
|
{
|
|
cs->moMode = o->value.i;
|
|
cubeUpdateOutputs (screen);
|
|
cubeUpdateGeometry (screen, screen->hsize, cs->invert);
|
|
damageScreen (screen);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
return compSetScreenOption (screen, o, value);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int
|
|
adjustVelocity (CubeScreen *cs)
|
|
{
|
|
float unfold, adjust, amount;
|
|
|
|
if (cs->unfolded)
|
|
unfold = 1.0f - cs->unfold;
|
|
else
|
|
unfold = 0.0f - cs->unfold;
|
|
|
|
adjust = unfold * 0.02f * cs->opt[CUBE_SCREEN_OPTION_ACCELERATION].value.f;
|
|
amount = fabs (unfold);
|
|
if (amount < 1.0f)
|
|
amount = 1.0f;
|
|
else if (amount > 3.0f)
|
|
amount = 3.0f;
|
|
|
|
cs->unfoldVelocity = (amount * cs->unfoldVelocity + adjust) /
|
|
(amount + 2.0f);
|
|
|
|
return (fabs (unfold) < 0.002f && fabs (cs->unfoldVelocity) < 0.01f);
|
|
}
|
|
|
|
static void
|
|
cubePreparePaintScreen (CompScreen *s,
|
|
int msSinceLastPaint)
|
|
{
|
|
int opt;
|
|
float x, progress;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->grabIndex)
|
|
{
|
|
int steps;
|
|
float amount, chunk;
|
|
|
|
amount = msSinceLastPaint * 0.2f *
|
|
cs->opt[CUBE_SCREEN_OPTION_SPEED].value.f;
|
|
steps = amount / (0.5f * cs->opt[CUBE_SCREEN_OPTION_TIMESTEP].value.f);
|
|
if (!steps) steps = 1;
|
|
chunk = amount / (float) steps;
|
|
|
|
while (steps--)
|
|
{
|
|
cs->unfold += cs->unfoldVelocity * chunk;
|
|
if (cs->unfold > 1.0f)
|
|
cs->unfold = 1.0f;
|
|
|
|
if (adjustVelocity (cs))
|
|
{
|
|
if (cs->unfold < 0.5f)
|
|
{
|
|
if (cs->grabIndex)
|
|
{
|
|
removeScreenGrab (s, cs->grabIndex, NULL);
|
|
cs->grabIndex = 0;
|
|
}
|
|
|
|
cs->unfold = 0.0f;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
memset (cs->cleared, 0, sizeof (Bool) * s->nOutputDev);
|
|
memset (cs->capsPainted, 0, sizeof (Bool) * s->nOutputDev);
|
|
|
|
/* Transparency handling */
|
|
if (cs->rotationState == RotationManual ||
|
|
(cs->rotationState == RotationChange &&
|
|
!cs->opt[CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY].value.b))
|
|
{
|
|
opt = cs->lastOpacityIndex = CUBE_SCREEN_OPTION_ACTIVE_OPACITY;
|
|
}
|
|
else if (cs->rotationState == RotationChange)
|
|
{
|
|
opt = cs->lastOpacityIndex = CUBE_SCREEN_OPTION_INACTIVE_OPACITY;
|
|
}
|
|
else
|
|
{
|
|
opt = CUBE_SCREEN_OPTION_INACTIVE_OPACITY;
|
|
}
|
|
|
|
cs->toOpacity = (cs->opt[opt].value.f / 100.0f) * OPAQUE;
|
|
|
|
(*cs->getRotation) (s, &x, &x, &progress);
|
|
|
|
if (cs->desktopOpacity != cs->toOpacity ||
|
|
(progress > 0.0 && progress < 1.0))
|
|
{
|
|
cs->desktopOpacity =
|
|
(cs->opt[CUBE_SCREEN_OPTION_INACTIVE_OPACITY].value.f -
|
|
((cs->opt[CUBE_SCREEN_OPTION_INACTIVE_OPACITY].value.f -
|
|
cs->opt[cs->lastOpacityIndex].value.f) * progress))
|
|
/ 100.0f * OPAQUE;
|
|
|
|
}
|
|
|
|
cs->paintAllViewports = (cs->desktopOpacity != OPAQUE);
|
|
|
|
UNWRAP (cs, s, preparePaintScreen);
|
|
(*s->preparePaintScreen) (s, msSinceLastPaint);
|
|
WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen);
|
|
}
|
|
|
|
static void
|
|
cubePaintScreen (CompScreen *s,
|
|
CompOutput *outputs,
|
|
int numOutputs,
|
|
unsigned int mask)
|
|
{
|
|
float x, progress;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
(*cs->getRotation) (s, &x, &x, &progress);
|
|
|
|
UNWRAP (cs, s, paintScreen);
|
|
if (cs->moMode == CUBE_MOMODE_ONE && s->nOutputDev &&
|
|
(progress > 0.0f || cs->desktopOpacity != OPAQUE))
|
|
(*s->paintScreen) (s, &s->fullscreenOutput, 1, mask);
|
|
else
|
|
(*s->paintScreen) (s, outputs, numOutputs, mask);
|
|
WRAP (cs, s, paintScreen, cubePaintScreen);
|
|
}
|
|
|
|
static Bool
|
|
cubePaintOutput (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
Region region,
|
|
CompOutput *output,
|
|
unsigned int mask)
|
|
{
|
|
Bool status;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->grabIndex || cs->desktopOpacity != OPAQUE)
|
|
{
|
|
mask &= ~PAINT_SCREEN_REGION_MASK;
|
|
mask |= PAINT_SCREEN_TRANSFORMED_MASK;
|
|
}
|
|
|
|
cs->srcOutput = (output->id != ~0) ? output->id : 0;
|
|
/* Always use BTF painting on non-transformed screen */
|
|
cs->paintOrder = BTF;
|
|
|
|
UNWRAP (cs, s, paintOutput);
|
|
status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
|
|
WRAP (cs, s, paintOutput, cubePaintOutput);
|
|
|
|
return status;
|
|
}
|
|
|
|
static void
|
|
cubeDonePaintScreen (CompScreen *s)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity)
|
|
damageScreen (s);
|
|
|
|
UNWRAP (cs, s, donePaintScreen);
|
|
(*s->donePaintScreen) (s);
|
|
WRAP (cs, s, donePaintScreen, cubeDonePaintScreen);
|
|
}
|
|
|
|
static Bool
|
|
cubeCheckOrientation (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
CompOutput *outputPtr,
|
|
CompVector *points)
|
|
{
|
|
CompTransform sTransform = *transform;
|
|
CompTransform mvp, pm;
|
|
CompVector pntA, pntB, pntC;
|
|
CompVector vecA, vecB, ortho;
|
|
Bool rv = FALSE;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
(*s->applyScreenTransform) (s, sAttrib, outputPtr, &sTransform);
|
|
matrixTranslate (&sTransform, cs->outputXOffset, -cs->outputYOffset, 0.0f);
|
|
matrixScale (&sTransform, cs->outputXScale, cs->outputYScale, 1.0f);
|
|
|
|
memcpy (pm.m, s->projection, sizeof (pm.m));
|
|
matrixMultiply (&mvp, &pm, &sTransform);
|
|
|
|
matrixMultiplyVector (&pntA, &points[0], &mvp);
|
|
|
|
if (pntA.w < 0.0f)
|
|
rv = !rv;
|
|
|
|
matrixVectorDiv (&pntA);
|
|
|
|
matrixMultiplyVector (&pntB, &points[1], &mvp);
|
|
|
|
if (pntB.w < 0.0f)
|
|
rv = !rv;
|
|
|
|
matrixVectorDiv (&pntB);
|
|
matrixMultiplyVector (&pntC, &points[2], &mvp);
|
|
matrixVectorDiv (&pntC);
|
|
|
|
vecA.x = pntC.x - pntA.x;
|
|
vecA.y = pntC.y - pntA.y;
|
|
vecA.z = pntC.z - pntA.z;
|
|
|
|
vecB.x = pntC.x - pntB.x;
|
|
vecB.y = pntC.y - pntB.y;
|
|
vecB.z = pntC.z - pntB.z;
|
|
|
|
ortho.x = vecA.y * vecB.z - vecA.z * vecB.y;
|
|
ortho.y = vecA.z * vecB.x - vecA.x * vecB.z;
|
|
ortho.z = vecA.x * vecB.y - vecA.y * vecB.x;
|
|
|
|
if (ortho.z > 0.0f)
|
|
rv = !rv;
|
|
|
|
return rv;
|
|
}
|
|
|
|
static Bool
|
|
cubeShouldPaintViewport (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
CompOutput *outputPtr,
|
|
PaintOrder order)
|
|
{
|
|
Bool ftb;
|
|
float pointZ;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
pointZ = cs->invert * cs->distance;
|
|
CompVector vPoints[3] = { {.v = { -0.5, 0.0, pointZ, 1.0 } },
|
|
{.v = { 0.0, 0.5, pointZ, 1.0 } },
|
|
{.v = { 0.0, 0.0, pointZ, 1.0 } } };
|
|
|
|
ftb = (*cs->checkOrientation) (s, sAttrib, transform, outputPtr, vPoints);
|
|
|
|
return (order == FTB && ftb) || (order == BTF && !ftb);
|
|
}
|
|
|
|
static void
|
|
cubeMoveViewportAndPaint (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
CompOutput *outputPtr,
|
|
unsigned int mask,
|
|
PaintOrder paintOrder,
|
|
int dx)
|
|
{
|
|
int output;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
if (!(*cs->shouldPaintViewport) (s,
|
|
sAttrib,
|
|
transform,
|
|
outputPtr,
|
|
paintOrder))
|
|
return;
|
|
|
|
output = (outputPtr->id != ~0) ? outputPtr->id : 0;
|
|
|
|
cs->paintOrder = paintOrder;
|
|
|
|
if (cs->nOutput > 1)
|
|
{
|
|
int cubeOutput, dView;
|
|
|
|
/* 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 compiz output */
|
|
output = cs->srcOutput = cs->output[cubeOutput];
|
|
|
|
setWindowPaintOffset (s, -dView * s->width, 0);
|
|
(*cs->paintViewport) (s, sAttrib, transform,
|
|
&s->outputDev[output].region,
|
|
&s->outputDev[output], mask);
|
|
setWindowPaintOffset (s, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
Region region;
|
|
|
|
setWindowPaintOffset (s, dx * s->width, 0);
|
|
|
|
if (cs->moMode == CUBE_MOMODE_MULTI)
|
|
region = &outputPtr->region;
|
|
else
|
|
region = &s->region;
|
|
|
|
(*cs->paintViewport) (s, sAttrib, transform, region, outputPtr, mask);
|
|
|
|
setWindowPaintOffset (s, 0, 0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cubePaintAllViewports (CompScreen *s,
|
|
ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
Region region,
|
|
CompOutput *outputPtr,
|
|
unsigned int mask,
|
|
int xMove,
|
|
float size,
|
|
int hsize,
|
|
PaintOrder paintOrder)
|
|
{
|
|
ScreenPaintAttrib sa = *sAttrib;
|
|
|
|
int i;
|
|
int xMoveAdd;
|
|
int origXMoveAdd = 0; /* dx for the viewport we start
|
|
painting with (back-most). */
|
|
int iFirstSign; /* 1 if we do xMove += i first and
|
|
-1 if we do xMove -= i first. */
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->invert == 1)
|
|
{
|
|
/* xMove ==> dx for the viewport which is the
|
|
nearest to the viewer in z axis.
|
|
xMove +/- hsize / 2 ==> dx for the viewport
|
|
which is the farthest to the viewer in z axis. */
|
|
|
|
if ((sa.xRotate < 0.0f && hsize % 2 == 1) ||
|
|
(sa.xRotate > 0.0f && hsize % 2 == 0))
|
|
{
|
|
origXMoveAdd = hsize / 2;
|
|
iFirstSign = 1;
|
|
}
|
|
else
|
|
{
|
|
origXMoveAdd = -hsize / 2;
|
|
iFirstSign = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* xMove is already the dx for farthest viewport. */
|
|
if (sa.xRotate > 0.0f)
|
|
iFirstSign = -1;
|
|
else
|
|
iFirstSign = 1;
|
|
}
|
|
|
|
for (i = 0; i <= hsize / 2; i++)
|
|
{
|
|
/* move to the correct viewport (back to front). */
|
|
xMoveAdd = origXMoveAdd; /* move to farthest viewport. */
|
|
xMoveAdd += iFirstSign * i; /* move i more viewports to
|
|
the right / left. */
|
|
|
|
/* Needed especially for unfold.
|
|
We paint the viewports around xMove viewport.
|
|
Adding or subtracting hsize from xMove has no effect on
|
|
what viewport we paint, but can make shorter paths. */
|
|
if (xMoveAdd < -hsize / 2)
|
|
xMoveAdd += hsize;
|
|
else if (xMoveAdd > hsize / 2)
|
|
xMoveAdd -= hsize;
|
|
|
|
/* Paint the viewport. */
|
|
xMove += xMoveAdd;
|
|
|
|
sa.yRotate -= cs->invert * xMoveAdd * 360.0f / size;
|
|
cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
|
|
paintOrder, xMove);
|
|
sa.yRotate += cs->invert * xMoveAdd * 360.0f / size;
|
|
|
|
xMove -= xMoveAdd;
|
|
|
|
/* do the same for an equally far viewport. */
|
|
if (i == 0 || i * 2 == hsize)
|
|
continue;
|
|
|
|
xMoveAdd = origXMoveAdd; /* move to farthest viewport. */
|
|
xMoveAdd -= iFirstSign * i; /* move i more viewports to the
|
|
left / right (opposite side
|
|
from the one chosen first) */
|
|
|
|
if (xMoveAdd < -hsize / 2)
|
|
xMoveAdd += hsize;
|
|
else if (xMoveAdd > hsize / 2)
|
|
xMoveAdd -= hsize;
|
|
|
|
xMove += xMoveAdd;
|
|
|
|
sa.yRotate -= cs->invert * xMoveAdd * 360.0f / size;
|
|
cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
|
|
paintOrder, xMove);
|
|
sa.yRotate += cs->invert * xMoveAdd * 360.0f / size;
|
|
|
|
xMove -= xMoveAdd;
|
|
}
|
|
}
|
|
|
|
static void
|
|
cubeGetRotation (CompScreen *s,
|
|
float *x,
|
|
float *v,
|
|
float *progress)
|
|
{
|
|
*x = 0.0f;
|
|
*v = 0.0f;
|
|
*progress = 0.0f;
|
|
}
|
|
|
|
static void
|
|
cubeClearTargetOutput (CompScreen *s,
|
|
float xRotate,
|
|
float vRotate)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->sky.name)
|
|
{
|
|
screenLighting (s, FALSE);
|
|
|
|
glPushMatrix ();
|
|
|
|
if (cs->opt[CUBE_SCREEN_OPTION_SKYDOME_ANIM].value.b &&
|
|
cs->grabIndex == 0)
|
|
{
|
|
glRotatef (vRotate / 5.0f + 90.0f, 1.0f, 0.0f, 0.0f);
|
|
glRotatef (xRotate, 0.0f, 0.0f, -1.0f);
|
|
}
|
|
else
|
|
{
|
|
glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
glCallList (cs->skyListId);
|
|
glPopMatrix ();
|
|
}
|
|
else
|
|
{
|
|
clearTargetOutput (s->display, GL_COLOR_BUFFER_BIT);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cubePaintTop (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
CompOutput *output,
|
|
int size)
|
|
{
|
|
ScreenPaintAttrib sa = *sAttrib;
|
|
CompTransform sTransform = *transform;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
screenLighting (s, TRUE);
|
|
|
|
glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity);
|
|
|
|
glPushMatrix ();
|
|
|
|
sa.yRotate += (360.0f / size) * (cs->xRotations + 1);
|
|
if (!cs->opt[CUBE_SCREEN_OPTION_ADJUST_IMAGE].value.b)
|
|
sa.yRotate -= (360.0f / size) * s->x;
|
|
|
|
(*s->applyScreenTransform) (s, &sa, output, &sTransform);
|
|
|
|
glLoadMatrixf (sTransform.m);
|
|
glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
|
|
glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
|
|
|
|
if (cs->desktopOpacity != OPAQUE)
|
|
{
|
|
screenTexEnvMode (s, GL_MODULATE);
|
|
glEnable (GL_BLEND);
|
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
}
|
|
|
|
glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
|
|
|
|
if (cs->invert == 1 && size == 4 && cs->texture.name)
|
|
{
|
|
enableTexture (s, &cs->texture, COMP_TEXTURE_FILTER_GOOD);
|
|
glTexCoordPointer (2, GL_FLOAT, 0, cs->tc);
|
|
glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nVertices >> 1);
|
|
disableTexture (s, &cs->texture);
|
|
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
else
|
|
{
|
|
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nVertices >> 1);
|
|
}
|
|
|
|
glPopMatrix ();
|
|
|
|
glColor4usv (defaultColor);
|
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
|
|
screenTexEnvMode (s, GL_REPLACE);
|
|
glDisable (GL_BLEND);
|
|
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
}
|
|
|
|
static void
|
|
cubePaintBottom (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
CompOutput *output,
|
|
int size)
|
|
{
|
|
ScreenPaintAttrib sa = *sAttrib;
|
|
CompTransform sTransform = *transform;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
screenLighting (s, TRUE);
|
|
|
|
glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity);
|
|
|
|
glPushMatrix ();
|
|
|
|
sa.yRotate += (360.0f / size) * (cs->xRotations + 1);
|
|
if (!cs->opt[CUBE_SCREEN_OPTION_ADJUST_IMAGE].value.b)
|
|
sa.yRotate -= (360.0f / size) * s->x;
|
|
|
|
(*s->applyScreenTransform) (s, &sa, output, &sTransform);
|
|
|
|
glLoadMatrixf (sTransform.m);
|
|
glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
|
|
glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
|
|
|
|
if (cs->desktopOpacity != OPAQUE)
|
|
{
|
|
screenTexEnvMode (s, GL_MODULATE);
|
|
glEnable (GL_BLEND);
|
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
}
|
|
|
|
glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
|
|
|
|
glDrawArrays (GL_TRIANGLE_FAN, cs->nVertices >> 1,
|
|
cs->nVertices >> 1);
|
|
|
|
glPopMatrix ();
|
|
|
|
glColor4usv (defaultColor);
|
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
|
|
screenTexEnvMode (s, GL_REPLACE);
|
|
glDisable (GL_BLEND);
|
|
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
}
|
|
|
|
static void
|
|
cubePaintInside (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
CompOutput *output,
|
|
int size)
|
|
{
|
|
}
|
|
|
|
static void
|
|
cubeEnableOutputClipping (CompScreen *s,
|
|
const CompTransform *transform,
|
|
Region region,
|
|
CompOutput *output)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->rotationState != RotationNone)
|
|
{
|
|
glPushMatrix ();
|
|
glLoadMatrixf (transform->m);
|
|
glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
|
|
glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
|
|
|
|
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);
|
|
}
|
|
|
|
glEnable (GL_CLIP_PLANE0);
|
|
glEnable (GL_CLIP_PLANE1);
|
|
glEnable (GL_CLIP_PLANE2);
|
|
glEnable (GL_CLIP_PLANE3);
|
|
|
|
glPopMatrix ();
|
|
}
|
|
else
|
|
{
|
|
UNWRAP (cs, s, enableOutputClipping);
|
|
(*s->enableOutputClipping) (s, transform, region, output);
|
|
WRAP (cs, s, enableOutputClipping, cubeEnableOutputClipping);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cubePaintViewport (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
Region region,
|
|
CompOutput *output,
|
|
unsigned int mask)
|
|
{
|
|
(*s->paintTransformedOutput) (s, sAttrib, transform, region, output, mask);
|
|
}
|
|
|
|
static void
|
|
cubePaintTransformedOutput (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
const CompTransform *transform,
|
|
Region region,
|
|
CompOutput *outputPtr,
|
|
unsigned int mask)
|
|
{
|
|
ScreenPaintAttrib sa = *sAttrib;
|
|
float xRotate, vRotate, progress;
|
|
int hsize;
|
|
float size;
|
|
GLenum filter = s->display->textureFilter;
|
|
PaintOrder paintOrder;
|
|
Bool wasCulled = FALSE;
|
|
Bool paintCaps;
|
|
int cullNorm, cullInv;
|
|
int output = 0;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
output = (outputPtr->id != ~0) ? outputPtr->id : 0;
|
|
|
|
if (((outputPtr->id != ~0) && cs->recalcOutput) ||
|
|
((outputPtr->id == ~0) && !cs->recalcOutput && cs->nOutput > 1))
|
|
{
|
|
cs->recalcOutput = (outputPtr->id == ~0);
|
|
cs->nOutput = 1;
|
|
cubeUpdateGeometry (s, s->hsize, cs->invert);
|
|
}
|
|
|
|
hsize = s->hsize * cs->nOutput;
|
|
size = hsize;
|
|
|
|
glGetIntegerv (GL_CULL_FACE_MODE, &cullNorm);
|
|
cullInv = (cullNorm == GL_BACK)? GL_FRONT : GL_BACK;
|
|
wasCulled = glIsEnabled (GL_CULL_FACE);
|
|
|
|
if (!cs->fullscreenOutput)
|
|
{
|
|
cs->outputXScale = (float) s->width / outputPtr->width;
|
|
cs->outputYScale = (float) s->height / outputPtr->height;
|
|
|
|
cs->outputXOffset =
|
|
(s->width / 2.0f -
|
|
(outputPtr->region.extents.x1 +
|
|
outputPtr->region.extents.x2) / 2.0f) /
|
|
(float) outputPtr->width;
|
|
|
|
cs->outputYOffset =
|
|
(s->height / 2.0f -
|
|
(outputPtr->region.extents.y1 +
|
|
outputPtr->region.extents.y2) / 2.0f) /
|
|
(float) outputPtr->height;
|
|
}
|
|
else
|
|
{
|
|
cs->outputXScale = 1.0f;
|
|
cs->outputYScale = 1.0f;
|
|
cs->outputXOffset = 0.0f;
|
|
cs->outputYOffset = 0.0f;
|
|
}
|
|
|
|
(*cs->getRotation) (s, &xRotate, &vRotate, &progress);
|
|
|
|
sa.xRotate += xRotate;
|
|
sa.vRotate += vRotate;
|
|
|
|
if (!cs->cleared[output])
|
|
{
|
|
float rRotate;
|
|
|
|
rRotate = xRotate - ((s->x *360.0f) / s->hsize);
|
|
|
|
(*cs->clearTargetOutput) (s, rRotate, vRotate);
|
|
cs->cleared[output] = TRUE;
|
|
}
|
|
|
|
mask &= ~PAINT_SCREEN_CLEAR_MASK;
|
|
|
|
UNWRAP (cs, s, paintTransformedOutput);
|
|
|
|
if (cs->grabIndex)
|
|
{
|
|
sa.vRotate = 0.0f;
|
|
|
|
size += cs->unfold * 8.0f;
|
|
size += powf (cs->unfold, 6) * 64.0;
|
|
size += powf (cs->unfold, 16) * 8192.0;
|
|
|
|
sa.zTranslate = -cs->invert * (0.5f / tanf (M_PI / size));
|
|
|
|
/* distance we move the camera back when unfolding the cube.
|
|
currently hardcoded to 1.5 but it should probably be optional. */
|
|
sa.zCamera -= cs->unfold * 1.5f;
|
|
}
|
|
else
|
|
{
|
|
if (vRotate > 100.0f)
|
|
sa.vRotate = 100.0f;
|
|
else if (vRotate < -100.0f)
|
|
sa.vRotate = -100.0f;
|
|
else
|
|
sa.vRotate = vRotate;
|
|
|
|
sa.zTranslate = -cs->invert * cs->distance;
|
|
}
|
|
|
|
if (sa.xRotate > 0.0f)
|
|
cs->xRotations = (int) (hsize * sa.xRotate + 180.0f) / 360.0f;
|
|
else
|
|
cs->xRotations = (int) (hsize * sa.xRotate - 180.0f) / 360.0f;
|
|
|
|
sa.xRotate -= (360.0f * cs->xRotations) / hsize;
|
|
sa.xRotate *= cs->invert;
|
|
|
|
sa.xRotate = sa.xRotate / size * hsize;
|
|
|
|
if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
|
|
s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
|
|
|
|
if (cs->invert == 1)
|
|
{
|
|
/* Outside cube - start with FTB faces */
|
|
paintOrder = FTB;
|
|
glCullFace (cullInv);
|
|
}
|
|
else
|
|
{
|
|
/* Inside cube - start with BTF faces */
|
|
paintOrder = BTF;
|
|
}
|
|
|
|
if (cs->invert == -1 || cs->paintAllViewports)
|
|
cubePaintAllViewports (s, &sa, transform, region, outputPtr,
|
|
mask, cs->xRotations, size, hsize, paintOrder);
|
|
|
|
glCullFace (cullNorm);
|
|
|
|
if (wasCulled && cs->paintAllViewports)
|
|
glDisable (GL_CULL_FACE);
|
|
|
|
paintCaps = !cs->grabIndex && (hsize > 2) && !cs->capsPainted[output] &&
|
|
(cs->invert != 1 || cs->desktopOpacity != OPAQUE ||
|
|
cs->paintAllViewports || sa.vRotate != 0.0f ||
|
|
sa.yTranslate != 0.0f);
|
|
|
|
if (paintCaps)
|
|
{
|
|
Bool topDir, bottomDir, allCaps;
|
|
|
|
static CompVector top[3] = { { .v = { 0.5, 0.5, 0.0, 1.0} },
|
|
{ .v = { 0.0, 0.5, -0.5, 1.0} },
|
|
{ .v = { 0.0, 0.5, 0.0, 1.0} } };
|
|
static CompVector bottom[3] = { { .v = { 0.5, -0.5, 0.0, 1.0} },
|
|
{ .v = { 0.0, -0.5, -0.5, 1.0} },
|
|
{ .v = { 0.0, -0.5, 0.0, 1.0} } };
|
|
|
|
topDir = (*cs->checkOrientation) (s, &sa, transform, outputPtr, top);
|
|
bottomDir = (*cs->checkOrientation) (s, &sa, transform,
|
|
outputPtr, bottom);
|
|
|
|
cs->capsPainted[output] = TRUE;
|
|
|
|
allCaps = cs->paintAllViewports || cs->invert != 1;
|
|
|
|
if (topDir && bottomDir)
|
|
{
|
|
glNormal3f (0.0f, -1.0f, 0.0f);
|
|
if (allCaps)
|
|
{
|
|
(*cs->paintBottom) (s, &sa, transform, outputPtr, hsize);
|
|
glNormal3f (0.0f, 0.0f, -1.0f);
|
|
(*cs->paintInside) (s, &sa, transform, outputPtr, hsize);
|
|
glNormal3f (0.0f, -1.0f, 0.0f);
|
|
}
|
|
(*cs->paintTop) (s, &sa, transform, outputPtr, hsize);
|
|
}
|
|
else if (!topDir && !bottomDir)
|
|
{
|
|
glNormal3f (0.0f, 1.0f, 0.0f);
|
|
if (allCaps)
|
|
{
|
|
(*cs->paintTop) (s, &sa, transform, outputPtr, hsize);
|
|
glNormal3f (0.0f, 0.0f, -1.0f);
|
|
(*cs->paintInside) (s, &sa, transform, outputPtr, hsize);
|
|
glNormal3f (0.0f, 1.0f, 0.0f);
|
|
}
|
|
(*cs->paintBottom) (s, &sa, transform, outputPtr, hsize);
|
|
}
|
|
else if (allCaps)
|
|
{
|
|
glNormal3f (0.0f, 1.0f, 0.0f);
|
|
(*cs->paintTop) (s, &sa, transform, outputPtr, hsize);
|
|
glNormal3f (0.0f, -1.0f, 0.0f);
|
|
(*cs->paintBottom) (s, &sa, transform, outputPtr, hsize);
|
|
glNormal3f (0.0f, 0.0f, -1.0f);
|
|
(*cs->paintInside) (s, &sa, transform, outputPtr, hsize);
|
|
}
|
|
glNormal3f (0.0f, 0.0f, -1.0f);
|
|
}
|
|
|
|
if (wasCulled)
|
|
glEnable (GL_CULL_FACE);
|
|
|
|
if (cs->invert == 1)
|
|
{
|
|
/* Outside cube - continue with BTF faces */
|
|
paintOrder = BTF;
|
|
}
|
|
else
|
|
{
|
|
/* Inside cube - continue with FTB faces */
|
|
paintOrder = FTB;
|
|
glCullFace (cullInv);
|
|
}
|
|
|
|
if (cs->invert == 1 || cs->paintAllViewports)
|
|
cubePaintAllViewports (s, &sa, transform, region,
|
|
outputPtr, mask, cs->xRotations,
|
|
size, hsize, paintOrder);
|
|
|
|
glCullFace (cullNorm);
|
|
|
|
s->display->textureFilter = filter;
|
|
|
|
WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput);
|
|
}
|
|
|
|
static Bool
|
|
cubePaintWindow (CompWindow *w,
|
|
const WindowPaintAttrib *attrib,
|
|
const CompTransform *transform,
|
|
Region region,
|
|
unsigned int mask)
|
|
{
|
|
Bool status;
|
|
CompScreen *s = w->screen;
|
|
CUBE_SCREEN (s);
|
|
|
|
if ((w->type & CompWindowTypeDesktopMask) &&
|
|
(attrib->opacity != cs->desktopOpacity))
|
|
{
|
|
WindowPaintAttrib wAttrib = *attrib;
|
|
|
|
wAttrib.opacity = cs->desktopOpacity;
|
|
|
|
UNWRAP (cs, s, paintWindow);
|
|
status = (*s->paintWindow) (w, &wAttrib, transform, region, mask);
|
|
WRAP (cs, s, paintWindow, cubePaintWindow);
|
|
}
|
|
else
|
|
{
|
|
UNWRAP (cs, s, paintWindow);
|
|
status = (*s->paintWindow) (w, attrib, transform, region, mask);
|
|
WRAP (cs, s, paintWindow, cubePaintWindow);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static void
|
|
cubeInitWindowWalker (CompScreen *s, CompWalker* walker)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
UNWRAP (cs, s, initWindowWalker);
|
|
(*s->initWindowWalker) (s, walker);
|
|
WRAP (cs, s, initWindowWalker, cubeInitWindowWalker);
|
|
|
|
if (cs->paintOrder == FTB)
|
|
{
|
|
WalkInitProc tmpInit = walker->first;
|
|
WalkStepProc tmpStep = walker->next;
|
|
|
|
walker->first = walker->last;
|
|
walker->last = tmpInit;
|
|
|
|
walker->next = walker->prev;
|
|
walker->prev = tmpStep;
|
|
}
|
|
}
|
|
|
|
static void
|
|
cubeApplyScreenTransform (CompScreen *s,
|
|
const ScreenPaintAttrib *sAttrib,
|
|
CompOutput *output,
|
|
CompTransform *transform)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
matrixTranslate (transform, cs->outputXOffset, -cs->outputYOffset, 0.0f);
|
|
matrixScale (transform, cs->outputXScale, cs->outputYScale, 1.0f);
|
|
|
|
UNWRAP (cs, s, applyScreenTransform);
|
|
(*s->applyScreenTransform) (s, sAttrib, output, transform);
|
|
WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
|
|
|
|
matrixScale (transform, 1.0f / cs->outputXScale,
|
|
1.0f / cs->outputYScale, 1.0f);
|
|
matrixTranslate (transform, -cs->outputXOffset, cs->outputYOffset, 0.0f);
|
|
}
|
|
|
|
static Bool
|
|
cubeUnfold (CompDisplay *d,
|
|
CompAction *action,
|
|
CompActionState state,
|
|
CompOption *option,
|
|
int nOption)
|
|
{
|
|
CompScreen *s;
|
|
Window xid;
|
|
|
|
xid = getIntOptionNamed (option, nOption, "root", 0);
|
|
|
|
s = findScreenAtDisplay (d, xid);
|
|
if (s)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
if (s->hsize * cs->nOutput < 4)
|
|
return FALSE;
|
|
|
|
if (otherScreenGrabExist (s, "rotate", "switcher", "cube", NULL))
|
|
return FALSE;
|
|
|
|
if (!cs->grabIndex)
|
|
cs->grabIndex = pushScreenGrab (s, s->invisibleCursor, "cube");
|
|
|
|
if (cs->grabIndex)
|
|
{
|
|
cs->unfolded = TRUE;
|
|
damageScreen (s);
|
|
}
|
|
|
|
if (state & CompActionStateInitButton)
|
|
action->state |= CompActionStateTermButton;
|
|
|
|
if (state & CompActionStateInitKey)
|
|
action->state |= CompActionStateTermKey;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
cubeFold (CompDisplay *d,
|
|
CompAction *action,
|
|
CompActionState state,
|
|
CompOption *option,
|
|
int nOption)
|
|
{
|
|
CompScreen *s;
|
|
Window xid;
|
|
|
|
xid = getIntOptionNamed (option, nOption, "root", 0);
|
|
|
|
for (s = d->screens; s; s = s->next)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
if (xid && s->root != xid)
|
|
continue;
|
|
|
|
if (cs->grabIndex)
|
|
{
|
|
cs->unfolded = FALSE;
|
|
damageScreen (s);
|
|
}
|
|
}
|
|
|
|
action->state &= ~(CompActionStateTermButton | CompActionStateTermKey);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
cubeNextImage (CompDisplay *d,
|
|
CompAction *action,
|
|
CompActionState state,
|
|
CompOption *option,
|
|
int nOption)
|
|
{
|
|
CompScreen *s;
|
|
Window xid;
|
|
|
|
xid = getIntOptionNamed (option, nOption, "root", 0);
|
|
|
|
s = findScreenAtDisplay (d, xid);
|
|
if (s)
|
|
{
|
|
int imgNFile;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
imgNFile = cs->opt[CUBE_SCREEN_OPTION_IMAGES].value.list.nValue;
|
|
if (imgNFile)
|
|
{
|
|
cubeLoadImg (s, (cs->imgCurFile + 1) % imgNFile);
|
|
damageScreen (s);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
cubePrevImage (CompDisplay *d,
|
|
CompAction *action,
|
|
CompActionState state,
|
|
CompOption *option,
|
|
int nOption)
|
|
{
|
|
CompScreen *s;
|
|
Window xid;
|
|
|
|
xid = getIntOptionNamed (option, nOption, "root", 0);
|
|
|
|
s = findScreenAtDisplay (d, xid);
|
|
if (s)
|
|
{
|
|
int imgNFile;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
imgNFile = cs->opt[CUBE_SCREEN_OPTION_IMAGES].value.list.nValue;
|
|
if (imgNFile)
|
|
{
|
|
cubeLoadImg (s, (cs->imgCurFile - 1 + imgNFile) % imgNFile);
|
|
damageScreen (s);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
cubeOutputChangeNotify (CompScreen *s)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
cubeUpdateOutputs (s);
|
|
cubeUpdateGeometry (s, s->hsize, cs->invert);
|
|
|
|
if (cs->opt[CUBE_SCREEN_OPTION_IMAGES].value.list.nValue)
|
|
cubeLoadImg (s, cs->imgCurFile);
|
|
|
|
UNWRAP (cs, s, outputChangeNotify);
|
|
(*s->outputChangeNotify) (s);
|
|
WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
|
|
}
|
|
|
|
static Bool
|
|
cubeSetOptionForPlugin (CompObject *o,
|
|
const char *plugin,
|
|
const char *name,
|
|
CompOptionValue *value)
|
|
{
|
|
Bool status;
|
|
|
|
CUBE_CORE (&core);
|
|
|
|
UNWRAP (cc, &core, setOptionForPlugin);
|
|
status = (*core.setOptionForPlugin) (o, plugin, name, value);
|
|
WRAP (cc, &core, setOptionForPlugin, cubeSetOptionForPlugin);
|
|
|
|
if (status && o->type == COMP_OBJECT_TYPE_SCREEN)
|
|
{
|
|
if (strcmp (plugin, "core") == 0 && strcmp (name, "hsize") == 0)
|
|
{
|
|
CompScreen *s = (CompScreen *) o;
|
|
|
|
CUBE_SCREEN (s);
|
|
|
|
cubeUpdateGeometry (s, s->hsize, cs->invert);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static CompOption *
|
|
cubeGetDisplayOptions (CompPlugin *plugin,
|
|
CompDisplay *display,
|
|
int *count)
|
|
{
|
|
CUBE_DISPLAY (display);
|
|
|
|
*count = NUM_OPTIONS (cd);
|
|
return cd->opt;
|
|
}
|
|
|
|
static Bool
|
|
cubeSetDisplayOption (CompPlugin *plugin,
|
|
CompDisplay *display,
|
|
const char *name,
|
|
CompOptionValue *value)
|
|
{
|
|
CompOption *o;
|
|
int index;
|
|
|
|
CUBE_DISPLAY (display);
|
|
|
|
o = compFindOption (cd->opt, NUM_OPTIONS (cd), name, &index);
|
|
if (!o)
|
|
return FALSE;
|
|
|
|
switch (index) {
|
|
case CUBE_DISPLAY_OPTION_ABI:
|
|
case CUBE_DISPLAY_OPTION_INDEX:
|
|
break;
|
|
default:
|
|
return compSetDisplayOption (display, o, value);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
cubeInitCore (CompPlugin *p,
|
|
CompCore *c)
|
|
{
|
|
CubeCore *cc;
|
|
|
|
if (!checkPluginABI ("core", CORE_ABIVERSION))
|
|
return FALSE;
|
|
|
|
cc = malloc (sizeof (CubeCore));
|
|
if (!cc)
|
|
return FALSE;
|
|
|
|
cubeDisplayPrivateIndex = allocateDisplayPrivateIndex ();
|
|
if (cubeDisplayPrivateIndex < 0)
|
|
{
|
|
free (cc);
|
|
return FALSE;
|
|
}
|
|
|
|
WRAP (cc, &core, setOptionForPlugin, cubeSetOptionForPlugin);
|
|
|
|
c->base.privates[cubeCorePrivateIndex].ptr = cc;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
cubeFiniCore (CompPlugin *p,
|
|
CompCore *c)
|
|
{
|
|
CUBE_CORE (c);
|
|
|
|
UNWRAP (cc, &core, setOptionForPlugin);
|
|
|
|
freeDisplayPrivateIndex (cubeDisplayPrivateIndex);
|
|
|
|
free (cc);
|
|
}
|
|
|
|
static const CompMetadataOptionInfo cubeDisplayOptionInfo[] = {
|
|
{ "abi", "int", 0, 0, 0 },
|
|
{ "index", "int", 0, 0, 0 },
|
|
{ "unfold_key", "key", 0, cubeUnfold, cubeFold },
|
|
{ "next_slide_key", "key", "<passive_grab>false</passive_grab>",
|
|
cubeNextImage, 0 },
|
|
{ "prev_slide_key", "key", "<passive_grab>false</passive_grab>",
|
|
cubePrevImage, 0 }
|
|
};
|
|
|
|
static Bool
|
|
cubeInitDisplay (CompPlugin *p,
|
|
CompDisplay *d)
|
|
{
|
|
CubeDisplay *cd;
|
|
|
|
cd = malloc (sizeof (CubeDisplay));
|
|
if (!cd)
|
|
return FALSE;
|
|
|
|
if (!compInitDisplayOptionsFromMetadata (d,
|
|
&cubeMetadata,
|
|
cubeDisplayOptionInfo,
|
|
cd->opt,
|
|
CUBE_DISPLAY_OPTION_NUM))
|
|
{
|
|
free (cd);
|
|
return FALSE;
|
|
}
|
|
|
|
cd->opt[CUBE_DISPLAY_OPTION_ABI].value.i = CUBE_ABIVERSION;
|
|
cd->opt[CUBE_DISPLAY_OPTION_INDEX].value.i = cubeDisplayPrivateIndex;
|
|
|
|
cd->screenPrivateIndex = allocateScreenPrivateIndex (d);
|
|
if (cd->screenPrivateIndex < 0)
|
|
{
|
|
compFiniDisplayOptions (d, cd->opt, CUBE_DISPLAY_OPTION_NUM);
|
|
free (cd);
|
|
return FALSE;
|
|
}
|
|
|
|
d->base.privates[cubeDisplayPrivateIndex].ptr = cd;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
cubeFiniDisplay (CompPlugin *p,
|
|
CompDisplay *d)
|
|
{
|
|
CUBE_DISPLAY (d);
|
|
|
|
freeScreenPrivateIndex (d, cd->screenPrivateIndex);
|
|
|
|
compFiniDisplayOptions (d, cd->opt, CUBE_DISPLAY_OPTION_NUM);
|
|
|
|
free (cd);
|
|
}
|
|
|
|
static const CompMetadataOptionInfo cubeScreenOptionInfo[] = {
|
|
{ "color", "color", 0, 0, 0 },
|
|
{ "in", "bool", 0, 0, 0 },
|
|
{ "scale_image", "bool", 0, 0, 0 },
|
|
{ "images", "list", "<type>string</type>", 0, 0 },
|
|
{ "skydome", "bool", 0, 0, 0 },
|
|
{ "skydome_image", "string", 0, 0, 0 },
|
|
{ "skydome_animated", "bool", 0, 0, 0 },
|
|
{ "skydome_gradient_start_color", "color", 0, 0, 0 },
|
|
{ "skydome_gradient_end_color", "color", 0, 0, 0 },
|
|
{ "acceleration", "float", "<min>1.0</min>", 0, 0 },
|
|
{ "speed", "float", "<min>0.1</min>", 0, 0 },
|
|
{ "timestep", "float", "<min>0.1</min>", 0, 0 },
|
|
{ "mipmap", "bool", 0, 0, 0 },
|
|
{ "adjust_image", "bool", 0, 0, 0 },
|
|
{ "active_opacity", "float", "<min>0.0</min><max>100.0</max>", 0, 0 },
|
|
{ "inactive_opacity", "float", "<min>0.0</min><max>100.0</max>", 0, 0 },
|
|
{ "transparent_manual_only", "bool", 0, 0, 0 },
|
|
{ "multioutput_mode", "int", "<min>0</min><max>2</max>", 0, 0 }
|
|
};
|
|
|
|
static Bool
|
|
cubeInitScreen (CompPlugin *p,
|
|
CompScreen *s)
|
|
{
|
|
CubeScreen *cs;
|
|
|
|
CUBE_DISPLAY (s->display);
|
|
|
|
cs = malloc (sizeof (CubeScreen));
|
|
if (!cs)
|
|
return FALSE;
|
|
|
|
if (!compInitScreenOptionsFromMetadata (s,
|
|
&cubeMetadata,
|
|
cubeScreenOptionInfo,
|
|
cs->opt,
|
|
CUBE_SCREEN_OPTION_NUM))
|
|
{
|
|
free (cs);
|
|
return FALSE;
|
|
}
|
|
|
|
cs->pw = 0;
|
|
cs->ph = 0;
|
|
|
|
cs->invert = 1;
|
|
|
|
cs->tc[0] = cs->tc[1] = cs->tc[2] = cs->tc[3] = 0.0f;
|
|
cs->tc[4] = cs->tc[5] = cs->tc[6] = cs->tc[7] = 0.0f;
|
|
|
|
memcpy (cs->color, cs->opt[CUBE_SCREEN_OPTION_COLOR].value.c,
|
|
sizeof (cs->color));
|
|
|
|
cs->nVertices = 0;
|
|
cs->vertices = NULL;
|
|
|
|
cs->grabIndex = 0;
|
|
|
|
cs->srcOutput = 0;
|
|
|
|
cs->skyListId = 0;
|
|
|
|
cs->getRotation = cubeGetRotation;
|
|
cs->clearTargetOutput = cubeClearTargetOutput;
|
|
cs->paintTop = cubePaintTop;
|
|
cs->paintBottom = cubePaintBottom;
|
|
cs->paintInside = cubePaintInside;
|
|
cs->checkOrientation = cubeCheckOrientation;
|
|
cs->paintViewport = cubePaintViewport;
|
|
cs->shouldPaintViewport = cubeShouldPaintViewport;
|
|
|
|
s->base.privates[cd->screenPrivateIndex].ptr = cs;
|
|
|
|
initTexture (s, &cs->texture);
|
|
initTexture (s, &cs->sky);
|
|
|
|
cs->imgCurFile = 0;
|
|
|
|
cs->unfolded = FALSE;
|
|
cs->unfold = 0.0f;
|
|
|
|
cs->unfoldVelocity = 0.0f;
|
|
|
|
cs->paintAllViewports = FALSE;
|
|
cs->fullscreenOutput = TRUE;
|
|
|
|
cs->outputXScale = 1.0f;
|
|
cs->outputYScale = 1.0f;
|
|
cs->outputXOffset = 0.0f;
|
|
cs->outputYOffset = 0.0f;
|
|
|
|
cs->rotationState = RotationNone;
|
|
|
|
cs->desktopOpacity = OPAQUE;
|
|
|
|
cs->lastOpacityIndex = CUBE_SCREEN_OPTION_INACTIVE_OPACITY;
|
|
|
|
cs->moMode = cs->opt[CUBE_SCREEN_OPTION_MULTIOUTPUT_MODE].value.i;
|
|
|
|
cs->recalcOutput = FALSE;
|
|
|
|
memset (cs->cleared, 0, sizeof (cs->cleared));
|
|
|
|
cubeUpdateOutputs (s);
|
|
|
|
if (!cubeUpdateGeometry (s, s->hsize, cs->invert))
|
|
{
|
|
compFiniScreenOptions (s, cs->opt, CUBE_SCREEN_OPTION_NUM);
|
|
free (cs);
|
|
return FALSE;
|
|
}
|
|
|
|
if (cs->opt[CUBE_SCREEN_OPTION_IMAGES].value.list.nValue)
|
|
{
|
|
cubeLoadImg (s, cs->imgCurFile);
|
|
damageScreen (s);
|
|
}
|
|
|
|
WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen);
|
|
WRAP (cs, s, donePaintScreen, cubeDonePaintScreen);
|
|
WRAP (cs, s, paintScreen, cubePaintScreen);
|
|
WRAP (cs, s, paintOutput, cubePaintOutput);
|
|
WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput);
|
|
WRAP (cs, s, enableOutputClipping, cubeEnableOutputClipping);
|
|
WRAP (cs, s, paintWindow, cubePaintWindow);
|
|
WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
|
|
WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
|
|
WRAP (cs, s, initWindowWalker, cubeInitWindowWalker);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
cubeFiniScreen (CompPlugin *p,
|
|
CompScreen *s)
|
|
{
|
|
CUBE_SCREEN (s);
|
|
|
|
if (cs->vertices)
|
|
free (cs->vertices);
|
|
|
|
if (cs->skyListId)
|
|
glDeleteLists (cs->skyListId, 1);
|
|
|
|
UNWRAP (cs, s, preparePaintScreen);
|
|
UNWRAP (cs, s, donePaintScreen);
|
|
UNWRAP (cs, s, paintScreen);
|
|
UNWRAP (cs, s, paintOutput);
|
|
UNWRAP (cs, s, paintTransformedOutput);
|
|
UNWRAP (cs, s, enableOutputClipping);
|
|
UNWRAP (cs, s, paintWindow);
|
|
UNWRAP (cs, s, applyScreenTransform);
|
|
UNWRAP (cs, s, outputChangeNotify);
|
|
UNWRAP (cs, s, initWindowWalker);
|
|
|
|
finiTexture (s, &cs->texture);
|
|
finiTexture (s, &cs->sky);
|
|
|
|
compFiniScreenOptions (s, cs->opt, CUBE_SCREEN_OPTION_NUM);
|
|
|
|
free (cs);
|
|
}
|
|
|
|
static CompBool
|
|
cubeInitObject (CompPlugin *p,
|
|
CompObject *o)
|
|
{
|
|
static InitPluginObjectProc dispTab[] = {
|
|
(InitPluginObjectProc) cubeInitCore,
|
|
(InitPluginObjectProc) cubeInitDisplay,
|
|
(InitPluginObjectProc) cubeInitScreen
|
|
};
|
|
|
|
RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
|
|
}
|
|
|
|
static void
|
|
cubeFiniObject (CompPlugin *p,
|
|
CompObject *o)
|
|
{
|
|
static FiniPluginObjectProc dispTab[] = {
|
|
(FiniPluginObjectProc) cubeFiniCore,
|
|
(FiniPluginObjectProc) cubeFiniDisplay,
|
|
(FiniPluginObjectProc) cubeFiniScreen
|
|
};
|
|
|
|
DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
|
|
}
|
|
|
|
static CompOption *
|
|
cubeGetObjectOptions (CompPlugin *plugin,
|
|
CompObject *object,
|
|
int *count)
|
|
{
|
|
static GetPluginObjectOptionsProc dispTab[] = {
|
|
(GetPluginObjectOptionsProc) 0, /* GetCoreOptions */
|
|
(GetPluginObjectOptionsProc) cubeGetDisplayOptions,
|
|
(GetPluginObjectOptionsProc) cubeGetScreenOptions
|
|
};
|
|
|
|
*count = 0;
|
|
RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab),
|
|
(void *) count, (plugin, object, count));
|
|
}
|
|
|
|
static CompBool
|
|
cubeSetObjectOption (CompPlugin *plugin,
|
|
CompObject *object,
|
|
const char *name,
|
|
CompOptionValue *value)
|
|
{
|
|
static SetPluginObjectOptionProc dispTab[] = {
|
|
(SetPluginObjectOptionProc) 0, /* SetCoreOption */
|
|
(SetPluginObjectOptionProc) cubeSetDisplayOption,
|
|
(SetPluginObjectOptionProc) cubeSetScreenOption
|
|
};
|
|
|
|
RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab), FALSE,
|
|
(plugin, object, name, value));
|
|
}
|
|
|
|
static Bool
|
|
cubeInit (CompPlugin *p)
|
|
{
|
|
if (!compInitPluginMetadataFromInfo (&cubeMetadata,
|
|
p->vTable->name,
|
|
cubeDisplayOptionInfo,
|
|
CUBE_DISPLAY_OPTION_NUM,
|
|
cubeScreenOptionInfo,
|
|
CUBE_SCREEN_OPTION_NUM))
|
|
return FALSE;
|
|
|
|
cubeCorePrivateIndex = allocateCorePrivateIndex ();
|
|
if (cubeCorePrivateIndex < 0)
|
|
{
|
|
compFiniMetadata (&cubeMetadata);
|
|
return FALSE;
|
|
}
|
|
|
|
compAddMetadataFromFile (&cubeMetadata, p->vTable->name);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
cubeFini (CompPlugin *p)
|
|
{
|
|
freeCorePrivateIndex (cubeCorePrivateIndex);
|
|
compFiniMetadata (&cubeMetadata);
|
|
}
|
|
|
|
static CompMetadata *
|
|
cubeGetMetadata (CompPlugin *plugin)
|
|
{
|
|
return &cubeMetadata;
|
|
}
|
|
|
|
CompPluginVTable cubeVTable = {
|
|
"cube",
|
|
cubeGetMetadata,
|
|
cubeInit,
|
|
cubeFini,
|
|
cubeInitObject,
|
|
cubeFiniObject,
|
|
cubeGetObjectOptions,
|
|
cubeSetObjectOption
|
|
};
|
|
|
|
CompPluginVTable *
|
|
getCompPluginInfo20070830 (void)
|
|
{
|
|
return &cubeVTable;
|
|
}
|