~linaro-graphics-wg/compiz-plugins-main/oneiric-gles2

« back to all changes in this revision

Viewing changes to put/src/put.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-09-20 07:43:55 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110920074355-puzdutejjwsu3ta2
Sync - Remove Plugins

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2006 Darryll Truchan <moppsy@comcast.net>
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU General Public License
6
 
 * as published by the Free Software Foundation; either version 2
7
 
 * of the License, or (at your option) any later version.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17
 
 *
18
 
 */
19
 
 
20
 
#include "put.h"
21
 
 
22
 
#include <cmath>
23
 
 
24
 
COMPIZ_PLUGIN_20090315 (put, PutPluginVTable);
25
 
 
26
 
#define PUT_ONLY_EMPTY(type) (type >= PutEmptyBottomLeft && \
27
 
                              type <= PutEmptyTopRight)
28
 
 
29
 
#define TOP_BORDER(w) ((w)->border ().top)
30
 
#define LEFT_BORDER(w) ((w)->border ().left)
31
 
#define RIGHT_BORDER(w) ((w)->border ().right + 2 * (w)->serverGeometry ().border ())
32
 
#define BOTTOM_BORDER(w) ((w)->border ().bottom + 2 * (w)->serverGeometry ().border ())
33
 
 
34
 
#define HALF_WIDTH(w) ((w)->serverWidth () / 2 + (w)->serverGeometry ().border ())
35
 
#define HALF_HEIGHT(w) ((w)->serverHeight () / 2 + (w)->serverGeometry ().border ())
36
 
 
37
 
/*
38
 
 * Maximumize functions
39
 
 * Functions are from Maximumize plugin
40
 
 * (Author:Kristian Lyngstøl  <kristian@bohemians.org>)
41
 
 */
42
 
 
43
 
/* Generates a region containing free space (here the
44
 
 * active window counts as free space). The region argument
45
 
 * is the start-region (ie: the output dev).
46
 
 * Logic borrowed from opacify (courtesy of myself).
47
 
 */
48
 
CompRegion
49
 
PutScreen::emptyRegion (CompWindow      *window,
50
 
                        const CompRect& outputRect)
51
 
{
52
 
    CompRegion newRegion;
53
 
 
54
 
    newRegion += outputRect;
55
 
 
56
 
    foreach(CompWindow *w, screen->windows ())
57
 
    {
58
 
        if (w->id () == window->id ())
59
 
            continue;
60
 
 
61
 
        if (w->invisible () || /*w->hidden () ||*/ w->minimized ())
62
 
            continue;
63
 
 
64
 
        if (w->wmType () & CompWindowTypeDesktopMask)
65
 
            continue;
66
 
 
67
 
        if (w->wmType () & CompWindowTypeDockMask)
68
 
        {
69
 
            if (w->struts ())
70
 
            {
71
 
                CompRegion tmpRegion;
72
 
 
73
 
                tmpRegion += w->struts ()->left;
74
 
                tmpRegion += w->struts ()->right;
75
 
                tmpRegion += w->struts ()->top;
76
 
                tmpRegion += w->struts ()->bottom;
77
 
 
78
 
                newRegion -= tmpRegion;
79
 
            }
80
 
            continue;
81
 
        }
82
 
 
83
 
        newRegion -= w->serverBorderRect ();
84
 
    }
85
 
 
86
 
    return newRegion;
87
 
}
88
 
 
89
 
/* Returns true if box a has a larger area than box b.
90
 
 */
91
 
bool
92
 
PutScreen::boxCompare (const CompRect& a,
93
 
                       const CompRect& b)
94
 
{
95
 
    int areaA, areaB;
96
 
 
97
 
    areaA = a.width () * a.height ();
98
 
    areaB = b.width () * b.height ();
99
 
 
100
 
    return (areaA > areaB);
101
 
}
102
 
 
103
 
/* Extends the given box for Window w to fit as much space in region r.
104
 
 * If XFirst is true, it will first expand in the X direction,
105
 
 * then Y. This is because it gives different results.
106
 
 * PS: Decorations are icky.
107
 
 */
108
 
 
109
 
#define LEFT   0
110
 
#define RIGHT  1
111
 
#define TOP    2
112
 
#define BOTTOM 3
113
 
 
114
 
inline void
115
 
addToCorner (CompRect&    rect,
116
 
             unsigned int corner,
117
 
             const short  inc)
118
 
{
119
 
    switch (corner) {
120
 
        case LEFT:
121
 
            rect.setX (rect.x () + inc);
122
 
            break;
123
 
        case RIGHT:
124
 
            rect.setWidth (rect.width () + inc);
125
 
            break;
126
 
        case TOP:
127
 
            rect.setY (rect.y () + inc);
128
 
            break;
129
 
        case BOTTOM:
130
 
            rect.setHeight (rect.height () + inc);
131
 
            break;
132
 
    }
133
 
}
134
 
 
135
 
inline void
136
 
expandCorner (CompWindow        *w,
137
 
              CompRect&         tmp,
138
 
              const CompRegion& r,
139
 
              unsigned int      corner,
140
 
              int               direction)
141
 
{
142
 
    bool touch = false;
143
 
 
144
 
#define CHECKREC                                                               \
145
 
    r.contains (CompRect (tmp.x () - LEFT_BORDER (w),                         \
146
 
                          tmp.y () - TOP_BORDER (w),                          \
147
 
                          tmp.width () + LEFT_BORDER (w) + RIGHT_BORDER (w), \
148
 
                          tmp.height () + TOP_BORDER (w) + BOTTOM_BORDER (w)))
149
 
 
150
 
    while (CHECKREC) {
151
 
        addToCorner (tmp, corner, direction);
152
 
        touch = true;
153
 
    }
154
 
 
155
 
    if (touch)
156
 
        addToCorner (tmp, corner, -direction);
157
 
 
158
 
#undef CHECKREC
159
 
}
160
 
 
161
 
CompRect
162
 
PutScreen::extendBox (CompWindow        *w,
163
 
                      const CompRect&   tmp,
164
 
                      const CompRegion& r,
165
 
                      bool              xFirst,
166
 
                      bool              left,
167
 
                      bool              right,
168
 
                      bool              up,
169
 
                      bool              down)
170
 
{
171
 
    short int counter = 0;
172
 
    CompRect  result = tmp;
173
 
 
174
 
    while (counter < 1)
175
 
    {
176
 
        if ((xFirst && counter == 0) || (!xFirst && counter == 1))
177
 
        {
178
 
            if (left)
179
 
                expandCorner (w, result, r, LEFT, -1);
180
 
 
181
 
            if (right)
182
 
                expandCorner (w, result, r, RIGHT, 1);
183
 
 
184
 
            counter++;
185
 
        }
186
 
 
187
 
        if ((xFirst && counter == 1) || (!xFirst && counter == 0))
188
 
        {
189
 
            if (down)
190
 
                expandCorner (w, result, r, BOTTOM, 1);
191
 
 
192
 
            if (up)
193
 
                expandCorner (w, result, r, TOP, -1);
194
 
 
195
 
            counter++;
196
 
        }
197
 
    }
198
 
 
199
 
    return result;
200
 
}
201
 
 
202
 
