~ubuntu-branches/ubuntu/lucid/compiz-fusion-plugins-extra/lucid

« back to all changes in this revision

Viewing changes to src/cubecaps/cubecaps.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2008-05-27 12:58:26 UTC
  • mfrom: (1.1.20 upstream)
  • Revision ID: james.westby@ubuntu.com-20080527125826-fvnkfpg60l7sarwp
Tags: 0.7.4+git20080527-0ubuntu1
new git snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Compiz Cube Caps plugin
3
 
 *
4
 
 * cubecaps.c
5
 
 *
6
 
 * Copyright : (C) 2007 Guillaume Seguin
7
 
 * E-mail    : guillaume@segu.in
8
 
 *
9
 
 * Modifications for proper handling of opacity added by:
10
 
 * Kevin Lange <klange@ogunderground.com>
11
 
 *
12
 
 * This program is free software; you can redistribute it and/or
13
 
 * modify it under the terms of the GNU General Public License
14
 
 * as published by the Free Software Foundation; either version 2
15
 
 * of the License, or (at your option) any later version.
16
 
 *
17
 
 * This program is distributed in the hope that it will be useful,
18
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 
 * GNU General Public License for more details.
21
 
 */
22
 
 
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
#include <stdio.h>
26
 
#include <signal.h>
27
 
#include <unistd.h>
28
 
 
29
 
#include <compiz-core.h>
30
 
#include <compiz-cube.h>
31
 
#include "cubecaps_options.h"
32
 
 
33
 
static int displayPrivateIndex;
34
 
 
35
 
static int cubeDisplayPrivateIndex;
36
 
 
37
 
typedef struct _CubeCapsDisplay
38
 
{
39
 
    int screenPrivateIndex;
40
 
} CubeCapsDisplay;
41
 
 
42
 
typedef struct _CubeCap
43
 
{
44
 
    int             current;
45
 
    CompListValue           *files;
46
 
 
47
 
    CompTexture     texture;
48
 
    GLfloat                 tc[12];
49
 
 
50
 
    Bool                    scale;
51
 
    int             pw;
52
 
    int             ph;
53
 
} CubeCap;
54
 
 
55
 
typedef struct _CubeCapsScreen
56
 
{
57
 
    PreparePaintScreenProc  preparePaintScreen;
58
 
    CubePaintTopProc        paintTop;
59
 
    CubePaintBottomProc     paintBottom;
60
 
 
61
 
    CubeCap                 topCap;
62
 
    CubeCap                 bottomCap;
63
 
} CubeCapsScreen;
64
 
 
65
 
#define GET_CUBECAPS_DISPLAY(d)                                         \
66
 
    ((CubeCapsDisplay *) (d)->base.privates[displayPrivateIndex].ptr)
67
 
#define CUBECAPS_DISPLAY(d)                                             \
68
 
    CubeCapsDisplay *ccd = GET_CUBECAPS_DISPLAY (d);
69
 
 
70
 
#define GET_CUBECAPS_SCREEN(s, ccd)                                     \
71
 
    ((CubeCapsScreen *) (s)->base.privates[(ccd)->screenPrivateIndex].ptr)
72
 
#define CUBECAPS_SCREEN(s)                                              \
73
 
    CubeCapsScreen *ccs = GET_CUBECAPS_SCREEN (s,                       \
74
 
                          GET_CUBECAPS_DISPLAY (s->display))
75
 
 
76
 
/* Actual caps handling ----------------------------------------------------- */
77
 
 
78
 
/*
79
 
 * Initiate a CubeCap
80
 
 */
81
 
static void
82
 
cubecapsInitCap (CompScreen *s, CubeCap *cap)
83
 
{
84
 
    memset (cap->tc, 0, sizeof (cap->tc));
85
 
 
86
 
    initTexture (s, &cap->texture);
87
 
 
88
 
    cap->current    = 0;
89
 
    cap->files      = NULL;
90
 
 
91
 
    cap->scale      = FALSE;
92
 
    cap->pw         = 0;
93
 
    cap->ph         = 0;
94
 
}
95
 
 
96
 
/*
97
 
 * Prepare cap texture coordinates
98
 
 */
99
 
static void
100
 
cubecapsInitTextureCoords (CompScreen * s, CubeCap * cap,
101
 
                           unsigned int width, unsigned int height)
