~lbrulet-8/compiz-plugins-main/fix-876591

« back to all changes in this revision

Viewing changes to expo/src/expo.cpp

  • Committer: Package Import Robot
  • Author(s): Didier Roche
  • Date: 2011-09-15 19:59:56 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: package-import@ubuntu.com-20110915195956-c8u92ig0zuvn8agu
Tags: 1:0.9.5.94+bzr20110915-0ubuntu1
* New upstream snapshot:
  - UIFe: Spread - center the workspace switcher to account for the
    launcher and pan (LP: #837545)
* debian/patches/01-grid-fix-rev87.patch:
  - removed in upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "expo.h"
27
27
#include <math.h>
28
28
#include <GL/glu.h>
 
29
#include <X11/cursorfont.h>
29
30
 
30
31
COMPIZ_PLUGIN_20090315 (expo, ExpoPluginVTable);
31
32
 
67
68
 
68
69
    if (dndState == DnDDuring || dndState == DnDStart)
69
70
    {
70
 
        if (dndWindow)
 
71
        if (dndWindows.size ())
71
72
            finishWindowMovement ();
72
73
 
73
74
        dndState  = DnDNone;
74
 
        dndWindow = NULL;
75
75
 
76
76
        action->setState (action->state () & CompAction::StateInitButton);
77
77
        cScreen->damageScreen ();
107
107
        clickTime   = 0;
108
108
 
109
109
        dndState  = DnDNone;
110
 
        dndWindow = NULL;
111
110
 
112
111
        selectedVp = screen->vp ();
113
112
        origVp     = screen->vp ();
150
149
        vpUpdateMode = VPUpdateMouseOver;
151
150
 
152
151
    dndState  = DnDNone;
153
 
    dndWindow = NULL;
154
152
 
155
153
    screen->removeAction (&optionGetDndButton ());
156
154
    screen->removeAction (&optionGetExitButton ());
263
261
void
264
262
ExpoScreen::finishWindowMovement ()
265
263
{
266
 
    dndWindow->syncPosition ();
267
 
    dndWindow->ungrabNotify ();
268
 
 
269
 
    screen->moveViewport (screen->vp ().x () - selectedVp.x (),
270
 
                          screen->vp ().y () - selectedVp.y (), true);
271
 
 
272
 
    /* update saved window attributes in case we moved the
273
 
       window to a new viewport */
274
 
    if (dndWindow->saveMask () & CWX)
275
 
    {
276
 
        dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
277
 
        if (dndWindow->saveWc ().x < 0)
278
 
            dndWindow->saveWc ().x += screen->width ();
279
 
    }
280
 
    if (dndWindow->saveMask () & CWY)
281
 
    {
282
 
        dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
283
 
        if (dndWindow->saveWc ().y < 0)
284
 
            dndWindow->saveWc ().y += screen->height ();
285
 
    }
286
 
 
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);
291
 
 
292
 
#if 0 /* FIXME: obsolete in the meantime? */
293
 
    {
294
 
        int lastOutput;
295
 
        int centerX, centerY;
296
 
 
297
 
        /* make sure we snap to the correct output */
298
 
        lastOutput = s->currentOutputDev;
299
 
        centerX = (WIN_X (w) + WIN_W (w) / 2) % s->width;
300
 
        if (centerX < 0)
301
 
            centerX += s->width;
302
 
        centerY = (WIN_Y (w) + WIN_H (w) / 2) % s->height;
303
 
        if (centerY < 0)
304
 
            centerY += s->height;
305
 
 
306
 
        s->currentOutputDev = outputDeviceForPoint (s, centerX, centerY);
307
 
 
308
 
        updateWindowAttributes (w, CompStackingUpdateModeNone);
309
 
 
310
 
        s->currentOutputDev = lastOutput;
311
 
    }
312
 
#endif
 
264
    foreach (CompWindow *dndWindow, dndWindows)
 
265
    {
 
266
        if (dndWindow->grabbed ())
 
267
        {
 
268
            dndWindow->syncPosition ();
 
269
            dndWindow->ungrabNotify ();
 
270
 
 
271
            screen->updateGrab (grabIndex, None);
 
272
 
 
273
            screen->moveViewport (screen->vp ().x () - selectedVp.x (),
 
274
                                  screen->vp ().y () - selectedVp.y (), true);
 
275
 
 
276
            /* update saved window attributes in case we moved the
 
277
    window to a new viewport */
 
278
            if (dndWindow->saveMask () & CWX)
 
279
            {
 
280
                dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
 
281
                if (dndWindow->saveWc ().x < 0)
 
282
                    dndWindow->saveWc ().x += screen->width ();
 
283
            }
 
284
            if (dndWindow->saveMask () & CWY)
 
285
            {
 
286
                dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
 
287
                if (dndWindow->saveWc ().y < 0)
 
288
                    dndWindow->saveWc ().y += screen->height ();
 
289
            }
 
290
 
 
291
            /* update window attibutes to make sure a moved maximized window
 
292
           is properly snapped to the work area */
 
293
            if (dndWindow->state () & MAXIMIZE_STATE)
 
294
                dndWindow->updateAttributes (CompStackingUpdateModeNone);
 
295
        }
 
296
    }
313
297
}
314
298
 
315
299
void
380
364
    screen->handleEvent (event);
381
365
}
382
366
 
 
367
bool
 