/* Create a box for resizing in the given region
203
 
 * Also shrinks the window box in case of minor overlaps.
204
 
 * FIXME: should be somewhat cleaner.
205
 
 */
206
 
CompRect
207
 
PutScreen::findRect (CompWindow        *w,
208
 
                     const CompRegion& r,
209
 
                     bool              left,
210
 
                     bool              right,
211
 
                     bool              up,
212
 
                     bool              down)
213
 
{
214
 
    CompRect windowBox, ansA, ansB, orig;
215
 
 
216
 
    windowBox.setGeometry (w->serverX (), w->serverY (),
217
 
                           w->serverWidth (), w->serverHeight ());
218
 
 
219
 
    orig = windowBox;
220
 
 
221
 
    ansA = extendBox (w, windowBox, r, true, left, right, up, down);
222
 
    ansB = extendBox (w, windowBox, r, false, left, right, up, down);
223
 
 
224
 
    if (boxCompare (orig, ansA) && boxCompare (orig, ansB))
225
 
        return orig;
226
 
 
227
 
    if (boxCompare (ansA, ansB))
228
 
        return ansA;
229
 
    else
230
 
        return ansB;
231
 
 
232
 
}
233
 
 
234
 
/* Calls out to compute the resize */
235
 
unsigned int
236
 
PutScreen::computeResize (CompWindow     *w,
237
 
                          XWindowChanges *xwc,
238
 
                          bool           left,
239
 
                          bool           right,
240
 
                          bool           up,
241
 
                          bool           down)
242
 
{
243
 
    unsigned int mask = 0;
244
 
    CompRect     box;
245
 
    CompRegion   region;
246
 
    int          outputDevice = w->outputDevice ();
247
 
 
248
 
    region = emptyRegion (w, screen->outputDevs ()[outputDevice]);
249
 
    box    = findRect (w, region, left, right, up, down);
250
 
 
251
 
    if (box.x () != w->serverX ())
252
 
        mask |= CWX;
253
 
 
254
 
    if (box.y () != w->serverY ())
255
 
        mask |= CWY;
256
 
 
257
 
    if (box.width () != w->serverWidth ())
258
 
        mask |= CWWidth;
259
 
 
260
 
    if (box.height () != w->height ())
261
 
        mask |= CWHeight;
262
 
 
263
 
    xwc->x = box.x ();
264
 
    xwc->y = box.y ();
265
 
    xwc->width = box.width ();
266
 
    xwc->height = box.height ();
267
 
 
268
 
    return mask;
269
 
}
270
 
 
271
 
/*
272
 
 * End of Maximumize functions
273
 
 */
274
 
 
275
 
/*
276
 
 * calculate the velocity for the moving window
277
 
 */
278
 
int
279
 
PutScreen::adjustVelocity (CompWindow *w)
280
 
{
281
 
    float dx, dy, adjust, amount;
282
 
    float x1, y1;
283
 
 
284
 
    PUT_WINDOW (w);
285
 
 
286
 
    x1 = pw->targetX;
287
 
    y1 = pw->targetY;
288
 
 
289
 
    dx = x1 - (w->x () + pw->tx);
290
 
    dy = y1 - (w->y () + pw->ty);
291
 
 
292
 
    adjust = dx * 0.15f;
293
 
    amount = fabs (dx) * 1.5;
294
 
    if (amount < 0.5f)
295
 
        amount = 0.5f;
296
 
    else if (amount > 5.0f)
297
 
        amount = 5.0f;
298
 
 
299
 
    pw->xVelocity = (amount * pw->xVelocity + adjust) / (amount + 1.0f);
300
 
 
301
 
    adjust = dy * 0.15f;
302
 
    amount = fabs (dy) * 1.5f;
303
 
    if (amount < 0.5f)
304
 
        amount = 0.5f;
305
 
    else if (amount > 5.0f)
306
 
        amount = 5.0f;
307
 
 
308
 
    pw->yVelocity = (amount * pw->yVelocity + adjust) / (amount + 1.0f);
309
 
 
310
 
    if (fabs (dx) < 0.1f && fabs (pw->xVelocity) < 0.2f &&
311
 
        fabs (dy) < 0.1f && fabs (pw->yVelocity) < 0.2f)
312
 
    {
313
 
        /* animation done */
314
 
        pw->xVelocity = pw->yVelocity = 0.0f;
315
 
 
316
 
        pw->tx = x1 - w->x ();
317
 
        pw->ty = y1 - w->y ();
318
 
        return 0;
319
 
    }
320
 
    return 1;
321
 
}
322
 
 
323
 
void
324
 
PutScreen::finishWindowMovement (CompWindow *w)
325
 
{
326
 
    PUT_WINDOW (w);
327
 
 
328
 
    w->move (pw->targetX - w->x (),
329
 
             pw->targetY - w->y (),
330
 
             true);
331
 
    w->syncPosition ();
332
 
 
333
 
    if (w->state () & (MAXIMIZE_STATE | CompWindowStateFullscreenMask))
334
 
        w->updateAttributes (CompStackingUpdateModeNone);
335
 
}
336
 
 
337
 
unsigned int
338
 
PutScreen::getOutputForWindow (CompWindow *w)
339
 
{
340
 
    PUT_WINDOW (w);
341
 
 
342
 
    if (!pw->adjust)
343
 
        return w->outputDevice ();
344
 
 
345
 
    /* outputDeviceForWindow uses the server geometry,
346
 
       so specialcase a running animation, which didn't
347
 
       apply the server geometry yet */
348
 
    CompWindow::Geometry geom;
349
 
 
350
 
    geom.set (w->x () + pw->tx, w->y () + pw->ty,
351
 
              w->width (), w->height (), w->geometry ().border ());
352
 
 
353
 
    return screen->outputDeviceForGeometry (geom);
354
 
}
355
 
 
356
 
CompPoint
357
 
PutScreen::getDistance (CompWindow         *w,
358
 
                        PutType            type,
359
 
                        CompOption::Vector &option)
360
 
