7
* Copyright (c) 2008 Dennis Kasprzyk <racarr@opencompositing.org>
8
* Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
11
* Robert Carr <racarr@beryl-project.org>
12
* Dennis Kasprzyk <onestone@opencompositing.org>
14
* This program is free software; you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License
16
* as published by the Free Software Foundation; either version 2
17
* of the License, or (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
30
COMPIZ_PLUGIN_20090315 (expo, ExpoPluginVTable);
32
#define sigmoid(x) (1.0f / (1.0f + exp (-5.5f * 2 * ((x) - 0.5))))
33
#define sigmoidProgress(x) ((sigmoid (x) - sigmoid (0)) / \
34
(sigmoid (1) - sigmoid (0)))
36
#define interpolate(a, b, val) (((val) * (a)) + ((1 - (val)) * (b)))
39
ExpoScreen::dndInit (CompAction *action,
40
CompAction::State state,
41
CompOption::Vector& options)
43
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
44
if (xid != screen->root ())
50
action->setState (action->state () | CompAction::StateTermButton);
51
cScreen->damageScreen ();
60
ExpoScreen::dndFini (CompAction *action,
61
CompAction::State state,
62
CompOption::Vector& options)
64
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
65
if (xid != screen->root ())
68
if (dndState == DnDDuring || dndState == DnDStart)
71
finishWindowMovement ();
76
action->setState (action->state () & CompAction::StateInitButton);
77
cScreen->damageScreen ();
86
ExpoScreen::doExpo (CompAction *action,
87
CompAction::State state,
88
CompOption::Vector& options)
90
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
91
if (xid != screen->root ())
94
if (screen->otherGrabExist ("expo", NULL))
100
grabIndex = screen->pushGrab (None, "expo");
112
selectedVp = screen->vp ();
113
origVp = screen->vp ();
115
screen->addAction (&optionGetDndButton ());
116
screen->addAction (&optionGetExitButton ());
117
screen->addAction (&optionGetNextVpButton ());
118
screen->addAction (&optionGetPrevVpButton ());
120
cScreen->damageScreen ();
124
termExpo (action, state, options);
131
ExpoScreen::termExpo (CompAction *action,
132
CompAction::State state,
133
CompOption::Vector& options)
135
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
136
if (xid && xid != screen->root ())
144
if (dndState != DnDNone)
145
dndFini (action, state, options);
147
if (state & CompAction::StateCancel)
148
vpUpdateMode = VPUpdatePrevious;
150
vpUpdateMode = VPUpdateMouseOver;
155
screen->removeAction (&optionGetDndButton ());
156
screen->removeAction (&optionGetExitButton ());
157
screen->removeAction (&optionGetNextVpButton ());
158
screen->removeAction (&optionGetPrevVpButton ());
160
cScreen->damageScreen ();
161
screen->focusDefaultWindow ();
167
ExpoScreen::exitExpo (CompAction *action,
168
CompAction::State state,
169
CompOption::Vector& options)
171
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
172
if (xid != screen->root ())
178
termExpo (action, 0, noOptions);
180
cScreen->damageScreen ();
186
ExpoScreen::nextVp (CompAction *action,
187
CompAction::State state,
188
CompOption::Vector& options)
190
unsigned int newX, newY;
191
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
192
if (xid != screen->root ())
198
newX = selectedVp.x () + 1;
199
newY = selectedVp.y ();
201
if (newX >= (unsigned int) screen->vpSize ().width ())
205
if (newY >= (unsigned int) screen->vpSize ().height ())
209
moveFocusViewport (newX - selectedVp.x (),
210
newY - selectedVp.y ());
211
cScreen->damageScreen ();
217
ExpoScreen::prevVp (CompAction *action,
218
CompAction::State state,
219
CompOption::Vector& options)
221
unsigned int newX, newY;
222
Window xid = CompOption::getIntOptionNamed (options, "root", 0);
223
if (xid != screen->root ())
229
newX = selectedVp.x () - 1;
230
newY = selectedVp.y ();
234
newX = screen->vpSize ().width () - 1;
237
newY = screen->vpSize ().height () - 1;
240
moveFocusViewport (newX - selectedVp.x (),
241
newY - selectedVp.y ());
242
cScreen->damageScreen ();
248
ExpoScreen::moveFocusViewport (int dx,
253
newX = selectedVp.x () + dx;
254
newY = selectedVp.y () + dy;
256
newX = MAX (0, MIN ((int) screen->vpSize ().width () - 1, newX));
257
newY = MAX (0, MIN ((int) screen->vpSize ().height () - 1, newY));
259
selectedVp.set (newX, newY);
260
cScreen->damageScreen ();
264
ExpoScreen::finishWindowMovement ()
266
dndWindow->syncPosition ();
267
dndWindow->ungrabNotify ();
269
screen->moveViewport (screen->vp ().x () - selectedVp.x (),
270
screen->vp ().y () - selectedVp.y (), true);
272
/* update saved window attributes in case we moved the
273
window to a new viewport */
274
if (dndWindow->saveMask () & CWX)
276
dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
277
if (dndWindow->saveWc ().x < 0)
278
dndWindow->saveWc ().x += screen->width ();
280
if (dndWindow->saveMask () & CWY)
282
dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
283
if (dndWindow->saveWc ().y < 0)
284
dndWindow->saveWc ().y += screen->height ();
287
/* update window attibutes to make sure a moved maximized window
288
is properly snapped to the work area */
289
if (dndWindow->state () & MAXIMIZE_STATE)
290
dndWindow->updateAttributes (CompStackingUpdateModeNone);
292
#if 0 /* FIXME: obsolete in the meantime? */
295
int centerX, centerY;
297
/* make sure we snap to the correct output */
298
lastOutput = s->currentOutputDev;
299
centerX = (WIN_X (w) + WIN_W (w) / 2) % s->width;
302
centerY = (WIN_Y (w) + WIN_H (w) / 2) % s->height;
304
centerY += s->height;
306
s->currentOutputDev = outputDeviceForPoint (s, centerX, centerY);
308
updateWindowAttributes (w, CompStackingUpdateModeNone);
310
s->currentOutputDev = lastOutput;
316
ExpoScreen::handleEvent (XEvent *event)
318
switch (event->type) {
320
if (expoMode && event->xkey.root == screen->root ())
322
if (event->xkey.keycode == leftKey)
323
moveFocusViewport (-1, 0);
324
else if (event->xkey.keycode == rightKey)
325
moveFocusViewport (1, 0);
326
else if (event->xkey.keycode == upKey)
327
moveFocusViewport (0, -1);
328
else if (event->xkey.keycode == downKey)
329
moveFocusViewport (0, 1);
334
if (expoMode && event->xbutton.button == Button1 &&
335
event->xbutton.root == screen->root ())
340
clickTime = event->xbutton.time;
342
else if (event->xbutton.time - clickTime <=
343
(unsigned int) optionGetDoubleClickTime ())
349
clickTime = event->xbutton.time;
352
cScreen->damageScreen ();
357
if (expoMode && event->xbutton.button == Button1 &&
358
event->xbutton.root == screen->root ())
360
if (event->xbutton.time - clickTime >
361
(unsigned int) optionGetDoubleClickTime ())
366
else if (doubleClick)
368
CompAction& action = optionGetExpoKey ();
373
termExpo (&action, 0, noOptions);
380
screen->handleEvent (event);
384
ExpoScreen::preparePaint (int msSinceLastPaint)
386
float val = ((float) msSinceLastPaint / 1000.0) / optionGetZoomTime ();
389
expoCam = MIN (1.0, expoCam + val);
391
expoCam = MAX (0.0, expoCam - val);
395
unsigned int i, j, vp;
396
unsigned int vpCount = screen->vpSize ().width () *
397
screen->vpSize ().height ();
399
if (vpActivity.size () < vpCount)
401
vpActivity.resize (vpCount);
402
foreach (float& activity, vpActivity)
406
for (i = 0; i < (unsigned int) screen->vpSize ().width (); i++)
408
for (j = 0; j < (unsigned int) screen->vpSize ().height (); j++)
410
vp = (j * screen->vpSize ().width ()) + i;
412
if (CompPoint (i, j) == selectedVp)
413
vpActivity[vp] = MIN (1.0, vpActivity[vp] + val);
415
vpActivity[vp] = MAX (0.0, vpActivity[vp] - val);
419
for (i = 0; i < 360; i++)
421
float fi = (float) i;
423
vpNormals[i * 3] = (-sin (fi * DEG2RAD) / screen->width ()) *
425
vpNormals[(i * 3) + 1] = 0.0;
426
vpNormals[(i * 3) + 2] = (-cos (fi * DEG2RAD) * expoCam) -
431
cScreen->preparePaint (msSinceLastPaint);
435
ExpoScreen::updateWraps (bool enable)
437
screen->handleEventSetEnabled (this, enable);
438
cScreen->preparePaintSetEnabled (this, enable);
439
cScreen->paintSetEnabled (this, enable);
440
cScreen->donePaintSetEnabled (this, enable);
441
gScreen->glPaintOutputSetEnabled (this, enable);
442
gScreen->glPaintTransformedOutputSetEnabled (this, enable);
444
foreach (CompWindow *w, screen->windows ())
446
ExpoWindow *ew = ExpoWindow::get (w);
448
ew->cWindow->damageRectSetEnabled (ew, enable);
449
ew->gWindow->glPaintSetEnabled (ew, enable);
450
ew->gWindow->glDrawSetEnabled (ew, enable);
451
ew->gWindow->glAddGeometrySetEnabled (ew, enable);
452
ew->gWindow->glDrawTextureSetEnabled (ew, enable);
457
ExpoScreen::paint (CompOutput::ptrList& outputs,
460
int width = outputs.front ()->width ();
461
int height = outputs.front ()->height ();
462
bool sizeDiff = false;
464
/* "One big wall" does not make sense where outputs are different
465
* sizes, so force multiple walls in this case
467
* TODO: Is it possible to re-create "one big wall" using
468
* independent output painting in this case? */
470
foreach (CompOutput *o, outputs)
472
if (o->width () != width || o->height () != height)
479
if (expoCam > 0.0 && outputs.size () > 1 &&
480
optionGetMultioutputMode () == MultioutputModeOneBigWall &&
484
outputs.push_back (&screen->fullscreenOutput ());
487
cScreen->paint (outputs, mask);
491
ExpoScreen::donePaint ()
493
switch (vpUpdateMode) {
494
case VPUpdateMouseOver:
495
screen->moveViewport (screen->vp ().x () - selectedVp.x (),
496
screen->vp ().y () - selectedVp.y (), true);
497
screen->focusDefaultWindow ();
498
vpUpdateMode = VPUpdateNone;
500
case VPUpdatePrevious:
501
screen->moveViewport (screen->vp ().x () - origVp.x (),
502
screen->vp ().y () - origVp.y (), true);
504
screen->focusDefaultWindow ();
505
vpUpdateMode = VPUpdateNone;
511
if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone)
512
cScreen->damageScreen ();
516
foreach (float& vp, vpActivity)
517
if (vp != 0.0 && vp != 1.0)
518
cScreen->damageScreen ();
521
if (grabIndex && expoCam <= 0.0f && !expoMode)
523
screen->removeGrab (grabIndex, NULL);
528
cScreen->donePaint ();
534
dndWindow->move (newCursor.x () - prevCursor.x (),
535
newCursor.y () - prevCursor.y (),
536
optionGetExpoImmediateMove ());
538
prevCursor = newCursor;
539
cScreen->damageScreen ();
545
int xOffset, yOffset;
546
CompWindowList::reverse_iterator iter;
548
xOffset = screen->vpSize ().width () * screen->width ();
549
yOffset = screen->vpSize ().height () * screen->height ();
553
for (iter = screen->windows ().rbegin ();
554
iter != screen->windows ().rend (); ++iter)
556
CompWindow *w = *iter;
557
CompRect input (w->inputRect ());
564
if (!w->shaded () && !w->isViewable ())
567
if (w->onAllViewports ())
569
nx = (newCursor.x () + xOffset) % screen->width ();
570
ny = (newCursor.y () + yOffset) % screen->height ();
574
nx = newCursor.x () -
575
(screen->vp ().x () * screen->width ());
576
ny = newCursor.y () -
577
(screen->vp ().y () * screen->height ());
580
inWindow = (nx >= input.left () && nx <= input.right ()) ||
581
(nx >= (input.left () + xOffset) &&
582
nx <= (input.right () + xOffset));
584
inWindow &= (ny >= input.top () && ny <= input.bottom ()) ||
585
(ny >= (input.top () + yOffset) &&
586
ny <= (input.bottom () + yOffset));
591
/* make sure we never move windows we're not allowed to move */
594
else if (!(w->actions () & CompWindowActionMoveMask))
596
else if (w->type () & (CompWindowTypeDockMask |
597
CompWindowTypeDesktopMask))
600
dndState = DnDDuring;
603
w->grabNotify (nx, ny, 0,
604
CompWindowGrabMoveMask |
605
CompWindowGrabButtonMask);
608
w->moveInputFocusTo ();
612
prevCursor = newCursor;
621
ExpoScreen::invertTransformedVertex (const GLScreenPaintAttrib& attrib,
622
const GLMatrix& transform,
626
GLMatrix sTransform (transform);
627
GLdouble p1[3], p2[3], v[3], alpha;
628
GLdouble mvm[16], pm[16];
632
gScreen->glApplyTransform (attrib, output, &sTransform);
633
sTransform.toScreenSpace (output, -attrib.zTranslate);
635
glGetIntegerv (GL_VIEWPORT, viewport);
636
for (i = 0; i < 16; i++)
638
mvm[i] = sTransform[i];
639
pm[i] = gScreen->projectionMatrix ()[i];
642
gluUnProject (vertex[0], screen->height () - vertex[1], 0, mvm, pm,
643
viewport, &p1[0], &p1[1], &p1[2]);
644
gluUnProject (vertex[0], screen->height () - vertex[1], -1.0, mvm, pm,
645
viewport, &p2[0], &p2[1], &p2[2]);
647
for (i = 0; i < 3; i++)
648
v[i] = p1[i] - p2[i];
650
alpha = -p1[2] / v[2];
652
if (optionGetDeform () == DeformCurve && screen->desktopWindowCount ())
654
const float sws = screen->width () * screen->width ();
655
const float rs = (curveDistance * curveDistance) + 0.25;
656
const float p = ((2.0 * sws * (p1[2] - curveDistance) * v[2]) +
657
(2.0 * p1[0] * v[0]) -
658
(v[0] * (float) screen->width ())) /
659
((v[2] * v[2] * sws) + (v[0] * v[0]));
660
const float q = (-(sws * rs) + (sws * (p1[2] - curveDistance) *
661
(p1[2] - curveDistance)) +
662
(0.25 * sws) + (p1[0] * p1[0]) -
663
(p1[0] * (float) screen->width ())) /
664
((v[2] * v[2] * sws) + (v[0] * v[0]));
666
const float rq = (0.25 * p * p) - q;
667
const float ph = -p * 0.5;
677
alpha = ph + sqrt(rq);
678
if (p1[2] + (alpha * v[2]) > 0.0)
687
vertex[0] = ceil (p1[0] + (alpha * v[0]));
688
vertex[1] = ceil (p1[1] + (alpha * v[1]));
692
ExpoScreen::paintWall (const GLScreenPaintAttrib& attrib,
693
const GLMatrix& transform,
694
const CompRegion& region,
699
GLMatrix sTransformW, sTransform (transform);
701
GLenum oldFilter = gScreen->textureFilter ();
703
float sx = (float) screen->width () / output->width ();
704
float sy = (float) screen->height () / output->height ();
706
float oScale, rotation = 0.0f, progress, vpp;
707
float aspectX = 1.0f, aspectY = 1.0f;
709
CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
711
/* amount of gap between viewports */
712
const float gapY = optionGetVpDistance () * 0.1f * expoCam;
713
const float gapX = optionGetVpDistance () * 0.1f * screen->height () /
714
screen->width () * expoCam;
716
int glPaintTransformedOutputIndex =
717
gScreen->glPaintTransformedOutputGetCurrentIndex ();
719
// Make sure that the base glPaintTransformedOutput function is called
720
gScreen->glPaintTransformedOutputSetCurrentIndex (MAXSHORT);
722
/* Zoom animation stuff */
723
/* camera position for the selected viewport */
724
GLVector vpCamPos (0, 0, 0, 0);
726
/* camera position during expo mode */
727
GLVector expoCamPos (0, 0, 0, 0);
729
if (optionGetDeform () == DeformCurve)
731
vpCamPos[GLVector::x] = -sx * (0.5 - (((float) output->x () +
732
(output->width () / 2.0)) /
733
(float) screen->width ()));
737
vpCamPos[GLVector::x] = (screen->vp ().x () * sx) + 0.5 +
738
(output->x () / output->width ()) -
739
(vpSize.x () * 0.5 * sx) +
740
gapX * screen->vp ().x ();
742
vpCamPos[GLVector::y] = -((screen->vp ().y () * sy) + 0.5 +
743
(output->y () / output->height ())) +
744
(vpSize.y () * 0.5 * sy) -
745
gapY * screen->vp ().y ();
747
biasZ = MAX (vpSize.x () * sx, vpSize.y () * sy);
748
if (optionGetDeform () == DeformTilt || optionGetReflection ())
749
biasZ *= (0.15 + optionGetDistance ());
751
biasZ *= optionGetDistance ();
753
progress = sigmoidProgress (expoCam);
755
if (optionGetDeform () != DeformCurve)
756
expoCamPos[GLVector::x] = gapX * (vpSize.x () - 1) * 0.5;
758
expoCamPos[GLVector::y] = -gapY * (vpSize.y () - 1) * 0.5;
759
expoCamPos[GLVector::z] = -DEFAULT_Z_CAMERA + DEFAULT_Z_CAMERA *
760
(MAX (vpSize.x () + (vpSize.x () - 1) * gapX,
761
vpSize.y () + (vpSize.y () - 1) * gapY) +
764
/* interpolate between vpCamPos and expoCamPos */
765
cam[GLVector::x] = vpCamPos[GLVector::x] * (1 - progress) +
766
expoCamPos[GLVector::x] * progress;
767
cam[GLVector::y] = vpCamPos[GLVector::y] * (1 - progress) +
768
expoCamPos[GLVector::y] * progress;
769
cam[GLVector::z] = vpCamPos[GLVector::z] * (1 - progress) +
770
expoCamPos[GLVector::z] * progress;
772
if (vpSize.x () > vpSize.y ())
774
aspectY = (float) vpSize.x () / (float) vpSize.y ();
776
aspectY *= -optionGetAspectRatio () + 1.0;
782
aspectX = (float) vpSize.y () / (float) vpSize.x ();
784
aspectX *= -optionGetAspectRatio () + 1.0;
789
/* End of Zoom animation stuff */
791
if (optionGetDeform () == DeformTilt)
793
if (optionGetExpoAnimation () == ExpoAnimationZoom)
794
rotation = 10.0 * sigmoidProgress (expoCam);
796
rotation = 10.0 * expoCam;
799
if (optionGetMipmaps ())
800
gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
802
/* ALL TRANSFORMATION ARE EXECUTED FROM BOTTOM TO TOP */
804
oScale = 1 / (1 + ((MAX (sx, sy) - 1) * progress));
806
sTransform.scale (oScale, oScale, 1.0);
809
oScale = DEFAULT_Z_CAMERA / (cam[GLVector::z] + DEFAULT_Z_CAMERA);
810
sTransform.scale (oScale, oScale, oScale);
811
glNormal3f (0.0, 0.0, -oScale);
812
sTransform.translate (-cam[GLVector::x], -cam[GLVector::y],
813
-cam[GLVector::z] - DEFAULT_Z_CAMERA);
817
float scaleFactor = optionGetScaleFactor ();
819
sTransform.translate (0.0,
820
(vpSize.y () + ((vpSize.y () - 1) * gapY * 2)) *
823
sTransform.scale (1.0, -1.0, 1.0);
824
sTransform.translate (0.0,
825
- (1 - scaleFactor) / 2 * sy * aspectY *
826
(vpSize.y () + ((vpSize.y () - 1) * gapY * 2)),
828
sTransform.scale (1.0, scaleFactor, 1.0);
829
glCullFace (GL_FRONT);
833
sTransform.rotate (rotation, 0.0f, 1.0f, 0.0f);
834
sTransform.scale (aspectX, aspectY, 1.0);
836
/* translate expo to center */
837
sTransform.translate (vpSize.x () * sx * -0.5,
838
vpSize.y () * sy * 0.5, 0.0f);
840
if (optionGetDeform () == DeformCurve)
841
sTransform.translate ((vpSize.x () - 1) * sx * 0.5, 0.0, 0.0);
843
sTransformW = sTransform;
845
/* revert prepareXCoords region shift. Now all screens display the same */
846
sTransform.translate (0.5f, -0.5f, DEFAULT_Z_CAMERA);
849
/* we can't have 90 degree for the left/right most viewport */
850
curveAngle = interpolate (359 / ((vpSize.x () - 1) * 2), 1,
853
curveAngle = interpolate (180 / vpSize.x (), 1, optionGetCurve ());
855
curveDistance = ((0.5f * sx) + (gapX / 2.0)) /
856
tanf (DEG2RAD * curveAngle / 2.0);
857
curveRadius = ((0.5f * sx) + (gapX / 2.0)) /
858
sinf (DEG2RAD * curveAngle / 2.0);
862
for (j = 0; j < vpSize.y (); j++)
864
GLMatrix sTransform2 (sTransform), sTransform3;
866
for (i = 0; i < vpSize.x (); i++)
868
if (optionGetExpoAnimation () == ExpoAnimationVortex)
869
sTransform2.rotate (360 * expoCam,
870
0.0f, 1.0f, 2.0f * expoCam);
872
sTransform3 = sTransform2;
874
sTransform3.translate (output->x () / output->width (),
875
-output->y () / output->height (), 0.0);
877
cScreen->setWindowPaintOffset ((screen->vp ().x () - i) *
879
(screen->vp ().y () - j) *
882
vp = (j * vpSize.x ()) + i;
884
vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
885
vpp = sigmoidProgress (vpp);
887
vpBrightness = vpp + ((1.0 - vpp) *
888
optionGetVpBrightness () / 100.0);
889
vpSaturation = vpp + ((1.0 - vpp) *
890
optionGetVpSaturation () / 100.0);
892
paintingVp.set (i, j);
894
if (optionGetDeform () == DeformCurve)
898
sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
899
curveDistance - DEFAULT_Z_CAMERA);
901
rotateX = -i + interpolate (((float) vpSize.x () / 2.0) - 0.5,
902
screen->vp ().x (), progress);
904
sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
906
sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
907
DEFAULT_Z_CAMERA - curveDistance);
910
gScreen->glPaintTransformedOutput (attrib, sTransform3,
911
screen->region (), output,
916
int cursor[2] = { pointerX, pointerY };
918
invertTransformedVertex (attrib, sTransform3,
921
if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
922
(cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
924
newCursor.setX (i * screen->width () + cursor[0]);
925
newCursor.setY (j * screen->height () + cursor[1]);
927
if (anyClick || dndState != DnDNone)
929
/* Used to save last viewport interaction was in */
930
selectedVp.set (i, j);
936
/* not sure this will work with different resolutions */
937
if (optionGetDeform () != DeformCurve)
938
sTransform2.translate (sx + gapX, 0.0f, 0.0);
941
/* not sure this will work with different resolutions */
942
sTransform.translate (0.0, -(sy + gapY), 0.0f);
945
glNormal3f (0.0, 0.0, -1.0);
950
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
954
if (optionGetDeform () != DeformCurve)
956
glLoadMatrixf (sTransformW.getMatrix ());
959
glColor4f (0.0, 0.0, 0.0, 1.0);
960
glVertex2f (0.0, 0.0);
961
glColor4f (0.0, 0.0, 0.0, 0.5);
962
glVertex2f (0.0, -vpSize.y () * (sy + gapY));
963
glVertex2f (vpSize.x () * sx * (1.0 + gapX),
964
-vpSize.y () * sy * (1.0 + gapY));
965
glColor4f (0.0, 0.0, 0.0, 1.0);
966
glVertex2f (vpSize.x () * sx * (1.0 + gapX), 0.0);
971
glCullFace (GL_BACK);
973
glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
976
glColor4f (0.0, 0.0, 0.0, 1.0 * expoCam);
977
glVertex2f (-0.5, -0.5);
978
glVertex2f (0.5, -0.5);
979
glColor4f (0.0, 0.0, 0.0, 0.5 * expoCam);
980
glVertex2f (0.5, 0.0);
981
glVertex2f (-0.5, 0.0);
982
glColor4f (0.0, 0.0, 0.0, 0.5 * expoCam);
983
glVertex2f (-0.5, 0.0);
984
glVertex2f (0.5, 0.0);
985
glColor4f (0.0, 0.0, 0.0, 0.0);
986
glVertex2f (0.5, 0.5);
987
glVertex2f (-0.5, 0.5);
990
glCullFace (GL_BACK);
993
glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
995
if (optionGetGroundSize () > 0.0)
998
glColor4usv (optionGetGroundColor1 ());
999
glVertex2f (-0.5, -0.5);
1000
glVertex2f (0.5, -0.5);
1001
glColor4usv (optionGetGroundColor2 ());
1002
glVertex2f (0.5, -0.5 + optionGetGroundSize ());
1003
glVertex2f (-0.5, -0.5 + optionGetGroundSize ());
1007
glColor4usv (defaultColor);
1009
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1010
glDisable (GL_BLEND);
1016
cScreen->setWindowPaintOffset (0, 0);
1018
gScreen->glPaintTransformedOutputSetCurrentIndex (glPaintTransformedOutputIndex);
1019
gScreen->setTextureFilter (oldFilter);
1023
ExpoScreen::glPaintOutput (const GLScreenPaintAttrib& attrib,
1024
const GLMatrix& transform,
1025
const CompRegion& region,
1030
mask |= PAINT_SCREEN_TRANSFORMED_MASK | PAINT_SCREEN_CLEAR_MASK;
1032
return gScreen->glPaintOutput (attrib, transform, region, output, mask);
1036
ExpoScreen::glPaintTransformedOutput (const GLScreenPaintAttrib& attrib,
1037
const GLMatrix& transform,
1038
const CompRegion& region,
1045
mask |= PAINT_SCREEN_CLEAR_MASK;
1047
if (expoCam <= 0 || (expoCam > 0.0 && expoCam < 1.0 &&
1048
optionGetExpoAnimation () != ExpoAnimationZoom))
1050
gScreen->glPaintTransformedOutput (attrib, transform, region,
1055
gScreen->clearOutput (output, GL_COLOR_BUFFER_BIT);
1058
mask &= ~PAINT_SCREEN_CLEAR_MASK;
1062
if (optionGetReflection ())
1063
paintWall (attrib, transform, region, output, mask, true);
1065
paintWall (attrib, transform, region, output, mask, false);
1071
ExpoWindow::glDraw (const GLMatrix& transform,
1072
GLFragment::Attrib& fragment,
1073
const CompRegion& region,
1076
if (eScreen->expoCam == 0.0f)
1077
return gWindow->glDraw (transform, fragment, region, mask);
1079
GLFragment::Attrib fA (fragment);
1082
expoAnimation = eScreen->optionGetExpoAnimation ();
1084
if (eScreen->expoActive)
1086
if (expoAnimation != ExpoScreen::ExpoAnimationZoom)
1087
fA.setOpacity (fragment.getOpacity () * eScreen->expoCam);
1089
if (window->wmType () & CompWindowTypeDockMask &&
1090
eScreen->optionGetHideDocks ())
1092
if (expoAnimation == ExpoScreen::ExpoAnimationZoom &&
1093
eScreen->paintingVp == eScreen->selectedVp)
1095
fA.setOpacity (fragment.getOpacity () *
1096
(1 - sigmoidProgress (eScreen->expoCam)));
1104
fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
1105
fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
1109
if (expoAnimation == ExpoScreen::ExpoAnimationZoom)
1110
fA.setBrightness (0);
1112
fA.setBrightness (fragment.getBrightness () *
1113
(1 - sigmoidProgress (eScreen->expoCam)));
1116
return gWindow->glDraw (transform, fA, region, mask);
1119
#define EXPO_GRID_SIZE 100
1122
ExpoWindow::glAddGeometry (const GLTexture::MatrixList& matrices,
1123
const CompRegion& region,
1124
const CompRegion& clip,
1125
unsigned int maxGridWidth,
1126
unsigned int maxGridHeight)
1128
if (eScreen->expoCam > 0.0 &&
1129
screen->desktopWindowCount () &&
1130
eScreen->optionGetDeform () == ExpoScreen::DeformCurve)
1132
int i, oldVCount = gWindow->geometry ().vCount;
1135
float lastX, lastZ = 0.0;
1136
const float radSquare = pow (eScreen->curveDistance, 2) + 0.25;
1139
gWindow->glAddGeometry (matrices, region, clip,
1140
MIN(maxGridWidth , EXPO_GRID_SIZE),
1143
v = gWindow->geometry ().vertices;
1144
v += gWindow->geometry ().vertexStride - 3;
1145
v += gWindow->geometry ().vertexStride * oldVCount;
1147
if (!window->onAllViewports ())
1149
offset = eScreen->cScreen->windowPaintOffset ();
1150
offset = window->getMovementForOffset (offset);
1153
lastX = -1000000000.0;
1155
for (i = oldVCount; i < gWindow->geometry ().vCount; i++)
1161
else if (v[0] + offset.x () >= -EXPO_GRID_SIZE &&
1162
v[0] + offset.x () < screen->width () + EXPO_GRID_SIZE)
1164
ang = (((v[0] + offset.x ()) / (float) screen->width ()) - 0.5);
1166
if (ang < radSquare)
1168
v[2] = eScreen->curveDistance - sqrt (radSquare - ang);
1169
v[2] *= sigmoidProgress (eScreen->expoCam);
1176
v += gWindow->geometry ().vertexStride;
1181
gWindow->glAddGeometry (matrices, region, clip, maxGridWidth, maxGridHeight);
1186
ExpoWindow::glDrawTexture (GLTexture *texture,
1187
GLFragment::Attrib& attrib,
1190
if (eScreen->expoCam > 0.0 &&
1191
eScreen->optionGetDeform () == ExpoScreen::DeformCurve &&
1192
eScreen->gScreen->lighting () &&
1193
screen->desktopWindowCount ())
1195
unsigned int i, idx, vCount;
1200
vCount = gWindow->geometry ().vCount;
1202
if (eScreen->winNormals.size () < vCount * 3)
1203
eScreen->winNormals.resize (vCount * 3);
1205
if (!window->onAllViewports ())
1207
offset = eScreen->cScreen->windowPaintOffset ();
1208
offset = window->getMovementForOffset (offset);
1211
v = gWindow->geometry ().vertices +
1212
(gWindow->geometry ().vertexStride - 3);
1214
for (i = 0; i < vCount; i++)
1216
x = (float) (v[0] + offset.x () - screen->width () / 2) *
1217
eScreen->curveAngle / screen->width ();
1224
eScreen->winNormals[i * 3] = -eScreen->vpNormals[idx * 3];
1225
eScreen->winNormals[(i * 3) + 1] =
1226
eScreen->vpNormals[(idx * 3) + 1];
1227
eScreen->winNormals[(i * 3) + 2] =
1228
eScreen->vpNormals[(idx * 3) + 2];
1230
v += gWindow->geometry ().vertexStride;
1233
glEnable (GL_NORMALIZE);
1234
glNormalPointer (GL_FLOAT,0, &eScreen->winNormals.at (0));
1236
glEnableClientState (GL_NORMAL_ARRAY);
1238
gWindow->glDrawTexture (texture, attrib, mask);
1240
glDisable (GL_NORMALIZE);
1241
glDisableClientState (GL_NORMAL_ARRAY);
1242
glNormal3f (0.0, 0.0, -1.0);
1246
glEnable (GL_NORMALIZE);
1247
gWindow->glDrawTexture (texture, attrib, mask);
1248
glDisable (GL_NORMALIZE);
1253
ExpoWindow::glPaint (const GLWindowPaintAttrib& attrib,
1254
const GLMatrix& transform,
1255
const CompRegion& region,
1258
if (eScreen->expoActive)
1260
float opacity = 1.0;
1264
zoomAnim = eScreen->optionGetExpoAnimation () ==
1265
ExpoScreen::ExpoAnimationZoom;
1266
hide = eScreen->optionGetHideDocks () &&
1267
(window->wmType () & CompWindowTypeDockMask);
1269
if (eScreen->expoCam > 0.0)
1271
if (eScreen->expoCam < 1.0 && !zoomAnim)
1272
mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1274
mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1278
opacity = attrib.opacity * eScreen->expoCam;
1282
if (zoomAnim && eScreen->paintingVp == eScreen->selectedVp)
1283
opacity = attrib.opacity *
1284
(1 - sigmoidProgress (eScreen->expoCam));
1290
mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1293
return gWindow->glPaint (attrib, transform, region, mask);
1297
ExpoWindow::damageRect (bool initial,
1298
const CompRect& rect)
1300
if (eScreen->expoCam > 0.0f)
1301
eScreen->cScreen->damageScreen ();
1303
return cWindow->damageRect (initial, rect);
1306
#define EXPOINITBIND(opt, func) \
1307
optionSet##opt##Initiate (boost::bind (&ExpoScreen::func, \
1309
#define EXPOTERMBIND(opt, func) \
1310
optionSet##opt##Terminate (boost::bind (&ExpoScreen::func, \
1313
ExpoScreen::ExpoScreen (CompScreen *s) :
1314
PluginClassHandler<ExpoScreen, CompScreen> (s),
1316
cScreen (CompositeScreen::get (s)),
1317
gScreen (GLScreen::get (s)),
1324
selectedVp (s->vp ()),
1325
vpUpdateMode (VPUpdateNone),
1327
doubleClick (false),
1328
vpNormals (360 * 3),
1331
leftKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Left"));
1332
rightKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Right"));
1333
upKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Up"));
1334
downKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Down"));
1336
EXPOINITBIND (ExpoKey, doExpo);
1337
EXPOTERMBIND (ExpoKey, termExpo);
1338
EXPOINITBIND (ExpoButton, doExpo);
1339
EXPOTERMBIND (ExpoButton, termExpo);
1340
EXPOINITBIND (ExpoEdge, doExpo);
1341
EXPOTERMBIND (ExpoButton, termExpo);
1343
EXPOINITBIND (DndButton, dndInit);
1344
EXPOTERMBIND (DndButton, dndFini);
1345
EXPOINITBIND (ExitButton, exitExpo);
1346
EXPOINITBIND (NextVpButton, nextVp);
1347
EXPOINITBIND (PrevVpButton, prevVp);
1349
ScreenInterface::setHandler (screen, false);
1350
CompositeScreenInterface::setHandler (cScreen, false);
1351
GLScreenInterface::setHandler (gScreen, false);
1354
ExpoWindow::ExpoWindow (CompWindow *w) :
1355
PluginClassHandler<ExpoWindow, CompWindow> (w),
1357
cWindow (CompositeWindow::get (w)),
1358
gWindow (GLWindow::get (w)),
1359
eScreen (ExpoScreen::get (screen))
1361
CompositeWindowInterface::setHandler (cWindow, false);
1362
GLWindowInterface::setHandler (gWindow, false);
1366
ExpoPluginVTable::init ()
1368
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1369
!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1370
!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))