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

« back to all changes in this revision

Viewing changes to .pc/00_bzr_fix_centered_expo.patch/expo/src/expo.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2011-06-06 16:19:03 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110606161903-xz6332s4mdh8llxe
Tags: 0.9.4+bzr20110527-0ubuntu1
* New bug fix release:
  - apps started fullscreen in unity can never unfullscreen (LP: #765422)
* debian/patches/00_bzr_fix_centered_expo.patch:
  - removed, applied upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 *
3
 
 * Compiz expo plugin
4
 
 *
5
 
 * expo.c
6
 
 *
7
 
 * Copyright (c) 2008 Dennis Kasprzyk <racarr@opencompositing.org>
8
 
 * Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
9
 
 *
10
 
 * Authors:
11
 
 * Robert Carr <racarr@beryl-project.org>
12
 
 * Dennis Kasprzyk <onestone@opencompositing.org>
13
 
 *
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.
18
 
 *
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.
23
 
 *
24
 
 **/
25
 
 
26
 
#include "expo.h"
27
 
#include <math.h>
28
 
#include <GL/glu.h>
29
 
 
30
 
COMPIZ_PLUGIN_20090315 (expo, ExpoPluginVTable);
31
 
 
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)))
35
 
 
36
 
#define interpolate(a, b, val) (((val) * (a)) + ((1 - (val)) * (b)))
37
 
 
38
 
bool
39
 
ExpoScreen::dndInit (CompAction          *action,
40
 
                     CompAction::State   state,
41
 
                     CompOption::Vector& options)
42
 
{
43
 
    Window xid = CompOption::getIntOptionNamed (options, "root", 0);
44
 
    if (xid != screen->root ())
45
 
        return false;
46
 
 
47
 
    if (expoMode)
48
 
    {
49
 
        dndState = DnDStart;
50
 
        action->setState (action->state () | CompAction::StateTermButton);
51
 
        cScreen->damageScreen ();
52
 
 
53
 
        return true;
54
 
    }
55
 
 
56
 
    return false;
57
 
}
58
 
 
59
 
bool
60
 
ExpoScreen::dndFini (CompAction          *action,
61
 
                     CompAction::State   state,
62
 
                     CompOption::Vector& options)
63
 
{
64
 
    Window xid = CompOption::getIntOptionNamed (options, "root", 0);
65
 
    if (xid != screen->root ())
66
 
        return false;
67
 
 
68
 
    if (dndState == DnDDuring || dndState == DnDStart)
69
 
    {
70
 
        if (dndWindow)
71
 
            finishWindowMovement ();
72
 
 
73
 
        dndState  = DnDNone;
74
 
        dndWindow = NULL;
75
 
 
76
 
        action->setState (action->state () & CompAction::StateInitButton);
77
 
        cScreen->damageScreen ();
78
 
 
79
 
        return true;
80
 
    }
81
 
 
82
 
    return false;
83
 
}
84
 
 
85
 
bool
86
 
ExpoScreen::doExpo (CompAction          *action,
87
 
                    CompAction::State   state,
88
 
                    CompOption::Vector& options)
89
 
{
90
 
    Window xid = CompOption::getIntOptionNamed (options, "root", 0);
91
 
    if (xid != screen->root ())
92
 
        return false;
93
 
 
94
 
    if (screen->otherGrabExist ("expo", NULL))
95
 
        return false;
96
 
 
97
 
    if (!expoMode)
98
 
    {
99
 
        if (!grabIndex)
100
 
            grabIndex = screen->pushGrab (None, "expo");
101
 
 
102
 
        updateWraps (true);
103
 
 
104
 
        expoMode    = true;
105
 
        anyClick    = false;
106
 
        doubleClick = false;
107
 
        clickTime   = 0;
108
 
 
109
 
        dndState  = DnDNone;
110
 
        dndWindow = NULL;
111
 
 
112
 
        selectedVp = screen->vp ();
113
 
        origVp     = screen->vp ();
114
 
 
115
 
        screen->addAction (&optionGetDndButton ());
116
 
        screen->addAction (&optionGetExitButton ());
117
 
        screen->addAction (&optionGetNextVpButton ());
118
 
        screen->addAction (&optionGetPrevVpButton ());
119
 
 
120
 
        cScreen->damageScreen ();
121
 
    }
122
 
    else
123
 
    {
124
 
        termExpo (action, state, options);
125
 
    }
126
 
 
127
 
    return true;
128
 
}
129
 
 
130
 
bool
131
 
ExpoScreen::termExpo (CompAction          *action,
132
 
                      CompAction::State   state,
133
 
                      CompOption::Vector& options)
134
 
{
135
 
    Window xid = CompOption::getIntOptionNamed (options, "root", 0);
136
 
    if (xid && xid != screen->root ())
137
 
        return false;
138
 
 
139
 
    if (!expoMode)
140
 
        return true;
141
 
 
142
 
    expoMode = false;
143
 
 
144
 
    if (dndState != DnDNone)
145
 
        dndFini (action, state, options);
146
 
 
147
 
    if (state & CompAction::StateCancel)
148
 
        vpUpdateMode = VPUpdatePrevious;
149
 
    else
150
 
        vpUpdateMode = VPUpdateMouseOver;
151
 
 
152
 
    dndState  = DnDNone;
153
 
    dndWindow = NULL;
154
 
 
155
 
    screen->removeAction (&optionGetDndButton ());
156
 
    screen->removeAction (&optionGetExitButton ());
157
 
    screen->removeAction (&optionGetNextVpButton ());
158
 
    screen->removeAction (&optionGetPrevVpButton ());
159
 
 
160
 
    cScreen->damageScreen ();
161
 
    screen->focusDefaultWindow ();
162
 
 
163
 
    return true;
164
 
}
165
 
 
166
 
bool
167
 
ExpoScreen::exitExpo (CompAction          *action,
168
 
                      CompAction::State   state,
169
 
                      CompOption::Vector& options)
170
 