{
361
 
    CompScreen *s = screen;
362
 
    int        x, y, dx, dy, posX, posY;
363
 
    int        viewport, output;
364
 
    CompRect   workArea;
365
 
    CompPoint  result;
366
 
 
367
 
    PUT_SCREEN (s);
368
 
    PUT_WINDOW (w);
369
 
 
370
 
    posX = CompOption::getIntOptionNamed (option,"x", 0);
371
 
    posY = CompOption::getIntOptionNamed (option,"y", 0);
372
 
 
373
 
    /* get the output device number from the options list */
374
 
    output = CompOption::getIntOptionNamed (option,"output", -1);
375
 
    /* no output in options list -> use the current output */
376
 
    if (output == -1)
377
 
    {
378
 
        /* no output given, so use the current output if
379
 
           this wasn't a double tap */
380
 
 
381
 
        if (ps->lastType != type || ps->lastWindow != w->id ())
382
 
            output = getOutputForWindow (w);
383
 
    }
384
 
    else
385
 
    {
386
 
        /* make sure the output number is not out of bounds */
387
 
        output = MIN (output,  (int) s->outputDevs ().size () - 1);
388
 
    }
389
 
 
390
 
    if (output == -1)
391
 
    {
392
 
        /* user double-tapped the key, so use the screen work area */
393
 
        workArea = s->workArea ();
394
 
        /* set the type to unknown to have a toggle-type behaviour
395
 
           between 'use output work area' and 'use screen work area' */
396
 
        ps->lastType = PutUnknown;
397
 
    }
398
 
    else
399
 
    {
400
 
        /* single tap or output provided via options list,
401
 
           use the output work area */
402
 
        workArea = s->getWorkareaForOutput (output);
403
 
        ps->lastType = type;
404
 
    }
405
 
 
406
 
    if (PUT_ONLY_EMPTY (type))
407
 
    {
408
 
        unsigned int   mask;
409
 
        XWindowChanges xwc;
410
 
        bool           left, right, up, down;
411
 
 
412
 
        left = right = up = down = false;
413
 
 
414
 
        switch (type) {
415
 
            case PutEmptyBottomLeft:
416
 
                left = down = true;
417
 
                break;
418
 
            case PutEmptyBottom:
419
 
                down = true;
420
 
                break;
421
 
            case PutEmptyBottomRight:
422
 
                right = down = true;
423
 
                break;
424
 
            case PutEmptyLeft:
425
 
                left = true;
426
 
                break;
427
 
            case PutEmptyCenter:
428
 
                left = right = up = down = true;
429
 
                break;
430
 
            case PutEmptyRight:
431
 
                right = true;
432
 
                break;
433
 
            case PutEmptyTopLeft:
434
 
                left = up = true;
435
 
                break;
436
 
            case PutEmptyTop:
437
 
                up = true;
438
 
                break;
439
 
            case PutEmptyTopRight:
440
 
                right = up = true;
441
 
                break;
442
 
            default:
443
 
                break;
444
 
        }
445
 
 
446
 
        mask = computeResize (w, &xwc, left,right,up,down);
447
 
        if (mask)
448
 
        {
449
 
            if (w->constrainNewWindowSize (xwc.width, xwc.height,
450
 
                                           &xwc.width, &xwc.height))
451
 
                mask |= CWWidth | CWHeight;
452
 
        }
453
 
 
454
 
        workArea.setGeometry (xwc.x, xwc.y, xwc.width, xwc.height);
455
 
    }
456
 
    /* the windows location */
457
 
    x = w->x () + pw->tx;
458
 
    y = w->y () + pw->ty;
459
 
 
460
 
    switch (type) {
461
 
    case PutEmptyCenter:
462
 
    case PutCenter:
463
 
        /* center of the screen */
464
 
        dx = (workArea.width () / 2) - HALF_WIDTH (w) -
465
 
              w->serverGeometry ().border () - (x - workArea.x ());
466
 
        dy = (workArea.height () / 2) - HALF_HEIGHT (w) -
467
 
              w->serverGeometry ().border () - (y - workArea.y ());
468
 
        break;
469
 
    case PutLeft:
470
 
        /* center of the left edge */
471
 
        dx = -(x - workArea.x ()) + LEFT_BORDER (w) + ps->optionGetPadLeft ();
472
 
        dy = (workArea.height () / 2) - HALF_HEIGHT (w) -
473
 
             (y - workArea.y ());
474
 
        break;
475
 
    case PutEmptyLeft:
476
 
        /* center of the left edge */
477
 
        workArea.setX (workArea.x () - LEFT_BORDER (w));
478
 
        dx = -(x - workArea.x ()) + LEFT_BORDER (w) + ps->optionGetPadLeft ();
479
 
        dy = (workArea.height () / 2) - HALF_HEIGHT (w) -
480
 
             (y - workArea.y ());
481
 
        break;
482
 
    case PutTopLeft:
483
 
        /* top left corner */
484
 
        dx = -(x - workArea.x ()) + LEFT_BORDER (w) + ps->optionGetPadLeft ();
485
 
        dy = -(y - workArea.y ()) + TOP_BORDER (w) + ps->optionGetPadTop ();
486
 
        break;
487
 
    case PutEmptyTopLeft:
488
 
        /* top left corner */
489
 
        workArea.setX (workArea.x () - LEFT_BORDER (w));
490
 
        workArea.setY (workArea.y () - TOP_BORDER (w));
491
 
        dx = -(x - workArea.x ()) + LEFT_BORDER (w) + ps->optionGetPadLeft ();
492
 
        dy = -(y - workArea.y ()) + TOP_BORDER (w) + ps->optionGetPadTop ();
493
 
        break;
494
 
    case PutTop:
495
 
        /* center of top edge */
496
 
        dx = (workArea.width () / 2) - HALF_WIDTH (w) -
497
 
             (x - workArea.x ());
498
 
        dy = -(y - workArea.y ()) + TOP_BORDER (w) + ps->optionGetPadTop ();
499
 
        break;
500
 
    case PutEmptyTop:
501
 
        /* center of top edge */
502
 
        workArea.setY (workArea.x () - TOP_BORDER (w));
503
 
        dx = (workArea.width () / 2) - HALF_WIDTH (w) -
504
 
             (x - workArea.x ());
505
 
        dy = -(y - workArea.y ()) + TOP_BORDER (w) + ps->optionGetPadTop ();
506
 
        break;
507
 
    case PutTopRight:
508
 
        /* top right corner */
509
 
        dx = workArea.width () - w->serverWidth () - (x - workArea.x ()) -
510
 
             RIGHT_BORDER (w) - ps->optionGetPadRight ();
511
 
        dy = -(y - workArea.y ()) + TOP_BORDER (w) + ps->optionGetPadTop ();
512
 
        break;
513
 
    case PutEmptyTopRight:
514
 
        /* top right corner */
515
 
        workArea.setX (workArea.x () + RIGHT_BORDER (w));
516
 
        workArea.setY (workArea.y () - TOP_BORDER (w));
517
 
        dx = workArea.width () - w->serverWidth () - (x - workArea.x ()) -
518
 
             RIGHT_BORDER (w) - ps->optionGetPadRight ();
519
 
        dy = -(y - workArea.y ()) + TOP_BORDER (w) + ps->optionGetPadTop ();
520
 
        break;
521
 
    case PutRight:
522
 
        /* center of right edge */
523
 
        dx = workArea.width () - w->serverWidth () - (x - workArea.x ()) -
524
 
             RIGHT_BORDER (w) - ps->optionGetPadRight ();
525
 
        dy = (workArea.height () / 2) - HALF_HEIGHT (w) -
526
 
             (y - workArea.y ());
527
 
        break;
528
 
    case PutEmptyRight:
529
 
        /* center of right edge */
530
 
        workArea.setX (workArea.x () + RIGHT_BORDER (w));
531
 
        dx = workArea.width () - w->serverWidth () - (x - workArea.x ()) -
532
 
             RIGHT_BORDER (w) - ps->optionGetPadRight ();
533
 
        dy = (workArea.height () / 2) - HALF_HEIGHT (w) -
534
 
             (y - workArea.y ());
535
 
        break;
536
 
    case PutBottomRight:
537
 
        /* bottom right corner */
538
 
        dx = workArea.width () - w->serverWidth () - (x - workArea.x ()) -
539
 
            RIGHT_BORDER (w) - ps->optionGetPadRight ();
540
 
        dy = workArea.height () - w->serverHeight () - (y - workArea.y ()) -
541
 
            BOTTOM_BORDER (w) - ps->optionGetPadBottom ();
542
 
        break;
543
 
    case PutEmptyBottomRight:
544
 
        /* bottom right corner */
545
 
        workArea.setX (workArea.x () + RIGHT_BORDER (w));
546
 
        workArea.setY (workArea.y () + BOTTOM_BORDER (w));
547
 
        dx = workArea.width () - w->serverWidth () - (x - workArea.x ()) -
548
 
             RIGHT_BORDER (w) - ps->optionGetPadRight ();
549
 
        dy = workArea.height () - w->serverHeight () - (y - workArea.y ()) -
550
 
             BOTTOM_BORDER (w)- ps->optionGetPadBottom ();
551
 
        break;
552
 
    case PutBottom:
553
 
        /* center of bottom edge */
554
 
        dx = (workArea.width () / 2) - HALF_WIDTH (w) -
555
 
             (x - workArea.x ());
556
 
        dy = workArea.height () - w->serverHeight () - (y - workArea.y ()) -
557
 
             BOTTOM_BORDER (w) - ps->optionGetPadBottom ();
558
 
        break;
559
 
    case PutEmptyBottom:
560
 
        /* center of bottom edge */
561
 
        workArea.setY (workArea.y () + BOTTOM_BORDER (w));
562
 
        dx = (workArea.width () / 2) - HALF_WIDTH (w) -
563
 
             (x - workArea.x ());
564
 
        dy = workArea.height () - w->serverHeight () - (y - workArea.y ()) -
565
 
             BOTTOM_BORDER (w) - ps->optionGetPadBottom ();
566
 
        break;
567
 
    case PutBottomLeft:
568
 
        /* bottom left corner */
569
 
        dx = -(x - workArea.x ()) + LEFT_BORDER (w) + ps->optionGetPadLeft ();
570
 
        dy = workArea.height () - w->serverHeight () - (y - workArea.y ()) -
571
 
             BOTTOM_BORDER (w) - ps->optionGetPadBottom ();
572
 
        break;
573
 
    case PutEmptyBottomLeft:
574
 
        /* bottom left corner */
575
 
        workArea.setX (workArea.x () - LEFT_BORDER (w));
576
 
        workArea.setY (workArea.y () + BOTTOM_BORDER (w));
577
 
        dx = -(x - workArea.x ()) + LEFT_BORDER (w) + ps->optionGetPadLeft ();
578
 
        dy = workArea.height () - w->serverHeight () - (y - workArea.y ()) -
579
 
             BOTTOM_BORDER (w) - ps->optionGetPadBottom ();
580
 
        break;
581
 
    case PutRestore:
582
 
        /* back to last position */
583
 
        dx = pw->lastX - x;
584
 
        dy = pw->lastY - y;
585
 
        break;
586
 
    case PutViewport:
587
 
        {
588
 
            int vpX, vpY, hDirection, vDirection;
589
 
 
590
 
            /* get the viewport to move to from the options list */
591
 
            viewport = CompOption::getIntOptionNamed (option, "viewport", -1);
592
 
 
593
 
            /* if viewport wasn't supplied, bail out */
594
 
            if (viewport < 0)
595
 
                return result;
596
 
 
597
 
            /* split 1D viewport value into 2D x and y viewport */
598
 
            vpX = viewport % s->vpSize ().width ();
599
 
            vpY = viewport / s->vpSize ().width ();
600
 
            if (vpY > (int) s->vpSize ().height ())
601
 
                vpY = s->vpSize ().height () - 1;
602
 
 
603
 
            /* take the shortest horizontal path to the destination viewport */
604
 
            hDirection = (vpX - s->vp ().x ());
605
 
            if (hDirection > (int) s->vpSize ().width () / 2)
606
 
                hDirection = (hDirection - s->vpSize ().width ());
607
 
            else if (hDirection < - ((int) s->vpSize ().width ()) / 2)
608
 
                hDirection = (hDirection + s->vpSize ().width ());
609
 
 
610
 
            /* we need to do this for the vertical destination viewport too */
611
 
            vDirection = (vpY - s->vp ().y ());
612
 
            if (vDirection > (int) s->vpSize ().height () / 2)
613
 
                vDirection = (vDirection - s->vpSize ().height ());
614
 
            else if (vDirection < -((int) s->vpSize ().height ()) / 2)
615
 
                vDirection = (vDirection + s->vpSize ().height ());
616
 
 
617
 
            dx = s->width () * hDirection;
618
 
            dy = s->height () * vDirection;
619
 
            break;
620
 
        }
621
 
    case PutViewportLeft:
622
 
        /* move to the viewport on the left */
623
 
        dx = (s->vp ().x () >= 1) ? -s->width () : 0;
624
 
        dy = 0;
625
 
        break;
626
 
    case PutViewportRight:
627
 
        /* move to the viewport on the right */
628
 
        dx = (s->vp ().x () < s->vpSize ().width ()-1) ? s->width () : 0;
629
 
        dy = 0;
630
 
        break;
631
 
    case PutViewportUp:
632
 
        /* move to the viewport above */
633
 
        dx = 0;
634
 
        dy = (s->vp ().y () >= 1) ? -s->height () : 0;
635
 
        break;
636
 
    case PutViewportDown:
637
 
        /* move to the viewport below */
638
 
        dx = 0;
639
 
        dy = (s->vp ().y () < s->vpSize ().height ()-1) ? s->height () : 0;
640
 
        break;
641
 
    case PutNextOutput:
642
 
        {
643
 
            int        outputNum, currentNum;
644
 
            int        nOutputDev = s->outputDevs ().size ();
645
 
            CompOutput *currentOutput, *newOutput;
646
 
 
647
 
            if (nOutputDev < 2)
648
 
                return result;
649
 
 
650
 
            currentNum = getOutputForWindow (w);
651
 
            outputNum  = (currentNum + 1) % nOutputDev;
652
 
            outputNum  = CompOption::getIntOptionNamed (option,"output",
653
 
                                                        outputNum);
654
 
 
655
 
            if (outputNum >= nOutputDev)
656
 
                return result;
657
 
 
658
 
            currentOutput = &s->outputDevs ().at(currentNum);
659
 
            newOutput     = &s->outputDevs ().at(outputNum);
660
 
 
661
 
            /* move by the distance of the output center points */
662
 
            dx = (newOutput->x1 () + newOutput->width () / 2) -
663
 
                 (currentOutput->x1 () + currentOutput->width () / 2);
664
 
            dy = (newOutput->y1 () + newOutput->height () / 2) -
665
 
                 (currentOutput->y1 () + currentOutput->height () / 2);
666
 
 
667
 
            /* update work area for new output */
668
 
            workArea = newOutput->workArea ();
669
 
        }
670
 
        break;
671
 
    case PutAbsolute:
672
 
        /* move the window to an exact position */
673
 
        if (posX < 0)
674
 
            /* account for a specified negative position,
675
 
               like geometry without (-0) */
676
 
            dx = posX + s->width () - w->serverWidth () - x - RIGHT_BORDER (w);
677
 
        else
678
 
            dx = posX - x + LEFT_BORDER (w);
679
 
 
680
 
        if (posY < 0)
681
 
            /* account for a specified negative position,
682
 
               like geometry without (-0) */
683
 
            dy = posY + s->height () - w->height () - y - BOTTOM_BORDER (w);
684
 
        else
685
 
            dy = posY - y + TOP_BORDER (w);
686
 
        break;
687
 
    case PutRelative:
688
 
        /* move window by offset */
689
 
        dx = posX;
690
 
        dy = posY;
691
 
        break;
692
 
    case PutPointer:
693
 
        {
694
 
            /* move the window to the pointers position
695
 
             * using the current quad of the screen to determine
696
 
             * which corner to move to the pointer
697
 
             */
698
 
            int          rx, ry;
699
 
            Window       root, child;
700
 
            int          winX, winY;
701
 
            unsigned int pMask;
702
 
 
703
 
            /* get the pointers position from the X server */
704
 
            if (XQueryPointer (s->dpy (), w->id (), &root, &child,
705
 
                               &rx, &ry, &winX, &winY, &pMask))
706
 
            {
707
 
                if (ps->optionGetWindowCenter ())
708
 
                {
709
 
                    /* window center */
710
 
                    dx = rx - HALF_WIDTH (w) - x;
711
 
                    dy = ry - HALF_HEIGHT (w) - y;
712
 
                }
713
 
                else if (rx < (int) s->workArea ().width () / 2 &&
714
 
                         ry < (int) s->workArea ().height () / 2)
715
 
                {
716
 
                    /* top left quad */
717
 
                    dx = rx - x + LEFT_BORDER (w);
718
 
                    dy = ry - y + TOP_BORDER (w);
719
 
                }
720
 
                else if (rx < (int) s->workArea ().width () / 2 &&
721
 
                         ry >= (int) s->workArea ().height () / 2)
722
 
                {
723
 
                    /* bottom left quad */
724
 
                    dx = rx - x + LEFT_BORDER (w);
725
 
                    dy = ry - w->height () - y - BOTTOM_BORDER (w);
726
 
                }
727
 
                else if (rx >= (int) s->workArea ().width () / 2 &&
728
 
                         ry < (int) s->workArea ().height () / 2)
729
 
                {
730
 
                    /* top right quad */
731
 
                    dx = rx - w->width () - x - RIGHT_BORDER (w);
732
 
                    dy = ry - y + TOP_BORDER (w);
733
 
                }
734
 
                else
735
 
                {
736
 
                    /* bottom right quad */
737
 
                    dx = rx - w->width () - x - RIGHT_BORDER (w);
738
 
                    dy = ry - w->height () - y - BOTTOM_BORDER (w);
739
 
                }
740
 
            }
741
 
            else
742
 
            {
743
 
                dx = dy = 0;
744
 
            }
745
 
        }
746
 
        break;
747
 
    default:
748
 
        /* if an unknown type is specified, do nothing */
749
 
        dx = dy = 0;
750
 
        break;
751
 
    }
752
 
 
753
 
    if ((dx || dy) && ps->optionGetAvoidOffscreen () &&
754
 
        !(w->type () & CompWindowTypeFullscreenMask))
755
 
    {
756
 
        /* avoids window borders offscreen, but allow full
757
 
           viewport movements */
758
 
        int               inDx, dxBefore;
759
 
        int               inDy, dyBefore;
760
 
        CompWindowExtents extents, area;
761
 
 
762
 
        inDx = dxBefore = dx % s->width ();
763
 
        inDy = dyBefore = dy % s->height ();
764
 
 
765
 
        extents.left   = x + inDx - LEFT_BORDER (w);
766
 
        extents.top    = y + inDy - TOP_BORDER (w);
767
 
        extents.right  = x + inDx + w->serverWidth () + RIGHT_BORDER (w);
768
 
        extents.bottom = y + inDy + w->serverHeight () + BOTTOM_BORDER (w);
769
 
 
770
 
        area.left   = workArea.left () + ps->optionGetPadLeft ();
771
 
        area.top    = workArea.top () + ps->optionGetPadTop ();
772
 
        area.right  = workArea.right () - ps->optionGetPadRight ();
773
 
        area.bottom = workArea.bottom () - ps->optionGetPadBottom ();
774
 
 
775
 
        if (extents.left < area.left)
776
 
        {
777
 
            inDx += area.left - extents.left;
778
 
        }
779
 
        else if (w->serverWidth () <= workArea.width () &&
780
 
                 extents.right > area.right)
781
 
        {
782
 
            inDx += area.right - extents.right;
783
 
        }
784
 
 
785
 
        if (extents.top < area.top)
786
 
        {
787
 
            inDy += area.top - extents.top;
788
 
        }
789
 
        else if (w->serverHeight () <= workArea.height () &&
790
 
                 extents.bottom > area.bottom)
791
 
        {
792
 
            inDy += area.bottom - extents.bottom;
793
 
        }
794
 
 
795
 
        /* apply the change */
796
 
        dx += inDx - dxBefore;
797
 
        dy += inDy - dyBefore;
798
 
    }
799
 
 
800
 
    result.set (dx, dy);
801
 
 
802
 
    return result;
803
 
}
804
 
 
805
 
