~ubuntu-branches/ubuntu/natty/compiz-fusion-plugins-main/natty

« back to all changes in this revision

Viewing changes to src/wall/wall.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-10-19 12:07:20 UTC
  • mfrom: (1.1.38 upstream)
  • Revision ID: james.westby@ubuntu.com-20101019120720-c3wffrxv7khh2ll8
Tags: 0.9.2.1-0ubuntu1
* New upstream release
* debian/control, debian/rules:
  - convert to cmake, remove autoconf, and convert to debhelper7
* debian/control:
  - bump compiz build-dep and deps to 0.9,
  - reintroduce coreabiversion trick to dep on the good package
* debian/install:
  - removed, seems we shipped all files anyway. Now install in the package
    directly
* debian/docs:
  - adapt to latest upstream shipped file
* debian/source:
  - switch to quilt format
* debian/patches/01-animation-defaults.patch,
  debian/patches/03_default_options.patch,
  debian/patches/06_bug326995.patch,
  debian/patches/08_disable_desktop_vpswitch.patch:
  - adapt to latest version
* debian/patches/02_fix_edges.patch:
  - removed for now: the plugin has been rewritten and have a different
    behavior
* debian/control:
  - remove compiz-fusion-bcop as a build-dep, now built in the core itself
* debian/rules:
  - add some switch to build in package mode, not in debug one

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 *
3
 
 * Compiz wall plugin
4
 
 *
5
 
 * wall.c
6
 
 *
7
 
 * Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
8
 
 *
9
 
 * Authors:
10
 
 * Robert Carr <racarr@beryl-project.org>
11
 
 * Dennis Kasprzyk <onestone@opencompositing.org>
12
 
 *
13
 
 * This program is free software; you can redistribute it and/or
14
 
 * modify it under the terms of the GNU General Public License
15
 
 * as published by the Free Software Foundation; either version 2
16
 
 * of the License, or (at your option) any later version.
17
 
 *
18
 
 * This program is distributed in the hope that it will be useful,
19
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 
 * GNU General Public License for more details.
22
 
 *
23
 
 **/
24
 
 
25
 
#include <stdio.h>
26
 
#include <stdlib.h>
27
 
#include <string.h>
28
 
#include <math.h>
29
 
#include <sys/time.h>
30
 
 
31
 
#include <compiz-core.h>
32
 
#include "wall_options.h"
33
 
 
34
 
#include <GL/glu.h>
35
 
 
36
 
#include <cairo-xlib-xrender.h>
37
 
#include <cairo.h>
38
 
 
39
 
#define PI 3.14159265359f
40
 
#define VIEWPORT_SWITCHER_SIZE 100
41
 
#define ARROW_SIZE 33
42
 
 
43
 
#define WIN_X(w) ((w)->attrib.x - (w)->input.left)
44
 
#define WIN_Y(w) ((w)->attrib.y - (w)->input.top)
45
 
#define WIN_W(w) ((w)->width + (w)->input.left + (w)->input.right)
46
 
#define WIN_H(w) ((w)->height + (w)->input.top + (w)->input.bottom)
47
 
 
48
 
#define getColorRGBA(name, _display) \
49
 
    r = wallGet##name##Red(_display) / 65535.0f;\
50
 
    g = wallGet##name##Green(_display) / 65535.0f; \
51
 
    b = wallGet##name##Blue(_display) / 65535.0f; \
52
 
    a = wallGet##name##Alpha(_display) / 65535.0f
53
 
 
54
 
static int WallDisplayPrivateIndex;
55
 
static int WallCorePrivateIndex;
56
 
 
57
 
/* Enums */
58
 
typedef enum
59
 
{
60
 
    Up = 0,
61
 
    Left,
62
 
    Down,
63
 
    Right
64
 
} Direction;
65
 
 
66
 
typedef enum
67
 
{
68
 
    NoTransformation,
69
 
    MiniScreen,
70
 
    Sliding
71
 
} ScreenTransformation;
72
 
 
73
 
typedef struct _WallCairoContext
74
 
{
75
 
    Pixmap      pixmap;
76
 
    CompTexture texture;
77
 
 
78
 
    cairo_surface_t *surface;
79
 
    cairo_t         *cr;
80
 
 
81
 
    int width;
82
 
    int height;
83
 
} WallCairoContext;
84
 
 
85
 
typedef struct _WallCore
86
 
{
87
 
    ObjectAddProc          objectAdd;
88
 
    SetOptionForPluginProc setOptionForPlugin;
89
 
} WallCore;
90
 
 
91
 
typedef struct _WallDisplay
92
 
{
93
 
    int screenPrivateIndex;
94
 
 
95
 
    HandleEventProc            handleEvent;
96
 
    MatchExpHandlerChangedProc matchExpHandlerChanged;
97
 
    MatchPropertyChangedProc   matchPropertyChanged;
98
 
} WallDisplay;
99
 
 
100
 
typedef struct _WallScreen
101
 
{
102
 
    int windowPrivateIndex;
103
 
 
104
 
    DonePaintScreenProc          donePaintScreen;
105
 
    PaintOutputProc              paintOutput;
106
 
    PaintScreenProc              paintScreen;
107
 
    PreparePaintScreenProc       preparePaintScreen;
108
 
    PaintTransformedOutputProc   paintTransformedOutput;
109
 
    PaintWindowProc              paintWindow;
110
 
    WindowGrabNotifyProc         windowGrabNotify;
111
 
    WindowUngrabNotifyProc       windowUngrabNotify;
112
 
    ActivateWindowProc           activateWindow;
113
 
 
114
 
    Bool moving; /* Used to track miniview movement */
115
 
    Bool showPreview;
116
 
 
117
 
    float curPosX;
118
 
    float curPosY;
119
 
    int   gotoX;
120
 
    int   gotoY;
121
 
    int   direction; /* >= 0 : direction arrow angle, < 0 : no direction */
122
 
 
123
 
    int boxTimeout;
124
 
    int boxOutputDevice;
125
 
 
126
 
    int grabIndex;
127
 
    int timer;
128
 
 
129
 
    Window moveWindow;
130
 
 
131
 
    CompWindow *grabWindow;
132
 
 
133
 
    Bool focusDefault;
134
 
 
135
 
    ScreenTransformation transform;
136
 
    CompOutput           *currOutput;
137
 
 
138
 
    WindowPaintAttrib mSAttribs;
139
 
    float             mSzCamera;
140
 
 
141
 
    int firstViewportX;
142
 
    int firstViewportY;
143
 
    int viewportWidth;
144
 
    int viewportHeight;
145
 
    int viewportBorder;
146
 
 
147
 
    int moveWindowX;
148
 
    int moveWindowY;
149
 
 
150
 
    WallCairoContext switcherContext;
151
 
    WallCairoContext thumbContext;
152
 
    WallCairoContext highlightContext;
153
 
    WallCairoContext arrowContext;
154
 
} WallScreen;
155
 
 
156
 
typedef struct _WallWindow
157
 
{
158
 
    Bool isSliding;
159
 
} WallWindow;
160
 
 
161
 
/* Helpers */
162
 
#define WALL_CORE(c)    PLUGIN_CORE(c, Wall, w)
163
 
#define WALL_DISPLAY(d) PLUGIN_DISPLAY(d, Wall, w)
164
 
#define WALL_SCREEN(s)  PLUGIN_SCREEN(s, Wall, w)
165
 
#define WALL_WINDOW(w)  PLUGIN_WINDOW(w, Wall, w)
166
 
 
167
 
#define GET_SCREEN                                      \
168
 
    CompScreen *s;                                      \
169
 
    Window xid;                                         \
170
 
    xid = getIntOptionNamed(option, nOption, "root", 0);\
171
 
    s = findScreenAtDisplay(d, xid);                    \
172
 
    if (!s)                                             \
173
 
        return FALSE;
174
 
 
175
 
#define sigmoid(x) (1.0f / (1.0f + exp (-5.5f * 2 * ((x) - 0.5))))
176
 
#define sigmoidProgress(x) ((sigmoid (x) - sigmoid (0)) / \
177
 
                            (sigmoid (1) - sigmoid (0)))
178
 
 
179
 
 
180
 
static void
181
 
wallClearCairoLayer (cairo_t *cr)
182
 
{
183
 
    cairo_save (cr);
184
 
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
185
 
    cairo_paint (cr);
186
 
    cairo_restore (cr);
187
 
}
188
 
 
189
 
static void
190
 
wallDrawSwitcherBackground (CompScreen *s)
191
 
{
192
 
    cairo_t         *cr;
193
 
    cairo_pattern_t *pattern;
194
 
    float           outline = 2.0f;
195
 
    int             width, height, radius;
196
 
    float           r, g, b, a;
197
 
    int             i, j;
198
 
 
199
 
    WALL_SCREEN (s);
200
 
 
201
 
    cr = ws->switcherContext.cr;
202
 
    wallClearCairoLayer (cr);
203
 
 
204
 
    width = ws->switcherContext.width - outline;
205
 
    height = ws->switcherContext.height - outline;
206
 
 
207
 
    cairo_save (cr);
208
 
    cairo_translate (cr, outline / 2.0f, outline / 2.0f);
209
 
 
210
 
    /* set the pattern for the switcher's background */
211
 
    pattern = cairo_pattern_create_linear (0, 0, width, height);
212
 
    getColorRGBA (BackgroundGradientBaseColor, s->display);
213
 
    cairo_pattern_add_color_stop_rgba (pattern, 0.00f, r, g, b, a);
214
 
    getColorRGBA (BackgroundGradientHighlightColor, s->display);
215
 
    cairo_pattern_add_color_stop_rgba (pattern, 0.65f, r, g, b, a);
216
 
    getColorRGBA (BackgroundGradientShadowColor, s->display);
217
 
    cairo_pattern_add_color_stop_rgba (pattern, 0.85f, r, g, b, a);
218
 
    cairo_set_source (cr, pattern);
219
 
 
220
 
    /* draw the border's shape */
221
 
    radius = wallGetEdgeRadius (s->display);
222
 
    if (radius)
223
 
    {
224
 
        cairo_arc (cr, radius, radius, radius, PI, 1.5f * PI);
225
 
        cairo_arc (cr, radius + width - 2 * radius,
226
 
                   radius, radius, 1.5f * PI, 2.0 * PI);
227
 
        cairo_arc (cr, width - radius, height - radius, radius, 0,  PI / 2.0f);
228
 
        cairo_arc (cr, radius, height - radius, radius,  PI / 2.0f, PI);
229
 
    }
230
 
    else
231
 
        cairo_rectangle (cr, 0, 0, width, height);
232
 
 
233
 
    cairo_close_path (cr);
234
 
 
235
 
    /* apply pattern to background... */
236
 
    cairo_fill_preserve (cr);
237
 
 
238
 
    /* ... and draw an outline */
239
 
    cairo_set_line_width (cr, outline);
240
 
    getColorRGBA (OutlineColor, s->display);
241
 
    cairo_set_source_rgba (cr, r, g, b, a);
242
 
    cairo_stroke(cr);
243
 
 
244
 
    cairo_pattern_destroy (pattern);
245
 
    cairo_restore (cr);
246
 
 
247
 
    cairo_save (cr);
248
 
    for (i = 0; i < s->vsize; i++)
249
 
    {
250
 
        cairo_translate (cr, 0.0, ws->viewportBorder);
251
 
        cairo_save (cr);
252
 
        for (j = 0; j < s->hsize; j++)
253
 
        {
254
 
            cairo_translate (cr, ws->viewportBorder, 0.0);
255
 
 
256
 
            /* this cuts a hole into our background */
257
 
            cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
258
 
            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
259
 
            cairo_rectangle (cr, 0, 0, ws->viewportWidth, ws->viewportHeight);
260
 
 
261
 
            cairo_fill_preserve (cr);
262
 
            cairo_set_operator (cr, CAIRO_OPERATOR_XOR);
263
 
            cairo_fill (cr);
264
 
 
265
 
            cairo_translate (cr, ws->viewportWidth, 0.0);
266
 
        }
267
 
        cairo_restore(cr);
268
 
 
269
 
        cairo_translate (cr, 0.0, ws->viewportHeight);
270
 
    }
271
 
    cairo_restore (cr);
272
 
}
273
 
 
274
 