102
 
{
103
 
    float x1, x2, y1, y2;
104
 
    CompMatrix *matrix;
105
 
 
106
 
    if (!cap)
107
 
        return;
108
 
 
109
 
    matrix = &cap->texture.matrix;
110
 
 
111
 
    if (cap->scale)
112
 
    {
113
 
        x1 = 0.0f;
114
 
        y1 = 0.0f;
115
 
        x2 = width;
116
 
        y2 = height;
117
 
    }
118
 
    else
119
 
    {
120
 
        int bigscr, i;
121
 
        int bigWidth, bigHeight;
122
 
 
123
 
        CUBE_SCREEN(s);
124
 
        bigWidth = s->width;
125
 
        bigHeight = s->height;
126
 
 
127
 
        /* Scale the texture in a sane way for multi head too */
128
 
        if (s->nOutputDev > 1 && cs->moMode != CUBE_MOMODE_ONE)
129
 
        {
130
 
            for (i = bigscr = 0; i < s->nOutputDev; i++)
131
 
                if (s->outputDev[i].width > s->outputDev[bigscr].width)
132
 
                    bigscr = i;
133
 
            bigWidth = s->outputDev[bigscr].width;
134
 
            bigHeight = s->outputDev[bigscr].height;
135
 
        }
136
 
 
137
 
        x1 = width / 2.0f - bigWidth / 2.0f;
138
 
        y1 = height / 2.0f - bigHeight / 2.0f;
139
 
        x2 = width / 2.0f + bigWidth / 2.0f;
140
 
        y2 = height / 2.0f + bigHeight / 2.0f;
141
 
    }
142
 
 
143
 
    cap->tc[0] = COMP_TEX_COORD_X (matrix, width / 2.0f);
144
 
    cap->tc[1] = COMP_TEX_COORD_Y (matrix, height / 2.0f);
145
 
 
146
 
    cap->tc[2] = COMP_TEX_COORD_X (matrix, x2);
147
 
    cap->tc[3] = COMP_TEX_COORD_Y (matrix, y1);
148
 
 
149
 
    cap->tc[4] = COMP_TEX_COORD_X (matrix, x1);
150
 
    cap->tc[5] = COMP_TEX_COORD_Y (matrix, y1);
151
 
 
152
 
    cap->tc[6] = COMP_TEX_COORD_X (matrix, x1);
153
 
    cap->tc[7] = COMP_TEX_COORD_Y (matrix, y2);
154
 
 
155
 
    cap->tc[8] = COMP_TEX_COORD_X (matrix, x2);
156
 
    cap->tc[9] = COMP_TEX_COORD_Y (matrix, y2);
157
 
 
158
 
    cap->tc[10] = COMP_TEX_COORD_X (matrix, x2);
159
 
    cap->tc[11] = COMP_TEX_COORD_Y (matrix, y1);
160
 
}
161
 
 
162
 
/*
163
 
 * Attempt to load current cap image (if any)
164
 
 */
165
 
static void
166
 
cubecapsLoadCap (CompScreen *s,
167
 
                 CubeCap    *cap)
168
 
{
169
 
    unsigned int    width, height;
170
 
    int             pw, ph;
171
 
 
172
 
    CUBE_SCREEN (s);
173
 
 
174
 
    if (!cs->fullscreenOutput)
175
 
    {
176
 
        pw = s->width;
177
 
        ph = s->height;
178
 
    }
179
 
    else
180
 
    {
181
 
        pw = s->outputDev[0].width;
182
 
        ph = s->outputDev[0].height;
183
 
    }
184
 
 
185
 
    if (!cap->files || !cap->files->nValue || cap->pw != pw || cap->ph != ph)
186
 
    {
187
 
        finiTexture (s, &cap->texture);
188
 
        initTexture (s, &cap->texture);
189
 
 
190
 
        if (!cap->files || !cap->files->nValue)
191
 
            return;
192
 
    }
193
 
 
194
 
    cap->current = cap->current % cap->files->nValue;
195
 
 
196
 
    if (!readImageToTexture (s, &cap->texture,
197
 
                             cap->files->value[cap->current].s,
198
 
                             &width, &height))
199
 
    {
200
 
        compLogMessage (s->display, "cubecaps", CompLogLevelWarn,
201
 
                        "Failed to load image: %s",
202
 
                        cap->files->value[cap->current].s);
203
 
 
204
 
        finiTexture (s, &cap->texture);
205
 
        initTexture (s, &cap->texture);
206
 
 
207
 
        return;
208
 
    }
209
 
 
210
 
    cubecapsInitTextureCoords (s, cap, width, height);
211
 
}
212
 
 
213
 