void
806
 
PutScreen::preparePaint (int ms)
807
 
{
808
 
 
809
 
    PUT_SCREEN (screen);
810
 
 
811
 
    if (ps->moreAdjust && ps->grabIndex)
812
 
    {
813
 
        int        steps;
814
 
        float      amount, chunk;
815
 
 
816
 
        amount = ms * 0.025f * ps->optionGetSpeed ();
817
 
        steps = amount / (0.5f * ps->optionGetTimestep ());
818
 
        if (!steps)
819
 
            steps = 1;
820
 
        chunk = amount / (float)steps;
821
 
 
822
 
        while (steps--)
823
 
        {
824
 
            Window endAnimationWindow = None;
825
 
 
826
 
            ps->moreAdjust = 0;
827
 
            foreach(CompWindow *w, screen->windows ())
828
 
            {
829
 
                PUT_WINDOW (w);
830
 
 
831
 
                if (pw->adjust)
832
 
                {
833
 
                    pw->adjust = adjustVelocity (w);
834
 
                    ps->moreAdjust |= pw->adjust;
835
 
 
836
 
                    pw->tx += pw->xVelocity * chunk;
837
 
                    pw->ty += pw->yVelocity * chunk;
838
 
 
839
 
                    if (!pw->adjust)
840
 
                    {
841
 
                        /* animation done */
842
 
                        finishWindowMovement (w);
843
 
 
844
 
                        if (w->id  () == screen->activeWindow ())
845
 
                            endAnimationWindow = w->id ();
846
 
 
847
 
                        pw->tx = pw->ty = 0;
848
 
                    }
849
 
                }
850
 
            }
851
 
            if (!ps->moreAdjust)
852
 
            {
853
 
                /* unfocus moved window if enabled */
854
 
                if (ps->optionGetUnfocusWindow ())
855
 
                    screen->focusDefaultWindow ();
856
 
                else if (endAnimationWindow)
857
 
                    screen->sendWindowActivationRequest (endAnimationWindow);
858
 
                break;
859
 
            }
860
 
        }
861
 
    }
862
 
 
863
 
    cScreen->preparePaint (ms);
864
 
}
865
 
 
866
 