368
ExpoScreen::windowsOnVp (CompPoint &p)
 
369
{
 
370
    foreach (CompWindow *w, screen->clientList (true))
 
371
    {
 
372
        CompPoint viewport;
 
373
 
 
374
        screen->viewportForGeometry (w->geometry (), viewport);
 
375
 
 
376
        if (viewport == p&&
 
377
            w->type () != CompWindowTypeDesktopMask &&
 
378
            w->type () != CompWindowTypeDockMask)
 
379
        {
 
380
            return true;
 
381
        }
 
382
    }
 
383
 
 
384
    return false;
 
385
}
 
386
 
383
387
void
384
388
ExpoScreen::preparePaint (int msSinceLastPaint)
385
389
{
390
394
    else
391
395
        expoCam = MAX (0.0, expoCam - val);
392
396
 
 
397
    if (dndState == DnDDuring)
 
398
    {
 
399
        foreach (CompWindow *w, dndWindows)
 
400
            ExpoWindow::get (w)->dndOpacity = MIN (1.0, ExpoWindow::get (w)->dndOpacity + val);
 
401
    }
 
402
    else if (dndState == DnDNone)
 
403
    {
 
404
        CompWindowList::iterator it = dndWindows.begin ();
 
405
 
 
406
        while (it != dndWindows.end ())
 
407
        {
 
408
            ExpoWindow::get ((*it))->dndOpacity = MAX (0.0, ExpoWindow::get ((*it))->dndOpacity - val);
 
409
 
 
410
            if (ExpoWindow::get ((*it))->dndOpacity <= 0.0f)
 
411
            {
 
412
                dndWindows.erase (it);
 
413
                it = dndWindows.begin ();
 
414
            }
 
415
            else
 
416
                it++;
 
417
        }
 
418
    }
 
419
 
393
420
    if (expoCam)
394
421
    {
395
422
        unsigned int i, j, vp;
408
435
            for (j = 0; j < (unsigned int) screen->vpSize ().height (); j++)
409
436
            {
410
437
                vp = (j * screen->vpSize ().width ()) + i;
 
438
                CompPoint vpPos = CompPoint (i, j);
411
439
 
412
 
                if (CompPoint (i, j) == selectedVp)
 
440
                if (windowsOnVp (vpPos))
413
441
                    vpActivity[vp] = MIN (1.0, vpActivity[vp] + val);
414
442
                else
415
443
                    vpActivity[vp] = MAX (0.0, vpActivity[vp] - val);
437
465
    screen->handleEventSetEnabled (this, enable);
438
466
    cScreen->preparePaintSetEnabled (this, enable);
439
467
    cScreen->paintSetEnabled (this, enable);
 
468
    cScreen->getWindowPaintListSetEnabled (this, false);
440
469
    cScreen->donePaintSetEnabled (this, enable);
441
470
    gScreen->glPaintOutputSetEnabled (this, enable);
442
471
    gScreen->glPaintTransformedOutputSetEnabled (this, enable);
516
545
        foreach (float& vp, vpActivity)
517
546
            if (vp != 0.0 && vp != 1.0)
518
547
                cScreen->damageScreen ();
 
548
 
 
549
        foreach (CompWindow *w, dndWindows)
 
550
            if (ExpoWindow::get (w)->dndOpacity != 0.0f &&
 
551
                ExpoWindow::get (w)->dndOpacity != 1.0f)
 
552
                cScreen->damageScreen ();
519
553
    }
520
554
 
521
555
    if (grabIndex && expoCam <= 0.0f && !expoMode)
530
564
    switch (dndState) {
531
565
    case DnDDuring:
532
566
        {
533
 
            if (dndWindow)
534
 
                dndWindow->move (newCursor.x () - prevCursor.x (),
535
 
                                 newCursor.y () - prevCursor.y (),
536
 
                                 optionGetExpoImmediateMove ());
 
567
            if (dndWindows.size ())
 
568
            {
 
569
                foreach (CompWindow *dndWindow, dndWindows)
 
570
                {
 
571
                    if (dndWindow->grabbed ())
 
572
                    {
 
573
                        dndWindow->move (newCursor.x () - prevCursor.x (),
 
574
                                         newCursor.y () - prevCursor.y (),
 
575
                                         optionGetExpoImmediateMove ());
 
576
                    }
 
577
                }
 
578
            }
537
579
 
538
580
            prevCursor = newCursor;
539
581
            cScreen->damageScreen ();
598
640
                    break;
599
641
 
600
642
                dndState  = DnDDuring;
601
 
                dndWindow = w;
 
643
                dndWindows.push_back (w);
602
644
 
603
645
                w->grabNotify (nx, ny, 0,
604
646
                               CompWindowGrabMoveMask |
605
647
                               CompWindowGrabButtonMask);
606
648
 
 
649
                screen->updateGrab (grabIndex, mMoveCursor);
 
650
 
607
651
                w->raise ();
608
652
                w->moveInputFocusTo ();
609
653
                break;
689
733
}
690
734
 
691
735
void
 
736
ExpoScreen::paintViewport (const GLScreenPaintAttrib& attrib,
 
737
                           const GLMatrix&            transform,
 
738
                           const CompRegion&          region,
 
739
                           CompOutput                 *output,
 
740
                           unsigned int               mask,
 
741
                           CompPoint                  vpPos,
 
742
                           GLVector                   &vpCamPos,
 
743
                           bool                       reflection)
 
744
{
 
745
    GLMatrix     sTransform (transform);
 
746
    GLMatrix     sTransform2, sTransform3;
 
747
    float        sx = (float) screen->width () / output->width ();
 
748
    float        sy = (float) screen->height () / output->height ();
 
749
    float        vpp;
 
750
    float        progress = sigmoidProgress (expoCam);
 
751
    unsigned int vp;
 
752
    CompPoint    vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
 
753
 
 
754
    const float gapY = optionGetVpDistance () * 0.1f * expoCam;
 
755
    const float gapX = optionGetVpDistance () * 0.1f * screen->height () /
 
756
                       screen->width () * expoCam;
 
757
 
 
758
    /* not sure this will work with different resolutions */
 
759
    sTransform.translate (0.0, MAX (0, vpPos.y ()) * -(sy + gapY), 0.0f);
 
760
 
 
761
    sTransform2 = sTransform;
 
762
 
 
763
    /* not sure this will work with different resolutions */
 
764
    if (optionGetDeform () != DeformCurve)
 
765
        sTransform2.translate (MAX (0, vpPos.x ()) * (sx + gapX), 0.0f, 0.0);
 
766
 
 
767
 
 
768
    if (optionGetExpoAnimation () == ExpoAnimationVortex)
 
769
        sTransform2.rotate (360 * expoCam,
 
770
                            0.0f, 1.0f, 2.0f * expoCam);
 
771
 
 
772
    sTransform3 = sTransform2;
 
773
 
 
774
    sTransform3.translate (output->x () / output->width (),
 
775
                           -output->y () / output->height (), 0.0);
 
776
 
 
777
    cScreen->setWindowPaintOffset ((screen->vp ().x () - vpPos.x ()) *
 
778
                                   screen->width (),
 
779
                                   (screen->vp ().y () - vpPos.y ()) *
 
780
                                   screen->height ());
 
781
 
 
782
    vp = (vpPos.y () * vpSize.x ()) + vpPos.x ();
 
783
 
 
784
    vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
 
785
    vpp = sigmoidProgress (vpp);
 
786
 
 
787
    vpBrightness = vpp + ((1.0 - vpp) *
 
788
                          optionGetVpBrightness () / 100.0);
 
789
    vpSaturation = vpp + ((1.0 - vpp) *
 
790
                          optionGetVpSaturation () / 100.0);
 
791
 
 
792
    paintingVp = vpPos;
 
793
 
 
794
    if (optionGetDeform () == DeformCurve)
 
795
    {
 
796
        float rotateX;
 
797
 
 
798
        sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
 
799
                               curveDistance - DEFAULT_Z_CAMERA);
 
800
 
 
801
        rotateX = -vpPos.x () + interpolate (((float) vpSize.x () / 2.0) - 0.5,
 
802
                                    screen->vp ().x (), progress);
 
803
 
 
804
        sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
 
805
 
 
806
        sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
 
807
                               DEFAULT_Z_CAMERA - curveDistance);
 
808
    }
 
809
 
 
810
    cScreen->getWindowPaintListSetEnabled (this, paintingDndWindow);
 
811
 
 
812
    gScreen->glPaintTransformedOutput (attrib, sTransform3,
 
813
                                       screen->region (), output,
 
814
                                       mask);
 
815
 
 
816
    cScreen->getWindowPaintListSetEnabled (this, !paintingDndWindow);
 
817
 
 
818
    if (!reflection && !paintingDndWindow)
 
819
    {
 
820
        int cursor[2] = { pointerX, pointerY };
 
821
 
 
822
        invertTransformedVertex (attrib, sTransform3,
 
823
                                 output, cursor);
 
824
 
 
825
        if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
 
826
                (cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
 
827
        {
 
828
            newCursor.setX (vpPos.x () * screen->width () + cursor[0]);
 
829
            newCursor.setY (vpPos.y () * screen->height () + cursor[1]);
 
830
 
 
831
            if (anyClick || dndState != DnDNone)
 
832
            {
 
833
                /* Used to save last viewport interaction was in */
 
834
                selectedVp = vpPos;
 
835
                anyClick = false;
 
836
            }
 
837
        }
 
838
    }
 
839
 
 
840
    /* Calculate the current viewport size */
 
841
    int tl[2] = { 0, 0 };
 
842
    int br[2] = { screen->width (), screen->height () };
 
843
 
 
844
    invertTransformedVertex (attrib, sTransform3, output, tl);
 
845
    invertTransformedVertex (attrib, sTransform3, output, br);
 
846
 
 
847
    viewport_size = CompSize (br[0] - tl[0], br[1] - tl[1]);
 
848
}
 
849
 
 
850
void
692
851
ExpoScreen::paintWall (const GLScreenPaintAttrib& attrib,
693
852
                       const GLMatrix&            transform,
694
853
                       const CompRegion&          region,
697
856
                       bool                       reflection)
698
857
{
699
858
    GLMatrix sTransformW, sTransform (transform);
700
 
    int      i, j, vp;
701
859
    GLenum   oldFilter = gScreen->textureFilter ();
702
 
 
703
 
    float     sx = (float) screen->width () / output->width ();
704
 
    float     sy = (float) screen->height () / output->height ();
 
860
    float        sx = (float) screen->width () / output->width ();
 
861
    float        sy = (float) screen->height () / output->height ();
705
862
    float     biasZ;
706
 
    float     oScale, rotation = 0.0f, progress, vpp;
 
863
    float     oScale, rotation = 0.0f, progress;
707
864
    float     aspectX = 1.0f, aspectY = 1.0f;
708
865
    GLVector  cam;
709
866
    CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
833
990
    sTransform.rotate (rotation, 0.0f, 1.0f, 0.0f);
834
991
    sTransform.scale (aspectX, aspectY, 1.0);
835
992
 
836
 
    float xoffset = ((vpSize.x () * sx) / ((float) screen->width ()) * optionGetXOffset ()) * sigmoidProgress (expoCam);
837
 
    float yoffset = ((vpSize.y () * sy) / ((float) screen->height ()) * optionGetYOffset ()) * sigmoidProgress (expoCam);
838
 
    float xadjs = 1.0f - ((float) optionGetXOffset () / (float) screen->width ()) * sigmoidProgress (expoCam);
839
 
    float yadjs = 1.0f - ((float) optionGetYOffset () / (float) screen->height ()) * sigmoidProgress (expoCam);
 
993
    float xoffset = 0.0;
 
994
    float yoffset = 0.0;
 
995
    float xadjs = 1.0f;
 
996
    float yadjs = 1.0f;
 
997
 
 
998
    if (output->left () == 0)
 
999
    {
 
1000
        xoffset = ((vpSize.x () * sx) / ((float) output->width ()) * (optionGetXOffset ()) * sigmoidProgress (expoCam));
 
1001
        xadjs = 1.0f - ((float) (optionGetXOffset ()) / (float) (output->width ())) * sigmoidProgress (expoCam);
 
1002
    }
 
1003
 
 
1004
    if (output->top () == 0)
 
1005
    {
 
1006
        yoffset = ((vpSize.y () * sy) / ((float) output->height ()) * (optionGetYOffset ()) * sigmoidProgress (expoCam));
 
1007
 
 
1008
        yadjs = 1.0f - ((float) (optionGetYOffset ()) / (float) output->height ()) * sigmoidProgress (expoCam);
 
1009
    }
840
1010
 
841
1011
    /* translate expo to center */
842
1012
    sTransform.translate (vpSize.x () * sx * -0.5 + xoffset,
865
1035
 
866
1036
    expoActive = true;
867
1037
 
868
 
    for (j = 0; j < vpSize.y (); j++)
 
1038
    for (int j = 0; j < screen->vpSize ().height (); j++)
 
1039
        for (int i = 0; i < screen->vpSize().width (); i++)
 
1040
            paintViewport (attrib, sTransform, region, output, mask, CompPoint (i, j), vpCamPos, reflection);
 
1041
 
 
1042
    paintingDndWindow = true;
 
1043
 
 
1044
    foreach (CompWindow *dndWindow, dndWindows)
869
1045
    {
870
 
        GLMatrix sTransform2 (sTransform), sTransform3;
871
 
 
872
 
        for (i = 0; i < vpSize.x (); i++)
873
 
        {
874
 
            if (optionGetExpoAnimation () == ExpoAnimationVortex)
875
 
                sTransform2.rotate (360 * expoCam,
876
 
                                    0.0f, 1.0f, 2.0f * expoCam);
877
 
 
878
 
            sTransform3 = sTransform2;
879
 
 
880
 
            sTransform3.translate (output->x () / output->width (),
881
 
                                   -output->y () / output->height (), 0.0);
882
 
 
883
 
            cScreen->setWindowPaintOffset ((screen->vp ().x () - i) *
884
 
                                           screen->width (),
885
 
                                           (screen->vp ().y () - j) *
886
 
                                           screen->height ());
887
 
 
888
 
            vp = (j * vpSize.x ()) + i;
889
 
 
890
 
            vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
891
 
            vpp = sigmoidProgress (vpp);
892
 
 
893
 
            vpBrightness = vpp + ((1.0 - vpp) *
894
 
                                  optionGetVpBrightness () / 100.0);
895
 
            vpSaturation = vpp + ((1.0 - vpp) *
896
 
                                  optionGetVpSaturation () / 100.0);
897
 
 
898
 
            paintingVp.set (i, j);
899
 
 
900
 
            if (optionGetDeform () == DeformCurve)
901
 
            {
902
 
                float rotateX;
903
 
 
904
 
                sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
905
 
                                       curveDistance - DEFAULT_Z_CAMERA);
906
 
 
907
 
                rotateX = -i + interpolate (((float) vpSize.x () / 2.0) - 0.5,
908
 
                                            screen->vp ().x (), progress);
909
 
 
910
 
                sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
911
 
 
912
 
                sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
913
 
                                       DEFAULT_Z_CAMERA - curveDistance);
914
 
            }
915
 
 
916
 
            gScreen->glPaintTransformedOutput (attrib, sTransform3,
917
 
                                               screen->region (), output,
918
 
                                               mask);
919
 
 
920
 
            if (!reflection)
921
 
            {
922
 
                int cursor[2] = { pointerX, pointerY };
923
 
 
924
 
                invertTransformedVertex (attrib, sTransform3,
925
 
                                         output, cursor);
926
 
 
927
 
                if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
928
 
                    (cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
929
 
                {
930
 
                    newCursor.setX (i * screen->width () + cursor[0]);
931
 
                    newCursor.setY (j * screen->height () + cursor[1]);
932
 
 
933
 
                    if (anyClick || dndState != DnDNone)
934
 
                    {
935
 
                        /* Used to save last viewport interaction was in */
936
 
                        selectedVp.set (i, j);
937
 
                        anyClick = false;
938
 
                    }
939
 
                }
940
 
            }
941
 
 
942
 
            /* not sure this will work with different resolutions */
943
 
            if (optionGetDeform () != DeformCurve)
944
 
                sTransform2.translate (sx + gapX, 0.0f, 0.0);
945
 
        }
946
 
 
947
 
        /* not sure this will work with different resolutions */
948
 
        sTransform.translate (0.0, -(sy + gapY), 0.0f);
 
1046
        CompPoint vp;
 
1047
 
 
1048
        screen->viewportForGeometry (dndWindow->geometry (), vp);
 
1049
 
 
1050
        while (vp.x () < 0)
 
1051
            vp.setX (screen->vpSize ().width () + vp.x ());
 
1052
 
 
1053
        while (vp.y () < 0)
 
1054
            vp.setY (screen->vpSize ().height () + vp.y ());
 
1055
 
 
1056
        paintViewport (attrib, sTransform, infiniteRegion, output, mask, vp, vpCamPos, reflection);
949
1057
    }
950
1058
 
 
1059
    paintingDndWindow = false;
 
1060
 
951
1061
    glNormal3f (0.0, 0.0, -1.0);
952
1062
 
953
1063
    if (reflection)
1025
1135
    gScreen->setTextureFilter (oldFilter);
1026
1136
}
1027
1137
 
 
1138
const CompWindowList &
 
1139
ExpoScreen::getWindowPaintList ()
 
1140
{
 
1141
    return dndWindows;
 
1142
}
 
1143
 
1028
1144
bool
1029
1145
ExpoScreen::glPaintOutput (const GLScreenPaintAttrib& attrib,
1030
1146
                           const GLMatrix&            transform,
1079
1195
                    const CompRegion&   region,
1080
1196
                    unsigned int        mask)
1081
1197
{
 
1198
    GLMatrix wTransform (transform);
 
1199
    CompPoint vp;
 
1200
 
 
1201
    screen->viewportForGeometry (window->geometry (), vp);
 
1202
 
1082
1203
    if (eScreen->expoCam == 0.0f)
1083
1204
        return gWindow->glDraw (transform, fragment, region, mask);
1084
1205
 
1107
1228
            }
1108
1229
        }
1109
1230
 
1110
 
        fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
1111
 
        fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
 
1231
        if (vp == eScreen->paintingVp || window->onAllViewports ())
 
1232
        {
 
1233
            fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
 
1234
            fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
 
1235
        }
1112
1236
    }