{
171
 
    Window xid = CompOption::getIntOptionNamed (options, "root", 0);
172
 
    if (xid != screen->root ())
173
 
        return false;
174
 
 
175
 
    if (!expoMode)
176
 
        return false;
177
 
 
178
 
    termExpo (action, 0, noOptions);
179
 
    anyClick = true;
180
 
    cScreen->damageScreen ();
181
 
 
182
 
    return true;
183
 
}
184
 
 
185
 
bool
186
 
ExpoScreen::nextVp (CompAction          *action,
187
 
                    CompAction::State   state,
188
 
                    CompOption::Vector& options)
189
 
{
190
 
    unsigned int newX, newY;
191
 
    Window       xid = CompOption::getIntOptionNamed (options, "root", 0);
192
 
    if (xid != screen->root ())
193
 
        return false;
194
 
 
195
 
    if (!expoMode)
196
 
        return false;
197
 
 
198
 
    newX = selectedVp.x () + 1;
199
 
    newY = selectedVp.y ();
200
 
 
201
 
    if (newX >= (unsigned int) screen->vpSize ().width ())
202
 
    {
203
 
        newX = 0;
204
 
        newY = newY + 1;
205
 
        if (newY >= (unsigned int) screen->vpSize ().height ())
206
 
            newY = 0;
207
 
    }
208
 
 
209
 
    moveFocusViewport (newX - selectedVp.x (),
210
 
                       newY - selectedVp.y ());
211
 
    cScreen->damageScreen ();
212
 
 
213
 
    return true;
214
 
}
215
 
 
216
 
bool
217
 
ExpoScreen::prevVp (CompAction          *action,
218
 
                    CompAction::State   state,
219
 
                    CompOption::Vector& options)
220
 
{
221
 
    unsigned int newX, newY;
222
 
    Window       xid = CompOption::getIntOptionNamed (options, "root", 0);
223
 
    if (xid != screen->root ())
224
 
        return false;
225
 
 
226
 
    if (!expoMode)
227
 
        return false;
228
 
 
229
 
    newX = selectedVp.x () - 1;
230
 
    newY = selectedVp.y ();
231
 
 
232
 
    if (newX < 0)
233
 
    {
234
 
        newX = screen->vpSize ().width () - 1;
235
 
        newY = newY - 1;
236
 
        if (newY < 0)
237
 
            newY = screen->vpSize ().height () - 1;
238
 
    }
239
 
 
240
 
    moveFocusViewport (newX - selectedVp.x (),
241
 
                       newY - selectedVp.y ());
242
 
    cScreen->damageScreen ();
243
 
 
244
 
    return true;
245
 
}
246
 
 
247
 
void
248
 
ExpoScreen::moveFocusViewport (int dx,
249
 
                               int dy)
250
 
{
251
 
    int newX, newY;
252
 
 
253
 
    newX = selectedVp.x () + dx;
254
 
    newY = selectedVp.y () + dy;
255
 
 
256
 
    newX = MAX (0, MIN ((int) screen->vpSize ().width () - 1, newX));
257
 
    newY = MAX (0, MIN ((int) screen->vpSize ().height () - 1, newY));
258
 
 
259
 
    selectedVp.set (newX, newY);
260
 
    cScreen->damageScreen ();
261
 
}
262
 
 
263
 
void
264
 
ExpoScreen::finishWindowMovement ()
265
 
{
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
313
 
}
314
 
 
315
 
void
316
 
ExpoScreen::handleEvent (XEvent *event)
317
 
{
318
 
    switch (event->type) {
319
 
    case KeyPress:
320
 
        if (expoMode && event->xkey.root == screen->root ())
321
 
        {
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);
330
 
        }
331
 
        break;
332
 
 
333
 
    case ButtonPress:
334
 
        if (expoMode && event->xbutton.button == Button1 &&
335
 
            event->xbutton.root == screen->root ())
336
 
        {
337
 
            anyClick = true;
338
 
            if (clickTime == 0)
339
 
            {
340
 
                clickTime = event->xbutton.time;
341
 
            }
342
 
            else if (event->xbutton.time - clickTime <=
343
 
                     (unsigned int) optionGetDoubleClickTime ())
344
 
            {
345
 
                doubleClick = true;
346
 
            }
347
 
            else
348
 
            {
349
 
                clickTime   = event->xbutton.time;
350
 
                doubleClick = false;
351
 
            }
352
 
            cScreen->damageScreen ();
353
 
        }
354
 
        break;
355
 
 
356
 
    case ButtonRelease:
357
 
        if (expoMode && event->xbutton.button == Button1 &&
358
 
            event->xbutton.root == screen->root ())
359
 
        {
360
 
            if (event->xbutton.time - clickTime >
361
 
                (unsigned int) optionGetDoubleClickTime ())
362
 
            {
363
 
                clickTime   = 0;
364
 
                doubleClick = false;
365
 
            }
366
 
            else if (doubleClick)
367
 
            {
368
 
                CompAction& action = optionGetExpoKey ();
369
 
 
370
 
                clickTime   = 0;
371
 
                doubleClick = false;
372
 
 
373
 
                termExpo (&action, 0, noOptions);
374
 
                anyClick = true;
375
 
            }
376
 
        }
377
 
        break;
378
 
    }
379
 
 
380
 
    screen->handleEvent (event);
381
 
}
382
 
 
383
 
void
384
 
ExpoScreen::preparePaint (int msSinceLastPaint)
385
 