/* This is the guts of the paint function. You can transform the way the
867
 
 * entire output is painted or you can just draw things on screen with openGL.
868
 
 * The unsigned int here is a mask for painting the screen, see opengl/opengl.h
869
 
 * on how you can change it
870
 
 */
871
 
 
872
 
bool
873
 
PutScreen::glPaintOutput (const GLScreenPaintAttrib     &attrib,
874
 
                          const GLMatrix                &transform,
875
 
                          const CompRegion              &region,
876
 
                          CompOutput                    *output,
877
 
                          unsigned int                  mask)
878
 
{
879
 
    bool status;
880
 
 
881
 
    PUT_SCREEN (screen);
882
 
 
883
 
    if (ps->moreAdjust)
884
 
        mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
885
 
 
886
 
    status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
887
 
 
888
 
    return status;
889
 
}
890
 
 
891
 
void
892
 
PutScreen::donePaint ()
893
 
{
894
 
    PUT_SCREEN (screen);
895
 
 
896
 
    if (ps->moreAdjust && ps->grabIndex)
897
 
    {
898
 
        cScreen->damageScreen (); // FIXME
899
 
    }
900
 
    else
901
 
    {
902
 
        if (ps->grabIndex)
903
 
        {
904
 
            /* release the screen grab */
905
 
            screen->removeGrab (ps->grabIndex, NULL);
906
 
            ps->grabIndex = 0;
907
 
        }
908
 
    }
909
 
 
910
 
    cScreen->donePaint ();
911
 
}
912
 
 
913
 