1113
1237
    else
1114
1238
    {
1119
1243
                              (1 - sigmoidProgress (eScreen->expoCam)));
1120
1244
    }
1121
1245
 
1122
 
    return gWindow->glDraw (transform, fA, region, mask);
 
1246
    bool status = gWindow->glDraw (wTransform, fA, region, mask);
 
1247
 
 
1248
    if (window->type () & CompWindowTypeDesktopMask)
 
1249
    {
 
1250
        /* We want to set the geometry of the polka dots to the window
 
1251
         * region */
 
1252
        CompRegion reg = CompRegion (0, 0, window->width (), window->height ());
 
1253
 
 
1254
        foreach(GLTexture * tex, eScreen->polkadots_texture)
 
1255
        {
 
1256
            GLTexture::MatrixList matl;
 
1257
            GLTexture::Matrix     mat = tex->matrix();
 
1258
            CompRegion            paintRegion(region);
 
1259
 
 
1260
            /* We can reset the window geometry since it will be
 
1261
             * re-added later */
 
1262
            gWindow->geometry().reset();
 
1263
 
 
1264
            float xScale = screen->width () / (float) eScreen->viewport_size.width ();
 
1265
            float yScale = screen->height () / (float) eScreen->viewport_size.height ();
 
1266
 
 
1267
            mat.xx *= xScale;
 
1268
            mat.yy *= yScale;
 
1269
 
 
1270
            /* Not sure what this does, but it is necessary
 
1271
             * (adjusts for scale?) */
 
1272
            mat.x0 -= mat.xx * reg.boundingRect().x1();
 
1273
            mat.y0 -= mat.yy * reg.boundingRect().y1();
 
1274
 
 
1275
            matl.push_back(mat);
 
1276
 
 
1277
            if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
 
1278
                paintRegion = infiniteRegion;
 
1279
 
 
1280
            /* Now allow plugins to mess with the geometry of our
 
1281
             * dim (so we get a nice render for things like
 
1282
             * wobbly etc etc */
 
1283
            gWindow->glAddGeometry(matl, reg, paintRegion);
 
1284
 
 
1285
            /* Did it succeed? */
 
1286
            if (gWindow->geometry().vertices)
 
1287
            {
 
1288
                unsigned int glDrawTextureIndex = gWindow->glDrawTextureGetCurrentIndex();
 
1289
                fA.setOpacity (fragment.getOpacity () * (((1.0 - eScreen->vpBrightness) + (1.0 - eScreen->vpSaturation) / 2.0)));
 
1290
                /* Texture rendering set-up */
 
1291
                eScreen->gScreen->setTexEnvMode(GL_MODULATE);
 
1292
                glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
1293
                /* Draw the dim texture with all of it's modified
 
1294
                 * geometry glory */
 
1295
                gWindow->glDrawTextureSetCurrentIndex(MAXSHORT);
 
1296
                gWindow->glDrawTexture(tex, fA, mask | PAINT_WINDOW_BLEND_MASK
 
1297
                                       | PAINT_WINDOW_TRANSLUCENT_MASK |
 
1298
                                       PAINT_WINDOW_TRANSFORMED_MASK);
 
1299
                gWindow->glDrawTextureSetCurrentIndex(glDrawTextureIndex);
 
1300
                /* Texture rendering tear-down */
 
1301
                glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
1302
                eScreen->gScreen->setTexEnvMode(GL_REPLACE);
 
1303
            }
 
1304
        }
 
1305
 
 
1306
        /* Paint the outline */
 
1307
        if (mGlowQuads && eScreen->paintingVp == eScreen->selectedVp)
 
1308
        {
 
1309
            if (region.numRects ())
 
1310
            {
 
1311
                /* reset geometry and paint */
 
1312
                gWindow->geometry ().reset ();
 
1313
 
 
1314
                paintGlow (fragment, infiniteRegion, mask);
 
1315
            }
 
1316
        }
 
1317
 
 
1318
  }
 