static void
275
 
wallDrawThumb (CompScreen *s)
276
 
{
277
 
    cairo_t         *cr;
278
 
    cairo_pattern_t *pattern;
279
 
    float           r, g, b, a;
280
 
    float           outline = 2.0f;
281
 
    int             width, height;
282
 
 
283
 
    WALL_SCREEN(s);
284
 
 
285
 
    cr = ws->thumbContext.cr;
286
 
    wallClearCairoLayer (cr);
287
 
 
288
 
    width  = ws->thumbContext.width - outline;
289
 
    height = ws->thumbContext.height - outline;
290
 
 
291
 
    cairo_translate (cr, outline / 2.0f, outline / 2.0f);
292
 
 
293
 
    pattern = cairo_pattern_create_linear (0, 0, width, height);
294
 
    getColorRGBA (ThumbGradientBaseColor, s->display);
295
 
    cairo_pattern_add_color_stop_rgba (pattern, 0.0f, r, g, b, a);
296
 
    getColorRGBA (ThumbGradientHighlightColor, s->display);
297
 
    cairo_pattern_add_color_stop_rgba (pattern, 1.0f, r, g, b, a);
298
 
 
299
 
    /* apply the pattern for thumb background */
300
 
    cairo_set_source (cr, pattern);
301
 
    cairo_rectangle (cr, 0, 0, width, height);
302
 
    cairo_fill_preserve (cr);
303
 
 
304
 
    cairo_set_line_width (cr, outline);
305
 
    getColorRGBA (OutlineColor, s->display);
306
 
    cairo_set_source_rgba (cr, r, g, b, a);
307
 
    cairo_stroke (cr);
308
 
 
309
 
    cairo_pattern_destroy (pattern);
310
 
 
311
 
    cairo_restore (cr);
312
 
}
313
 
 
314
 
static void
315
 
wallDrawHighlight(CompScreen *s)
316
 
{
317
 
    cairo_t         *cr;
318
 
    cairo_pattern_t *pattern;
319
 
    int             width, height;
320
 
    float           r, g, b, a;
321
 
    float           outline = 2.0f;
322
 
 
323
 
 
324
 
    WALL_SCREEN(s);
325
 
 
326
 
    cr = ws->highlightContext.cr;
327
 
    wallClearCairoLayer (cr);
328
 
 
329
 
    width  = ws->highlightContext.width - outline;
330
 
    height = ws->highlightContext.height - outline;
331
 
 
332
 
    cairo_translate (cr, outline / 2.0f, outline / 2.0f);
333
 
 
334
 
    pattern = cairo_pattern_create_linear (0, 0, width, height);
335
 
    getColorRGBA (ThumbHighlightGradientBaseColor, s->display);
336
 
    cairo_pattern_add_color_stop_rgba (pattern, 0.0f, r, g, b, a);
337
 
    getColorRGBA (ThumbHighlightGradientShadowColor, s->display);
338
 
    cairo_pattern_add_color_stop_rgba (pattern, 1.0f, r, g, b, a);
339
 
 
340
 
    /* apply the pattern for thumb background */
341
 
    cairo_set_source (cr, pattern);
342
 
    cairo_rectangle (cr, 0, 0, width, height);
343
 
    cairo_fill_preserve (cr);
344
 
 
345
 
    cairo_set_line_width (cr, outline);
346
 
    getColorRGBA (OutlineColor, s->display);
347
 
    cairo_set_source_rgba (cr, r, g, b, a);
348
 
    cairo_stroke (cr);
349
 
 
350
 
    cairo_pattern_destroy (pattern);
351
 
 
352
 
    cairo_restore (cr);
353
 
}
354
 
 
355
 
static void
356
 
wallDrawArrow (CompScreen *s)
357
 
{
358
 
    cairo_t *cr;
359
 
    float   outline = 2.0f;
360
 
    float   r, g, b, a;
361
 
 
362
 
    WALL_SCREEN(s);
363
 
 
364
 
    cr = ws->arrowContext.cr;
365
 
    wallClearCairoLayer (cr);
366
 
 
367
 
    cairo_translate (cr, outline / 2.0f, outline / 2.0f);
368
 
 
369
 
    /* apply the pattern for thumb background */
370
 
    cairo_set_line_width (cr, outline);
371
 
 
372
 
    /* draw top part of the arrow */
373
 
    getColorRGBA (ArrowBaseColor, s->display);
374
 
    cairo_set_source_rgba (cr, r, g, b, a);
375
 
    cairo_move_to (cr, 15, 0);
376
 
    cairo_line_to (cr, 30, 30);
377
 
    cairo_line_to (cr, 15, 24.5);
378
 
    cairo_line_to (cr, 15, 0);
379
 
    cairo_fill (cr);
380
 
 
381
 
    /* draw bottom part of the arrow */
382
 
    getColorRGBA (ArrowShadowColor, s->display);
383
 
    cairo_set_source_rgba (cr, r, g, b, a);
384
 
    cairo_move_to (cr, 15, 0);
385
 
    cairo_line_to (cr, 0, 30);
386
 
    cairo_line_to (cr, 15, 24.5);
387
 
    cairo_line_to (cr, 15, 0);
388
 
    cairo_fill (cr);
389
 
 
390
 
    /* draw the arrow outline */
391
 
    getColorRGBA (OutlineColor, s->display);
392
 
    cairo_set_source_rgba (cr, r, g, b, a);
393
 
    cairo_move_to (cr, 15, 0);
394
 
    cairo_line_to (cr, 30, 30);
395
 
    cairo_line_to (cr, 15, 24.5);
396
 
    cairo_line_to (cr, 0, 30);
397
 
    cairo_line_to (cr, 15, 0);
398
 
    cairo_stroke (cr);
399
 
 
400
 
    cairo_restore (cr);
401
 
}
402
 
 
403
 
static void
404
 
wallSetupCairoContext (CompScreen       *s,
405
 
                       WallCairoContext *context)
406
 
{
407
 
    XRenderPictFormat *format;
408
 
    Screen            *screen;
409
 
    int               width, height;
410
 
 
411
 
    screen = ScreenOfDisplay (s->display->display, s->screenNum);
412
 
 
413
 
    width = context->width;
414
 
    height = context->height;
415
 
 
416
 
    initTexture (s, &context->texture);
417
 
 
418
 
    format = XRenderFindStandardFormat (s->display->display,
419
 
                                        PictStandardARGB32);
420
 
 
421
 
    context->pixmap = XCreatePixmap (s->display->display, s->root,
422
 
                                     width, height, 32);
423
 
 
424
 
    if (!bindPixmapToTexture(s, &context->texture, context->pixmap,
425
 
                             width, height, 32))
426
 
    {
427
 
        compLogMessage ("wall", CompLogLevelError,
428
 
                        "Couldn't create cairo context for switcher");
429
 
    }
430
 
 
431
 
    context->surface =
432
 
        cairo_xlib_surface_create_with_xrender_format (s->display->display,
433
 
                                                       context->pixmap,
434
 
                                                       screen, format,
435
 
                                                       width, height);
436
 
 
437
 
    context->cr = cairo_create (context->surface);
438
 
    wallClearCairoLayer (context->cr);
439
 
}
440
 
 
441
 
static void
442
 
wallDestroyCairoContext (CompScreen       *s,
443
 
                         WallCairoContext *context)
444
 
{
445
 
    if (context->cr)
446
 
        cairo_destroy (context->cr);
447
 
 
448
 
    if (context->surface)
449
 
        cairo_surface_destroy (context->surface);
450
 
 
451
 
    finiTexture (s, &context->texture);
452
 
 
453
 
    if (context->pixmap)
454
 
        XFreePixmap (s->display->display, context->pixmap);
455
 
}
456
 
 
457
 
static Bool
458
 
wallCheckDestination (CompScreen *s,
459
 
                      int        destX,
460
 
                      int        destY)
461
 
{
462
 
    if (s->x - destX < 0)
463
 
        return FALSE;
464
 
 
465
 
    if (s->x - destX >= s->hsize)
466
 
        return FALSE;
467
 
 
468
 
    if (s->y - destY >= s->vsize)
469
 
        return FALSE;
470
 
 
471
 
    if (s->y - destY < 0)
472
 
        return FALSE;
473
 
 
474
 
    return TRUE;
475
 
}
476
 
 
477
 
static void
478
 
wallReleaseMoveWindow (CompScreen *s)
479
 
{
480
 
    CompWindow *w;
481
 
    WALL_SCREEN (s);
482
 
 
483
 
    w = findWindowAtScreen (s, ws->moveWindow);
484
 
    if (w)
485
 
        syncWindowPosition (w);
486
 
 
487
 
    ws->moveWindow = 0;
488
 
}
489
 
 
490
 
static void
491
 
wallComputeTranslation (CompScreen *s,
492
 
                        float      *x,
493
 
                        float      *y)
494
 
{
495
 
    float dx, dy, elapsed, duration;
496
 
 
497
 
    WALL_SCREEN (s);
498
 
 
499
 
    duration = wallGetSlideDuration (s->display) * 1000.0;
500
 
    if (duration != 0.0)
501
 
        elapsed = 1.0 - (ws->timer / duration);
502
 
    else
503
 
        elapsed = 1.0;
504
 
 
505
 
    if (elapsed < 0.0)
506
 
        elapsed = 0.0;
507
 
    if (elapsed > 1.0)
508
 
        elapsed = 1.0;
509
 
 
510
 
    /* Use temporary variables to you can pass in &ps->cur_x */
511
 
    dx = (ws->gotoX - ws->curPosX) * elapsed + ws->curPosX;
512
 
    dy = (ws->gotoY - ws->curPosY) * elapsed + ws->curPosY;
513
 
 
514
 
    *x = dx;
515
 
    *y = dy;
516
 
}
517
 
 
518
 
/* movement remainder that gets ignored for direction calculation */
519
 
#define IGNORE_REMAINDER 0.05
520
 
 
521
 
static void
522
 
wallDetermineMovementAngle (CompScreen *s)
523
 
{
524
 
    int angle;
525
 
    float dx, dy;
526
 
 
527
 
    WALL_SCREEN (s);
528
 
 
529
 
    dx = ws->gotoX - ws->curPosX;
530
 
    dy = ws->gotoY - ws->curPosY;
531
 
 
532
 
    if (dy > IGNORE_REMAINDER)
533
 
        angle = (dx > IGNORE_REMAINDER) ? 135 :
534
 
                (dx < -IGNORE_REMAINDER) ? 225 : 180;
535
 
    else if (dy < -IGNORE_REMAINDER)
536
 
        angle = (dx > IGNORE_REMAINDER) ? 45 :
537
 
                (dx < -IGNORE_REMAINDER) ? 315 : 0;
538
 
    else
539
 
        angle = (dx > IGNORE_REMAINDER) ? 90 :
540
 
                (dx < -IGNORE_REMAINDER) ? 270 : -1;
541
 
 
542
 
    ws->direction = angle;
543
 
}
544
 
 
545
 
static Bool
546
 
wallMoveViewport (CompScreen *s,
547
 
                  int        x,
548
 
                  int        y,
549
 
                  Window     moveWindow)
550
 
