~vanvugt/compiz-plugins-main/fix-1084386

« back to all changes in this revision

Viewing changes to thumbnail/src/thumbnail.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-08-12 06:36:10 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110812063610-8mcxo2xohctyp2ak
Sync - Remove Plugins

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *
3
 
 * Compiz thumbnail plugin
4
 
 *
5
 
 * thumbnail.cpp
6
 
 *
7
 
 * Copyright : (C) 2007 by Dennis Kasprzyk
8
 
 * E-mail    : onestone@beryl-project.org
9
 
 *
10
 
 * Ported to Compiz 0.9
11
 
 * Copyright : (C) 2009 by Sam Spilsbury
12
 
 * E-mail    : smspillaz@gmail.com
13
 
 *
14
 
 * Based on thumbnail.c:
15
 
 * Copyright : (C) 2007 Stjepan Glavina
16
 
 * E-mail    : stjepang@gmail.com
17
 
 *
18
 
 * This program is free software; you can redistribute it and/or
19
 
 * modify it under the terms of the GNU General Public License
20
 
 * as published by the Free Software Foundation; either version 2
21
 
 * of the License, or (at your option) any later version.
22
 
 *
23
 
 * This program is distributed in the hope that it will be useful,
24
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 
 * GNU General Public License for more details.
27
 
 *
28
 
 */
29
 
 
30
 
#include "thumbnail.h"
31
 
#include "thumbnail_tex.h"
32
 
 
33
 
COMPIZ_PLUGIN_20090315 (thumbnail, ThumbPluginVTable);
34
 
 
35
 
void
36
 
ThumbScreen::freeThumbText (Thumbnail  *t)
37
 
{
38
 
    if (!t->text)
39
 
        return;
40
 
 
41
 
    delete t->text;
42
 
    t->text = NULL;
43
 
}
44
 
 
45
 
void
46
 
ThumbScreen::renderThumbText (Thumbnail  *t,
47
 
                              bool       freeThumb)
48
 
{
49
 
    CompText::Attrib tA;
50
 
 
51
 
    if (freeThumb || !t->text)
52
 
    {
53
 
        freeThumbText (t);
54
 
        t->text = new CompText ();
55
 
    }
56
 
 
57
 
    if (!textPluginLoaded)
58
 
        return;
59
 
 
60
 
    tA.maxWidth   = t->width;
61
 
    tA.maxHeight  = 100;
62
 
 
63
 
    tA.size       = optionGetFontSize ();
64
 
    tA.color[0]   = optionGetFontColorRed ();
65
 
    tA.color[1]   = optionGetFontColorGreen ();
66
 
    tA.color[2]   = optionGetFontColorBlue ();
67
 
    tA.color[3]   = optionGetFontColorAlpha ();
68
 
    tA.flags      = CompText::Ellipsized;
69
 
    if (optionGetFontBold ())
70
 
        tA.flags |= CompText::StyleBold;
71
 
    tA.family     = "Sans";
72
 
 
73
 
    t->textValid = t->text->renderWindowTitle (t->win->id (), false, tA);
74
 
}
75
 
 
76
 
void
77
 
ThumbScreen::damageThumbRegion (Thumbnail  *t)
78
 
{
79
 
    int x = t->x - t->offset;
80
 
    int y = t->y - t->offset;
81
 
    int width = t->width + (t->offset * 2);
82
 
    int height = t->height + (t->offset * 2);
83
 
    CompRect   rect (x, y, width, height);
84
 
 
85
 
    if (t->text)
86
 
        rect.setHeight (rect.height () + t->text->getHeight () + TEXT_DISTANCE);
87
 
 
88
 
    CompRegion region (rect);
89
 
 
90
 
    cScreen->damageRegion (region);
91
 
}
92
 
 
93
 
#define GET_DISTANCE(a,b) \
94
 
    (sqrt((((a)[0] - (b)[0]) * ((a)[0] - (b)[0])) + \
95
 
          (((a)[1] - (b)[1]) * ((a)[1] - (b)[1]))))
96
 
 
97
 
void
98
 
ThumbScreen::thumbUpdateThumbnail ()
99
 