{
386
 
    float val = ((float) msSinceLastPaint / 1000.0) / optionGetZoomTime ();
387
 
 
388
 
    if (expoMode)
389
 
        expoCam = MIN (1.0, expoCam + val);
390
 
    else
391
 
        expoCam = MAX (0.0, expoCam - val);
392
 
 
393
 
    if (expoCam)
394
 
    {
395
 
        unsigned int i, j, vp;
396
 
        unsigned int vpCount = screen->vpSize ().width () *
397
 
                               screen->vpSize ().height ();
398
 
 
399
 
        if (vpActivity.size () < vpCount)
400
 
        {
401
 
            vpActivity.resize (vpCount);
402
 
            foreach (float& activity, vpActivity)
403
 
                activity = 1.0f;
404
 
        }
405
 
 
406
 
        for (i = 0; i < (unsigned int) screen->vpSize ().width (); i++)
407
 
        {
408
 
            for (j = 0; j < (unsigned int) screen->vpSize ().height (); j++)
409
 
            {
410
 
                vp = (j * screen->vpSize ().width ()) + i;
411
 
 
412
 
                if (CompPoint (i, j) == selectedVp)
413
 
                    vpActivity[vp] = MIN (1.0, vpActivity[vp] + val);
414
 
                else
415
 
                    vpActivity[vp] = MAX (0.0, vpActivity[vp] - val);
416
 
            }
417
 
        }
418
 
 
419
 
        for (i = 0; i < 360; i++)
420
 
        {
421
 
            float fi = (float) i;
422
 
 
423
 
            vpNormals[i * 3] = (-sin (fi * DEG2RAD) / screen->width ()) *
424
 
                               expoCam;
425
 
            vpNormals[(i * 3) + 1] = 0.0;
426
 
            vpNormals[(i * 3) + 2] = (-cos (fi * DEG2RAD) * expoCam) -
427
 
                                     (1 - expoCam);
428
 
        }
429
 
    }
430
 
 
431
 
    cScreen->preparePaint (msSinceLastPaint);
432
 
}
433
 
 
434
 
void
435
 
ExpoScreen::updateWraps (bool enable)
436
 
{
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);
443
 
 
444
 
    foreach (CompWindow *w, screen->windows ())
445
 
    {
446
 
        ExpoWindow *ew = ExpoWindow::get (w);
447
 
 
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);
453
 
    }
454
 
}
455
 
 
456
 
void
457
 
ExpoScreen::paint (CompOutput::ptrList& outputs,
458
 
                   unsigned int         mask)
459
 
{
460
 
    int width = outputs.front ()->width ();
461
 
    int height = outputs.front ()->height ();
462
 
    bool sizeDiff = false;
463
 
 
464
 
    /* "One big wall" does not make sense where outputs are different
465
 
     * sizes, so force multiple walls in this case
466
 
     *
467
 
     * TODO: Is it possible to re-create "one big wall" using
468
 
     * independent output painting in this case? */
469
 
 
470
 
    foreach (CompOutput *o, outputs)
471
 
    {
472
 
        if (o->width () != width || o->height () != height)
473
 
        {
474
 
            sizeDiff = true;
475
 
            break;
476
 
        }
477
 
    }
478
 
 
479
 
    if (expoCam > 0.0 && outputs.size () > 1 &&
480
 
        optionGetMultioutputMode () == MultioutputModeOneBigWall &&
481
 
        !sizeDiff)
482
 
    {
483
 
        outputs.clear ();
484
 
        outputs.push_back (&screen->fullscreenOutput ());
485
 
    }
486
 
 
487
 
    cScreen->paint (outputs, mask);
488
 
}
489
 
 
490
 
void
491
 
ExpoScreen::donePaint ()
492
 
{
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;
499
 
        break;
500
 
    case VPUpdatePrevious:
501
 
        screen->moveViewport (screen->vp ().x () - origVp.x (),
502
 
                              screen->vp ().y () - origVp.y (), true);
503
 
        selectedVp = origVp;
504
 
        screen->focusDefaultWindow ();
505
 
        vpUpdateMode = VPUpdateNone;
506
 
        break;
507
 
    default:
508
 
        break;
509
 
    }
510
 
 
511
 
    if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone)
512
 
        cScreen->damageScreen ();
513
 
 
514
 
    if (expoCam == 1.0f)
515
 
    {
516
 
        foreach (float& vp, vpActivity)
517
 
            if (vp != 0.0 && vp != 1.0)
518
 
                cScreen->damageScreen ();
519
 
    }
520
 
 
521
 
    if (grabIndex && expoCam <= 0.0f && !expoMode)
522
 
    {
523
 
        screen->removeGrab (grabIndex, NULL);
524
 
        grabIndex = 0;
525
 
        updateWraps (false);
526
 
    }
527
 
 
528
 
    cScreen->donePaint ();
529
 
 
530
 
    switch (dndState) {
531
 
    case DnDDuring:
532
 
        {
533
 
            if (dndWindow)
534
 
                dndWindow->move (newCursor.x () - prevCursor.x (),
535
 
                                 newCursor.y () - prevCursor.y (),
536
 
                                 optionGetExpoImmediateMove ());
537
 
 
538
 
            prevCursor = newCursor;
539
 
            cScreen->damageScreen ();
540
 
        }
541
 
        break;
542
 
 
543
 
    case DnDStart:
544
 
        {
545
 
            int                              xOffset, yOffset;
546
 
            CompWindowList::reverse_iterator iter;
547
 
 
548
 
            xOffset = screen->vpSize ().width () * screen->width ();
549
 
            yOffset = screen->vpSize ().height () * screen->height ();
550
 
 
551
 
            dndState = DnDNone;
552
 
 
553
 
            for (iter = screen->windows ().rbegin ();
554
 
                 iter != screen->windows ().rend (); ++iter)
555
 
            {
556
 
                CompWindow *w = *iter;
557
 
                CompRect   input (w->inputRect ());
558
 
                bool       inWindow;
559
 
                int        nx, ny;
560
 
 
561
 
                if (w->destroyed ())
562
 
                    continue;
563
 
 
564
 
                if (!w->shaded () && !w->isViewable ())
565
 
                    continue;
566
 
 
567
 
                if (w->onAllViewports ())
568
 
                {
569
 
                    nx = (newCursor.x () + xOffset) % screen->width ();
570
 
                    ny = (newCursor.y () + yOffset) % screen->height ();
571
 
                }
572
 
                else
573
 
                {
574
 
                    nx = newCursor.x () -
575
 
                         (screen->vp ().x () * screen->width ());
576
 
                    ny = newCursor.y () -
577
 
                         (screen->vp ().y () * screen->height ());
578
 
                }
579
 
 
580
 
                inWindow = (nx >= input.left () && nx <= input.right ()) ||
581
 
                           (nx >= (input.left () + xOffset) &&
582
 
                            nx <= (input.right () + xOffset));
583
 
 
584
 
                inWindow &= (ny >= input.top () && ny <= input.bottom ()) ||
585
 
                            (ny >= (input.top () + yOffset) &&
586
 
                             ny <= (input.bottom () + yOffset));
587
 
 
588
 
                if (!inWindow)
589
 
                    continue;
590
 
 
591
 
                /* make sure we never move windows we're not allowed to move */
592
 
                if (!w->managed ())
593
 
                    break;
594
 
                else if (!(w->actions () & CompWindowActionMoveMask))
595
 
                    break;
596
 
                else if (w->type () & (CompWindowTypeDockMask |
597
 
                                       CompWindowTypeDesktopMask))
598
 
                    break;
599
 
 
600
 
                dndState  = DnDDuring;
601
 
                dndWindow = w;
602
 
 
603
 
                w->grabNotify (nx, ny, 0,
604
 
                               CompWindowGrabMoveMask |
605
 
                               CompWindowGrabButtonMask);
606
 
 
607
 
                w->raise ();
608
 
                w->moveInputFocusTo ();
609
 
                break;
610
 
            }
611
 
 
612
 
            prevCursor = newCursor;
613
 
        }
614
 
        break;
615
 
    default:
616
 
        break;
617
 
    }