1319
 
 
1320
  return status;
 
1321
 
1123
1322
}
1124
1323
 
1125
1324
#define EXPO_GRID_SIZE 100
1261
1460
                     const CompRegion&          region,
1262
1461
                     unsigned int               mask)
1263
1462
{
 
1463
    GLMatrix            wTransform (transform);
 
1464
    GLWindowPaintAttrib wAttrib (attrib);
 
1465
    CompPoint           vp;
 
1466
 
 
1467
    screen->viewportForGeometry (window->geometry (), vp);
 
1468
 
1264
1469
    if (eScreen->expoActive)
1265
1470
    {
1266
1471
        float opacity = 1.0;
1294
1499
 
1295
1500
        if (opacity <= 0)
1296
1501
            mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1297
 
    }
1298
 
 
1299
 
    return gWindow->glPaint (attrib, transform, region, mask);
 
1502
        else
 
1503
            wAttrib.opacity = wAttrib.opacity * opacity;
 
1504
    }
 
1505
 
 
1506
    /* Stretch maximized windows a little so that you don't
 
1507
     * have an awkward gap */
 
1508
    if (window->state () & MAXIMIZE_STATE)
 
1509
    {
 
1510
        CompOutput *o = &screen->outputDevs ()[screen->outputDeviceForGeometry(window->geometry())];
 
1511
        float yS = 1.0 + ((o->height () / (float) window->height ()) - 1.0f) * sigmoidProgress (eScreen->expoCam);
 
1512
        wTransform.translate (window->x () + window->width () / 2,
 
1513
                              window->y () + window->height (),
 
1514
                              0.0f);
 
1515
        wTransform.scale (1.0f, yS, 1.0f);
 
1516
        wTransform.translate (-(window->x () + window->width () / 2),
 
1517
                              -(window->y () + window->height ()),
 
1518
                              0.0f);
 
1519
 
 
1520
        if (eScreen->paintingVp != vp)
 
1521
            mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
 
1522
 
 
1523
        mask |= PAINT_WINDOW_TRANSFORMED_MASK;
 
1524
    }
 