{
100
 
    int        igMidPoint[2], tMidPoint[2];
101
 
    int        tPos[2], tmpPos[2];
102
 
    float      distance = 1000000;
103
 
    int        off, oDev, tHeight;
104
 
    CompRect   oGeom;
105
 
    float      maxSize = optionGetThumbSize ();
106
 
    double     scale  = 1.0;
107
 
    ThumbWindow *tw;
108
 
    CompWindow *w;
109
 
 
110
 
    if (thumb.win == pointedWin)
111
 
        return;
112
 
 
113
 
    if (thumb.opacity > 0.0 && oldThumb.opacity > 0.0)
114
 
        return;
115
 
 
116
 
    if (thumb.win)
117
 
        damageThumbRegion (&thumb);
118
 
 
119
 
    freeThumbText (&oldThumb);
120
 
 
121
 
    if (oldThumb.win)
122
 
    {
123
 
        tw = ThumbWindow::get (oldThumb.win);
124
 
 
125
 
        /* Disable painting on the old thumb */
126
 
        tw->cWindow->damageRectSetEnabled (tw, false);
127
 
        tw->gWindow->glPaintSetEnabled (tw, false);
128
 
        tw->window->resizeNotifySetEnabled (tw, false);
129
 
    }
130
 
 
131
 
    oldThumb       = thumb;
132
 
    thumb.text     = NULL;
133
 
    thumb.win      = pointedWin;
134
 
    thumb.dock     = dock;
135
 
 
136
 
    if (!thumb.win || !dock)
137
 
    {
138
 
        thumb.win  = NULL;
139
 
        thumb.dock = NULL;
140
 
        return;
141
 
    }
142
 
 
143
 
    w = thumb.win;
144
 
    tw = ThumbWindow::get (w);
145
 
 
146
 
    tw->cWindow->damageRectSetEnabled (tw, true);
147
 
    tw->gWindow->glPaintSetEnabled (tw, true);
148
 
    tw->window->resizeNotifySetEnabled (tw, true);
149
 
 
150
 
    /* do we nee to scale the window down? */
151
 
    if (WIN_W (w) > maxSize || WIN_H (w) > maxSize)
152
 
    {
153
 
        if (WIN_W (w) >= WIN_H (w))
154
 
            scale = maxSize / WIN_W (w);
155
 
        else
156
 
            scale = maxSize / WIN_H (w);
157
 
    }
158
 
 
159
 
    thumb.width  = WIN_W (w)* scale;
160
 
    thumb.height = WIN_H (w) * scale;
161
 
    thumb.scale  = scale;
162
 
 
163
 
    if (optionGetTitleEnabled ())
164
 
        renderThumbText (&thumb, false);
165
 
    else
166
 
        freeThumbText (&thumb);
167
 
 
168
 
    igMidPoint[0] = w->iconGeometry ().x () + (w->iconGeometry ().width () / 2);
169
 
    igMidPoint[1] = w->iconGeometry ().y () + (w->iconGeometry ().height () / 2);
170
 
 
171
 
    off = optionGetBorder ();
172
 
    oDev = screen->outputDeviceForPoint (w->iconGeometry ().x () +
173
 
                                 (w->iconGeometry ().width () / 2),
174
 
                                 w->iconGeometry ().y () +
175
 
                                 (w->iconGeometry ().height () / 2));
176
 
 
177
 
    if (screen->outputDevs ().size () == 1 ||
178
 
        (unsigned int) oDev > screen->outputDevs ().size ())
179
 
    {
180
 
        oGeom.setGeometry (0, 0, screen->width (), screen->height ());
181
 
    }
182
 
    else
183
 
    {
184
 
        oGeom = screen->outputDevs ()[oDev];
185
 
    }
186
 
 
187
 
    tHeight = thumb.height;
188
 
    if (thumb.text)
189
 
        tHeight += thumb.text->getHeight () + TEXT_DISTANCE;
190
 
 
191
 
    /* Could someone please explain how this works */
192
 
 
193
 
    // failsave position
194
 
    tPos[0] = igMidPoint[0] - (thumb.width / 2.0);
195
 
 
196
 
    if (w->iconGeometry ().y () - tHeight >= 0)
197
 
        tPos[1] = w->iconGeometry ().y () - tHeight;
198
 
    else
199
 
        tPos[1] = w->iconGeometry ().y () + w->iconGeometry ().height ();
200
 
 
201
 
    // above
202
 
    tmpPos[0] = igMidPoint[0] - (thumb.width / 2.0);
203
 
 
204
 
    if (tmpPos[0] - off < oGeom.x1 ())
205
 
        tmpPos[0] = oGeom.x1 () + off;
206
 
 
207
 
    if (tmpPos[0] + off + thumb.width > oGeom.x2 ())
208
 
    {
209
 
        if (thumb.width + (2 * off) <= oGeom.width ())
210
 
            tmpPos[0] = oGeom.x2 () - thumb.width - off;
211
 
        else
212
 
            tmpPos[0] = oGeom.x1 () + off;
213
 
    }
214
 
 
215
 
    tMidPoint[0] = tmpPos[0] + (thumb.width / 2.0);
216
 
 
217
 
    tmpPos[1] = WIN_Y (dock) - tHeight - off;
218
 
    tMidPoint[1] = tmpPos[1] + (tHeight / 2.0);
219
 
 
220
 
    if (tmpPos[1] > oGeom.y1 ())
221
 
    {
222
 
        tPos[0]  = tmpPos[0];
223
 
        tPos[1]  = tmpPos[1];
224
 
        distance = GET_DISTANCE (igMidPoint, tMidPoint);
225
 
    }
226
 
 
227
 
    // below
228
 
    tmpPos[1] = WIN_Y (dock) + WIN_H (dock) + off;
229
 
 
230
 
    tMidPoint[1] = tmpPos[1] + (tHeight / 2.0);
231
 
 
232
 
    if (tmpPos[1] + tHeight + off < oGeom.y2 () &&
233
 
        GET_DISTANCE (igMidPoint, tMidPoint) < distance)
234
 
    {
235
 
        tPos[0]  = tmpPos[0];
236
 
        tPos[1]  = tmpPos[1];
237
 
        distance = GET_DISTANCE (igMidPoint, tMidPoint);
238
 
    }
239
 
 
240
 
    // left
241
 
    tmpPos[1] = igMidPoint[1] - (tHeight / 2.0);
242
 
 
243
 
    if (tmpPos[1] - off < oGeom.y1 ())
244
 
        tmpPos[1] = oGeom.y1 () + off;
245
 
 
246
 
    if (tmpPos[1] + off + tHeight > oGeom.y2 ())
247
 
    {
248
 
        if (tHeight + (2 * off) <= oGeom.height ())
249
 
            tmpPos[1] = oGeom.y2 () - thumb.height - off;
250
 
        else
251
 
            tmpPos[1] = oGeom.y1 () + off;
252
 
    }
253
 
 
254
 
    tMidPoint[1] = tmpPos[1] + (tHeight / 2.0);
255
 
 
256
 
    tmpPos[0] = WIN_X (dock) - thumb.width - off;
257
 
    tMidPoint[0] = tmpPos[0] + (thumb.width / 2.0);
258
 
 
259
 
    if (tmpPos[0] > oGeom.x1 () && GET_DISTANCE (igMidPoint, tMidPoint) < distance)
260
 
    {
261
 
        tPos[0]  = tmpPos[0];
262
 
        tPos[1]  = tmpPos[1];
263
 
        distance = GET_DISTANCE (igMidPoint, tMidPoint);
264
 
    }
265
 
 
266
 
    // right
267
 
    tmpPos[0] = WIN_X (dock) + WIN_W (dock) + off;
268
 
 
269
 
    tMidPoint[0] = tmpPos[0] + (thumb.width / 2.0);
270
 
 
271
 
    if (tmpPos[0] + thumb.width + off < oGeom.x2 () &&
272
 
        GET_DISTANCE (igMidPoint, tMidPoint) < distance)
273
 
    {
274
 
        tPos[0]  = tmpPos[0];
275
 
        tPos[1]  = tmpPos[1];
276
 
        distance = GET_DISTANCE (igMidPoint, tMidPoint);
277
 
    }
278
 
 
279
 
    thumb.x       = tPos[0];
280
 
    thumb.y       = tPos[1];
281
 
    thumb.offset  = off;
282
 
    thumb.opacity = 0.0;
283
 
 
284
 
    damageThumbRegion (&thumb);
285
 
 
286
 
    cScreen->preparePaintSetEnabled (this, true);
287
 
    cScreen->donePaintSetEnabled (this, true);
288
 
    gScreen->glPaintOutputSetEnabled (this, true);
289
 
}
290
 
 
291
 