{
551
 
    WALL_SCREEN (s);
552
 
 
553
 
    if (!x && !y)
554
 
        return FALSE;
555
 
 
556
 
    if (otherScreenGrabExist (s, "move", "switcher", "group-drag", "wall", NULL))
557
 
        return FALSE;
558
 
 
559
 
    if (!wallCheckDestination (s, x, y))
560
 
        return FALSE;
561
 
 
562
 
    if (ws->moveWindow != moveWindow)
563
 
    {
564
 
        CompWindow *w;
565
 
 
566
 
        wallReleaseMoveWindow (s);
567
 
        w = findWindowAtScreen (s, moveWindow);
568
 
        if (w)
569
 
        {
570
 
            if (!(w->type & (CompWindowTypeDesktopMask |
571
 
                             CompWindowTypeDockMask)))
572
 
            {
573
 
                if (!(w->state & CompWindowStateStickyMask))
574
 
                {
575
 
                    ws->moveWindow = w->id;
576
 
                    ws->moveWindowX = w->attrib.x;
577
 
                    ws->moveWindowY = w->attrib.y;
578
 
                    raiseWindow (w);
579
 
                }
580
 
            }
581
 
        }
582
 
    }
583
 
 
584
 
    if (!ws->moving)
585
 
    {
586
 
        ws->curPosX = s->x;
587
 
        ws->curPosY = s->y;
588
 
    }
589
 
    ws->gotoX = s->x - x;
590
 
    ws->gotoY = s->y - y;
591
 
 
592
 
    wallDetermineMovementAngle (s);
593
 
 
594
 
    if (!ws->grabIndex)
595
 
        ws->grabIndex = pushScreenGrab (s, s->invisibleCursor, "wall");
596
 
 
597
 
    moveScreenViewport (s, x, y, TRUE);
598
 
 
599
 
    ws->moving          = TRUE;
600
 
    ws->focusDefault    = TRUE;
601
 
    ws->boxOutputDevice = outputDeviceForPoint (s, pointerX, pointerY);
602
 
 
603
 
    if (wallGetShowSwitcher (s->display))
604
 
        ws->boxTimeout = wallGetPreviewTimeout (s->display) * 1000;
605
 
    else
606
 
        ws->boxTimeout = 0;
607
 
 
608
 
    ws->timer = wallGetSlideDuration (s->display) * 1000;
609
 
 
610
 
    damageScreen (s);
611
 
 
612
 
    return TRUE;
613
 
}
614
 
 
615
 
static void
616
 
wallHandleEvent (CompDisplay *d,
617
 
                 XEvent      *event)
618
 
{
619
 
    WALL_DISPLAY (d);
620
 
 
621
 
    switch (event->type) {
622
 
    case ClientMessage:
623
 
        if (event->xclient.message_type == d->desktopViewportAtom)
624
 
        {
625
 
            int        dx, dy;
626
 
            CompScreen *s;
627
 
 
628
 
            s = findScreenAtDisplay (d, event->xclient.window);
629
 
            if (!s)
630
 
                break;
631
 
 
632
 
            if (otherScreenGrabExist (s, "switcher", "wall", NULL))
633
 
                break;
634
 
 
635
 
            dx = event->xclient.data.l[0] / s->width - s->x;
636
 
            dy = event->xclient.data.l[1] / s->height - s->y;
637
 
 
638
 
            if (!dx && !dy)
639
 
                break;
640
 
 
641
 
            wallMoveViewport (s, -dx, -dy, None);
642
 
        }
643
 
        break;
644
 
    }
645
 
 
646
 
    UNWRAP (wd, d, handleEvent);
647
 
    (*d->handleEvent) (d, event);
648
 
    WRAP (wd, d, handleEvent, wallHandleEvent);
649
 
}
650
 
 
651
 
static void
652
 
wallActivateWindow (CompWindow *w)
653
 
{
654
 
    CompScreen *s = w->screen;
655
 
 
656
 
    WALL_SCREEN (s);
657
 
 
658
 
    if (w->placed && !otherScreenGrabExist (s, "wall", "switcher", NULL))
659
 
    {
660
 
        int dx, dy;
661
 
 
662
 
        defaultViewportForWindow (w, &dx, &dy);
663
 
        dx -= s->x;
664
 
        dy -= s->y;
665
 
        
666
 
        if (dx || dy)
667
 
        {
668
 
            wallMoveViewport (s, -dx, -dy, None);
669
 
            ws->focusDefault = FALSE;
670
 
        }
671
 
    }
672
 
 
673
 
    UNWRAP (ws, s, activateWindow);
674
 
    (*s->activateWindow) (w);
675
 
    WRAP (ws, s, activateWindow, wallActivateWindow);
676
 
}
677
 
 
678
 
static void
679
 
wallCheckAmount (CompScreen *s,
680
 
                 int        dx,
681
 
                 int        dy,
682
 
                 int        *amountX,
683
 
                 int        *amountY)
684
 
{
685
 
    *amountX = -dx;
686
 
    *amountY = -dy;
687
 
 
688
 
    if (wallGetAllowWraparound (s->display))
689
 
    {
690
 
        if ((s->x + dx) < 0)
691
 
            *amountX = -(s->hsize + dx);
692
 
        else if ((s->x + dx) >= s->hsize)
693
 
            *amountX = s->hsize - dx;
694
 
 
695
 
        if ((s->y + dy) < 0)
696
 
            *amountY = -(s->vsize + dy);
697
 
        else if ((s->y + dy) >= s->vsize)
698
 
            *amountY = s->vsize - dy;
699
 
    }
700
 
}
701
 
 
702
 
static Bool
703
 
wallInitiate (CompScreen      *s,
704
 
              int             dx,
705
 
              int             dy,
706
 
              Window          win,
707
 
              CompAction      *action,
708
 
              CompActionState state)
709
 
{
710
 
    int amountX, amountY;
711
 
 
712
 
    WALL_SCREEN (s);
713
 
 
714
 
    wallCheckAmount (s, dx, dy, &amountX, &amountY);
715
 
    if (!wallMoveViewport (s, amountX, amountY, win))
716
 
        return TRUE;
717
 
 
718
 
    if (state & CompActionStateInitKey)
719
 
        action->state |= CompActionStateTermKey;
720
 
 
721
 
    if (state & CompActionStateInitButton)
722
 
        action->state |= CompActionStateTermButton;
723
 
 
724
 
    ws->showPreview = wallGetShowSwitcher (s->display);
725
 
 
726
 
    return TRUE;
727
 
}
728
 
 
729
 
static Bool
730
 
wallTerminate (CompDisplay     *d,
731
 
               CompAction      *action,
732
 
               CompActionState state,
733
 
               CompOption      *option,
734
 
               int             nOption)
735
 
{
736
 
    CompScreen *s;
737
 
 
738
 
    for (s = d->screens; s; s = s->next)
739
 
    {
740
 
        WALL_SCREEN (s);
741
 
 
742
 
        if (ws->showPreview)
743
 
        {
744
 
            ws->showPreview = FALSE;
745
 
            damageScreen (s);
746
 
        }
747
 
    }
748
 
 
749
 
    if (action)
750
 
        action->state &= ~(CompActionStateTermKey | CompActionStateTermButton);
751
 
 
752
 
    return FALSE;
753
 
}
754
 
 
755
 
static Bool
756
 
wallInitiateFlip (CompScreen *s,
757
 
                  Direction  direction,
758
 
                  Bool       dnd)
759
 
{
760
 
    int dx, dy;
761
 
    int amountX, amountY;
762
 
 
763
 
    if (otherScreenGrabExist (s, "wall", "move", "group-drag", NULL))
764
 
        return FALSE;
765
 
 
766
 
    if (dnd)
767
 
    {
768
 
        if (!wallGetEdgeflipDnd (s))
769
 
            return FALSE;
770
 
 
771
 
        if (otherScreenGrabExist (s, "wall", NULL))
772
 
            return FALSE;
773
 
    }
774
 
    else if (otherScreenGrabExist (s, "wall", "group-drag", NULL))
775
 
    {
776
 
        /* not wall or group means move */
777
 
        if (!wallGetEdgeflipMove (s))
778
 
            return FALSE;
779
 
 
780
 
        WALL_SCREEN (s);
781
 
 
782
 
        if (!ws->grabWindow)
783
 
            return FALSE;
784
 
 
785
 
        /* bail out if window is sticky */
786
 
        if (ws->grabWindow->state & CompWindowStateStickyMask)
787
 
            return FALSE;
788
 
    }
789
 
    else if (otherScreenGrabExist (s, "wall", NULL))
790
 
    {
791
 
        /* move was ruled out before, so we have group */
792
 
        if (!wallGetEdgeflipDnd (s))
793
 
            return FALSE;
794
 
    }
795
 
    else if (!wallGetEdgeflipPointer (s))
796
 
        return FALSE;
797
 
 
798
 
    switch (direction) {
799
 
    case Left:
800
 
        dx = -1; dy = 0;
801
 
        break;
802
 
    case Right:
803
 
        dx = 1; dy = 0;
804
 
        break;
805
 
    case Up:
806
 
        dx = 0; dy = -1;
807
 
        break;
808
 
    case Down:
809
 
        dx = 0; dy = 1;
810
 
        break;
811
 
    default:
812
 
        dx = 0; dy = 0;
813
 
        break;
814
 
    }
815
 
 
816
 
    wallCheckAmount (s, dx, dy, &amountX, &amountY);
817
 
    if (wallMoveViewport (s, amountX, amountY, None))
818
 
    {
819
 
        int offsetX, offsetY;
820
 
        int warpX, warpY;
821
 
 
822
 
        if (dx < 0)
823
 
        {
824
 
            offsetX = s->width - 10;
825
 
            warpX = pointerX + s->width;
826
 
        }
827
 
        else if (dx > 0)
828
 
        {
829
 
            offsetX = 1- s->width;
830
 
            warpX = pointerX - s->width;
831
 
        }
832
 
        else
833
 
        {
834
 
            offsetX = 0;
835
 
            warpX = lastPointerX;
836
 
        }
837
 
 
838
 
        if (dy < 0)
839
 
        {
840
 
            offsetY = s->height - 10;
841
 
            warpY = pointerY + s->height;
842
 
        }
843
 
        else if (dy > 0)
844
 
        {
845
 
            offsetY = 1- s->height;
846
 
            warpY = pointerY - s->height;
847
 
        }
848
 
        else
849
 
        {
850
 
            offsetY = 0;
851
 
            warpY = lastPointerY;
852
 
        }
853
 
 
854
 
        warpPointer (s, offsetX, offsetY);
855
 
        lastPointerX = warpX;
856
 
        lastPointerY = warpY;
857
 
    }
858
 
 
859
 
    return TRUE;
860
 
}
861
 
 
862
 
static Bool
863
 
wallLeft (CompDisplay     *d,
864
 
          CompAction      *action,
865
 
          CompActionState state,
866
 
          CompOption      *option,
867
 
          int             nOption)
868
 
{
869
 
    GET_SCREEN;
870
 
 
871
 
    return wallInitiate (s, -1, 0, None, action, state);
872
 
}
873
 
 
874
 
static Bool
875
 
wallRight (CompDisplay     *d,
876
 
           CompAction      *action,
877
 
           CompActionState state,
878
 
           CompOption      *option,
879
 
           int             nOption)
880
 
{
881
 
    GET_SCREEN;
882
 
 
883
 
    return wallInitiate (s, 1, 0, None, action, state);
884
 
}
885
 
 
886
 
static Bool
887
 
wallUp (CompDisplay     *d,
888
 
        CompAction      *action,
889
 
        CompActionState state,
890
 
        CompOption      *option,
891
 
        int             nOption)
892
 
{
893
 
    GET_SCREEN;
894
 
 
895
 
    return wallInitiate (s, 0, -1, None, action, state);
896
 
}
897
 
 
898
 
static Bool
899
 
wallDown (CompDisplay     *d,
900
 
          CompAction      *action,
901
 
          CompActionState state,
902
 
          CompOption      *option,
903
 
          int             nOption)
904
 
{
905
 
    GET_SCREEN;
906
 
 
907
 
    return wallInitiate (s, 0, 1, None, action, state);
908
 
}
909
 
 
910
 
static Bool
911
 
wallNext (CompDisplay     *d,
912
 
          CompAction      *action,
913
 
          CompActionState state,
914
 
          CompOption      *option,
915
 
          int             nOption)
916
 