/* This is our event handler. It directly hooks into the screen's X Event handler and allows us to handle
914
 
 * our raw X Events
915
 
 */
916
 
 
917
 
void
918
 
PutScreen::handleEvent (XEvent *event)
919
 
{
920
 
    switch (event->type) {
921
 
    /* handle client events */
922
 
    case ClientMessage:
923
 
        /* accept the custom atom for putting windows */
924
 
        if (event->xclient.message_type == compizPutWindowAtom)
925
 
        {
926
 
            CompWindow *w;
927
 
 
928
 
            w = screen->findWindow (event->xclient.window);
929
 
            if (w)
930
 
            {
931
 
                /*
932
 
                 * get the values from the xclientmessage event and populate
933
 
                 * the options for put initiate
934
 
                 *
935
 
                 * the format is 32
936
 
                 * and the data is
937
 
                 * l[0] = x position - unused (for future PutExact)
938
 
                 * l[1] = y position - unused (for future PutExact)
939
 
                 * l[2] = viewport number
940
 
                 * l[3] = put type, int value from enum
941
 
                 * l[4] = output number
942
 
                 */
943
 
                CompOption::Vector opt (5);
944
 
 
945
 
                CompOption::Value value0 = (int) event->xclient.window;
946
 
                opt.push_back (CompOption ( "window",CompOption::TypeInt));
947
 
                opt[0].set (value0);
948
 
 
949
 
                CompOption::Value value1 = (int) event->xclient.data.l[0];
950
 
                opt.push_back (CompOption ( "x",CompOption::TypeInt));
951
 
                opt[1].set (value1);
952
 
 
953
 
                CompOption::Value value2 = (int) event->xclient.data.l[1];
954
 
                opt.push_back (CompOption ( "y",CompOption::TypeInt));
955
 
                opt[2].set (value2);
956
 
 
957
 
                CompOption::Value value3 = (int) event->xclient.data.l[2];
958
 
                opt.push_back (CompOption ( "viewport",CompOption::TypeInt));
959
 
                opt[3].set (value3);
960
 
 
961
 
                CompOption::Value value4 = (int) event->xclient.data.l[4];
962
 
                opt.push_back (CompOption ( "output",CompOption::TypeInt));
963
 
                opt[4].set (value4);
964
 
 
965
 
                initiateCommon (NULL, 0, opt,
966
 
                                (PutType) event->xclient.data.l[3]);
967
 
            }
968
 
        }
969
 
        break;
970
 
    default:
971
 
        break;
972
 
    }
973
 
    screen->handleEvent (event);
974
 
}
975
 
 
976
 
/* This gets called whenever the window needs to be repainted.
977
 
 * WindowPaintAttrib gives you some attributes like brightness/saturation etc
978
 
 * to play around with. GLMatrix is the window's transformation matrix. The
979
 
 * unsigned int is the mask, have a look at opengl.h on what you can do
980
 
 * with it */