bool
292
 
ThumbScreen::thumbShowThumbnail ()
293
 
{
294
 
    showingThumb   = true;
295
 
 
296
 
    thumbUpdateThumbnail ();
297
 
    damageThumbRegion (&thumb);
298
 
 
299
 
    return false;
300
 
}
301
 
 
302
 
bool
303
 
ThumbScreen::checkPosition (CompWindow *w)
304
 
{
305
 
    if (optionGetCurrentViewport ())
306
 
    {
307
 
        if (w->serverX () >= screen->width ()    ||
308
 
            w->serverX () + w->serverWidth () <= 0  ||
309
 
            w->serverY () >= screen->height ()   ||
310
 
            w->serverY () + w->serverHeight () <= 0)
311
 
        {
312
 
            return false;
313
 
        }
314
 
    }
315
 
 
316
 
    return true;
317
 
}
318
 
 
319
 
void
320
 
ThumbScreen::positionUpdate (const CompPoint &p)
321
 
{
322
 
    CompWindow *found = NULL;
323
 
 
324
 
    foreach (CompWindow *cw, screen->windows ())
325
 
    {
326
 
        THUMB_WINDOW (cw);
327
 
 
328
 
        if (cw->destroyed ())
329
 
            continue;
330
 
 
331
 
        if (cw->iconGeometry ().isEmpty ())
332
 
            continue;
333
 
 
334
 
        if (!cw->isMapped ())
335
 
            continue;
336
 
 
337
 
        if (cw->state () & CompWindowStateSkipTaskbarMask)
338
 
            continue;
339
 
 
340
 
        if (cw->state () & CompWindowStateSkipPagerMask)
341
 
            continue;
342
 
 
343
 
        if (!cw->managed ())
344
 
            continue;
345
 
 
346
 
        if (!tw->cWindow->pixmap ())
347
 
            continue;
348
 
 
349
 
        if (cw->iconGeometry ().contains (p) &&
350
 
            checkPosition (cw))
351
 
        {
352
 
            found = cw;
353
 
            break;
354
 
        }
355
 
    }
356
 
 
357
 
    if (found)
358
 
    {
359
 
        if (!showingThumb &&
360
 
            !(thumb.opacity != 0.0 && thumb.win == found))
361
 
        {
362
 
            if (displayTimeout.active ())
363
 
 
364
 
            {
365
 
                if (pointedWin != found)
366
 
                {
367
 
                    displayTimeout.stop ();
368
 
                    displayTimeout.start (boost::bind
369
 
                                           (&ThumbScreen::thumbShowThumbnail,
370
 
                                            this),
371
 
                                          optionGetShowDelay (),
372
 
                                          optionGetShowDelay () + 500);
373
 
                }
374
 
            }
375
 
            else
376
 
            {
377
 
            displayTimeout.stop ();
378
 
            displayTimeout.start (boost::bind (&ThumbScreen::thumbShowThumbnail,
379
 
                                                this),
380
 
                                  optionGetShowDelay (),
381
 
                                  optionGetShowDelay () + 500);
382
 
            }
383
 
        }
384
 
 
385
 
        pointedWin = found;
386
 
        thumbUpdateThumbnail ();
387
 
    }
388
 
    else
389
 
    {
390
 
        if (displayTimeout.active ())
391
 
        {
392
 
            displayTimeout.stop ();
393
 
        }
394
 
 
395
 
        pointedWin   = NULL;
396
 
        showingThumb = false;
397
 
 
398
 
        cScreen->preparePaintSetEnabled (this, true);
399
 
        cScreen->donePaintSetEnabled (this, true);
400
 
    }
401
 
}
402
 
 
403
 
 
404
 