/*
214
 
 * Paint a cap
215
 
 */
216
 
static void
217
 
cubecapsPaintCap (CompScreen        *s,
218
 
                  int               offset,
219
 
                  CubeCap           *capOutside,
220
 
                  CubeCap           *capInside,
221
 
                  unsigned short    *colorOutside,
222
 
                  unsigned short    *colorInside,
223
 
                  Bool              clampToBorderOutside,
224
 
                  Bool              clampToBorderInside)
225
 
{
226
 
    CubeCap         *cap;
227
 
    unsigned short  opacity;
228
 
    Bool            clampToBorder;
229
 
 
230
 
    CUBE_SCREEN(s);
231
 
 
232
 
    opacity = cs->desktopOpacity;
233
 
 
234
 
    if (cs->invert == 1)
235
 
    {
236
 
        cap = capOutside;
237
 
        clampToBorder = clampToBorderOutside;
238
 
        // Honor selected opacity AND cube opacity
239
 
        opacity = (opacity * colorOutside[3]) / 0xffff;
240
 
        glColor4us (colorOutside[0],
241
 
                    colorOutside[1],
242
 
                    colorOutside[2],
243
 
                    opacity);
244
 
    }
245
 
    else if (cs->invert != 1)
246
 
    {
247
 
        cap = capInside;
248
 
        clampToBorder = clampToBorderInside;
249
 
        opacity = (opacity * colorInside[3]) / 0xffff;
250
 
        glColor4us (colorInside[0],
251
 
                    colorInside[1],
252
 
                    colorInside[2],
253
 
                    opacity);
254
 
    }
255
 
 
256
 
    glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
257
 
    glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
258
 
 
259
 
    glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
260
 
 
261
 
    glEnable (GL_BLEND);
262
 
    /* Draw cap once and reset color so that image will get correctly
263
 
     * blended, and for non-4-horizontal-viewports setups */
264
 
    if (opacity != OPAQUE)
265
 
    {
266
 
        screenTexEnvMode (s, GL_MODULATE);
267
 
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
268
 
        glDrawArrays (GL_TRIANGLE_FAN, offset, cs->nVertices >> 1);
269
 
        glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
270
 
    }
271
 
    else
272
 
        glDrawArrays (GL_TRIANGLE_FAN, offset, cs->nVertices >> 1);
273
 
 
274
 
    glColor4usv (defaultColor);
275
 
 
276
 
    /* It is not really a good idea to draw the cap texture when there are 
277
 
     * only three viewports */
278
 
    if (cap && cap->texture.name && s->hsize >= 4)
279
 
    {
280
 
        /* Apply blend strategy to blend correctly color and image */
281
 
        
282
 
        glColor4us (cs->desktopOpacity, cs->desktopOpacity,
283
 
                    cs->desktopOpacity, cs->desktopOpacity);
284
 
        enableTexture (s, &cap->texture, COMP_TEXTURE_FILTER_GOOD);
285
 
 
286
 
        /* Use CLAMP_TO_BORDER if available to avoid weird looking clamping 
287
 
         * of non-scaled images (it also improves scaled images a bit but 
288
 
         * that's much less obvious) */
289
 
        if (clampToBorder && s->textureBorderClamp)
290
 
        {
291
 
            glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_S,
292
 
                             GL_CLAMP_TO_BORDER);
293
 
            glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_T,
294
 
                             GL_CLAMP_TO_BORDER);
295
 
        }
296
 
        else
297
 
        {
298
 
            glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_S,
299
 
                             GL_CLAMP_TO_EDGE);
300
 
            glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_T,
301
 
                             GL_CLAMP_TO_EDGE);
302
 
        }
303
 
 
304
 
        if (s->hsize == 4)
305
 
        {
306
 
            /* 4 viewports is pretty much straight forward ... */
307
 
            glTexCoordPointer (2, GL_FLOAT, 0, cap->tc - (offset << 1));
308
 
            glDrawArrays (GL_TRIANGLE_FAN, offset, cs->nVertices >> 1);
309
 
        }