981
 
bool
982
 
PutWindow::glPaint (const GLWindowPaintAttrib &attrib,
983
 
                    const GLMatrix            &transform,
984
 
                    const CompRegion          &region,
985
 
                    unsigned int              mask)
986
 
{
987
 
    GLMatrix wTransform (transform);
988
 
 
989
 
    if (adjust)
990
 
    {
991
 
        wTransform.translate (tx, ty, 0.0f);
992
 
        mask |= PAINT_WINDOW_TRANSFORMED_MASK;
993
 
    }
994
 
 
995
 
    return gWindow->glPaint (attrib, wTransform, region, mask);
996
 
}
997
 
 
998
 
/*
999
 
 * initiate action callback
1000
 
 */
1001
 
bool
1002
 
PutScreen::initiateCommon (CompAction         *action,
1003
 
                           CompAction::State  state,
1004
 
                           CompOption::Vector &option,
1005
 
                           PutType            type)
1006
 
{
1007
 
    CompWindow *w;
1008
 
    Window     xid;
1009
 
 
1010
 
    xid = CompOption::getIntOptionNamed (option,  "window", 0);
1011
 
    if (!xid)
1012
 
        xid = screen->activeWindow ();
1013
 
 
1014
 
    w = screen->findWindow (xid);
1015
 
    if (w)
1016
 
    {
1017
 
        CompScreen *s = screen;
1018
 
        CompPoint  delta;
1019
 
 
1020
 
        /* we don't want to do anything with override redirect windows */
1021
 
        if (w->overrideRedirect ())
1022
 
            return false;
1023
 
 
1024
 
        /* we don't want to be moving the desktop and docks */
1025
 
        if (w->type () & (CompWindowTypeDesktopMask |
1026
 
                          CompWindowTypeDockMask))
1027
 
            return false;
1028
 
 
1029
 
        /* don't move windows without move action */
1030
 
        if (!(w->actions () & CompWindowActionMoveMask))
1031
 
            return false;
1032
 
 
1033
 
        /* only allow movement of fullscreen windows to next output */
1034
 
        if (type != PutNextOutput &&
1035
 
            (w->type () & CompWindowTypeFullscreenMask))
1036
 
        {
1037
 
            return false;
1038
 
        }
1039
 
 
1040
 
        /*
1041
 
         * handle the put types
1042
 
         */
1043
 
        delta = getDistance (w, type, option);
1044
 
 
1045
 
        /* don't do anything if there is nothing to do */
1046
 
        if (!delta.x () && !delta.y ())
1047
 
            return true;
1048
 
 
1049
 
        if (!grabIndex)
1050
 
        {
1051
 
            /* this will keep put from working while something
1052
 
               else has a screen grab */
1053
 
            if (s->otherGrabExist ("put", NULL))
1054
 
                return false;
1055
 
 
1056
 
            /* we are ok, so grab the screen */
1057
 
            grabIndex = s->pushGrab (s->invisibleCursor (), "put");
1058
 
        }
1059
 
 
1060
 
        if (grabIndex)
1061
 
        {
1062
 
            PUT_WINDOW (w);
1063
 
 
1064
 
            lastWindow = w->id ();
1065
 
 
1066
 
            /* save the windows position in the saveMask
1067
 
             * this is used when unmaximizing the window
1068
 
             */
1069
 
            if (w->saveMask () & CWX)
1070
 
                w->saveWc ().x += delta.x ();
1071
 
 
1072
 
            if (w->saveMask () & CWY)
1073
 
                w->saveWc ().y += delta.y ();
1074
 
 
1075
 
            /* Make sure everyting starts out at the windows
1076
 
               current position */
1077
 
            pw->lastX = w->x () + pw->tx;
1078
 
            pw->lastY = w->y () + pw->ty;
1079
 
 
1080
 
            pw->targetX = pw->lastX + delta.x ();
1081
 
            pw->targetY = pw->lastY + delta.y ();
1082
 
 
1083
 
            /* mark for animation */
1084
 
            pw->adjust = true;
1085
 
            moreAdjust = true;
1086
 
 
1087
 
            /* cause repainting */
1088
 
            pw->cWindow->addDamage ();
1089
 
        }
1090
 
    }
1091
 
 
1092
 
    /* tell event.c handleEvent to not call XAllowEvents */
1093
 
    return false;
1094
 
}
1095
 
 
1096
 
PutType
1097
 
PutScreen::typeFromString (const CompString &type)
1098
 
{
1099
 
    if (type == "absolute")
1100
 
        return PutAbsolute;
1101
 
    else if (type == "relative")
1102
 
        return PutRelative;
1103
 
    else if (type == "pointer")
1104
 
        return PutPointer;
1105
 
    else if (type == "viewport")
1106
 
        return (PutType) PutViewport;
1107
 
    else if (type == "viewportleft")
1108
 
        return PutViewportLeft;
1109
 
    else if (type == "viewportright")
1110
 
        return PutViewportRight;
1111
 
    else if (type == "viewportup")
1112
 
        return PutViewportUp;
1113
 
    else if (type == "viewportdown")
1114
 
        return PutViewportDown;
1115
 
    else if (type == "nextoutput")
1116
 
        return PutNextOutput;
1117
 
    else if (type == "restore")
1118
 
        return PutRestore;
1119
 
    else if (type == "bottomleft")
1120
 
        return PutBottomLeft;
1121
 
    else if (type == "emptybottomleft")
1122
 
        return PutEmptyBottomLeft;
1123
 
    else if (type == "left")
1124
 
        return PutLeft;
1125
 
    else if (type == "emptyleft")
1126
 
        return PutEmptyLeft;
1127
 
    else if (type == "topleft")
1128
 
        return PutTopLeft;
1129
 
    else if (type == "emptytopleft")
1130
 
        return PutEmptyTopLeft;
1131
 
    else if (type == "top")
1132
 
        return PutTop;
1133
 
    else if (type == "emptytop")
1134
 
        return PutEmptyTop;
1135
 
    else if (type == "topright")
1136
 
        return PutTopRight;
1137
 
    else if (type == "emptytopright")
1138
 
        return PutEmptyTopRight;
1139
 
    else if (type == "right")
1140
 
        return PutRight;
1141
 
    else if (type == "emptyright")
1142
 
        return PutEmptyRight;
1143
 
    else if (type == "bottomright")
1144
 
        return PutBottomRight;
1145
 
    else if (type == "emptybottomright")
1146
 
        return PutEmptyBottomRight;
1147
 
    else if (type == "bottom")
1148
 
        return PutBottom;
1149
 
    else if (type == "emptybottom")
1150
 
        return PutEmptyBottom;
1151
 
    else if (type == "center")
1152
 
        return PutCenter;
1153
 
    else if (type == "emptycenter")
1154
 
        return PutEmptyCenter;
1155
 
    else
1156
 
        return PutUnknown;
1157
 
}
1158
 
 
1159
 
 
1160
 