618
 
}
619
 
 
620
 
void
621
 
ExpoScreen::invertTransformedVertex (const GLScreenPaintAttrib& attrib,
622
 
                                     const GLMatrix&            transform,
623
 
                                     CompOutput                 *output,
624
 
                                     int                        vertex[2])
625
 
{
626
 
    GLMatrix sTransform (transform);
627
 
    GLdouble p1[3], p2[3], v[3], alpha;
628
 
    GLdouble mvm[16], pm[16];
629
 
    GLint    viewport[4];
630
 
    int      i;
631
 
 
632
 
    gScreen->glApplyTransform (attrib, output, &sTransform);
633
 
    sTransform.toScreenSpace (output, -attrib.zTranslate);
634
 
 
635
 
    glGetIntegerv (GL_VIEWPORT, viewport);
636
 
    for (i = 0; i < 16; i++)
637
 
    {
638
 
        mvm[i] = sTransform[i];
639
 
        pm[i]  = gScreen->projectionMatrix ()[i];
640
 
    }
641
 
 
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]);
646
 
 
647
 
    for (i = 0; i < 3; i++)
648
 
        v[i] = p1[i] - p2[i];
649
 
 
650
 
    alpha = -p1[2] / v[2];
651
 
 
652
 
    if (optionGetDeform () == DeformCurve && screen->desktopWindowCount ())
653
 
    {
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]));
665
 
 
666
 
        const float rq = (0.25 * p * p) - q;
667
 
        const float ph = -p * 0.5;
668
 
 
669
 
        if (rq < 0.0)
670
 
        {
671
 
            vertex[0] = -1000;
672
 
            vertex[1] = -1000;
673
 
            return;
674
 
        }
675
 
        else
676
 
        {
677
 
            alpha = ph + sqrt(rq);
678
 
            if (p1[2] + (alpha * v[2]) > 0.0)
679
 
            {
680
 
                vertex[0] = -1000;
681
 
                vertex[1] = -1000;
682
 
                return;
683
 
            }
684
 
        }
685
 
    }
686
 
 
687
 
    vertex[0] = ceil (p1[0] + (alpha * v[0]));
688
 
    vertex[1] = ceil (p1[1] + (alpha * v[1]));
689
 
}
690
 
 
691
 
void
692
 
ExpoScreen::paintWall (const GLScreenPaintAttrib& attrib,
693
 
                       const GLMatrix&            transform,
694
 
                       const CompRegion&          region,
695
 
                       CompOutput                 *output,
696
 
                       unsigned int               mask,
697
 
                       bool                       reflection)
698
 
{
699
 
    GLMatrix sTransformW, sTransform (transform);
700
 
    int      i, j, vp;
701
 
    GLenum   oldFilter = gScreen->textureFilter ();
702
 
 
703
 
    float     sx = (float) screen->width () / output->width ();
704
 
    float     sy = (float) screen->height () / output->height ();
705
 
    float     biasZ;
706
 
    float     oScale, rotation = 0.0f, progress, vpp;
707
 
    float     aspectX = 1.0f, aspectY = 1.0f;
708
 
    GLVector  cam;
709
 
    CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
710
 
 
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;
715
 
 
716
 
    int      glPaintTransformedOutputIndex =
717
 
        gScreen->glPaintTransformedOutputGetCurrentIndex ();
718
 
 
719
 
    // Make sure that the base glPaintTransformedOutput function is called
720
 
    gScreen->glPaintTransformedOutputSetCurrentIndex (MAXSHORT);
721
 
 
722
 
    /* Zoom animation stuff */
723
 
    /* camera position for the selected viewport */
724
 
    GLVector vpCamPos (0, 0, 0, 0);
725
 
 
726
 
    /* camera position during expo mode */
727
 
    GLVector expoCamPos (0, 0, 0, 0);
728
 
 
729
 
    if (optionGetDeform () == DeformCurve)
730
 
    {
731
 
        vpCamPos[GLVector::x] = -sx * (0.5 - (((float) output->x () +
732
 
                                               (output->width () / 2.0)) /
733
 
                                              (float) screen->width ()));
734
 
    }
735
 
    else
736
 
    {
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 ();
741
 
    }
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 ();
746
 
 
747
 
    biasZ = MAX (vpSize.x () * sx, vpSize.y () * sy);
748
 
    if (optionGetDeform () == DeformTilt || optionGetReflection ())
749
 
        biasZ *= (0.15 + optionGetDistance ());
750
 
    else
751
 
        biasZ *= optionGetDistance ();
752
 
 
753
 
    progress = sigmoidProgress (expoCam);
754
 
 
755
 
    if (optionGetDeform () != DeformCurve)
756
 
        expoCamPos[GLVector::x] = gapX * (vpSize.x () - 1) * 0.5;
757
 
 
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) +
762
 
                               biasZ);