void
405
 
ThumbWindow::resizeNotify (int        dx,
406
 
                           int        dy,
407
 
                           int        dwidth,
408
 
                           int        dheight)
409
 
{
410
 
    THUMB_SCREEN (screen);
411
 
 
412
 
    ts->thumbUpdateThumbnail ();
413
 
 
414
 
    window->resizeNotify (dx, dy, dwidth, dheight);
415
 
}
416
 
 
417
 
void
418
 
ThumbScreen::handleEvent (XEvent * event)
419
 
{
420
 
 
421
 
    screen->handleEvent (event);
422
 
 
423
 
    CompWindow *w;
424
 
 
425
 
    switch (event->type)
426
 
    {
427
 
    case PropertyNotify:
428
 
        if (event->xproperty.atom == Atoms::wmName)
429
 
        {
430
 
            w = screen->findWindow (event->xproperty.window);
431
 
 
432
 
            if (w)
433
 
            {
434
 
                if (thumb.win == w && optionGetTitleEnabled ())
435
 
                    renderThumbText (&thumb, true);
436
 
            }
437
 
        }
438
 
        break;
439
 
 
440
 
    case ButtonPress:
441
 
        {
442
 
 
443
 
            if (displayTimeout.active ())
444
 
            {
445
 
                displayTimeout.stop ();
446
 
            }
447
 
 
448
 
            pointedWin   = 0;
449
 
            showingThumb = false;
450
 
        }
451
 
        break;
452
 
 
453
 
    case EnterNotify:
454
 
        w = screen->findWindow (event->xcrossing.window);
455
 
        if (w)
456
 
        {
457
 
            if (w->wmType () & CompWindowTypeDockMask)
458
 
            {
459
 
                if (dock != w)
460
 
                {
461
 
                    dock = w;
462
 
 
463
 
                    if (displayTimeout.active ())
464
 
                    {
465
 
                        displayTimeout.stop ();
466
 
                    }
467
 
 
468
 
                    pointedWin   = NULL;
469
 
                    showingThumb = false;
470
 
                }
471
 
 
472
 
                if (!poller.active ())
473
 
                {
474
 
                    poller.start ();
475
 
                }
476
 
            }
477
 
            else
478
 
            {
479
 
                dock = NULL;
480
 
 
481
 
                if (displayTimeout.active ())
482
 
                {
483
 
                    displayTimeout.stop ();
484
 
                }
485
 
 
486
 
                pointedWin   = NULL;
487
 
                showingThumb = false;
488
 
 
489
 
                if (poller.active ())
490
 
                {
491
 
                    poller.stop ();
492
 
                }
493
 
            }
494
 
        }
495
 
        break;
496
 
    case LeaveNotify:
497
 
        w = screen->findWindow (event->xcrossing.window);
498
 
        if (w)
499
 
        {
500
 
            if (w->wmType () & CompWindowTypeDockMask)
501
 
            {
502
 
                dock = NULL;
503
 
 
504
 
                if (displayTimeout.active ())
505
 
                {
506
 
                    displayTimeout.stop ();
507
 
                }
508
 
 
509
 
                pointedWin   = NULL;
510
 
                showingThumb = false;
511
 
 
512
 
                cScreen->preparePaintSetEnabled (this, true);
513
 
                cScreen->donePaintSetEnabled (this, true);
514
 
 
515
 
                if (poller.active ())
516
 
                {
517
 
                    poller.stop ();
518
 
                }
519
 
 
520
 
 
521
 
            }
522
 
        }
523
 
        break;
524
 
 
525
 
    default:
526
 
        break;
527
 
    }
528
 
}
529
 
 
530
 
 
531
 
void
532
 
ThumbScreen::paintTexture (int wx,
533
 
                          int wy,
534
 
                          int width,
535
 
                          int height,
536
 
                          int off)
537
 