bool
1161
 
PutScreen::initiate (CompAction         *action,
1162
 
                     CompAction::State  state,
1163
 
                     CompOption::Vector &option)
1164
 
{
1165
 
    PutType    type = PutUnknown;
1166
 
    CompString typeString;
1167
 
 
1168
 
    typeString = CompOption::getStringOptionNamed (option, "type");
1169
 
    if (!typeString.empty ())
1170
 
        type = typeFromString (typeString);
1171
 
 
1172
 
/*    if (type == (PutType) PutViewport)
1173
 
        return toViewport (action, state, option);
1174
 
    else*/
1175
 
    return initiateCommon (action, state, option,type);
1176
 
}
1177
 
 
1178
 
bool
1179
 
PutScreen::toViewport (CompAction         *action,
1180
 
                       CompAction::State  state,
1181
 
                       CompOption::Vector &option,
1182
 
                       int vp)
1183
 
{
1184
 
    int last = option.size ();
1185
 
    option.resize(last+1);
1186
 
    option[last].setName ("viewport",CompOption::TypeInt);
1187
 
    option[last].value ().set (vp-1);
1188
 
 
1189
 
    return initiateCommon (action, state, option, (PutType) PutViewport);
1190
 
}
1191
 
 
1192
 
 
1193
 
PutScreen::PutScreen (CompScreen *screen) :
1194
 
    PluginClassHandler <PutScreen, CompScreen> (screen),
1195
 
    PutOptions (),
1196
 
    screen (screen),
1197
 
    cScreen (CompositeScreen::get (screen)),
1198
 
    gScreen (GLScreen::get (screen)),
1199
 
    lastWindow (None),
1200
 
    lastType (PutUnknown),
1201
 
    moreAdjust (false),
1202
 
    grabIndex (0)
1203
 
{
1204
 
    ScreenInterface::setHandler (screen);
1205
 
    CompositeScreenInterface::setHandler (cScreen);
1206
 
    GLScreenInterface::setHandler (gScreen);
1207
 
 
1208
 
    compizPutWindowAtom = XInternAtom(screen->dpy (),
1209
 
                                      "_COMPIZ_PUT_WINDOW", 0);
1210
 
 
1211
 
    optionSetPutPutInitiate (boost::bind (&PutScreen::initiate, this,
1212
 
                                          _1, _2, _3));
1213
 
 
1214
 
#define setAction(action, type) \
1215
 
    optionSet##action##KeyInitiate (boost::bind (&PutScreen::initiateCommon,   \
1216
 
                                              this, _1,_2,_3,type));           \
1217
 
    optionSet##action##ButtonInitiate (boost::bind (&PutScreen::initiateCommon,\
1218
 
                                              this, _1,_2,_3,type))
1219
 
 
1220
 
    setAction (PutRestore, PutRestore);
1221
 
    setAction (PutPointer, PutPointer);
1222
 
    setAction (PutNextOutput, PutNextOutput);
1223
 
    setAction (PutCenter, PutCenter);
1224
 
    setAction (PutEmptyCenter, PutEmptyCenter);
1225
 
    setAction (PutLeft, PutLeft);
1226
 
    setAction (PutEmptyLeft, PutEmptyLeft);
1227
 
    setAction (PutRight, PutRight);
1228
 
    setAction (PutEmptyRight, PutEmptyRight);
1229
 
    setAction (PutTop, PutTop);
1230
 
    setAction (PutEmptyTop, PutEmptyTop);
1231
 
    setAction (PutBottom, PutBottom);
1232
 
    setAction (PutEmptyBottom, PutEmptyBottom);
1233
 
    setAction (PutTopleft, PutTopLeft);
1234
 
    setAction (PutEmptyTopleft, PutEmptyTopLeft);
1235
 
    setAction (PutTopright, PutTopRight);
1236
 
    setAction (PutEmptyTopright, PutEmptyTopRight);
1237
 
    setAction (PutBottomleft, PutBottomLeft);
1238
 
    setAction (PutEmptyBottomleft, PutEmptyBottomLeft);
1239
 
    setAction (PutBottomright, PutBottomRight);
1240
 
    setAction (PutEmptyBottomright, PutEmptyBottomRight);
1241
 
 
1242
 
#define setViewportAction(num)                                                 \
1243
 
    optionSetPutViewport##num##KeyInitiate(boost::bind (&PutScreen::toViewport,\
1244
 
                                this, _1,_2,_3,num));
1245
 
 
1246
 
    setViewportAction(1);
1247
 
    setViewportAction(2);
1248
 
    setViewportAction(3);
1249
 
    setViewportAction(4);
1250
 
    setViewportAction(5);
1251
 
    setViewportAction(6);
1252
 
    setViewportAction(7);
1253
 
    setViewportAction(8);
1254
 
    setViewportAction(9);
1255
 
    setViewportAction(10);
1256
 
    setViewportAction(11);
1257
 
    setViewportAction(12);
1258
 
 
1259
 
#define setDirectionAction(action) \
1260
 
    optionSet##action##KeyInitiate(boost::bind (&PutScreen::initiateCommon, \
1261
 
                                                this, _1,_2,_3,action))
1262
 
 
1263
 
    setDirectionAction(PutViewportLeft);
1264
 
    setDirectionAction(PutViewportRight);
1265
 
    setDirectionAction(PutViewportUp);
1266
 
    setDirectionAction(PutViewportDown);
1267
 
}
1268
 
 
1269
 
PutWindow::PutWindow (CompWindow *window) :
1270
 
    PluginClassHandler <PutWindow, CompWindow> (window),
1271
 
    window (window),
1272
 
    cWindow (CompositeWindow::get (window)),
1273
 
    gWindow (GLWindow::get (window)),
1274
 
    xVelocity (0),
1275
 
    yVelocity (0),
1276
 
    tx (0),
1277
 
    ty (0),
1278
 
    lastX (window->serverX ()),
1279
 
    lastY (window->serverY ()),
1280
 
    adjust (false)
1281
 
{
1282
 
    WindowInterface::setHandler (window);
1283
 
    CompositeWindowInterface::setHandler (cWindow);
1284
 
    GLWindowInterface::setHandler (gWindow);
1285
 
}
1286
 
 
1287
 
bool
1288
 
PutPluginVTable::init ()
1289
 
{
1290
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
1291
 
         return false;
1292
 
    if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
1293
 
         return false;
1294
 
    if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
1295
 
         return false;
1296
 
 
1297
 
    return true;
1298
 
}