763
 
 
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;
771
 
 
772
 
    if (vpSize.x () > vpSize.y ())
773
 
    {
774
 
        aspectY = (float) vpSize.x () / (float) vpSize.y ();
775
 
        aspectY -= 1.0;
776
 
        aspectY *= -optionGetAspectRatio () + 1.0;
777
 
        aspectY *= progress;
778
 
        aspectY += 1.0;
779
 
    }
780
 
    else
781
 
    {
782
 
        aspectX = (float) vpSize.y () / (float) vpSize.x ();
783
 
        aspectX -= 1.0;
784
 
        aspectX *= -optionGetAspectRatio () + 1.0;
785
 
        aspectX *= progress;
786
 
        aspectX += 1.0;
787
 
    }
788
 
 
789
 
    /* End of Zoom animation stuff */
790
 
 
791
 
    if (optionGetDeform () == DeformTilt)
792
 
    {
793
 
        if (optionGetExpoAnimation () == ExpoAnimationZoom)
794
 
            rotation = 10.0 * sigmoidProgress (expoCam);
795
 
        else
796
 
            rotation = 10.0 * expoCam;
797
 
    }
798
 
 
799
 
    if (optionGetMipmaps ())
800
 
        gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
801
 
 
802
 
    /* ALL TRANSFORMATION ARE EXECUTED FROM BOTTOM TO TOP */
803
 
 
804
 
    oScale = 1 / (1 + ((MAX (sx, sy) - 1) * progress));
805
 
 
806
 
    sTransform.scale (oScale, oScale, 1.0);
807
 
 
808
 
    /* zoom out */
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);
814
 
 
815
 
    if (reflection)
816
 
    {
817
 
        float scaleFactor = optionGetScaleFactor ();
818
 
 
819
 
        sTransform.translate (0.0,
820
 
                              (vpSize.y () + ((vpSize.y () - 1) * gapY * 2)) *
821
 
                              -sy * aspectY,
822
 
                              0.0);
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)),
827
 
                              0.0);
828
 
        sTransform.scale (1.0, scaleFactor, 1.0);
829
 
        glCullFace (GL_FRONT);
830
 
    }
831
 
 
832
 
    /* rotate */
833
 
    sTransform.rotate (rotation, 0.0f, 1.0f, 0.0f);
834
 
    sTransform.scale (aspectX, aspectY, 1.0);
835
 
 
836
 
    /* translate expo to center */
837
 
    sTransform.translate (vpSize.x () * sx * -0.5,
838
 
                          vpSize.y () * sy * 0.5, 0.0f);
839
 
 
840
 
    if (optionGetDeform () == DeformCurve)
841
 
        sTransform.translate ((vpSize.x () - 1) * sx * 0.5, 0.0, 0.0);
842
 
 
843
 
    sTransformW = sTransform;
844
 
 
845
 
    /* revert prepareXCoords region shift. Now all screens display the same */
846
 
    sTransform.translate (0.5f, -0.5f, DEFAULT_Z_CAMERA);
847
 
 
848
 
    if (vpSize.x () > 2)
849
 
        /* we can't have 90 degree for the left/right most viewport */
850
 
        curveAngle = interpolate (359 / ((vpSize.x () - 1) * 2), 1,
851
 
                                  optionGetCurve ());
852
 
    else
853
 
        curveAngle = interpolate (180 / vpSize.x (), 1, optionGetCurve ());
854
 
 
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);
859
 
 
860
 
    expoActive = true;
861
 
 
862
 
    for (j = 0; j < vpSize.y (); j++)
863
 
    {
864
 
        GLMatrix sTransform2 (sTransform), sTransform3;
865
 
 
866
 
        for (i = 0; i < vpSize.x (); i++)
867
 
        {
868
 
            if (optionGetExpoAnimation () == ExpoAnimationVortex)
869
 
                sTransform2.rotate (360 * expoCam,
870
 
                                    0.0f, 1.0f, 2.0f * expoCam);
871
 
 
872
 
            sTransform3 = sTransform2;
873
 
 
874
 
            sTransform3.translate (output->x () / output->width (),
875
 
                                   -output->y () / output->height (), 0.0);
876
 
 
877
 
            cScreen->setWindowPaintOffset ((screen->vp ().x () - i) *
878
 
                                           screen->width (),
879
 
                                           (screen->vp ().y () - j) *
880
 
                                           screen->height ());
881
 
 
882
 
            vp = (j * vpSize.x ()) + i;
883
 
 
884
 
            vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
885
 
            vpp = sigmoidProgress (vpp);
886
 
 
887
 
            vpBrightness = vpp + ((1.0 - vpp) *
888
 
                                  optionGetVpBrightness () / 100.0);
889
 
            vpSaturation = vpp + ((1.0 - vpp) *
890
 
                                  optionGetVpSaturation () / 100.0);
891
 
 
892
 
            paintingVp.set (i, j);
893
 
 
894
 
            if (optionGetDeform () == DeformCurve)
895
 
            {
896
 
                float rotateX;
897
 
 
898
 
                sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
899
 
                                       curveDistance - DEFAULT_Z_CAMERA);
900
 
 
901
 
                rotateX = -i + interpolate (((float) vpSize.x () / 2.0) - 0.5,
902
 
                                            screen->vp ().x (), progress);
903
 
 
904
 
                sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
905
 
 
906
 
                sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
907
 
                                       DEFAULT_Z_CAMERA - curveDistance);
908
 
            }
909
 
 
910
 
            gScreen->glPaintTransformedOutput (attrib, sTransform3,
911
 
                                               screen->region (), output,
912
 
                                               mask);
913
 
 
914
 
            if (!reflection)