{
917
 
    int amountX, amountY;
918
 
    GET_SCREEN;
919
 
 
920
 
    if ((s->x == s->hsize - 1) && (s->y == s->vsize - 1))
921
 
    {
922
 
        amountX = -(s->hsize - 1);
923
 
        amountY = -(s->vsize - 1);
924
 
    }
925
 
    else if (s->x == s->hsize - 1)
926
 
    {
927
 
        amountX = -(s->hsize - 1);
928
 
        amountY = 1;
929
 
    }
930
 
    else
931
 
    {
932
 
        amountX = 1;
933
 
        amountY = 0;
934
 
    }
935
 
 
936
 
    return wallInitiate (s, amountX, amountY, None, action, state);
937
 
}
938
 
 
939
 
static Bool
940
 
wallPrev (CompDisplay     *d,
941
 
          CompAction      *action,
942
 
          CompActionState state,
943
 
          CompOption      *option,
944
 
          int             nOption)
945
 
{
946
 
    int amountX, amountY;
947
 
    GET_SCREEN;
948
 
 
949
 
    if ((s->x == 0) && (s->y == 0))
950
 
    {
951
 
        amountX = s->hsize - 1;
952
 
        amountY = s->vsize - 1;
953
 
    }
954
 
    else if (s->x == 0)
955
 
    {
956
 
        amountX = s->hsize - 1;
957
 
        amountY = -1;
958
 
    }
959
 
    else
960
 
    {
961
 
        amountX = -1;
962
 
        amountY = 0;
963
 
    }
964
 
 
965
 
    return wallInitiate (s, amountX, amountY, None, action, state);
966
 
}
967
 
 
968
 
static Bool
969
 
wallFlipLeft (CompDisplay     *d,
970
 
              CompAction      *action,
971
 
              CompActionState state,
972
 
              CompOption      *option,
973
 
              int             nOption)
974
 
{
975
 
    GET_SCREEN;
976
 
 
977
 
    return wallInitiateFlip (s, Left, (state & CompActionStateInitEdgeDnd));
978
 
}
979
 
 
980
 
static Bool
981
 
wallFlipRight (CompDisplay     *d,
982
 
               CompAction      *action,
983
 
               CompActionState state,
984
 
               CompOption      *option,
985
 
               int             nOption)
986
 
{
987
 
    GET_SCREEN;
988
 
 
989
 
    return wallInitiateFlip (s, Right, (state & CompActionStateInitEdgeDnd));
990
 
}
991
 
 
992
 
static Bool
993
 
wallFlipUp (CompDisplay     *d,
994
 
            CompAction      *action,
995
 
            CompActionState state,
996
 
            CompOption      *option,
997
 
            int             nOption)
998
 
{
999
 
    GET_SCREEN;
1000
 
 
1001
 
    return wallInitiateFlip (s, Up, (state & CompActionStateInitEdgeDnd));
1002
 
}
1003
 
 
1004
 
static Bool
1005
 
wallFlipDown (CompDisplay     *d,
1006
 
              CompAction      *action,
1007
 
              CompActionState state,
1008
 
              CompOption      *option,
1009
 
              int             nOption)
1010
 
{
1011
 
    GET_SCREEN;
1012
 
 
1013
 
    return wallInitiateFlip (s, Down, (state & CompActionStateInitEdgeDnd));
1014
 
}
1015
 
 
1016
 
static Bool
1017
 
wallLeftWithWindow (CompDisplay     *d,
1018
 
                    CompAction      *action,
1019
 
                    CompActionState state,
1020
 
                    CompOption      *option,
1021
 
                    int             nOption)
1022
 
{
1023
 
    GET_SCREEN;
1024
 
    Window win = getIntOptionNamed (option, nOption, "window", 0);
1025
 
 
1026
 
    return wallInitiate (s, -1, 0, win, action, state);
1027
 
}
1028
 
 
1029
 
static Bool
1030
 
wallRightWithWindow (CompDisplay     *d,
1031
 
                     CompAction      *action,
1032
 
                     CompActionState state,
1033
 
                     CompOption      *option,
1034
 
                     int             nOption)
1035
 
{
1036
 
    GET_SCREEN;
1037
 
    Window win = getIntOptionNamed (option, nOption, "window", 0);
1038
 
 
1039
 
    return wallInitiate (s, 1, 0, win, action, state);
1040
 
}
1041
 
 
1042
 
static Bool
1043
 
wallUpWithWindow (CompDisplay     *d,
1044
 
                  CompAction      *action,
1045
 
                  CompActionState state,
1046
 
                  CompOption      *option,
1047
 
                  int             nOption)
1048
 
{
1049
 
    GET_SCREEN;
1050
 
    Window win = getIntOptionNamed (option, nOption, "window", 0);
1051
 
 
1052
 
    return wallInitiate (s, 0, -1, win, action, state);
1053
 
}
1054
 
 
1055
 
static Bool
1056
 
wallDownWithWindow (CompDisplay     *d,
1057
 
                    CompAction      *action,
1058
 
                    CompActionState state,
1059
 
                    CompOption      *option,
1060
 
                    int             nOption)
1061
 
{
1062
 
    GET_SCREEN;
1063
 
    Window win = getIntOptionNamed (option, nOption, "window", 0);
1064
 
 
1065
 
    return wallInitiate (s, 0, 1, win, action, state);
1066
 
}
1067
 
 
1068
 
static inline void
1069
 
wallDrawQuad (CompMatrix *matrix, BOX *box)
1070
 
{
1071
 
    glTexCoord2f (COMP_TEX_COORD_X (matrix, box->x1),
1072
 
                  COMP_TEX_COORD_Y (matrix, box->y2));
1073
 
    glVertex2i (box->x1, box->y2);
1074
 
    glTexCoord2f (COMP_TEX_COORD_X (matrix, box->x2),
1075
 
                  COMP_TEX_COORD_Y (matrix, box->y2));
1076
 
    glVertex2i (box->x2, box->y2);
1077
 
    glTexCoord2f (COMP_TEX_COORD_X (matrix, box->x2),
1078
 
                  COMP_TEX_COORD_Y (matrix, box->y1));
1079
 
    glVertex2i (box->x2, box->y1);
1080
 
    glTexCoord2f (COMP_TEX_COORD_X (matrix, box->x1),
1081
 
                  COMP_TEX_COORD_Y (matrix, box->y1));
1082
 
    glVertex2i (box->x1, box->y1);
1083
 
}
1084
 
 
1085
 
static void
1086
 
wallDrawCairoTextureOnScreen (CompScreen *s)
1087
 
{
1088
 
    float      centerX, centerY;
1089
 
    float      width, height;
1090
 
    float      topLeftX, topLeftY;
1091
 
    float      border;
1092
 
    int        i, j;
1093
 
    CompMatrix matrix;
1094
 
    BOX        box;
1095
 
 
1096
 
    WALL_SCREEN(s);
1097
 
 
1098
 
    glDisableClientState (GL_TEXTURE_COORD_ARRAY);
1099
 
    glEnable (GL_BLEND);
1100
 
 
1101
 
    centerX = s->outputDev[ws->boxOutputDevice].region.extents.x1 +
1102
 
              (s->outputDev[ws->boxOutputDevice].width / 2.0f);
1103
 
    centerY = s->outputDev[ws->boxOutputDevice].region.extents.y1 +
1104
 
              (s->outputDev[ws->boxOutputDevice].height / 2.0f);
1105
 
 
1106
 
    border = (float) ws->viewportBorder;
1107
 
    width  = (float) ws->switcherContext.width;
1108
 
    height = (float) ws->switcherContext.height;
1109
 
 
1110
 
    topLeftX = centerX - floor (width / 2.0f);
1111
 
    topLeftY = centerY - floor (height / 2.0f);
1112
 
 
1113
 
    ws->firstViewportX = topLeftX + border;
1114
 
    ws->firstViewportY = topLeftY + border;
1115
 
 
1116
 
    if (!ws->moving)
1117
 
    {
1118
 
        double left, timeout;
1119
 
 
1120
 
        timeout = wallGetPreviewTimeout (s->display) * 1000.0f;
1121
 
        left    = (timeout > 0) ? (float) ws->boxTimeout / timeout : 1.0f;
1122
 
 
1123
 
        if (left < 0)
1124
 
            left = 0.0f;
1125
 
        else if (left > 0.5)
1126
 
            left = 1.0f;
1127
 
        else
1128
 
            left = 2 * left;
1129
 
 
1130
 
        screenTexEnvMode (s, GL_MODULATE);
1131
 
 
1132
 
        glColor4f (left, left, left, left);
1133
 
        glTranslatef (0.0f,0.0f, -(1 - left));
1134
 
 
1135
 
        ws->mSzCamera = -(1 - left);
1136
 
    }
1137
 
    else
1138
 
        ws->mSzCamera = 0.0f;
1139
 
 
1140
 
    /* draw background */
1141
 
 
1142
 
    matrix = ws->switcherContext.texture.matrix;
1143
 
    matrix.x0 -= topLeftX * matrix.xx;
1144
 
    matrix.y0 -= topLeftY * matrix.yy;
1145
 
 
1146
 
    box.x1 = topLeftX;
1147
 
    box.x2 = box.x1 + width;
1148
 
    box.y1 = topLeftY;
1149
 
    box.y2 = box.y1 + height;
1150
 
 
1151
 
    enableTexture (s, &ws->switcherContext.texture, COMP_TEXTURE_FILTER_FAST);
1152
 
    glBegin (GL_QUADS);
1153
 
    wallDrawQuad (&matrix, &box);
1154
 
    glEnd ();
1155
 
    disableTexture (s, &ws->switcherContext.texture);
1156
 
 
1157
 
    /* draw thumb */
1158
 
    width = (float) ws->thumbContext.width;
1159
 
    height = (float) ws->thumbContext.height;
1160
 
 
1161
 
    enableTexture (s, &ws->thumbContext.texture, COMP_TEXTURE_FILTER_FAST);
1162
 
    glBegin (GL_QUADS);
1163
 
    for (i = 0; i < s->hsize; i++)
1164
 
    {
1165
 
        for (j = 0; j < s->vsize; j++)
1166
 
        {
1167
 
            if (i == ws->gotoX && j == ws->gotoY && ws->moving)
1168
 
                continue;
1169
 
 
1170
 
            box.x1 = i * (width + border);
1171
 
            box.x1 += topLeftX + border;
1172
 
            box.x2 = box.x1 + width;
1173
 
            box.y1 = j * (height + border);
1174
 
            box.y1 += topLeftY + border;
1175
 
            box.y2 = box.y1 + height;
1176
 
 
1177
 
            matrix = ws->thumbContext.texture.matrix;
1178
 
            matrix.x0 -= box.x1 * matrix.xx;
1179
 
            matrix.y0 -= box.y1 * matrix.yy;
1180
 
 
1181
 
            wallDrawQuad (&matrix, &box);
1182
 
        }
1183
 
    }
1184
 
    glEnd ();
1185
 
    disableTexture (s, &ws->thumbContext.texture);
1186
 
 
1187
 
    if (ws->moving || ws->showPreview)
1188
 
    {
1189
 
        /* draw highlight */
1190
 
        int   aW, aH;
1191
 
 
1192
 
        box.x1 = s->x * (width + border) + topLeftX + border;
1193
 
        box.x2 = box.x1 + width;
1194
 
        box.y1 = s->y * (height + border) + topLeftY + border;
1195
 
        box.y2 = box.y1 + height;
1196
 
 
1197
 
        matrix = ws->highlightContext.texture.matrix;
1198
 
        matrix.x0 -= box.x1 * matrix.xx;
1199
 
        matrix.y0 -= box.y1 * matrix.yy;
1200
 
 
1201
 
        enableTexture (s, &ws->highlightContext.texture,
1202
 
                       COMP_TEXTURE_FILTER_FAST);
1203
 
        glBegin (GL_QUADS);
1204
 
        wallDrawQuad (&matrix, &box);
1205
 
        glEnd ();
1206
 
        disableTexture (s, &ws->highlightContext.texture);
1207
 
 
1208
 
        /* draw arrow */
1209
 
        if (ws->direction >= 0)
1210
 
        {
1211
 
            enableTexture (s, &ws->arrowContext.texture,
1212
 
                           COMP_TEXTURE_FILTER_GOOD);
1213
 
 
1214
 
            aW = ws->arrowContext.width;
1215
 
            aH = ws->arrowContext.height;
1216
 
 
1217
 
            /* if we have a viewport preview we just paint the
1218
 
               arrow outside the switcher */
1219
 
            if (wallGetMiniscreen (s->display))
1220
 
            {
1221
 
                width  = (float) ws->switcherContext.width;
1222
 
                height = (float) ws->switcherContext.height;
1223
 
 
1224
 
                switch (ws->direction)
1225
 
                {
1226
 
                    /* top left */
1227
 
                    case 315:
1228
 
                        box.x1 = topLeftX - aW - border;
1229
 
                        box.y1 = topLeftY - aH - border;
1230
 
                        break;
1231
 
                        /* up */
1232
 
                    case 0:
1233
 
                        box.x1 = topLeftX + width / 2.0f - aW / 2.0f;
1234
 
                        box.y1 = topLeftY - aH - border;
1235
 
                        break;
1236
 
                        /* top right */
1237
 
                    case 45:
1238
 
                        box.x1 = topLeftX + width + border;
1239
 
                        box.y1 = topLeftY - aH - border;
1240
 
                        break;
1241
 
                        /* right */
1242
 
                    case 90:
1243
 
                        box.x1 = topLeftX + width + border;
1244
 
                        box.y1 = topLeftY + height / 2.0f - aH / 2.0f;
1245
 
                        break;
1246
 
                        /* bottom right */
1247
 
                    case 135:
1248
 
                        box.x1 = topLeftX + width + border;
1249
 
                        box.y1 = topLeftY + height + border;
1250
 
                        break;
1251
 
                        /* down */
1252
 
                    case 180:
1253
 
                        box.x1 = topLeftX + width / 2.0f - aW / 2.0f;
1254
 
                        box.y1 = topLeftY + height + border;
1255
 
                        break;
1256
 
                        /* bottom left */
1257
 
                    case 225:
1258
 
                        box.x1 = topLeftX - aW - border;
1259
 
                        box.y1 = topLeftY + height + border;
1260
 
                        break;
1261
 
                        /* left */
1262
 
                    case 270:
1263
 
                        box.x1 = topLeftX - aW - border;
1264
 
                        box.y1 = topLeftY + height / 2.0f - aH / 2.0f;
1265
 
                        break;
1266
 
                    default:
1267
 
                        break;
1268
 
                }
1269
 
            }
1270
 
            else
1271
 
            {
1272
 
                /* arrow is visible (no preview is painted over it) */
1273
 
                box.x1 = s->x * (width + border) + topLeftX + border;
1274
 
                box.x1 += width / 2 - aW / 2;
1275
 
                box.y1 = s->y * (height + border) + topLeftY + border;
1276
 
                box.y1 += height / 2 - aH / 2;
1277
 
            }
1278
 
 
1279
 
            box.x2 = box.x1 + aW;
1280
 
            box.y2 = box.y1 + aH;
1281
 
 
1282
 
            glTranslatef (box.x1 + aW / 2, box.y1 + aH / 2, 0.0f);
1283
 
            glRotatef (ws->direction, 0.0f, 0.0f, 1.0f);
1284
 
            glTranslatef (-box.x1 - aW / 2, -box.y1 - aH / 2, 0.0f);
1285
 
 
1286
 
            matrix = ws->arrowContext.texture.matrix;
1287
 
            matrix.x0 -= box.x1 * matrix.xx;
1288
 
            matrix.y0 -= box.y1 * matrix.yy;
1289
 
 
1290
 
            glBegin (GL_QUADS);
1291
 
            wallDrawQuad (&matrix, &box);
1292
 
            glEnd ();
1293
 
 
1294
 
            disableTexture (s, &ws->arrowContext.texture);
1295
 
        }
1296
 
    }
1297
 
 
1298
 
    glDisable (GL_BLEND);
1299
 
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
1300
 
    screenTexEnvMode (s, GL_REPLACE);
1301
 
    glColor4usv (defaultColor);
1302
 
}
1303
 
 
1304
 