{
538
 
    glBegin (GL_QUADS);
539
 
 
540
 
    glTexCoord2f (1, 1);
541
 
    glVertex2f (wx, wy);
542
 
    glVertex2f (wx, wy + height);
543
 
    glVertex2f (wx + width, wy + height);
544
 
    glVertex2f (wx + width, wy);
545
 
 
546
 
    glTexCoord2f (0, 0);
547
 
    glVertex2f (wx - off, wy - off);
548
 
    glTexCoord2f (0, 1);
549
 
    glVertex2f (wx - off, wy);
550
 
    glTexCoord2f (1, 1);
551
 
    glVertex2f (wx, wy);
552
 
    glTexCoord2f (1, 0);
553
 
    glVertex2f (wx, wy - off);
554
 
 
555
 
    glTexCoord2f (1, 0);
556
 
    glVertex2f (wx + width, wy - off);
557
 
    glTexCoord2f (1, 1);
558
 
    glVertex2f (wx + width, wy);
559
 
    glTexCoord2f (0, 1);
560
 
    glVertex2f (wx + width + off, wy);
561
 
    glTexCoord2f (0, 0);
562
 
    glVertex2f (wx + width + off, wy - off);
563
 
 
564
 
    glTexCoord2f (0, 1);
565
 
    glVertex2f (wx - off, wy + height);
566
 
    glTexCoord2f (0, 0);
567
 
    glVertex2f (wx - off, wy + height + off);
568
 
    glTexCoord2f (1, 0);
569
 
    glVertex2f (wx, wy + height + off);
570
 
    glTexCoord2f (1, 1);
571
 
    glVertex2f (wx, wy + height);
572
 
 
573
 
    glTexCoord2f (1, 1);
574
 
    glVertex2f (wx + width, wy + height);
575
 
    glTexCoord2f (1, 0);
576
 
    glVertex2f (wx + width, wy + height + off);
577
 
    glTexCoord2f (0, 0);
578
 
    glVertex2f (wx + width + off, wy + height + off);
579
 
    glTexCoord2f (0, 1);
580
 
    glVertex2f (wx + width + off, wy + height);
581
 
 
582
 
    glTexCoord2f (1, 0);
583
 
    glVertex2f (wx, wy - off);
584
 
    glTexCoord2f (1, 1);
585
 
    glVertex2f (wx, wy);
586
 
    glTexCoord2f (1, 1);
587
 
    glVertex2f (wx + width, wy);
588
 
    glTexCoord2f (1, 0);
589
 
    glVertex2f (wx + width, wy - off);
590
 
 
591
 
    glTexCoord2f (1, 1);
592
 
    glVertex2f (wx, wy + height);
593
 
    glTexCoord2f (1, 0);
594
 
    glVertex2f (wx, wy + height + off);
595
 
    glTexCoord2f (1, 0);
596
 
    glVertex2f (wx + width, wy + height + off);
597
 
    glTexCoord2f (1, 1);
598
 
    glVertex2f (wx + width, wy + height);
599
 
 
600
 
    glTexCoord2f (0, 1);
601
 
    glVertex2f (wx - off, wy);
602
 
    glTexCoord2f (0, 1);
603
 
    glVertex2f (wx - off, wy + height);
604
 
    glTexCoord2f (1, 1);
605
 
    glVertex2f (wx, wy + height);
606
 
    glTexCoord2f (1, 1);
607
 
    glVertex2f (wx, wy);
608
 
 
609
 
    glTexCoord2f (1, 1);
610
 
    glVertex2f (wx + width, wy);
611
 
    glTexCoord2f (1, 1);
612
 
    glVertex2f (wx + width, wy + height);
613
 
    glTexCoord2f (0, 1);
614
 
    glVertex2f (wx + width + off, wy + height);
615
 
    glTexCoord2f (0, 1);
616
 
    glVertex2f (wx + width + off, wy);
617
 
 
618
 
    glEnd ();
619
 
}
620
 
 
621
 
void
622
 
ThumbScreen::thumbPaintThumb (Thumbnail           *t,
623
 
                              const GLMatrix *transform)
624
 