915
 
            {
916
 
                int cursor[2] = { pointerX, pointerY };
917
 
 
918
 
                invertTransformedVertex (attrib, sTransform3,
919
 
                                         output, cursor);
920
 
 
921
 
                if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
922
 
                    (cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
923
 
                {
924
 
                    newCursor.setX (i * screen->width () + cursor[0]);
925
 
                    newCursor.setY (j * screen->height () + cursor[1]);
926
 
 
927
 
                    if (anyClick || dndState != DnDNone)
928
 
                    {
929
 
                        /* Used to save last viewport interaction was in */
930
 
                        selectedVp.set (i, j);
931
 
                        anyClick = false;
932
 
                    }
933
 
                }
934
 
            }
935
 
 
936
 
            /* not sure this will work with different resolutions */
937
 
            if (optionGetDeform () != DeformCurve)
938
 
                sTransform2.translate (sx + gapX, 0.0f, 0.0);
939
 
        }
940
 
 
941
 
        /* not sure this will work with different resolutions */
942
 
        sTransform.translate (0.0, -(sy + gapY), 0.0f);
943
 
    }
944
 
 
945
 
    glNormal3f (0.0, 0.0, -1.0);
946
 
 
947
 
    if (reflection)
948
 
    {
949
 
        glEnable (GL_BLEND);
950
 
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
951
 
 
952
 
        glPushMatrix ();
953
 
 
954
 
        if (optionGetDeform () != DeformCurve)
955
 
        {
956
 
            glLoadMatrixf (sTransformW.getMatrix ());
957
 
 
958
 
            glBegin (GL_QUADS);
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);
967
 
            glEnd ();
968
 
        }
969
 
        else
970
 
        {
971
 
            glCullFace (GL_BACK);
972
 
            glLoadIdentity ();
973
 
            glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
974
 
 
975
 
            glBegin (GL_QUADS);
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);
988
 
            glEnd ();
989
 
        }
990
 
        glCullFace (GL_BACK);
991
 
 
992
 
        glLoadIdentity ();
993
 
        glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
994
 
 
995
 
        if (optionGetGroundSize () > 0.0)
996
 
        {
997
 
            glBegin (GL_QUADS);
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 ());
1004
 
            glEnd ();
1005
 
        }
1006
 
 
1007
 
        glColor4usv (defaultColor);
1008
 
 
1009
 
        glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1010
 
        glDisable (GL_BLEND);
1011
 
        glPopMatrix ();
1012
 
    }
1013
 
 
1014
 
    expoActive = false;
1015
 
 
1016
 
    cScreen->setWindowPaintOffset (0, 0);
1017
 
 
1018
 
    gScreen->glPaintTransformedOutputSetCurrentIndex (glPaintTransformedOutputIndex);
1019
 
    gScreen->setTextureFilter (oldFilter);
1020
 
}
1021
 
 
1022
 
bool
1023
 
ExpoScreen::glPaintOutput (const GLScreenPaintAttrib& attrib,
1024
 
                           const GLMatrix&            transform,
1025
 
                           const CompRegion&          region,
1026
 
                           CompOutput                 *output,
1027
 
                           unsigned int               mask)
1028
 
{
1029
 
    if (expoCam > 0.0)
1030
 
        mask |= PAINT_SCREEN_TRANSFORMED_MASK | PAINT_SCREEN_CLEAR_MASK;
1031
 
 
1032
 
    return gScreen->glPaintOutput (attrib, transform, region, output, mask);
1033
 
}
1034
 
 
1035
 
void
1036
 
ExpoScreen::glPaintTransformedOutput (const GLScreenPaintAttrib& attrib,
1037
 
                                      const GLMatrix&            transform,
1038
 
                                      const CompRegion&          region,
1039
 
                                      CompOutput                 *output,
1040
 
                                      unsigned int               mask)
1041
 
{
1042
 
    expoActive = false;
1043
 
 
1044
 
    if (expoCam > 0)
1045
 
        mask |= PAINT_SCREEN_CLEAR_MASK;
1046
 
 
1047
 
    if (expoCam <= 0 || (expoCam > 0.0 && expoCam < 1.0 &&
1048
 
                         optionGetExpoAnimation () != ExpoAnimationZoom))
1049
 
    {
1050
 
        gScreen->glPaintTransformedOutput (attrib, transform, region,
1051
 
                                           output, mask);
1052
 
    }
1053
 
    else
1054
 
    {
1055
 
        gScreen->clearOutput (output, GL_COLOR_BUFFER_BIT);
1056
 
    }
1057
 
 
1058
 
    mask &= ~PAINT_SCREEN_CLEAR_MASK;
1059
 
 
1060
 
    if (expoCam > 0.0)
1061
 
    {
1062
 
        if (optionGetReflection ())
1063
 
            paintWall (attrib, transform, region, output, mask, true);
1064
 
 
1065
 
        paintWall (attrib, transform, region, output, mask, false);
1066
 
        anyClick = false;
1067
 
    }
1068
 
}
1069
 
 
1070
 
bool
1071
 
ExpoWindow::glDraw (const GLMatrix&     transform,
1072
 
                    GLFragment::Attrib& fragment,
1073
 
                    const CompRegion&   region,
1074
 
                    unsigned int        mask)
1075
 