1525
 
 
1526
    if (std::find (eScreen->dndWindows.begin(), eScreen->dndWindows.end (), window) != eScreen->dndWindows.end ())
 
1527
    {
 
1528
        if (!eScreen->paintingDndWindow)
 
1529
        {
 
1530
            if ((1.0f - dndOpacity) <= 0.0f || (eScreen->paintingVp == vp &&
 
1531
                                                eScreen->dndState != ExpoScreen::DnDNone))
 
1532
                mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
 
1533
            else if (!window->region ().subtracted (screen->region ()).isEmpty () &&
 
1534
                     eScreen->paintingVp != vp)
 
1535
                wAttrib.opacity = wAttrib.opacity * (1.0f - dndOpacity);
 
1536
        }
 
1537
        else
 
1538
        {
 
1539
            mask |= PAINT_WINDOW_TRANSFORMED_MASK;
 
1540
            if (!window->region ().subtracted (screen->region ()).isEmpty ())
 
1541
                wAttrib.opacity = wAttrib.opacity * dndOpacity;
 
1542
        }
 
1543
    }
 
1544
 
 
1545
    bool status = gWindow->glPaint (wAttrib, wTransform, region, mask);
 
1546
 
 
1547
    return status;
1300
1548
}
1301
1549
 
1302
1550
bool
1325
1573
    expoActive (false),