static void
1305
 
wallPaintScreen (CompScreen   *s,
1306
 
                 CompOutput   *outputs,
1307
 
                 int          numOutputs,
1308
 
                 unsigned int mask)
1309
 
{
1310
 
    WALL_SCREEN (s);
1311
 
 
1312
 
    if (ws->moving && numOutputs > 1 && wallGetMmmode(s) == MmmodeSwitchAll)
1313
 
    {
1314
 
        outputs = &s->fullscreenOutput;
1315
 
        numOutputs = 1;
1316
 
    }
1317
 
 
1318
 
    UNWRAP (ws, s, paintScreen);
1319
 
    (*s->paintScreen) (s, outputs, numOutputs, mask);
1320
 
    WRAP (ws, s, paintScreen, wallPaintScreen);
1321
 
}
1322
 
 
1323
 
static Bool
1324
 
wallPaintOutput (CompScreen              *s,
1325
 
                 const ScreenPaintAttrib *sAttrib,
1326
 
                 const CompTransform     *transform,
1327
 
                 Region                  region,
1328
 
                 CompOutput              *output,
1329
 
                 unsigned int            mask)
1330
 
{
1331
 
    Bool status;
1332
 
 
1333
 
    WALL_SCREEN (s);
1334
 
 
1335
 
    ws->transform = NoTransformation;
1336
 
    if (ws->moving)
1337
 
        mask |= PAINT_SCREEN_TRANSFORMED_MASK |
1338
 
                PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
1339
 
 
1340
 
    UNWRAP (ws, s, paintOutput);
1341
 
    status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
1342
 
    WRAP (ws, s, paintOutput, wallPaintOutput);
1343
 
 
1344
 
    if (wallGetShowSwitcher (s->display) &&
1345
 
        (ws->moving || ws->showPreview || ws->boxTimeout) &&
1346
 
        (output->id == ws->boxOutputDevice || output == &s->fullscreenOutput))
1347
 
    {
1348
 
        CompTransform sTransform = *transform;
1349
 
 
1350
 
        transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform);
1351
 
 
1352
 
        glPushMatrix ();
1353
 
        glLoadMatrixf (sTransform.m);
1354
 
 
1355
 
        wallDrawCairoTextureOnScreen (s);
1356
 
 
1357
 
        glPopMatrix ();
1358
 
 
1359
 
        if (wallGetMiniscreen (s->display))
1360
 
        {
1361
 
            int  i, j;
1362
 
            float mw, mh;
1363
 
 
1364
 
            mw = ws->viewportWidth;
1365
 
            mh = ws->viewportHeight;
1366
 
 
1367
 
            ws->transform = MiniScreen;
1368
 
            ws->mSAttribs.xScale = mw / s->width;
1369
 
            ws->mSAttribs.yScale = mh / s->height;
1370
 
            ws->mSAttribs.opacity = OPAQUE * (1.0 + ws->mSzCamera);
1371
 
            ws->mSAttribs.saturation = COLOR;
1372
 
 
1373
 
            for (j = 0; j < s->vsize; j++)
1374
 
            {
1375
 
                for (i = 0; i < s->hsize; i++)
1376
 
                {
1377
 
                    float        mx, my;
1378
 
                    unsigned int msMask;
1379
 
 
1380
 
                    mx = ws->firstViewportX +
1381
 
                         (i * (ws->viewportWidth + ws->viewportBorder));
1382
 
                    my = ws->firstViewportY + 
1383
 
                         (j * (ws->viewportHeight + ws->viewportBorder));
1384
 
 
1385
 
                    ws->mSAttribs.xTranslate = mx / output->width;
1386
 
                    ws->mSAttribs.yTranslate = -my / output->height;
1387
 
 
1388
 
                    ws->mSAttribs.brightness = 0.4f * BRIGHT;
1389
 
 
1390
 
                    if (i == s->x && j == s->y && ws->moving)
1391
 
                        ws->mSAttribs.brightness = BRIGHT;
1392
 
 
1393
 
                    if ((ws->boxTimeout || ws->showPreview) &&
1394
 
                        !ws->moving && i == s->x && j == s->y)
1395
 
                    {
1396
 
                        ws->mSAttribs.brightness = BRIGHT;
1397
 
                    }
1398
 
 
1399
 
                    setWindowPaintOffset (s, (s->x - i) * s->width,
1400
 
                                          (s->y - j) * s->height);
1401
 
 
1402
 
                    msMask = mask | PAINT_SCREEN_TRANSFORMED_MASK;
1403
 
                    (*s->paintTransformedOutput) (s, sAttrib, transform,
1404
 
                                                  region, output, msMask);
1405
 
 
1406
 
 
1407
 
                }
1408
 
            }
1409
 
            ws->transform = NoTransformation;
1410
 
            setWindowPaintOffset (s, 0, 0);
1411
 
        }
1412
 
    }
1413
 
 
1414
 
    return status;
1415
 
}
1416
 
 
1417
 
static void
1418
 
wallPreparePaintScreen (CompScreen *s,
1419
 
                        int        msSinceLastPaint)
1420
 
{
1421
 
    WALL_SCREEN (s);
1422
 
 
1423
 
    if (!ws->moving && !ws->showPreview && ws->boxTimeout)
1424
 
        ws->boxTimeout -= msSinceLastPaint;
1425
 
 
1426
 
    if (ws->timer)
1427
 
        ws->timer -= msSinceLastPaint;
1428
 
 
1429
 
    if (ws->moving)
1430
 
    {
1431
 
        wallComputeTranslation (s, &ws->curPosX, &ws->curPosY);
1432
 
 
1433
 
        if (ws->moveWindow)
1434
 
        {
1435
 
            CompWindow *w;
1436
 
 
1437
 
            w = findWindowAtScreen (s, ws->moveWindow);
1438
 
            if (w)
1439
 
            {
1440
 
                float dx, dy;
1441
 
 
1442
 
                dx = ws->gotoX - ws->curPosX;
1443
 
                dy = ws->gotoY - ws->curPosY;
1444
 
 
1445
 
                moveWindowToViewportPosition (w,
1446
 
                                              ws->moveWindowX - s->width * dx,
1447
 
                                              ws->moveWindowY - s->height * dy,
1448
 
                                              TRUE);
1449
 
            }
1450
 
        }
1451
 
    }
1452
 
 
1453
 
    if (ws->moving && ws->curPosX == ws->gotoX && ws->curPosY == ws->gotoY)
1454
 
    {
1455
 
        ws->moving = FALSE;
1456
 
        ws->timer  = 0;
1457
 
 
1458
 
        if (ws->moveWindow)
1459
 
            wallReleaseMoveWindow (s);
1460
 
        else if (ws->focusDefault)
1461
 
        {
1462
 
            int i;
1463
 
            for (i = 0; i < s->maxGrab; i++)
1464
 
                if (s->grabs[i].active)
1465
 
                    if (strcmp(s->grabs[i].name, "switcher") == 0)
1466
 
                        break;
1467
 
 
1468
 
            /* only focus default window if switcher is not active */
1469
 
            if (i == s->maxGrab)
1470
 
                focusDefaultWindow (s);
1471
 
        }
1472
 
    }
1473
 
 
1474
 
    UNWRAP (ws, s, preparePaintScreen);
1475
 
    (*s->preparePaintScreen) (s, msSinceLastPaint);
1476
 
    WRAP (ws, s, preparePaintScreen, wallPreparePaintScreen);
1477
 
}
1478
 
 
1479
 
static void
1480
 
wallPaintTransformedOutput (CompScreen              *s,
1481
 
                            const ScreenPaintAttrib *sAttrib,
1482
 
                            const CompTransform     *transform,
1483
 
                            Region                  region,
1484
 
                            CompOutput              *output,
1485
 
                            unsigned int            mask)