310
 
        else if (s->hsize > 4)
311
 
        {
312
 
            /* Paint image using custom vertexes */
313
 
            int centerx = *cs->vertices;
314
 
            int centery = *(cs->vertices + 1);
315
 
            int centerz = *(cs->vertices + 2);
316
 
            GLfloat x1, y1, x2, y2;
317
 
            x1 = cap->tc[4];
318
 
            x2 = cap->tc[2];
319
 
            y1 = cap->tc[3];
320
 
            y2 = cap->tc[9];
321
 
 
322
 
            glBegin (GL_QUADS);
323
 
 
324
 
            if (offset)
325
 
                centery -= 1;
326
 
 
327
 
            if (offset)
328
 
            {
329
 
                glTexCoord2f (x1, y1);
330
 
                glVertex3f (centerx - 0.5, centery + 0.5, centerz + 0.5);
331
 
                glTexCoord2f (x1, y2);
332
 
                glVertex3f (centerx - 0.5, centery + 0.5, centerz - 0.5);
333
 
                glTexCoord2f (x2, y2);
334
 
                glVertex3f (centerx + 0.5, centery + 0.5, centerz - 0.5);
335
 
                glTexCoord2f (x2, y1);
336
 
                glVertex3f (centerx + 0.5, centery + 0.5, centerz + 0.5);
337
 
            }
338
 
            else
339
 
            {
340
 
                glTexCoord2f (x2,y2);
341
 
                glVertex3f (centerx + 0.5, centery + 0.5, centerz + 0.5);
342
 
                glTexCoord2f (x2, y1);
343
 
                glVertex3f (centerx + 0.5, centery + 0.5, centerz - 0.5);
344
 
                glTexCoord2f (x1, y1);
345
 
                glVertex3f (centerx - 0.5, centery + 0.5, centerz - 0.5);
346
 
                glTexCoord2f (x1, y2);
347
 
                glVertex3f (centerx - 0.5, centery + 0.5, centerz + 0.5);
348
 
            }
349
 
 
350
 
            glEnd ();
351
 
        }
352
 
        disableTexture (s, &cap->texture);
353
 
    }
354
 
 
355
 
    if (opacity != OPAQUE)
356
 
        screenTexEnvMode (s, GL_REPLACE);
357
 
 
358
 
    glDisable (GL_BLEND);
359
 
}
360
 
 
361
 
/* Core painting hooks ------------------------------------------------------ */
362
 
 
363
 
/*
364
 
 * Force cube to paint all viewports if not drawing top or bottom cap(s)
365
 
 */
366
 
static void
367
 
cubecapsPreparePaintScreen (CompScreen *s,
368
 
                            int        msSinceLastPaint)
369
 
{
370
 
    CUBE_SCREEN (s);
371
 
    CUBECAPS_SCREEN (s);
372
 
 
373
 
    UNWRAP (ccs, s, preparePaintScreen);
374
 
    (*s->preparePaintScreen) (s, msSinceLastPaint);
375
 
    WRAP (ccs, s, preparePaintScreen, cubecapsPreparePaintScreen);
376
 
 
377
 
    if (cs->rotationState == RotationNone ||
378
 
        cs->rotationState != RotationManual)
379
 
        return;
380
 
 
381
 
    cs->paintAllViewports |= !cubecapsGetDrawTop (s)                    |
382
 
                             !cubecapsGetDrawBottom (s)                 |
383
 
                             (cubecapsGetTopColorAlpha (s) != OPAQUE)   |
384
 
                             (cubecapsGetBottomColorAlpha (s) != OPAQUE);
385
 
}
386
 
 
387
 
/* Cube hooks --------------------------------------------------------------- */
388
 
 
389
 
/*
390
 
 * Paint top cube face
391
 
 */
392
 
static void
393
 
cubecapsPaintTop (CompScreen              *s,
394
 
                  const ScreenPaintAttrib *sAttrib,
395
 
                  const CompTransform     *transform,
396
 
                  CompOutput              *output,
397
 
                  int                     size)
398
 