1326
1574
    expoMode (false),
1327
1575
    dndState (DnDNone),
1328
 
    dndWindow (NULL),
 
1576
    dndWindows (0),
1329
1577
    origVp (s->vp ()),
1330
1578
    selectedVp (s->vp ()),
1331
1579
    vpUpdateMode (VPUpdateNone),
1332
1580
    clickTime (0),
1333
1581
    doubleClick (false),
1334
1582
    vpNormals (360 * 3),
1335
 
    grabIndex (0)
 
1583
    grabIndex (0),
 
1584
    paintingDndWindow (false),
 
1585
    mGlowTextureProperties (&glowTextureProperties)
1336
1586
{
 
1587
    CompString fname;
 
1588
    CompString pname = "expo";
 
1589
    CompSize   size;
 
1590
 
 
1591
 
1337
1592
    leftKey  = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Left"));
1338
1593
    rightKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Right"));
1339
1594
    upKey    = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Up"));
1340
1595
    downKey  = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Down"));
1341
1596
 
 
1597
    mMoveCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
 
1598
 
1342
1599
    EXPOINITBIND (ExpoKey, doExpo);
1343
1600
    EXPOTERMBIND (ExpoKey, termExpo);
1344
1601
    EXPOINITBIND (ExpoButton, doExpo);
1355
1612
    ScreenInterface::setHandler (screen, false);
1356
1613
    CompositeScreenInterface::setHandler (cScreen, false);
1357
1614
    GLScreenInterface::setHandler (gScreen, false);
 
1615
 
 
1616
    outline_texture = GLTexture::imageDataToTexture (mGlowTextureProperties->textureData,
 
1617
                                                     CompSize (mGlowTextureProperties->textureSize,
 
1618
                                                               mGlowTextureProperties->textureSize),
 
1619
                                                     GL_RGBA, GL_UNSIGNED_BYTE);
 
1620
    fname = "texture_tile.png";
 
1621
    polkadots_texture = GLTexture::readImageToTexture (fname, pname, polkadots_texture_size);
 
1622
 
 
1623
    if (polkadots_texture.empty ())
 
1624
        compLogMessage ("expo", CompLogLevelWarn, "failed to bind image to texture");
 
1625
    else
 
1626
    {
 
1627
        foreach (GLTexture *tex, polkadots_texture)
 
1628
        {
 
1629
            tex->enable (GLTexture::Good);
 
1630
            glTexParameteri (tex->target (), GL_TEXTURE_WRAP_S, GL_REPEAT);
 
1631
            glTexParameteri (tex->target (), GL_TEXTURE_WRAP_T, GL_REPEAT);
 
1632
            tex->disable ();
 
1633
        }
 
1634
    }
 
1635
}
 