{
625
 
    int                   addWindowGeometryIndex;
626
 
    CompWindow            *w = t->win;
627
 
    int                   wx = t->x;
628
 
    int                   wy = t->y;
629
 
    float                 width  = t->width;
630
 
    float                 height = t->height;
631
 
    GLWindowPaintAttrib     sAttrib;
632
 
    unsigned int          mask = PAINT_WINDOW_TRANSFORMED_MASK |
633
 
                                 PAINT_WINDOW_TRANSLUCENT_MASK;
634
 
    GLWindow              *gWindow = GLWindow::get (w);
635
 
 
636
 
    if (!w)
637
 
        return;
638
 
 
639
 
    sAttrib = gWindow->paintAttrib ();
640
 
 
641
 
    if (t->text)
642
 
        height += t->text->getHeight () + TEXT_DISTANCE;
643
 
 
644
 
    /* Wrap drawWindowGeometry to make sure the general
645
 
       drawWindowGeometry function is used */
646
 
    addWindowGeometryIndex =
647
 
            gWindow->glAddGeometryGetCurrentIndex ();
648
 
 
649
 
    if (!gWindow->textures ().empty ())
650
 
    {
651
 
        int            off = t->offset;
652
 
        GLenum         filter = gScreen->textureFilter ();
653
 
        GLMatrix       wTransform (*transform);
654
 
 
655
 
        glEnable (GL_BLEND);
656
 
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
657
 
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
658
 
        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
659
 
 
660
 
        if (optionGetWindowLike ())
661
 
        {
662
 
            glColor4f (1.0, 1.0, 1.0, t->opacity);
663
 
            foreach (GLTexture *tex, windowTexture)
664
 
            {
665
 
                tex->enable (GLTexture::Good);
666
 
                paintTexture (wx, wy, width, height, off);
667
 
                tex->disable ();
668
 
            }
669
 
        }
670
 
        else
671
 
        {
672
 
            glColor4us (optionGetThumbColorRed (),
673
 
                        optionGetThumbColorGreen (),
674
 
                        optionGetThumbColorBlue (),
675
 
                        optionGetThumbColorAlpha () * t->opacity);
676
 
 
677
 
            foreach (GLTexture *tex, glowTexture)
678
 
            {
679
 
                tex->enable (GLTexture::Good);
680
 
                paintTexture (wx, wy, width, height, off);
681
 
                tex->disable ();
682
 
            }
683
 
        }
684
 
 
685
 
        glColor4usv (defaultColor);
686
 
 
687
 
        glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
688
 
 
689
 
        if (t->text)
690
 
        {
691
 
            float ox = 0.0;
692
 
 
693
 
            if (t->text->getWidth () < width)
694
 
                ox = (width - t->text->getWidth ()) / 2.0;
695
 
 
696
 
            t->text->draw (wx + ox, wy + height, t->opacity);
697
 
        }
698
 
 
699
 
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
700
 
        glDisable (GL_BLEND);
701
 
 
702
 
        gScreen->setTexEnvMode (GL_REPLACE);
703
 
 
704
 
        glColor4usv (defaultColor);
705
 
 
706
 
        sAttrib.opacity *= t->opacity;
707
 
        sAttrib.yScale = t->scale;
708
 
        sAttrib.xScale = t->scale;
709
 
 
710
 
        sAttrib.xTranslate = wx - w->x () + w->border ().left * sAttrib.xScale;
711
 
        sAttrib.yTranslate = wy - w->y () + w->border ().top * sAttrib.yScale;
712
 
 
713
 
        if (optionGetMipmap ())
714
 
            gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
715
 
 
716
 
        GLFragment::Attrib fragment (sAttrib);
717
 
 
718
 
        wTransform.translate (w->x (), w->y (), 0.0f);
719
 
        wTransform.scale (sAttrib.xScale, sAttrib.yScale, 1.0f);
720
 
        wTransform.translate (sAttrib.xTranslate / sAttrib.xScale - w->x (),
721
 
                              sAttrib.yTranslate / sAttrib.yScale - w->y (),
722
 
                              0.0f);
723
 
 
724
 
        glPushMatrix ();
725
 
        glLoadMatrixf (wTransform.getMatrix ());
726
 
        /* XXX: replacing the addWindowGeometry function like this is
727
 
           very ugly but necessary until the vertex stage has been made
728
 
           fully pluggable. */
729
 
        gWindow->glAddGeometrySetCurrentIndex (MAXSHORT);
730
 
        gWindow->glDraw (wTransform, fragment, infiniteRegion, mask);
731
 
        glPopMatrix ();
732
 
 
733
 
        gScreen->setTextureFilter (filter);
734
 
    }
735
 
 
736
 
    gWindow->glAddGeometrySetCurrentIndex (addWindowGeometryIndex);
737
 
}
738
 
 
739
 
/* From here onwards */
740
 
 
741
 
void
742
 
ThumbScreen::preparePaint (int ms)
743
 
{
744
 
    float val = ms;
745
 
 
746
 
    val /= 1000;
747
 
    val /= optionGetFadeSpeed ();
748
 
 
749
 
    /*if (screen->otherGrabExist ("")) // shouldn't there be a s->grabs.empty () or something?
750
 
    {
751
 
        dock = NULL;
752
 
 
753
 
        if (displayTimeout.active ())
754
 
        {
755
 
            displayTimeout.stop ();
756
 
        }
757
 
 
758
 
        pointedWin   = 0;
759
 
        showingThumb = false;
760
 
    }*/
761
 
 
762
 
    if (showingThumb && thumb.win == pointedWin)
763
 
    {
764
 
        thumb.opacity = MIN (1.0, thumb.opacity + val);
765
 
    }
766
 
 
767
 
    if (!showingThumb || thumb.win != pointedWin)
768
 
    {
769
 
        thumb.opacity = MAX (0.0, thumb.opacity - val);
770
 
        if (thumb.opacity == 0.0)
771
 
            thumb.win = NULL;
772
 
    }
773
 
 
774
 
    if (oldThumb.opacity > 0.0f)
775
 
    {
776
 
        oldThumb.opacity = MAX (0.0, oldThumb.opacity - val);
777
 
        if (oldThumb.opacity == 0.0)
778
 
        {
779
 
            damageThumbRegion (&oldThumb);
780
 
            freeThumbText (&oldThumb);
781
 
            oldThumb.win = NULL;
782
 
        }
783
 
    }
784
 
 
785
 
    if (oldThumb.win == NULL && thumb.win == NULL)
786
 
    {
787
 
        cScreen->preparePaintSetEnabled (this, false);
788
 
        cScreen->donePaintSetEnabled (this, false);
789
 
        gScreen->glPaintOutputSetEnabled (this, false);
790
 
    }
791
 
 
792
 
    cScreen->preparePaint (ms);
793
 
}
794
 
 
795
 