{
1076
 
    if (eScreen->expoCam == 0.0f)
1077
 
        return gWindow->glDraw (transform, fragment, region, mask);
1078
 
 
1079
 
    GLFragment::Attrib fA (fragment);
1080
 
    int                expoAnimation;
1081
 
 
1082
 
    expoAnimation = eScreen->optionGetExpoAnimation ();
1083
 
 
1084
 
    if (eScreen->expoActive)
1085
 
    {
1086
 
        if (expoAnimation != ExpoScreen::ExpoAnimationZoom)
1087
 
            fA.setOpacity (fragment.getOpacity () * eScreen->expoCam);
1088
 
 
1089
 
        if (window->wmType () & CompWindowTypeDockMask &&
1090
 
            eScreen->optionGetHideDocks ())
1091
 
        {
1092
 
            if (expoAnimation == ExpoScreen::ExpoAnimationZoom &&
1093
 
                eScreen->paintingVp == eScreen->selectedVp)
1094
 
            {
1095
 
                fA.setOpacity (fragment.getOpacity () *
1096
 
                               (1 - sigmoidProgress (eScreen->expoCam)));
1097
 
            }
1098
 
            else
1099
 
            {
1100
 
                fA.setOpacity (0);
1101
 
            }
1102
 
        }
1103
 
 
1104
 
        fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
1105
 
        fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
1106
 
    }
1107
 
    else
1108
 
    {
1109
 
        if (expoAnimation == ExpoScreen::ExpoAnimationZoom)
1110
 
            fA.setBrightness (0);
1111
 
        else
1112
 
            fA.setBrightness (fragment.getBrightness () *
1113
 
                              (1 - sigmoidProgress (eScreen->expoCam)));
1114
 
    }
1115
 
 
1116
 
    return gWindow->glDraw (transform, fA, region, mask);
1117
 
}
1118
 
 
1119
 
#define EXPO_GRID_SIZE 100
1120
 
 
1121
 
void
1122
 
ExpoWindow::glAddGeometry (const GLTexture::MatrixList& matrices,
1123
 
                           const CompRegion&            region,
1124
 
                           const CompRegion&            clip,
1125
 
                           unsigned int                 maxGridWidth,
1126
 
                           unsigned int                 maxGridHeight)
1127
 
{
1128
 
    if (eScreen->expoCam > 0.0        &&
1129
 
        screen->desktopWindowCount () &&
1130
 
        eScreen->optionGetDeform () == ExpoScreen::DeformCurve)
1131
 
    {
1132
 
        int         i, oldVCount = gWindow->geometry ().vCount;
1133
 
        GLfloat     *v;
1134
 
        CompPoint   offset;
1135
 
        float       lastX, lastZ = 0.0;
1136
 
        const float radSquare = pow (eScreen->curveDistance, 2) + 0.25;
1137
 
        float       ang;
1138
 
 
1139
 
        gWindow->glAddGeometry (matrices, region, clip,
1140
 
                                MIN(maxGridWidth , EXPO_GRID_SIZE),
1141
 
                                maxGridHeight);
1142
 
 
1143
 
        v  = gWindow->geometry ().vertices;
1144
 
        v += gWindow->geometry ().vertexStride - 3;
1145
 
        v += gWindow->geometry ().vertexStride * oldVCount;
1146
 
 
1147
 
        if (!window->onAllViewports ())
1148
 
        {
1149
 
            offset = eScreen->cScreen->windowPaintOffset ();
1150
 
            offset = window->getMovementForOffset (offset);
1151
 
        }
1152
 
 
1153
 
        lastX = -1000000000.0;
1154
 
 
1155
 
        for (i = oldVCount; i < gWindow->geometry ().vCount; i++)
1156
 
        {
1157
 
            if (v[0] == lastX)
1158
 
            {
1159
 
                v[2] = lastZ;
1160
 
            }
1161
 
            else if (v[0] + offset.x () >= -EXPO_GRID_SIZE &&
1162
 
                     v[0] + offset.x () < screen->width () + EXPO_GRID_SIZE)
1163
 
            {
1164
 
                ang = (((v[0] + offset.x ()) / (float) screen->width ()) - 0.5);
1165
 
                ang *= ang;
1166
 
                if (ang < radSquare)
1167
 
                {
1168
 
                    v[2] = eScreen->curveDistance - sqrt (radSquare - ang);
1169
 
                    v[2] *= sigmoidProgress (eScreen->expoCam);
1170
 
                }
1171
 
            }
1172
 
 
1173
 
            lastX = v[0];
1174
 
            lastZ = v[2];
1175
 
 
1176
 
            v += gWindow->geometry ().vertexStride;
1177
 
        }
1178
 
    }
1179
 
    else
1180
 
    {
1181
 
        gWindow->glAddGeometry (matrices, region, clip, maxGridWidth, maxGridHeight);
1182
 
    }
1183
 
}
1184
 
 
1185
 
void
1186
 
ExpoWindow::glDrawTexture (GLTexture           *texture,
1187
 
                           GLFragment::Attrib& attrib,
1188
 
                           unsigned int        mask)
1189
 
{
1190
 
    if (eScreen->expoCam > 0.0                                 &&
1191
 
        eScreen->optionGetDeform () == ExpoScreen::DeformCurve &&
1192
 
        eScreen->gScreen->lighting ()                          &&
1193
 
        screen->desktopWindowCount ())
1194
 
    {
1195
 
        unsigned int i, idx, vCount;
1196
 
        CompPoint    offset;
1197
 
        float        x;
1198
 
        GLfloat      *v;
1199
 
 
1200
 
        vCount = gWindow->geometry ().vCount;
1201
 
 
1202
 
        if (eScreen->winNormals.size () < vCount * 3)
1203
 
            eScreen->winNormals.resize (vCount * 3);
1204
 
 
1205
 
        if (!window->onAllViewports ())
1206
 
        {
1207
 
            offset = eScreen->cScreen->windowPaintOffset ();
1208
 
            offset = window->getMovementForOffset (offset);
1209
 
        }
1210
 
 
1211
 
        v = gWindow->geometry ().vertices +
1212
 
            (gWindow->geometry ().vertexStride - 3);
1213
 
 
1214
 
        for (i = 0; i < vCount; i++)
1215
 
        {
1216
 
            x = (float) (v[0] + offset.x () - screen->width () / 2) *
1217
 
                        eScreen->curveAngle / screen->width ();
1218
 
 
1219
 
            while (x < 0)
1220
 
                x += 360.0;
1221
 
 
1222
 
            idx = floor (x);
1223
 
 
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];
1229
 
 
1230
 
            v += gWindow->geometry ().vertexStride;
1231
 
        }
1232
 
 
1233
 
        glEnable (GL_NORMALIZE);
1234
 
        glNormalPointer (GL_FLOAT,0, &eScreen->winNormals.at (0));
1235
 
 
1236
 
        glEnableClientState (GL_NORMAL_ARRAY);
1237
 
 
1238
 
        gWindow->glDrawTexture (texture, attrib, mask);
1239
 
 
1240
 
        glDisable (GL_NORMALIZE);
1241
 
        glDisableClientState (GL_NORMAL_ARRAY);
1242
 
        glNormal3f (0.0, 0.0, -1.0);
1243
 
    }