{
399
 
    ScreenPaintAttrib sa = *sAttrib;
400
 
    CompTransform     sTransform = *transform;
401
 
 
402
 
    CUBE_SCREEN (s);
403
 
    CUBECAPS_SCREEN (s);
404
 
 
405
 
    /* Only paint if required */
406
 
    if (!cubecapsGetDrawTop (s))
407
 
        return;
408
 
 
409
 
    screenLighting (s, TRUE);
410
 
 
411
 
    glPushMatrix ();
412
 
 
413
 
    /* Readjust cap orientation ... */
414
 
    if (cs->invert == 1)
415
 
    {
416
 
        sa.yRotate += (360.0f / size) * (cs->xRotations + 1);
417
 
        if (!cubecapsGetAdjustTop (s)) /* ... Or not */
418
 
            sa.yRotate -= (360.0f / size) * s->x;
419
 
    }
420
 
    else
421
 
    {
422
 
        sa.yRotate -= (360.0f / size) * (cs->xRotations - 1);
423
 
        if (!cubecapsGetAdjustTop (s)) /* ... Or not */
424
 
            sa.yRotate += (360.0f / size) * s->x;
425
 
    }
426
 
 
427
 
    (*s->applyScreenTransform) (s, &sa, output, &sTransform);
428
 
 
429
 
    glLoadMatrixf (sTransform.m);
430
 
 
431
 
    /* Actually paint the cap */
432
 
    cubecapsPaintCap (s, 0, &ccs->topCap, &ccs->bottomCap,
433
 
                      cubecapsGetTopColor (s), cubecapsGetBottomColor (s),
434
 
                      cubecapsGetClampTopToBorder (s),
435
 
                      cubecapsGetClampBottomToBorder (s));
436
 
 
437
 
    glPopMatrix ();
438
 
 
439
 
    glColor4usv (defaultColor);
440
 
}
441
 
 
442
 
/*
443
 
 * Paint bottom cube face
444
 
 */
445
 
static void
446
 
cubecapsPaintBottom (CompScreen              *s,
447
 
                     const ScreenPaintAttrib *sAttrib,
448
 
                     const CompTransform     *transform,
449
 
                     CompOutput              *output,
450
 
                     int                     size)
451
 
{
452
 
    ScreenPaintAttrib sa = *sAttrib;
453
 
    CompTransform     sTransform = *transform;
454
 
 
455
 
    CUBE_SCREEN (s);
456
 
    CUBECAPS_SCREEN (s);
457
 
 
458
 
    /* Only paint if required */
459
 
    if (!cubecapsGetDrawBottom (s))
460
 
        return;
461
 
 
462
 
    screenLighting (s, TRUE);
463
 
 
464
 
    glPushMatrix ();
465
 
 
466
 
    /* Readjust cap orientation ... */
467
 
    if (cs->invert == 1)
468
 
    {
469
 
        sa.yRotate += (360.0f / size) * cs->xRotations;
470
 
        if (!cubecapsGetAdjustBottom (s)) /* ... Or not */
471
 
            sa.yRotate -= (360.0f / size) * s->x;
472
 
    }
473
 
    else
474
 
    {
475
 
        sa.yRotate -= (360.0f / size) * cs->xRotations;
476
 
        if (!cubecapsGetAdjustBottom (s)) /* ... Or not */
477
 
            sa.yRotate += (360.0f / size) * s->x;
478
 
    }
479
 
 
480
 
    (*s->applyScreenTransform) (s, &sa, output, &sTransform);
481
 
 
482
 
    glLoadMatrixf (sTransform.m);
483
 
 
484
 
    /* Actually paint the cap */
485
 
    cubecapsPaintCap (s, cs->nVertices >> 1, &ccs->bottomCap, &ccs->topCap,
486
 
                      cubecapsGetBottomColor (s), cubecapsGetTopColor (s),
487
 
                      cubecapsGetClampBottomToBorder (s),
488
 
                      cubecapsGetClampTopToBorder (s));
489
 
 
490
 
    glPopMatrix ();
491
 
 
492
 
    glColor4usv (defaultColor);
493
 
}
494
 
 
495
 
/* Settings handling -------------------------------------------------------- */
496
 
 
497
 
/*
498
 
 * Switch cap, load it and damage screen if possible
499
 
 */
500
 
static void
501
 
cubecapsChangeCap (CompScreen *s,
502
 
                   CubeCap    *cap,
503
 
                   int        change)
504
 