1486
 
{
1487
 
    WALL_SCREEN (s);
1488
 
    Bool clear = (mask & PAINT_SCREEN_CLEAR_MASK);
1489
 
 
1490
 
    if (ws->transform == MiniScreen)
1491
 
    {
1492
 
        CompTransform sTransform = *transform;
1493
 
 
1494
 
        mask &= ~PAINT_SCREEN_CLEAR_MASK;
1495
 
 
1496
 
        /* move each screen to the correct output position */
1497
 
 
1498
 
        matrixTranslate (&sTransform,
1499
 
                         -(float) output->region.extents.x1 /
1500
 
                          (float) output->width,
1501
 
                         (float) output->region.extents.y1 /
1502
 
                         (float) output->height, 0.0f);
1503
 
        matrixTranslate (&sTransform, 0.0f, 0.0f, -DEFAULT_Z_CAMERA);
1504
 
 
1505
 
        matrixTranslate (&sTransform,
1506
 
                         ws->mSAttribs.xTranslate,
1507
 
                         ws->mSAttribs.yTranslate,
1508
 
                         ws->mSzCamera);
1509
 
 
1510
 
        /* move origin to top left */
1511
 
        matrixTranslate (&sTransform, -0.5f, 0.5f, 0.0f);
1512
 
        matrixScale (&sTransform,
1513
 
                     ws->mSAttribs.xScale, ws->mSAttribs.yScale, 1.0);
1514
 
 
1515
 
        /* revert prepareXCoords region shift.
1516
 
           Now all screens display the same */
1517
 
        matrixTranslate (&sTransform, 0.5f, 0.5f, DEFAULT_Z_CAMERA);
1518
 
        matrixTranslate (&sTransform,
1519
 
                         (float) output->region.extents.x1 /
1520
 
                         (float) output->width,
1521
 
                         -(float) output->region.extents.y2 /
1522
 
                         (float) output->height, 0.0f);
1523
 
 
1524
 
        UNWRAP (ws, s, paintTransformedOutput);
1525
 
        (*s->paintTransformedOutput) (s, sAttrib, &sTransform,
1526
 
                                      &s->region, output, mask);
1527
 
        WRAP (ws, s, paintTransformedOutput, wallPaintTransformedOutput);
1528
 
        return;
1529
 
    }
1530
 
 
1531
 
    UNWRAP (ws, s, paintTransformedOutput);
1532
 
 
1533
 
    if (!ws->moving)
1534
 
        (*s->paintTransformedOutput) (s, sAttrib, transform,
1535
 
                                      region, output, mask);
1536
 
 
1537
 
    mask &= ~PAINT_SCREEN_CLEAR_MASK;
1538
 
 
1539
 
    if (ws->moving)
1540
 
    {
1541
 
        ScreenTransformation oldTransform = ws->transform;
1542
 
        CompTransform        sTransform = *transform;
1543
 
        float                xTranslate, yTranslate;
1544
 
        float                px, py;
1545
 
        int                  tx, ty;
1546
 
        Bool                 movingX, movingY;
1547
 
 
1548
 
        if (clear)
1549
 
            clearTargetOutput (s->display, GL_COLOR_BUFFER_BIT);
1550
 
 
1551
 
        ws->transform  = Sliding;
1552
 
        ws->currOutput = output;
1553
 
 
1554
 
        px = ws->curPosX;
1555
 
        py = ws->curPosY;
1556
 
 
1557
 
        movingX = ((int) floor (px)) != ((int) ceil (px));
1558
 
        movingY = ((int) floor (py)) != ((int) ceil (py));
1559
 
 
1560
 
        if (movingY)
1561
 
        {
1562
 
            ty = ceil (py) - s->y;
1563
 
            yTranslate = fmod (py, 1) - 1;
1564
 
 
1565
 
            matrixTranslate (&sTransform, 0.0f, yTranslate, 0.0f);
1566
 
 
1567
 
            if (movingX)
1568
 
            {
1569
 
                tx = ceil (px) - s->x;
1570
 
                xTranslate = 1 - fmod (px, 1);
1571
 
 
1572
 
                setWindowPaintOffset (s, (s->x - ceil(px)) * s->width,
1573
 
                                      (s->y - ceil(py)) * s->height);
1574
 
                
1575
 
                matrixTranslate (&sTransform, xTranslate, 0.0f, 0.0f);
1576
 
 
1577
 
                (*s->paintTransformedOutput) (s, sAttrib, &sTransform,
1578
 
                                              &output->region, output, mask);
1579
 
 
1580
 
                matrixTranslate (&sTransform, -xTranslate, 0.0f, 0.0f);
1581
 
            }
1582
 
 
1583
 
            tx = floor (px) - s->x;
1584
 
            xTranslate = -fmod (px, 1);
1585
 
 
1586
 
            setWindowPaintOffset (s, (s->x - floor(px)) * s->width,
1587
 
                                  (s->y - ceil(py)) * s->height);
1588
 
 
1589
 
            matrixTranslate (&sTransform, xTranslate, 0.0f, 0.0f);
1590
 
 
1591
 
            (*s->paintTransformedOutput) (s, sAttrib, &sTransform,
1592
 
                                          &output->region, output, mask);
1593
 
            matrixTranslate (&sTransform, -xTranslate, -yTranslate, 0.0f);
1594
 
        }
1595
 
 
1596
 
        ty = floor (py) - s->y;
1597
 
        yTranslate = fmod (py, 1);
1598
 
 
1599
 
        matrixTranslate (&sTransform, 0.0f, yTranslate, 0.0f);
1600
 
 
1601
 
        if (movingX)
1602
 
        {
1603
 
            tx = ceil (px) - s->x;
1604
 
            xTranslate = 1 - fmod (px, 1);
1605
 
 
1606
 
            setWindowPaintOffset (s, (s->x - ceil(px)) * s->width,
1607
 
                                  (s->y - floor(py)) * s->height);
1608
 
 
1609
 
            matrixTranslate (&sTransform, xTranslate, 0.0f, 0.0f);
1610
 
 
1611
 
            (*s->paintTransformedOutput) (s, sAttrib, &sTransform,
1612
 
                                          &output->region, output, mask);
1613
 
 
1614
 
            matrixTranslate (&sTransform, -xTranslate, 0.0f, 0.0f);
1615
 
        }
1616
 
 
1617
 
        tx = floor (px) - s->x;
1618
 
        xTranslate = -fmod (px, 1);
1619
 
 
1620
 
        setWindowPaintOffset (s, (s->x - floor(px)) * s->width,
1621
 
                              (s->y - floor(py)) * s->height);
1622
 
 
1623
 
        matrixTranslate (&sTransform, xTranslate, 0.0f, 0.0f);
1624
 
        (*s->paintTransformedOutput) (s, sAttrib, &sTransform,
1625
 
                                      &output->region, output, mask);
1626
 
 
1627
 
        setWindowPaintOffset (s, 0, 0);
1628
 
        ws->transform = oldTransform;
1629
 
    }
1630
 
 
1631
 
    WRAP (ws, s, paintTransformedOutput, wallPaintTransformedOutput);
1632
 
}
1633
 
 
1634
 
static Bool
1635
 
wallPaintWindow (CompWindow              *w,
1636
 
                 const WindowPaintAttrib *attrib,
1637
 
                 const CompTransform     *transform,
1638
 
                 Region                  region,
1639
 
                 unsigned int            mask)
1640
 
{
1641
 
    Bool       status;
1642
 
    CompScreen *s = w->screen;
1643
 
 
1644
 
    WALL_SCREEN (s);
1645
 
 
1646
 
    if (ws->transform == MiniScreen)
1647
 
    {
1648
 
        WindowPaintAttrib pA = *attrib;
1649
 
 
1650
 
        pA.opacity    = attrib->opacity *
1651
 
                        ((float) ws->mSAttribs.opacity / OPAQUE);
1652
 
        pA.brightness = attrib->brightness *
1653
 
                        ((float) ws->mSAttribs.brightness / BRIGHT);
1654
 
        pA.saturation = attrib->saturation *
1655
 
                        ((float) ws->mSAttribs.saturation / COLOR);
1656
 
 
1657
 
        if (!pA.opacity || !pA.brightness)
1658
 
            mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1659
 
 
1660
 
        UNWRAP (ws, s, paintWindow);
1661
 
        status = (*s->paintWindow) (w, &pA, transform, region, mask);
1662
 
        WRAP (ws, s, paintWindow, wallPaintWindow);
1663
 
    }
1664
 
    else if (ws->transform == Sliding)
1665
 
    {
1666
 
        CompTransform wTransform;
1667
 
 
1668
 
        WALL_WINDOW (w);
1669
 
 
1670
 
        if (!ww->isSliding)
1671
 
        {
1672
 
            matrixGetIdentity (&wTransform);
1673
 
            transformToScreenSpace (s, ws->currOutput, -DEFAULT_Z_CAMERA,
1674
 
                                    &wTransform);
1675
 
            mask |= PAINT_WINDOW_TRANSFORMED_MASK;
1676
 
        }
1677
 
        else
1678
 
        {
1679
 
            wTransform = *transform;
1680
 
        }
1681
 
 
1682
 
        UNWRAP (ws, s, paintWindow);
1683
 
        status = (*s->paintWindow) (w, attrib, &wTransform, region, mask);
1684
 
        WRAP (ws, s, paintWindow, wallPaintWindow);
1685
 
    }
1686
 
    else
1687
 
    {
1688
 
        UNWRAP (ws, s, paintWindow);
1689
 
        status = (*s->paintWindow) (w, attrib, transform, region, mask);
1690
 
        WRAP (ws, s, paintWindow, wallPaintWindow);
1691
 
    }
1692
 
 
1693
 
    return status;
1694
 
}
1695
 
 
1696
 
static void
1697
 
wallDonePaintScreen (CompScreen *s)
1698
 
{
1699
 
    WALL_SCREEN (s);
1700
 
 
1701
 
    if (ws->moving || ws->showPreview || ws->boxTimeout)
1702
 
    {
1703
 
        ws->boxTimeout = MAX (0, ws->boxTimeout);
1704
 
        damageScreen (s);
1705
 
    }
1706
 
 
1707
 
    if (!ws->moving && !ws->showPreview && ws->grabIndex)
1708
 
    {
1709
 
        removeScreenGrab (s, ws->grabIndex, NULL);
1710
 
        ws->grabIndex = 0;
1711
 
    }
1712
 
 
1713
 
    UNWRAP (ws, s, donePaintScreen);
1714
 
    (*s->donePaintScreen) (s);
1715
 
    WRAP (ws, s, donePaintScreen, wallDonePaintScreen);
1716
 
 
1717
 
}
1718
 
 
1719
 
static void
1720
 
wallCreateCairoContexts (CompScreen *s,
1721
 
                         Bool       initial)
1722
 