1244
 
    else
1245
 
    {
1246
 
        glEnable (GL_NORMALIZE);
1247
 
        gWindow->glDrawTexture (texture, attrib, mask);
1248
 
        glDisable (GL_NORMALIZE);
1249
 
    }
1250
 
}
1251
 
 
1252
 
bool
1253
 
ExpoWindow::glPaint (const GLWindowPaintAttrib& attrib,
1254
 
                     const GLMatrix&            transform,
1255
 
                     const CompRegion&          region,
1256
 
                     unsigned int               mask)
1257
 
{
1258
 
    if (eScreen->expoActive)
1259
 
    {
1260
 
        float opacity = 1.0;
1261
 
        bool  hide;
1262
 
        bool  zoomAnim;
1263
 
 
1264
 
        zoomAnim = eScreen->optionGetExpoAnimation () ==
1265
 
                   ExpoScreen::ExpoAnimationZoom;
1266
 
        hide     = eScreen->optionGetHideDocks () &&
1267
 
                   (window->wmType () & CompWindowTypeDockMask);
1268
 
 
1269
 
        if (eScreen->expoCam > 0.0)
1270
 
        {
1271
 
            if (eScreen->expoCam < 1.0 && !zoomAnim)
1272
 
                mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1273
 
            else if (hide)
1274
 
                mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1275
 
        }
1276
 
 
1277
 
        if (!zoomAnim)
1278
 
            opacity = attrib.opacity * eScreen->expoCam;
1279
 
 
1280
 
        if (hide)
1281
 
        {
1282
 
            if (zoomAnim && eScreen->paintingVp == eScreen->selectedVp)
1283
 
                opacity = attrib.opacity *
1284
 
                          (1 - sigmoidProgress (eScreen->expoCam));
1285
 
            else
1286
 
                opacity = 0;
1287
 
        }
1288
 
 
1289
 
        if (opacity <= 0)
1290
 
            mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1291
 
    }
1292
 
 
1293
 
    return gWindow->glPaint (attrib, transform, region, mask);
1294
 
}
1295
 
 
1296
 
bool
1297
 
ExpoWindow::damageRect (bool            initial,
1298
 
                        const CompRect& rect)
1299
 
{
1300
 
    if (eScreen->expoCam > 0.0f)
1301
 
        eScreen->cScreen->damageScreen ();
1302
 
 
1303
 
    return cWindow->damageRect (initial, rect);
1304
 
}
1305
 
 
1306
 
#define EXPOINITBIND(opt, func)                                \
1307
 
    optionSet##opt##Initiate (boost::bind (&ExpoScreen::func,  \
1308
 
                                           this, _1, _2, _3));
1309
 
#define EXPOTERMBIND(opt, func)                                \
1310
 
    optionSet##opt##Terminate (boost::bind (&ExpoScreen::func, \
1311
 
                                            this, _1, _2, _3));
1312
 
 
1313
 
ExpoScreen::ExpoScreen (CompScreen *s) :
1314
 
    PluginClassHandler<ExpoScreen, CompScreen> (s),
1315
 
    ExpoOptions (),
1316
 
    cScreen (CompositeScreen::get (s)),
1317
 
    gScreen (GLScreen::get (s)),
1318
 
    expoCam (0.0f),
1319
 
    expoActive (false),
1320
 
    expoMode (false),
1321
 
    dndState (DnDNone),
1322
 
    dndWindow (NULL),
1323
 
    origVp (s->vp ()),
1324
 
    selectedVp (s->vp ()),
1325
 
    vpUpdateMode (VPUpdateNone),
1326
 
    clickTime (0),
1327
 
    doubleClick (false),
1328
 
    vpNormals (360 * 3),
1329
 
    grabIndex (0)
1330
 
{
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"));
1335
 
 
1336
 
    EXPOINITBIND (ExpoKey, doExpo);
1337
 
    EXPOTERMBIND (ExpoKey, termExpo);
1338
 
    EXPOINITBIND (ExpoButton, doExpo);
1339
 
    EXPOTERMBIND (ExpoButton, termExpo);
1340
 
    EXPOINITBIND (ExpoEdge, doExpo);
1341
 
    EXPOTERMBIND (ExpoButton, termExpo);
1342
 
 
1343
 
    EXPOINITBIND (DndButton, dndInit);
1344
 
    EXPOTERMBIND (DndButton, dndFini);
1345
 
    EXPOINITBIND (ExitButton, exitExpo);
1346
 
    EXPOINITBIND (NextVpButton, nextVp);
1347
 
    EXPOINITBIND (PrevVpButton, prevVp);
1348
 
 
1349
 
    ScreenInterface::setHandler (screen, false);
1350
 
    CompositeScreenInterface::setHandler (cScreen, false);
1351
 
    GLScreenInterface::setHandler (gScreen, false);
1352
 
}
1353
 
 
1354
 
ExpoWindow::ExpoWindow (CompWindow *w) :
1355
 
    PluginClassHandler<ExpoWindow, CompWindow> (w),
1356
 
    window (w),
1357
 
    cWindow (CompositeWindow::get (w)),
1358
 
    gWindow (GLWindow::get (w)),
1359
 
    eScreen (ExpoScreen::get (screen))
1360
 
{
1361
 
    CompositeWindowInterface::setHandler (cWindow, false);
1362
 
    GLWindowInterface::setHandler (gWindow, false);
1363
 
}
1364
 
 
1365
 
bool
1366
 
ExpoPluginVTable::init ()
1367
 
{
1368
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1369
 
        !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1370
 
        !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
1371
 
        return false;
1372
 
 
1373
 
    return true;
1374
 
}
1375
 
 
1376