void
796
 
ThumbScreen::donePaint ()
797
 
{
798
 
    std::vector <Thumbnail *> damageThumbs;
799
 
 
800
 
    if (thumb.opacity > 0.0 && thumb.opacity < 1.0)
801
 
        damageThumbs.push_back (&thumb);
802
 
 
803
 
    if (oldThumb.opacity > 0.0 && oldThumb.opacity < 1.0)
804
 
        damageThumbs.push_back (&oldThumb);
805
 
 
806
 
    if (damageThumbs.size ())
807
 
    {
808
 
        foreach (Thumbnail *t, damageThumbs)
809
 
            damageThumbRegion (t);
810
 
    }
811
 
    else
812
 
    {
813
 
        cScreen->preparePaintSetEnabled (this, false);
814
 
        cScreen->donePaintSetEnabled (this, false);
815
 
    }
816
 
 
817
 
    cScreen->donePaint ();
818
 
}
819
 
 
820
 
bool
821
 
ThumbScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
822
 
                            const GLMatrix &transform,
823
 
                            const CompRegion &region,
824
 
                            CompOutput *output,
825
 
                            unsigned int mask)
826
 
{
827
 
    bool         status;
828
 
    unsigned int newMask = mask;
829
 
 
830
 
    painted = false;
831
 
 
832
 
    x = screen->vp ().x ();
833
 
    y = screen->vp ().y ();
834
 
 
835
 
    if ((oldThumb.opacity > 0.0 && oldThumb.win) ||
836
 
        (thumb.opacity > 0.0 && thumb.win))
837
 
    {
838
 
        newMask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
839
 
    }
840
 
 
841
 
    status = gScreen->glPaintOutput (attrib, transform, region, output, newMask);
842
 
 
843
 
    if (optionGetAlwaysOnTop () && !painted)
844
 
    {
845
 
        if (oldThumb.opacity > 0.0 && oldThumb.win)
846
 
        {
847
 
            GLMatrix sTransform = transform;
848
 
 
849
 
            sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
850
 
            glPushMatrix ();
851
 
            glLoadMatrixf (sTransform.getMatrix ());
852
 
            thumbPaintThumb (&oldThumb, &sTransform);
853
 
            glPopMatrix ();
854
 
        }
855
 
 
856
 
        if (thumb.opacity > 0.0 && thumb.win)
857
 
        {
858
 
            GLMatrix sTransform = transform;
859
 
 
860
 
            sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
861
 
            glPushMatrix ();
862
 
            glLoadMatrixf (sTransform.getMatrix ());
863
 
            thumbPaintThumb (&thumb, &sTransform);
864
 
            glPopMatrix ();
865
 
        }
866
 
    }
867
 
 
868
 
    return status;
869
 
}
870
 
 
871
 
void
872
 
ThumbScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib,
873
 
                                       const GLMatrix &transform,
874
 
                                       const CompRegion &region,
875
 
                                       CompOutput *output,
876
 
                                       unsigned int mask)
877
 
{
878
 
 
879
 
    gScreen->glPaintTransformedOutput (attrib, transform, region, output, mask);
880
 
 
881
 
    if (optionGetAlwaysOnTop () && x == screen->vp ().x () &&
882
 
                                   y == screen->vp ().y ())
883
 
    {
884
 
        painted = true;
885
 
 
886
 
        if (oldThumb.opacity > 0.0 && oldThumb.win)
887
 
        {
888
 
            GLMatrix sTransform = transform;
889
 
 
890
 
            gScreen->glApplyTransform (attrib, output, &sTransform);
891
 
            sTransform.toScreenSpace(output, -attrib.zTranslate);
892
 
            glPushMatrix ();
893
 
            glLoadMatrixf (sTransform.getMatrix ());
894
 
            thumbPaintThumb (&oldThumb, &sTransform);
895
 
            glPopMatrix ();
896
 
        }
897
 
 
898
 
        if (thumb.opacity > 0.0 && thumb.win)
899
 
        {
900
 
            GLMatrix sTransform = transform;
901
 
 
902
 
            gScreen->glApplyTransform (attrib, output, &sTransform);
903
 
            sTransform.toScreenSpace(output, -attrib.zTranslate);
904
 
            glPushMatrix ();
905
 
            glLoadMatrixf (sTransform.getMatrix ());
906
 
            thumbPaintThumb (&thumb, &sTransform);
907
 
            glPopMatrix ();
908
 
        }
909
 
    }
910
 
}
911
 
 
912
 
bool
913
 
ThumbWindow::glPaint (const GLWindowPaintAttrib &attrib,
914
 
                      const GLMatrix            &transform,
915
 
                      CompRegion                &region,
916
 
                      unsigned int              mask)
917
 