{
1723
 
    int width, height;
1724
 
 
1725
 
    WALL_SCREEN (s);
1726
 
 
1727
 
    ws->viewportWidth = VIEWPORT_SWITCHER_SIZE *
1728
 
                        (float) wallGetPreviewScale (s->display) / 100.0f;
1729
 
    ws->viewportHeight = ws->viewportWidth *
1730
 
                         (float) s->height / (float) s->width;
1731
 
    ws->viewportBorder = wallGetBorderWidth (s->display);
1732
 
 
1733
 
    width  = s->hsize * (ws->viewportWidth + ws->viewportBorder) +
1734
 
             ws->viewportBorder;
1735
 
    height = s->vsize * (ws->viewportHeight + ws->viewportBorder) +
1736
 
             ws->viewportBorder;
1737
 
 
1738
 
    wallDestroyCairoContext (s, &ws->switcherContext);
1739
 
    ws->switcherContext.width = width;
1740
 
    ws->switcherContext.height = height;
1741
 
    wallSetupCairoContext (s, &ws->switcherContext);
1742
 
    wallDrawSwitcherBackground (s);
1743
 
 
1744
 
    wallDestroyCairoContext (s, &ws->thumbContext);
1745
 
    ws->thumbContext.width = ws->viewportWidth;
1746
 
    ws->thumbContext.height = ws->viewportHeight;
1747
 
    wallSetupCairoContext (s, &ws->thumbContext);
1748
 
    wallDrawThumb (s);
1749
 
 
1750
 
    wallDestroyCairoContext (s, &ws->highlightContext);
1751
 
    ws->highlightContext.width = ws->viewportWidth;
1752
 
    ws->highlightContext.height = ws->viewportHeight;
1753
 
    wallSetupCairoContext (s, &ws->highlightContext);
1754
 
    wallDrawHighlight (s);
1755
 
 
1756
 
    if (initial)
1757
 
    {
1758
 
        ws->arrowContext.width = ARROW_SIZE;
1759
 
        ws->arrowContext.height = ARROW_SIZE;
1760
 
        wallSetupCairoContext (s, &ws->arrowContext);
1761
 
        wallDrawArrow (s);
1762
 
    }
1763
 
}
1764
 
 
1765
 
static void
1766
 
wallDisplayOptionChanged (CompDisplay        *display,
1767
 
                          CompOption         *opt,
1768
 
                          WallDisplayOptions num)
1769
 
{
1770
 
    CompScreen *s;
1771
 
 
1772
 
    switch(num)
1773
 
    {
1774
 
    case WallDisplayOptionOutlineColor:
1775
 
        for (s = display->screens; s; s = s->next)
1776
 
        {
1777
 
            wallDrawSwitcherBackground (s);
1778
 
            wallDrawHighlight (s);
1779
 
            wallDrawThumb (s);
1780
 
        }
1781
 
        break;
1782
 
 
1783
 
    case WallDisplayOptionEdgeRadius:
1784
 
    case WallDisplayOptionBackgroundGradientBaseColor:
1785
 
    case WallDisplayOptionBackgroundGradientHighlightColor:
1786
 
    case WallDisplayOptionBackgroundGradientShadowColor:
1787
 
        for (s = display->screens; s; s = s->next)
1788
 
            wallDrawSwitcherBackground (s);
1789
 
        break;
1790
 
 
1791
 
    case WallDisplayOptionBorderWidth:
1792
 
    case WallDisplayOptionPreviewScale:
1793
 
        for (s = display->screens; s; s = s->next)
1794
 
            wallCreateCairoContexts (s, FALSE);
1795
 
        break;
1796
 
 
1797
 
    case WallDisplayOptionThumbGradientBaseColor:
1798
 
    case WallDisplayOptionThumbGradientHighlightColor:
1799
 
        for (s = display->screens; s; s = s->next)
1800
 
            wallDrawThumb (s);
1801
 
        break;
1802
 
 
1803
 
    case WallDisplayOptionThumbHighlightGradientBaseColor:
1804
 
    case WallDisplayOptionThumbHighlightGradientShadowColor:
1805
 
        for (s = display->screens; s; s = s->next)
1806
 
            wallDrawHighlight (s);
1807
 
        break;
1808
 
 
1809
 
    case WallDisplayOptionArrowBaseColor:
1810
 
    case WallDisplayOptionArrowShadowColor:
1811
 
        for (s = display->screens; s; s = s->next)
1812
 
            wallDrawArrow (s);
1813
 
        break;
1814
 
 
1815
 
    case WallDisplayOptionNoSlideMatch:
1816
 
        for (s = display->screens; s; s = s->next)
1817
 
        {
1818
 
            CompWindow *w;
1819
 
 
1820
 
            for (w = s->windows; w; w = w->next)
1821
 
            {
1822
 
                WALL_WINDOW (w);
1823
 
                ww->isSliding = !matchEval (wallGetNoSlideMatch (display), w);
1824
 
            }
1825
 
        }
1826
 
        break;
1827
 
 
1828
 
    default:
1829
 
        break;
1830
 
    }
1831
 
}
1832
 
 
1833
 
static Bool
1834
 
wallSetOptionForPlugin (CompObject      *o,
1835
 
                        const char      *plugin,
1836
 
                        const char      *name,
1837
 
                        CompOptionValue *value)
1838
 
{
1839
 
    Bool status;
1840
 
 
1841
 
    WALL_CORE (&core);
1842
 
 
1843
 
    UNWRAP (wc, &core, setOptionForPlugin);
1844
 
    status = (*core.setOptionForPlugin) (o, plugin, name, value);
1845
 
    WRAP (wc, &core, setOptionForPlugin, wallSetOptionForPlugin);
1846
 
 
1847
 
    if (status && o->type == COMP_OBJECT_TYPE_SCREEN)
1848
 
    {
1849
 
        if (strcmp (plugin, "core") == 0)
1850
 
            if (strcmp (name, "hsize") == 0 || strcmp (name, "vsize") == 0)
1851
 
            {
1852
 
                CompScreen *s = (CompScreen *) o;
1853
 
                
1854
 
                wallCreateCairoContexts (s, FALSE);
1855
 
            }
1856
 
    }
1857
 
 
1858
 
    return status;
1859
 
}
1860
 
 
1861
 
static void
1862
 
wallMatchExpHandlerChanged (CompDisplay *d)
1863
 
{
1864
 
    CompScreen *s;
1865
 
 
1866
 
    WALL_DISPLAY (d);
1867
 
 
1868
 
    UNWRAP (wd, d, matchExpHandlerChanged);
1869
 
    (*d->matchExpHandlerChanged) (d);
1870
 
    WRAP (wd, d, matchExpHandlerChanged, wallMatchExpHandlerChanged);
1871
 
 
1872
 
    for (s = d->screens; s; s = s->next)
1873
 
    {
1874
 
        CompWindow *w;
1875
 
 
1876
 
        for (w = s->windows; w; w = w->next)
1877
 
        {
1878
 
            WALL_WINDOW (w);
1879
 
 
1880
 
            ww->isSliding = !matchEval (wallGetNoSlideMatch (d), w);
1881
 
        }
1882
 
    }
1883
 
}
1884
 
 
1885
 
static void
1886
 
wallMatchPropertyChanged (CompDisplay *d,
1887
 
                          CompWindow  *w)
1888
 
{
1889
 
    WALL_DISPLAY (d);
1890
 
    WALL_WINDOW (w);
1891
 
 
1892
 
    UNWRAP (wd, d, matchPropertyChanged);
1893
 
    (*d->matchPropertyChanged) (d, w);
1894
 
    WRAP (wd, d, matchPropertyChanged, wallMatchPropertyChanged);
1895
 
 
1896
 
    ww->isSliding = !matchEval (wallGetNoSlideMatch (d), w);
1897
 
}
1898
 
 
1899
 
static void
1900
 
wallWindowGrabNotify (CompWindow   *w,
1901
 
                      int            x,
1902
 
                      int            y,
1903
 
                      unsigned int state,
1904
 
                      unsigned int mask)
1905
 
{
1906
 
    WALL_SCREEN (w->screen);
1907
 
 
1908
 
    if (!ws->grabWindow)
1909
 
        ws->grabWindow = w;
1910
 
 
1911
 
    UNWRAP (ws, w->screen, windowGrabNotify);
1912
 
    (*w->screen->windowGrabNotify) (w, x, y, state, mask);
1913
 
    WRAP (ws, w->screen, windowGrabNotify, wallWindowGrabNotify);
1914
 
}
1915
 
 
1916
 
static void
1917
 
wallWindowUngrabNotify (CompWindow *w)
1918
 
{
1919
 
    WALL_SCREEN (w->screen);
1920
 
 
1921
 
    if (w == ws->grabWindow)
1922
 
        ws->grabWindow = NULL;
1923
 
 
1924
 
    UNWRAP (ws, w->screen, windowUngrabNotify);
1925
 
    (*w->screen->windowUngrabNotify) (w);
1926
 
    WRAP (ws, w->screen, windowUngrabNotify, wallWindowUngrabNotify);
1927
 
}
1928
 
 
1929
 
static void
1930
 
wallWindowAdd (CompScreen *s,
1931
 
               CompWindow *w)
1932
 
{
1933
 
    WALL_WINDOW (w);
1934
 
 
1935
 
    ww->isSliding = !matchEval (wallGetNoSlideMatch (s->display), w);
1936
 
}
1937
 
 
1938
 
static void
1939
 
wallObjectAdd (CompObject *parent,
1940
 
               CompObject *object)
1941
 
{
1942
 
    static ObjectAddProc dispTab[] = {
1943
 
        (ObjectAddProc) 0, /* CoreAdd */
1944
 
        (ObjectAddProc) 0, /* DisplayAdd */
1945
 
        (ObjectAddProc) 0, /* ScreenAdd */
1946
 
        (ObjectAddProc) wallWindowAdd
1947
 
    };
1948
 
 
1949
 
    WALL_CORE (&core);
1950
 
 
1951
 
    UNWRAP (wc, &core, objectAdd);
1952
 
    (*core.objectAdd) (parent, object);
1953
 
    WRAP (wc, &core, objectAdd, wallObjectAdd);
1954
 
 
1955
 
    DISPATCH (object, dispTab, ARRAY_SIZE (dispTab), (parent, object));
1956
 
}
1957
 
 
1958
 
static Bool
1959
 
wallInitCore (CompPlugin *p,
1960
 
              CompCore   *c)
1961
 
{
1962
 
    WallCore *wc;
1963
 
 
1964
 
    if (!checkPluginABI ("core", CORE_ABIVERSION))
1965
 
        return FALSE;
1966
 
 
1967
 
    wc = malloc (sizeof (WallCore));
1968
 
    if (!wc)
1969
 
        return FALSE;
1970
 
 
1971
 
    WallDisplayPrivateIndex = allocateDisplayPrivateIndex ();
1972
 
    if (WallDisplayPrivateIndex < 0)
1973
 
    {
1974
 
        free (wc);
1975
 
        return FALSE;
1976
 
    }
1977
 
 
1978
 
    WRAP (wc, c, setOptionForPlugin, wallSetOptionForPlugin);
1979
 
    WRAP (wc, c, objectAdd, wallObjectAdd);
1980
 
 
1981
 
    c->base.privates[WallCorePrivateIndex].ptr = wc;
1982
 
 
1983
 
    return TRUE;
1984
 
}
1985
 
 
1986
 
static void
1987
 
wallFiniCore (CompPlugin *p,
1988
 
              CompCore   *c)
1989
 
{
1990
 
    WALL_CORE (c);
1991
 
 
1992
 
    UNWRAP (wc, c, setOptionForPlugin);
1993
 
    UNWRAP (wc, c, objectAdd);
1994
 
 
1995
 
    freeDisplayPrivateIndex (WallDisplayPrivateIndex);
1996
 
 
1997
 
    free (wc);
1998
 
}
1999
 
 
2000
 
static Bool
2001
 
wallInitDisplay (CompPlugin  *p,
2002
 
                 CompDisplay *d)
2003
 