1636
 
 
1637
ExpoScreen::~ExpoScreen ()
 
1638
{
 
1639
    if (mMoveCursor)
 
1640
        XFreeCursor (screen->dpy (), mMoveCursor);
 
1641
}
 
1642
 
 
1643
void
 
1644
ExpoWindow::resizeNotify(int dx, int dy, int dw, int dh)
 
1645
{
 
1646
    window->resizeNotify (dx, dy, dw, dh);
 
1647
 
 
1648
    /* mGlowQuads contains positional info, so we need to recalc that */
 
1649
    if (mGlowQuads)
 
1650
    {
 
1651
        /* FIXME: we need to find a more multitexture friendly way
 
1652
         * of doing this */
 
1653
        GLTexture::Matrix tMat = eScreen->outline_texture.at (0)->matrix ();
 
1654
        computeGlowQuads (&tMat);
 
1655
    }
1358
1656
}
1359
1657
 
1360
1658
ExpoWindow::ExpoWindow (CompWindow *w) :
1362
1660
    window (w),
1363
1661
    cWindow (CompositeWindow::get (w)),
1364
1662
    gWindow (GLWindow::get (w)),
1365
 
    eScreen (ExpoScreen::get (screen))
 
1663
    eScreen (ExpoScreen::get (screen)),
 
1664
    dndOpacity (0.0f),
 
1665
    mGlowQuads (NULL)
1366
1666
{
1367
1667
    CompositeWindowInterface::setHandler (cWindow, false);
1368
1668
    GLWindowInterface::setHandler (gWindow, false);
 
1669
    WindowInterface::setHandler (window, true);
 
1670
 
 
1671
    if (window->type () & CompWindowTypeDesktopMask)
 
1672
    {
 
1673
        foreach (GLTexture *tex, eScreen->outline_texture)
 
1674
        {
 
1675
            GLTexture::Matrix mat = tex->matrix ();
 
1676
            computeGlowQuads (&mat);
 
1677
        }
 
1678
    }
 
1679
}
 
1680
 
 
1681
ExpoWindow::~ExpoWindow ()
 
1682
{
 
1683
    eScreen->dndWindows.remove (window);
 
1684
    computeGlowQuads (NULL);
1369
1685
}
1370
1686
 
1371
1687
bool