{
918
 
    bool status;
919
 
 
920
 
    THUMB_SCREEN (screen);
921
 
 
922
 
    status = gWindow->glPaint (attrib, transform, region, mask);
923
 
 
924
 
    if (!ts->optionGetAlwaysOnTop () && ts->x == screen->vp ().x () &&
925
 
                                    ts->y == screen->vp ().y ())
926
 
    {
927
 
        GLMatrix sTransform = transform;
928
 
        if (ts->oldThumb.opacity > 0.0 && ts->oldThumb.win &&
929
 
            ts->oldThumb.dock == window)
930
 
        {
931
 
            ts->thumbPaintThumb (&ts->oldThumb, &sTransform);
932
 
        }
933
 
 
934
 
        if (ts->thumb.opacity > 0.0 && ts->thumb.win && ts->thumb.dock == window)
935
 
        {
936
 
            ts->thumbPaintThumb (&ts->thumb, &sTransform);
937
 
        }
938
 
    }
939
 
 
940
 
    return status;
941
 
}
942
 
 
943
 
bool
944
 
ThumbWindow::damageRect (bool initial,
945
 
                         const CompRect &rect)
946
 
{
947
 
    THUMB_SCREEN (screen);
948
 
 
949
 
    if (ts->thumb.win == window && ts->thumb.opacity > 0.0)
950
 
        ts->damageThumbRegion (&ts->thumb);
951
 
 
952
 
    if (ts->oldThumb.win == window && ts->oldThumb.opacity > 0.0)
953
 
        ts->damageThumbRegion (&ts->oldThumb);
954
 
 
955
 
    return cWindow->damageRect (initial, rect);
956
 
}
957
 
 
958
 
ThumbScreen::ThumbScreen (CompScreen *screen) :
959
 
    PluginClassHandler <ThumbScreen, CompScreen> (screen),
960
 
    gScreen (GLScreen::get (screen)),
961
 
    cScreen (CompositeScreen::get (screen)),
962
 
    dock (NULL),
963
 
    pointedWin (NULL),
964
 
    showingThumb (false),
965
 
    painted (false),
966
 
    glowTexture (GLTexture::imageDataToTexture
967
 
                 (glowTex, CompSize (32, 32), GL_RGBA, GL_UNSIGNED_BYTE)),
968
 
    windowTexture (GLTexture::imageDataToTexture
969
 
                   (windowTex, CompSize (32, 32), GL_RGBA, GL_UNSIGNED_BYTE)),
970
 
    x (0),
971
 
    y (0)
972
 
{
973
 
    ScreenInterface::setHandler (screen);
974
 
    CompositeScreenInterface::setHandler (cScreen, false);
975
 
    GLScreenInterface::setHandler (gScreen, false);
976
 
 
977
 
    thumb.win = NULL;
978
 
    oldThumb.win = NULL;
979
 
 
980
 
    thumb.text = NULL;
981
 
    oldThumb.text = NULL;
982
 
 
983
 
    thumb.opacity = 0.0f;
984
 
    oldThumb.opacity = 0.0f;
985
 
 
986
 
    poller.setCallback (boost::bind (&ThumbScreen::positionUpdate, this, _1));
987
 
}
988
 
 
989
 
ThumbScreen::~ThumbScreen ()
990
 
{
991
 
    poller.stop ();
992
 
    displayTimeout.stop ();
993
 
 
994
 
    freeThumbText (&thumb);
995
 
    freeThumbText (&oldThumb);
996
 
}
997
 
 
998
 
ThumbWindow::ThumbWindow (CompWindow *window) :
999
 
    PluginClassHandler <ThumbWindow, CompWindow> (window),
1000
 
    window (window),
1001
 
    cWindow (CompositeWindow::get (window)),
1002
 
    gWindow (GLWindow::get (window))
1003
 
{
1004
 
    WindowInterface::setHandler (window, false);
1005
 
    CompositeWindowInterface::setHandler (cWindow, false);
1006
 
    GLWindowInterface::setHandler (gWindow, false);
1007
 
}
1008
 
 
1009
 
 
1010
 
ThumbWindow::~ThumbWindow ()
1011
 
{
1012
 
    THUMB_SCREEN (screen);
1013
 
 
1014
 
    if (ts->thumb.win == window)
1015
 
    {
1016
 
        ts->damageThumbRegion (&ts->thumb);
1017
 
        ts->thumb.win = NULL;
1018
 
        ts->thumb.opacity = 0;
1019
 
    }
1020
 
 
1021
 
    if (ts->oldThumb.win == window)
1022
 
    {
1023
 
        ts->damageThumbRegion (&ts->oldThumb);
1024
 
        ts->oldThumb.win = NULL;
1025
 
        ts->oldThumb.opacity = 0;
1026
 
    }
1027
 
 
1028
 
    if (ts->pointedWin == window)
1029
 
        ts->pointedWin = NULL;
1030
 
}
1031
 
 
1032
 
 
1033
 
bool
1034
 
ThumbPluginVTable::init ()
1035
 
{
1036
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
1037
 
        return false;
1038
 
    if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
1039
 
        return false;
1040
 
    if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
1041
 
        return false;
1042
 
    if (!CompPlugin::checkPluginABI ("mousepoll", COMPIZ_MOUSEPOLL_ABI))
1043
 
        return false;
1044
 
    if (CompPlugin::checkPluginABI ("text", COMPIZ_TEXT_ABI))
1045
 
        textPluginLoaded = true;
1046
 
    else
1047
 
        textPluginLoaded = false;
1048
 
 
1049
 
    return true;
1050
 
}