{
505
 
    if (cap->files && cap->files->nValue)
506
 
    {
507
 
        int count = cap->files->nValue;
508
 
        cap->current = (cap->current + change + count) % count;
509
 
        cubecapsLoadCap (s, cap);
510
 
        damageScreen (s);
511
 
    }
512
 
}
513
 
 
514
 
/*
515
 
 * Top images list changed, reload top cap if any
516
 
 */
517
 
static void
518
 
cubecapsTopImagesChanged (CompScreen            *s,
519
 
                          CompOption            *opt,
520
 
                          CubecapsScreenOptions num)
521
 
{
522
 
    CUBECAPS_SCREEN (s);
523
 
 
524
 
    ccs->topCap.files = cubecapsGetTopImages (s);
525
 
    cubecapsChangeCap (s, &ccs->topCap, 0);
526
 
}
527
 
 
528
 
/*
529
 
 * Bottom images list changed, reload bottom cap if any
530
 
 */
531
 
static void
532
 
cubecapsBottomImagesChanged (CompScreen            *s,
533
 
                             CompOption            *opt,
534
 
                             CubecapsScreenOptions num)
535
 
{
536
 
    CUBECAPS_SCREEN (s);
537
 
 
538
 
    ccs->bottomCap.files = cubecapsGetBottomImages (s);
539
 
    cubecapsChangeCap (s, &ccs->bottomCap, 0);
540
 
}
541
 
 
542
 
/*
543
 
 * scale_top_image setting changed, reload top cap if any to update texture
544
 
 * coordinates
545
 
 */
546
 
static void
547
 
cubecapsScaleTopImageChanged (CompScreen            *s,
548
 
                              CompOption            *opt,
549
 
                              CubecapsScreenOptions num)
550
 
{
551
 
    CUBECAPS_SCREEN (s);
552
 
 
553
 
    ccs->topCap.scale = cubecapsGetScaleTopImage (s);
554
 
    cubecapsChangeCap (s, &ccs->topCap, 0);
555
 
}
556
 
 
557
 
/*
558
 
 * scale_bottom_image setting changed, reload bottom cap if any to update
559
 
 * texture coordinates
560
 
 */
561
 
static void
562
 
cubecapsScaleBottomImageChanged (CompScreen             *s,
563
 
                                 CompOption             *opt,
564
 
                                 CubecapsScreenOptions  num)
565
 
{
566
 
    CUBECAPS_SCREEN (s);
567
 
 
568
 
    ccs->bottomCap.scale = cubecapsGetScaleBottomImage (s);
569
 
    cubecapsChangeCap (s, &ccs->bottomCap, 0);
570
 
}
571
 
 
572
 
/* Actions handling --------------------------------------------------------- */
573
 
 
574
 
/*
575
 
 * Switch to next top image
576
 
 */
577
 
static Bool
578
 
cubecapsTopNext (CompDisplay     *d,
579
 
                 CompAction      *action,
580
 
                 CompActionState state,
581
 
                 CompOption      *option,
582
 
                 int             nOption)
583
 
{
584
 
    CompScreen *s;
585
 
    Window     xid;
586
 
 
587
 
    xid = getIntOptionNamed (option, nOption, "root", 0);
588
 
 
589
 
    s = findScreenAtDisplay (d, xid);
590
 
 
591
 
    if (s)
592
 
    {
593
 
        CUBECAPS_SCREEN (s);
594
 
        cubecapsChangeCap (s, &ccs->topCap, 1);
595
 
    }
596
 
 
597
 
    return FALSE;
598
 
}
599
 
 
600
 
/*
601
 
 * Switch to previous top image
602
 
 */
603
 
static Bool
604
 
cubecapsTopPrev (CompDisplay     *d,
605
 
                 CompAction      *action,
606
 
                 CompActionState state,
607
 
                 CompOption      *option,
608
 
                 int             nOption)
609
 
{
610
 
    CompScreen *s;
611
 
    Window     xid;
612
 
 
613
 
    xid = getIntOptionNamed (option, nOption, "root", 0);
614
 
 
615
 
    s = findScreenAtDisplay (d, xid);
616
 
    if (s)
617
 
    {
618
 
        CUBECAPS_SCREEN (s);
619
 
        cubecapsChangeCap (s, &ccs->topCap, -1);
620
 
    }
621
 
 
622
 
    return FALSE;
623
 
}
624
 
 
625
 
/*
626
 
 * Switch to next bottom image
627
 
 */