{
2004
 
    WallDisplay *wd;
2005
 
 
2006
 
    wd = malloc (sizeof (WallDisplay));
2007
 
    if (!wd)
2008
 
        return FALSE;
2009
 
 
2010
 
    wd->screenPrivateIndex = allocateScreenPrivateIndex (d);
2011
 
    if (wd->screenPrivateIndex < 0)
2012
 
    {
2013
 
        free (wd);
2014
 
        return FALSE;
2015
 
    }
2016
 
 
2017
 
    wallSetLeftKeyInitiate (d, wallLeft);
2018
 
    wallSetLeftKeyTerminate (d, wallTerminate);
2019
 
    wallSetRightKeyInitiate (d, wallRight);
2020
 
    wallSetRightKeyTerminate (d, wallTerminate);
2021
 
    wallSetUpKeyInitiate (d, wallUp);
2022
 
    wallSetUpKeyTerminate (d, wallTerminate);
2023
 
    wallSetDownKeyInitiate (d, wallDown);
2024
 
    wallSetDownKeyTerminate (d, wallTerminate);
2025
 
    wallSetNextKeyInitiate (d, wallNext);
2026
 
    wallSetNextKeyTerminate (d, wallTerminate);
2027
 
    wallSetPrevKeyInitiate (d, wallPrev);
2028
 
    wallSetPrevKeyTerminate (d, wallTerminate);
2029
 
    wallSetLeftButtonInitiate (d, wallLeft);
2030
 
    wallSetLeftButtonTerminate (d, wallTerminate);
2031
 
    wallSetRightButtonInitiate (d, wallRight);
2032
 
    wallSetRightButtonTerminate (d, wallTerminate);
2033
 
    wallSetUpButtonInitiate (d, wallUp);
2034
 
    wallSetUpButtonTerminate (d, wallTerminate);
2035
 
    wallSetDownButtonInitiate (d, wallDown);
2036
 
    wallSetDownButtonTerminate (d, wallTerminate);
2037
 
    wallSetNextButtonInitiate (d, wallNext);
2038
 
    wallSetNextButtonTerminate (d, wallTerminate);
2039
 
    wallSetPrevButtonInitiate (d, wallPrev);
2040
 
    wallSetPrevButtonTerminate (d, wallTerminate);
2041
 
    wallSetLeftWindowKeyInitiate (d, wallLeftWithWindow);
2042
 
    wallSetLeftWindowKeyTerminate (d, wallTerminate);
2043
 
    wallSetRightWindowKeyInitiate (d, wallRightWithWindow);
2044
 
    wallSetRightWindowKeyTerminate (d, wallTerminate);
2045
 
    wallSetUpWindowKeyInitiate (d, wallUpWithWindow);
2046
 
    wallSetUpWindowKeyTerminate (d, wallTerminate);
2047
 
    wallSetDownWindowKeyInitiate (d, wallDownWithWindow);
2048
 
    wallSetDownWindowKeyTerminate (d, wallTerminate);
2049
 
    wallSetFlipLeftEdgeInitiate (d, wallFlipLeft);
2050
 
    wallSetFlipRightEdgeInitiate (d, wallFlipRight);
2051
 
    wallSetFlipUpEdgeInitiate (d, wallFlipUp);
2052
 
    wallSetFlipDownEdgeInitiate (d, wallFlipDown);
2053
 
 
2054
 
    wallSetEdgeRadiusNotify (d, wallDisplayOptionChanged);
2055
 
    wallSetBorderWidthNotify (d, wallDisplayOptionChanged);
2056
 
    wallSetPreviewScaleNotify (d, wallDisplayOptionChanged);
2057
 
    wallSetOutlineColorNotify (d, wallDisplayOptionChanged);
2058
 
    wallSetBackgroundGradientBaseColorNotify (d, wallDisplayOptionChanged);
2059
 
    wallSetBackgroundGradientHighlightColorNotify (d, wallDisplayOptionChanged);
2060
 
    wallSetBackgroundGradientShadowColorNotify (d, wallDisplayOptionChanged);
2061
 
    wallSetThumbGradientBaseColorNotify (d, wallDisplayOptionChanged);
2062
 
    wallSetThumbGradientHighlightColorNotify (d, wallDisplayOptionChanged);
2063
 
    wallSetThumbHighlightGradientBaseColorNotify (d, wallDisplayOptionChanged);
2064
 
    wallSetThumbHighlightGradientShadowColorNotify (d,
2065
 
                                                    wallDisplayOptionChanged);
2066
 
    wallSetArrowBaseColorNotify (d, wallDisplayOptionChanged);
2067
 
    wallSetArrowShadowColorNotify (d, wallDisplayOptionChanged);
2068
 
    wallSetNoSlideMatchNotify (d, wallDisplayOptionChanged);
2069
 
 
2070
 
    WRAP (wd, d, handleEvent, wallHandleEvent);
2071
 
    WRAP (wd, d, matchExpHandlerChanged, wallMatchExpHandlerChanged);
2072
 
    WRAP (wd, d, matchPropertyChanged, wallMatchPropertyChanged);
2073
 
 
2074
 
    d->base.privates[WallDisplayPrivateIndex].ptr = wd;
2075
 
 
2076
 
    return TRUE;
2077
 
}
2078
 
 
2079
 
static void
2080
 
wallFiniDisplay (CompPlugin  *p,
2081
 
                 CompDisplay *d)
2082
 
{
2083
 
    WALL_DISPLAY (d);
2084
 
 
2085
 
    UNWRAP (wd, d, handleEvent);
2086
 
    UNWRAP (wd, d, matchExpHandlerChanged);
2087
 
    UNWRAP (wd, d, matchPropertyChanged);
2088
 
 
2089
 
    freeScreenPrivateIndex (d, wd->screenPrivateIndex);
2090
 
    free (wd);
2091
 
}
2092
 
 
2093
 
static Bool
2094
 
wallInitScreen (CompPlugin *p,
2095
 
                CompScreen *s)
2096
 
{
2097
 
    WallScreen *ws;
2098
 
 
2099
 
    WALL_DISPLAY (s->display);
2100
 
 
2101
 
    ws = malloc (sizeof (WallScreen));
2102
 
    if (!ws)
2103
 
        return FALSE;
2104
 
 
2105
 
    ws->windowPrivateIndex = allocateWindowPrivateIndex (s);
2106
 
    if (ws->windowPrivateIndex < 0)
2107
 
    {
2108
 
        free (ws);
2109
 
        return FALSE;
2110
 
    }
2111
 
 
2112
 
    ws->timer      = 0;
2113
 
    ws->boxTimeout = 0;
2114
 
    ws->grabIndex  = 0;
2115
 
 
2116
 
    ws->moving       = FALSE;
2117
 
    ws->showPreview  = FALSE;
2118
 
    ws->focusDefault = TRUE;
2119
 
    ws->moveWindow   = None;
2120
 
    ws->grabWindow   = NULL;
2121
 
 
2122
 
    ws->transform  = NoTransformation;
2123
 
    ws->direction  = -1;
2124
 
 
2125
 
    memset (&ws->switcherContext, 0, sizeof (WallCairoContext));
2126
 
    memset (&ws->thumbContext, 0, sizeof (WallCairoContext));
2127
 
    memset (&ws->highlightContext, 0, sizeof (WallCairoContext));
2128
 
    memset (&ws->arrowContext, 0, sizeof (WallCairoContext));
2129
 
 
2130
 
    WRAP (ws, s, paintScreen, wallPaintScreen);
2131
 
    WRAP (ws, s, paintOutput, wallPaintOutput);
2132
 
    WRAP (ws, s, donePaintScreen, wallDonePaintScreen);
2133
 
    WRAP (ws, s, paintTransformedOutput, wallPaintTransformedOutput);
2134
 
    WRAP (ws, s, preparePaintScreen, wallPreparePaintScreen);
2135
 
    WRAP (ws, s, paintWindow, wallPaintWindow);
2136
 
    WRAP (ws, s, windowGrabNotify, wallWindowGrabNotify);
2137
 
    WRAP (ws, s, windowUngrabNotify, wallWindowUngrabNotify);
2138
 
    WRAP (ws, s, activateWindow, wallActivateWindow);
2139
 
 
2140
 
    s->base.privates[wd->screenPrivateIndex].ptr = ws;
2141
 
 
2142
 
    wallCreateCairoContexts (s, TRUE);
2143
 
 
2144
 
    return TRUE;
2145
 
}
2146
 
 
2147
 
static void
2148
 
wallFiniScreen (CompPlugin *p,
2149
 
                CompScreen *s)
2150
 
{
2151
 
    WALL_SCREEN (s);
2152
 
 
2153
 
    if (ws->grabIndex)
2154
 
        removeScreenGrab (s, ws->grabIndex, NULL);
2155
 
 
2156
 
    wallDestroyCairoContext (s, &ws->switcherContext);
2157
 
    wallDestroyCairoContext (s, &ws->thumbContext);
2158
 
    wallDestroyCairoContext (s, &ws->highlightContext);
2159
 
    wallDestroyCairoContext (s, &ws->arrowContext);
2160
 
 
2161
 
    UNWRAP (ws, s, paintScreen);
2162
 
    UNWRAP (ws, s, paintOutput);
2163
 
    UNWRAP (ws, s, donePaintScreen);
2164
 
    UNWRAP (ws, s, paintTransformedOutput);
2165
 
    UNWRAP (ws, s, preparePaintScreen);
2166
 
    UNWRAP (ws, s, paintWindow);
2167
 
    UNWRAP (ws, s, windowGrabNotify);
2168
 
    UNWRAP (ws, s, windowUngrabNotify);
2169
 
    UNWRAP (ws, s, activateWindow);
2170
 
    
2171
 
    freeWindowPrivateIndex (s, ws->windowPrivateIndex);
2172
 
 
2173
 
    free(ws);
2174
 
}
2175
 
 
2176
 
static CompBool
2177
 
wallInitWindow (CompPlugin *p,
2178
 
                CompWindow *w)
2179
 
{
2180
 
    WallWindow *ww;
2181
 
 
2182
 
    WALL_SCREEN (w->screen);
2183
 
 
2184
 
    ww = malloc (sizeof (WallWindow));
2185
 
    if (!ww)
2186
 
        return FALSE;
2187
 
 
2188
 
    ww->isSliding = TRUE;
2189
 
 
2190
 
    w->base.privates[ws->windowPrivateIndex].ptr = ww;
2191
 
 
2192
 
    return TRUE;
2193
 
}
2194
 
 
2195
 
static void
2196
 
wallFiniWindow (CompPlugin *p,
2197
 
                CompWindow *w)
2198
 
{
2199
 
    WALL_WINDOW (w);
2200
 
 
2201
 
    free (ww);
2202
 
}
2203
 
 
2204
 
static CompBool
2205
 
wallInitObject (CompPlugin *p,
2206
 
                CompObject *o)
2207
 
{
2208
 
    static InitPluginObjectProc dispTab[] = {
2209
 
        (InitPluginObjectProc) wallInitCore,
2210
 
        (InitPluginObjectProc) wallInitDisplay,
2211
 
        (InitPluginObjectProc) wallInitScreen,
2212
 
        (InitPluginObjectProc) wallInitWindow
2213
 
    };
2214
 
 
2215
 
    RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
2216
 
}
2217
 
 
2218
 
static void
2219
 
wallFiniObject (CompPlugin *p,
2220
 
                CompObject *o)
2221
 
{
2222
 
    static FiniPluginObjectProc dispTab[] = {
2223
 
        (FiniPluginObjectProc) wallFiniCore,
2224
 
        (FiniPluginObjectProc) wallFiniDisplay,
2225
 
        (FiniPluginObjectProc) wallFiniScreen,
2226
 
        (FiniPluginObjectProc) wallFiniWindow
2227
 
    };
2228
 
 
2229
 
    DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
2230
 
}
2231
 
 
2232
 
static Bool
2233
 
wallInit (CompPlugin *p)
2234
 
{
2235
 
    WallCorePrivateIndex = allocateCorePrivateIndex ();
2236
 
    if (WallCorePrivateIndex < 0)
2237
 
        return FALSE;
2238
 
 
2239
 
    return TRUE;
2240
 
}
2241
 
 
2242
 
static void
2243
 
wallFini (CompPlugin *p)
2244
 
{
2245
 
    freeCorePrivateIndex (WallCorePrivateIndex);
2246
 
}
2247
 
 
2248
 
CompPluginVTable wallVTable = {
2249
 
    "wall",
2250
 
    0,
2251
 
    wallInit,
2252
 
    wallFini,
2253
 
    wallInitObject,
2254
 
    wallFiniObject,
2255
 
    0,
2256
 
    0
2257
 
};
2258
 
 
2259
 
CompPluginVTable*
2260
 
getCompPluginInfo (void)
2261
 
{
2262
 
    return &wallVTable;
2263
 
}