628
 
static Bool
629
 
cubecapsBottomNext (CompDisplay     *d,
630
 
                    CompAction      *action,
631
 
                    CompActionState state,
632
 
                    CompOption      *option,
633
 
                    int             nOption)
634
 
{
635
 
    CompScreen *s;
636
 
    Window     xid;
637
 
 
638
 
    xid = getIntOptionNamed (option, nOption, "root", 0);
639
 
 
640
 
    s = findScreenAtDisplay (d, xid);
641
 
 
642
 
    if (s)
643
 
    {
644
 
        CUBECAPS_SCREEN (s);
645
 
        cubecapsChangeCap (s, &ccs->bottomCap, 1);
646
 
    }
647
 
 
648
 
    return FALSE;
649
 
}
650
 
 
651
 
/*
652
 
 * Switch to previous bottom image
653
 
 */
654
 
static Bool
655
 
cubecapsBottomPrev (CompDisplay     *d,
656
 
                    CompAction      *action,
657
 
                    CompActionState state,
658
 
                    CompOption      *option,
659
 
                    int             nOption)
660
 
{
661
 
    CompScreen *s;
662
 
    Window     xid;
663
 
 
664
 
    xid = getIntOptionNamed (option, nOption, "root", 0);
665
 
 
666
 
    s = findScreenAtDisplay (d, xid);
667
 
    if (s)
668
 
    {
669
 
        CUBECAPS_SCREEN (s);
670
 
        cubecapsChangeCap (s, &ccs->bottomCap, -1);
671
 
    }
672
 
 
673
 
    return FALSE;
674
 
}
675
 
 
676
 
/* Internal stuff ----------------------------------------------------------- */
677
 
 
678
 
static Bool
679
 
cubecapsInitDisplay (CompPlugin  *p,
680
 
                     CompDisplay *d)
681
 
{
682
 
    CubeCapsDisplay *ccd;
683
 
 
684
 
    if (!checkPluginABI ("core", CORE_ABIVERSION))
685
 
        return FALSE;
686
 
 
687
 
    if (!checkPluginABI ("cube", CUBE_ABIVERSION))
688
 
        return FALSE;
689
 
 
690
 
    if (!getPluginDisplayIndex (d, "cube", &cubeDisplayPrivateIndex))
691
 
        return FALSE;
692
 
 
693
 
    ccd = malloc (sizeof (CubeCapsDisplay));
694
 
 
695
 
    if (!ccd)
696
 
        return FALSE;
697
 
 
698
 
    ccd->screenPrivateIndex = allocateScreenPrivateIndex (d);
699
 
 
700
 
    if (ccd->screenPrivateIndex < 0)
701
 
    {
702
 
        free (ccd);
703
 
        return FALSE;
704
 
    }
705
 
 
706
 
    cubecapsSetTopNextKeyInitiate (d, cubecapsTopNext);
707
 
    cubecapsSetTopPrevKeyInitiate (d, cubecapsTopPrev);
708
 
    cubecapsSetBottomNextKeyInitiate (d, cubecapsBottomNext);
709
 
    cubecapsSetBottomPrevKeyInitiate (d, cubecapsBottomPrev);
710
 
 
711
 
    cubecapsSetTopNextButtonInitiate (d, cubecapsTopNext);
712
 
    cubecapsSetTopPrevButtonInitiate (d, cubecapsTopPrev);
713
 
    cubecapsSetBottomNextButtonInitiate (d, cubecapsBottomNext);
714
 
    cubecapsSetBottomPrevButtonInitiate (d, cubecapsBottomPrev);
715
 
 
716
 
    d->base.privates[displayPrivateIndex].ptr = ccd;
717
 
 
718
 
    return TRUE;
719
 
}
720
 
 
721
 
static void
722
 
cubecapsFiniDisplay (CompPlugin  *p,
723
 
                     CompDisplay *d)
724
 
{
725
 
    CUBECAPS_DISPLAY (d);
726
 
 
727
 
    freeScreenPrivateIndex (d, ccd->screenPrivateIndex);
728
 
    free (ccd);
729
 
}
730
 
 
731
 
static Bool
732
 
cubecapsInitScreen (CompPlugin *p,
733
 
                    CompScreen *s)
734
 
{
735
 
    CubeCapsScreen *ccs;
736
 
    CUBECAPS_DISPLAY (s->display);
737
 
    CUBE_SCREEN (s);
738
 
 
739
 
    ccs = malloc (sizeof (CubeCapsScreen));
740
 
 
741
 
    if (!ccs)
742
 
        return FALSE;
743
 
 
744
 
    cubecapsInitCap (s, &ccs->topCap);
745
 
    cubecapsInitCap (s, &ccs->bottomCap);
746
 
 
747
 
    ccs->topCap.files = cubecapsGetTopImages (s);
748
 
    ccs->bottomCap.files = cubecapsGetBottomImages (s);
749
 
 
750
 
    cubecapsSetTopImagesNotify (s, cubecapsTopImagesChanged);
751
 
    cubecapsSetBottomImagesNotify (s, cubecapsBottomImagesChanged);
752
 
 
753
 
    cubecapsSetScaleTopImageNotify (s, cubecapsScaleTopImageChanged);
754
 
    cubecapsSetScaleBottomImageNotify (s, cubecapsScaleBottomImageChanged);
755
 
 
756
 
    WRAP (ccs, s, preparePaintScreen, cubecapsPreparePaintScreen);
757
 
    WRAP (ccs, cs, paintTop, cubecapsPaintTop);
758
 
    WRAP (ccs, cs, paintBottom, cubecapsPaintBottom);
759
 
 
760
 
    s->base.privates[ccd->screenPrivateIndex].ptr = ccs;
761
 
 
762
 
    cubecapsChangeCap (s, &ccs->topCap, 0);
763
 
    cubecapsChangeCap (s, &ccs->bottomCap, 0);
764
 
 
765
 
    return TRUE;
766
 
}
767
 
 
768
 
static void
769
 
cubecapsFiniScreen (CompPlugin *p,
770
 
                    CompScreen *s)
771
 
{
772
 
    CUBECAPS_SCREEN (s);
773
 
    CUBE_SCREEN (s);
774
 
 
775
 
    UNWRAP (ccs, cs, paintTop);
776
 
    UNWRAP (ccs, cs, paintBottom);
777
 
    UNWRAP (ccs, s, preparePaintScreen);
778
 
 
779
 
    free (ccs);
780
 
}
781
 
 
782
 
static CompBool
783
 
cubecapsInitObject (CompPlugin *p,
784
 
                    CompObject *o)
785
 
{
786
 
    static InitPluginObjectProc dispTab[] = {
787
 
        (InitPluginObjectProc) 0, /* InitCore */
788
 
        (InitPluginObjectProc) cubecapsInitDisplay,
789
 
        (InitPluginObjectProc) cubecapsInitScreen
790
 
    };
791
 
 
792
 
    RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
793
 
}
794
 
 
795
 
static void
796
 
cubecapsFiniObject (CompPlugin *p,
797
 
                    CompObject *o)
798
 
{
799
 
    static FiniPluginObjectProc dispTab[] = {
800
 
        (FiniPluginObjectProc) 0, /* FiniCore */
801
 
        (FiniPluginObjectProc) cubecapsFiniDisplay,
802
 
        (FiniPluginObjectProc) cubecapsFiniScreen
803
 
    };
804
 
 
805
 
    DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
806
 
}
807
 
 
808
 
static Bool
809
 
cubecapsInit (CompPlugin * p)
810
 
{
811
 
    displayPrivateIndex = allocateDisplayPrivateIndex();
812
 
 
813
 
    if (displayPrivateIndex < 0)
814
 
        return FALSE;
815
 
 
816
 
    return TRUE;
817
 
}
818
 
 
819
 
static void
820
 
cubecapsFini (CompPlugin * p)
821
 
{
822
 
    if (displayPrivateIndex >= 0)
823
 
        freeDisplayPrivateIndex (displayPrivateIndex);
824
 
}
825
 
 
826
 
CompPluginVTable cubecapsVTable =
827
 
{
828
 
    "cubecaps",
829
 
    0,
830
 
    cubecapsInit,
831
 
    cubecapsFini,
832
 
    cubecapsInitObject,
833
 
    cubecapsFiniObject,
834
 
    NULL,
835
 
    NULL
836
 
};
837
 
 
838
 
CompPluginVTable *
839
 
getCompPluginInfo (void)
840
 
{
841
 
    return &cubecapsVTable;
842
 
}