~alan-griffiths/compiz-core/Bug-931283

« back to all changes in this revision

Viewing changes to plugins/resize.c

  • Committer: David Reveman
  • Date: 2006-02-09 06:03:09 UTC
  • Revision ID: git-v1:9959c2b13ded64a5e66359a8097250dc9d87fc1c
Initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2005 Novell, Inc.
 
3
 *
 
4
 * Permission to use, copy, modify, distribute, and sell this software
 
5
 * and its documentation for any purpose is hereby granted without
 
6
 * fee, provided that the above copyright notice appear in all copies
 
7
 * and that both that copyright notice and this permission notice
 
8
 * appear in supporting documentation, and that the name of
 
9
 * Novell, Inc. not be used in advertising or publicity pertaining to
 
10
 * distribution of the software without specific, written prior permission.
 
11
 * Novell, Inc. makes no representations about the suitability of this
 
12
 * software for any purpose. It is provided "as is" without express or
 
13
 * implied warranty.
 
14
 *
 
15
 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
16
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 
17
 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
18
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 
19
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
20
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
21
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
22
 *
 
23
 * Author: David Reveman <davidr@novell.com>
 
24
 */
 
25
 
 
26
#include <stdio.h>
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
 
 
30
#include <X11/cursorfont.h>
 
31
 
 
32
#include <compiz.h>
 
33
 
 
34
#define ResizeUpMask    (1L << 0)
 
35
#define ResizeDownMask  (1L << 1)
 
36
#define ResizeLeftMask  (1L << 2)
 
37
#define ResizeRightMask (1L << 3)
 
38
 
 
39
#define RESIZE_INITIATE_BUTTON_DEFAULT    Button3
 
40
#define RESIZE_INITIATE_MODIFIERS_DEFAULT (CompPressMask | CompAltMask)
 
41
 
 
42
#define RESIZE_TERMINATE_BUTTON_DEFAULT    Button3
 
43
#define RESIZE_TERMINATE_MODIFIERS_DEFAULT CompReleaseMask
 
44
 
 
45
struct _ResizeKeys {
 
46
    char *name;
 
47
    int  dx;
 
48
    int  dy;
 
49
} rKeys[] = {
 
50
    { "Left",  -1,  0 },
 
51
    { "Right",  1,  0 },
 
52
    { "Up",     0, -1 },
 
53
    { "Down",   0,  1 }
 
54
};
 
55
 
 
56
#define NUM_KEYS (sizeof (rKeys) / sizeof (rKeys[0]))
 
57
 
 
58
#define MIN_KEY_WIDTH_INC  24
 
59
#define MIN_KEY_HEIGHT_INC 24
 
60
 
 
61
static int displayPrivateIndex;
 
62
 
 
63
typedef struct _ResizeDisplay {
 
64
    int             screenPrivateIndex;
 
65
    HandleEventProc handleEvent;
 
66
 
 
67
    CompWindow   *w;
 
68
    int          releaseButton;
 
69
    unsigned int mask;
 
70
    int          width;
 
71
    int          height;
 
72
    KeyCode      key[NUM_KEYS];
 
73
} ResizeDisplay;
 
74
 
 
75
#define RESIZE_SCREEN_OPTION_INITIATE  0
 
76
#define RESIZE_SCREEN_OPTION_TERMINATE 1
 
77
#define RESIZE_SCREEN_OPTION_NUM       2
 
78
 
 
79
typedef struct _ResizeScreen {
 
80
    CompOption opt[RESIZE_SCREEN_OPTION_NUM];
 
81
 
 
82
    int grabIndex;
 
83
 
 
84
    Cursor leftCursor;
 
85
    Cursor rightCursor;
 
86
    Cursor upCursor;
 
87
    Cursor upLeftCursor;
 
88
    Cursor upRightCursor;
 
89
    Cursor downCursor;
 
90
    Cursor downLeftCursor;
 
91
    Cursor downRightCursor;
 
92
 
 
93
    int prevPointerX;
 
94
    int prevPointerY;
 
95
} ResizeScreen;
 
96
 
 
97
#define GET_RESIZE_DISPLAY(d)                                  \
 
98
    ((ResizeDisplay *) (d)->privates[displayPrivateIndex].ptr)
 
99
 
 
100
#define RESIZE_DISPLAY(d)                      \
 
101
    ResizeDisplay *rd = GET_RESIZE_DISPLAY (d)
 
102
 
 
103
#define GET_RESIZE_SCREEN(s, rd)                                   \
 
104
    ((ResizeScreen *) (s)->privates[(rd)->screenPrivateIndex].ptr)
 
105
 
 
106
#define RESIZE_SCREEN(s)                                                      \
 
107
    ResizeScreen *rs = GET_RESIZE_SCREEN (s, GET_RESIZE_DISPLAY (s->display))
 
108
 
 
109
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
 
110
 
 
111
static CompOption *
 
112
resizeGetScreenOptions (CompScreen *screen,
 
113
                        int        *count)
 
114
{
 
115
    RESIZE_SCREEN (screen);
 
116
 
 
117
    *count = NUM_OPTIONS (rs);
 
118
    return rs->opt;
 
119
}
 
120
 
 
121
static Bool
 
122
resizeSetScreenOption (CompScreen      *screen,
 
123
                       char            *name,
 
124
                       CompOptionValue *value)
 
125
{
 
126
    CompOption *o;
 
127
    int        index;
 
128
 
 
129
    RESIZE_SCREEN (screen);
 
130
 
 
131
    o = compFindOption (rs->opt, NUM_OPTIONS (rs), name, &index);
 
132
    if (!o)
 
133
        return FALSE;
 
134
 
 
135
    switch (index) {
 
136
    case RESIZE_SCREEN_OPTION_INITIATE:
 
137
        if (addScreenBinding (screen, &value->bind))
 
138
        {
 
139
            removeScreenBinding (screen, &o->value.bind);
 
140
 
 
141
            if (compSetBindingOption (o, value))
 
142
                return TRUE;
 
143
        }
 
144
        break;
 
145
    case RESIZE_SCREEN_OPTION_TERMINATE:
 
146
        if (compSetBindingOption (o, value))
 
147
            return TRUE;
 
148
        break;
 
149
    default:
 
150
        break;
 
151
    }
 
152
 
 
153
    return FALSE;
 
154
}
 
155
 
 
156
static void
 
157
resizeScreenInitOptions (ResizeScreen *rs,
 
158
                         Display      *display)
 
159
{
 
160
    CompOption *o;
 
161
 
 
162
    o = &rs->opt[RESIZE_SCREEN_OPTION_INITIATE];
 
163
    o->name                          = "initiate";
 
164
    o->shortDesc                     = "Initiate Window Resize";
 
165
    o->longDesc                      = "Start moving window";
 
166
    o->type                          = CompOptionTypeBinding;
 
167
    o->value.bind.type               = CompBindingTypeButton;
 
168
    o->value.bind.u.button.modifiers = RESIZE_INITIATE_MODIFIERS_DEFAULT;
 
169
    o->value.bind.u.button.button    = RESIZE_INITIATE_BUTTON_DEFAULT;
 
170
 
 
171
    o = &rs->opt[RESIZE_SCREEN_OPTION_TERMINATE];
 
172
    o->name                          = "terminate";
 
173
    o->shortDesc                     = "Terminate Window Resize";
 
174
    o->longDesc                      = "Stop moving window";
 
175
    o->type                          = CompOptionTypeBinding;
 
176
    o->value.bind.type               = CompBindingTypeButton;
 
177
    o->value.bind.u.button.modifiers = RESIZE_TERMINATE_MODIFIERS_DEFAULT;
 
178
    o->value.bind.u.button.button    = RESIZE_TERMINATE_BUTTON_DEFAULT;
 
179
}
 
180
 
 
181
static void
 
182
resizeInitiate (CompScreen   *s,
 
183
                Window       window,
 
184
                int          x,
 
185
                int          y,
 
186
                unsigned int state,
 
187
                unsigned int mask,
 
188
                int          releaseButton)
 
189
{
 
190
    CompWindow *w;
 
191
 
 
192
    RESIZE_DISPLAY (s->display);
 
193
 
 
194
    /* some plugin has already grabbed the screen */
 
195
    if (s->maxGrab)
 
196
        return;
 
197
 
 
198
    if (rd->w)
 
199
        return;
 
200
 
 
201
    w = findTopLevelWindowAtScreen (s, window);
 
202
    if (w)
 
203
    {
 
204
        RESIZE_SCREEN (s);
 
205
 
 
206
        if (w->type & (CompWindowTypeDesktopMask |
 
207
                       CompWindowTypeDockMask    |
 
208
                       CompWindowTypeFullscreenMask))
 
209
            return;
 
210
 
 
211
        if (w->attrib.override_redirect)
 
212
            return;
 
213
 
 
214
        rd->w      = w;
 
215
        rd->mask   = mask;
 
216
        rd->width  = w->attrib.width;
 
217
        rd->height = w->attrib.height;
 
218
 
 
219
        rs->prevPointerX = x;
 
220
        rs->prevPointerY = y;
 
221
 
 
222
        if (!rs->grabIndex)
 
223
        {
 
224
            Cursor cursor;
 
225
 
 
226
            if (mask & ResizeLeftMask)
 
227
            {
 
228
                if (mask & ResizeDownMask)
 
229
                    cursor = rs->downLeftCursor;
 
230
                else if (mask & ResizeUpMask)
 
231
                    cursor = rs->upLeftCursor;
 
232
                else
 
233
                    cursor = rs->leftCursor;
 
234
            }
 
235
            else if (mask & ResizeRightMask)
 
236
            {
 
237
                if (mask & ResizeDownMask)
 
238
                    cursor = rs->downRightCursor;
 
239
                else if (mask & ResizeUpMask)
 
240
                    cursor = rs->upRightCursor;
 
241
                else
 
242
                    cursor = rs->rightCursor;
 
243
            }
 
244
            else if (mask & ResizeUpMask)
 
245
            {
 
246
                cursor = rs->upCursor;
 
247
            }
 
248
            else
 
249
            {
 
250
                cursor = rs->downCursor;
 
251
            }
 
252
 
 
253
            rs->grabIndex = pushScreenGrab (s, cursor);
 
254
        }
 
255
 
 
256
        if (rs->grabIndex)
 
257
        {
 
258
            rd->releaseButton = releaseButton;
 
259
 
 
260
            (s->windowGrabNotify) (w, x, y, state,
 
261
                                   CompWindowGrabResizeMask |
 
262
                                   CompWindowGrabButtonMask);
 
263
        }
 
264
    }
 
265
}
 
266
 
 
267
static void
 
268
resizeTerminate (CompDisplay *d)
 
269
{
 
270
    RESIZE_DISPLAY (d);
 
271
 
 
272
    if (rd->w)
 
273
    {
 
274
        RESIZE_SCREEN (rd->w->screen);
 
275
 
 
276
        if (rs->grabIndex)
 
277
        {
 
278
            removeScreenGrab (rd->w->screen, rs->grabIndex, NULL);
 
279
            rs->grabIndex = 0;
 
280
        }
 
281
 
 
282
        (rd->w->screen->windowUngrabNotify) (rd->w);
 
283
 
 
284
        syncWindowPosition (rd->w);
 
285
 
 
286
        rd->w             = 0;
 
287
        rd->releaseButton = 0;
 
288
    }
 
289
}
 
290
 
 
291
static void
 
292
resizeUpdateWindowSize (CompDisplay *d)
 
293
{
 
294
    int width, height;
 
295
 
 
296
    RESIZE_DISPLAY (d);
 
297
 
 
298
    if (!rd->w)
 
299
        return;
 
300
 
 
301
    if (rd->w->state & CompWindowStateMaximizedVertMask)
 
302
        rd->height = rd->w->attrib.height;
 
303
 
 
304
    if (rd->w->state & CompWindowStateMaximizedHorzMask)
 
305
        rd->width = rd->w->attrib.width;
 
306
 
 
307
    if (rd->width  == rd->w->attrib.width &&
 
308
        rd->height == rd->w->attrib.height)
 
309
        return;
 
310
 
 
311
    if (rd->w->syncWait)
 
312
        return;
 
313
 
 
314
    if (constrainNewWindowSize (rd->w,
 
315
                                rd->width, rd->height,
 
316
                                &width, &height))
 
317
    {
 
318
        XWindowChanges xwc;
 
319
 
 
320
        xwc.x = rd->w->attrib.x;
 
321
        if (rd->mask & ResizeLeftMask)
 
322
            xwc.x -= width - rd->w->attrib.width;
 
323
 
 
324
        xwc.y = rd->w->attrib.y;
 
325
        if (rd->mask & ResizeUpMask)
 
326
            xwc.y -= height - rd->w->attrib.height;
 
327
 
 
328
        xwc.width  = width;
 
329
        xwc.height = height;
 
330
 
 
331
        sendSyncRequest (rd->w);
 
332
 
 
333
        XConfigureWindow (d->display, rd->w->id,
 
334
                          CWX | CWY | CWWidth | CWHeight,
 
335
                          &xwc);
 
336
    }
 
337
}
 
338
 
 
339
static void
 
340
resizeHandleMotionEvent (CompScreen *s,
 
341
                         int        xRoot,
 
342
                         int        yRoot)
 
343
{
 
344
    RESIZE_SCREEN (s);
 
345
 
 
346
    if (rs->grabIndex)
 
347
    {
 
348
        int pointerDx, pointerDy;
 
349
 
 
350
        RESIZE_DISPLAY (s->display);
 
351
 
 
352
        pointerDx = xRoot - rs->prevPointerX;
 
353
        pointerDy = yRoot - rs->prevPointerY;
 
354
        rs->prevPointerX = xRoot;
 
355
        rs->prevPointerY = yRoot;
 
356
 
 
357
        if (pointerDx || pointerDy)
 
358
        {
 
359
            if (rd->mask & ResizeLeftMask)
 
360
                rd->width -= pointerDx;
 
361
            else if (rd->mask & ResizeRightMask)
 
362
                rd->width += pointerDx;
 
363
 
 
364
            if (rd->mask & ResizeUpMask)
 
365
                rd->height -= pointerDy;
 
366
            else if (rd->mask & ResizeDownMask)
 
367
                rd->height += pointerDy;
 
368
 
 
369
            resizeUpdateWindowSize (s->display);
 
370
        }
 
371
    }
 
372
}
 
373
 
 
374
static void
 
375
resizeHandleEvent (CompDisplay *d,
 
376
                   XEvent      *event)
 
377
{
 
378
    CompScreen *s;
 
379
 
 
380
    RESIZE_DISPLAY (d);
 
381
 
 
382
    switch (event->type) {
 
383
    case KeyPress:
 
384
    case KeyRelease:
 
385
        s = findScreenAtDisplay (d, event->xkey.root);
 
386
        if (s)
 
387
        {
 
388
            RESIZE_SCREEN (s);
 
389
 
 
390
            if (EV_KEY (&rs->opt[RESIZE_SCREEN_OPTION_INITIATE], event))
 
391
                resizeInitiate (s,
 
392
                                event->xkey.window,
 
393
                                event->xkey.x_root,
 
394
                                event->xkey.y_root,
 
395
                                event->xkey.state,
 
396
                                ResizeDownMask | ResizeRightMask,
 
397
                                0);
 
398
 
 
399
            if (EV_KEY (&rs->opt[RESIZE_SCREEN_OPTION_TERMINATE], event) ||
 
400
                (event->type         == KeyPress &&
 
401
                 event->xkey.keycode == s->escapeKeyCode))
 
402
                resizeTerminate (d);
 
403
 
 
404
            if (rs->grabIndex && rd->w && event->type == KeyPress)
 
405
            {
 
406
                int i, widthInc, heightInc;
 
407
 
 
408
                widthInc  = rd->w->sizeHints.width_inc;
 
409
                heightInc = rd->w->sizeHints.height_inc;
 
410
 
 
411
                if (widthInc < MIN_KEY_WIDTH_INC)
 
412
                    widthInc = MIN_KEY_WIDTH_INC;
 
413
 
 
414
                if (heightInc < MIN_KEY_HEIGHT_INC)
 
415
                    heightInc = MIN_KEY_HEIGHT_INC;
 
416
 
 
417
                for (i = 0; i < NUM_KEYS; i++)
 
418
                {
 
419
                    if (event->xkey.keycode == rd->key[i])
 
420
                    {
 
421
                        XWarpPointer (d->display, None, None, 0, 0, 0, 0,
 
422
                                      rKeys[i].dx * widthInc,
 
423
                                      rKeys[i].dy * heightInc);
 
424
                        break;
 
425
                    }
 
426
                }
 
427
            }
 
428
        }
 
429
        break;
 
430
    case ButtonPress:
 
431
    case ButtonRelease:
 
432
        s = findScreenAtDisplay (d, event->xbutton.root);
 
433
        if (s)
 
434
        {
 
435
            RESIZE_SCREEN (s);
 
436
 
 
437
            if (EV_BUTTON (&rs->opt[RESIZE_SCREEN_OPTION_INITIATE], event))
 
438
                resizeInitiate (s,
 
439
                                event->xbutton.window,
 
440
                                event->xbutton.x_root,
 
441
                                event->xbutton.y_root,
 
442
                                event->xbutton.state,
 
443
                                ResizeDownMask | ResizeRightMask,
 
444
                                0);
 
445
 
 
446
            if (EV_BUTTON (&rs->opt[RESIZE_SCREEN_OPTION_TERMINATE], event))
 
447
                resizeTerminate (d);
 
448
 
 
449
            if (event->type == ButtonRelease &&
 
450
                (rd->releaseButton     == -1 ||
 
451
                 event->xbutton.button == rd->releaseButton))
 
452
                resizeTerminate (d);
 
453
        }
 
454
        break;
 
455
    case MotionNotify:
 
456
        s = findScreenAtDisplay (d, event->xmotion.root);
 
457
        if (s)
 
458
            resizeHandleMotionEvent (s,
 
459
                                     event->xmotion.x_root,
 
460
                                     event->xmotion.y_root);
 
461
        break;
 
462
    case ClientMessage:
 
463
        if (event->xclient.message_type == d->wmMoveResizeAtom)
 
464
        {
 
465
            CompWindow *w;
 
466
 
 
467
            if (event->xclient.data.l[2] <= WmMoveResizeSizeLeft ||
 
468
                event->xclient.data.l[2] == WmMoveResizeSizeKeyboard)
 
469
            {
 
470
                w = findWindowAtDisplay (d, event->xclient.window);
 
471
                if (w)
 
472
                {
 
473
                    if (event->xclient.data.l[2] == WmMoveResizeSizeKeyboard)
 
474
                    {
 
475
                        int x, y;
 
476
 
 
477
                        x = w->attrib.x + w->width / 2;
 
478
                        y = w->attrib.y + w->height / 2;
 
479
 
 
480
                        XWarpPointer (d->display, None, w->screen->root,
 
481
                                      0, 0, 0, 0, x, y);
 
482
 
 
483
                        resizeInitiate (w->screen, event->xclient.window,
 
484
                                        x, y, 0,
 
485
                                        ResizeDownMask | ResizeRightMask,
 
486
                                        0);
 
487
                    }
 
488
                    else
 
489
                    {
 
490
                        static unsigned int mask[] = {
 
491
                            ResizeUpMask | ResizeLeftMask,
 
492
                            ResizeUpMask,
 
493
                            ResizeUpMask | ResizeRightMask,
 
494
                            ResizeRightMask,
 
495
                            ResizeDownMask | ResizeRightMask,
 
496
                            ResizeDownMask,
 
497
                            ResizeDownMask | ResizeLeftMask,
 
498
                            ResizeLeftMask,
 
499
                        };
 
500
                        unsigned int        state;
 
501
                        Window              root, child;
 
502
                        int                 xRoot, yRoot, i;
 
503
 
 
504
                        XQueryPointer (d->display, w->screen->root,
 
505
                                       &root, &child, &xRoot, &yRoot,
 
506
                                       &i, &i, &state);
 
507
 
 
508
                        /* TODO: not only button 1 */
 
509
                        if (state & Button1Mask)
 
510
                        {
 
511
                            resizeInitiate (w->screen, event->xclient.window,
 
512
                                            event->xclient.data.l[0],
 
513
                                            event->xclient.data.l[1],
 
514
                                            state | CompPressMask,
 
515
                                            mask[event->xclient.data.l[2]],
 
516
                                            event->xclient.data.l[3] ?
 
517
                                            event->xclient.data.l[3] : -1);
 
518
 
 
519
                            resizeHandleMotionEvent (w->screen, xRoot, yRoot);
 
520
                        }
 
521
                    }
 
522
                }
 
523
            }
 
524
        }
 
525
        break;
 
526
    case DestroyNotify:
 
527
        if (rd->w && rd->w->id == event->xdestroywindow.window)
 
528
            resizeTerminate (d);
 
529
        break;
 
530
    case UnmapNotify:
 
531
        if (rd->w && rd->w->id == event->xunmap.window)
 
532
            resizeTerminate (d);
 
533
    default:
 
534
        if (event->type == d->syncEvent + XSyncAlarmNotify)
 
535
        {
 
536
            if (rd->w)
 
537
            {
 
538
                XSyncAlarmNotifyEvent *sa;
 
539
 
 
540
                sa = (XSyncAlarmNotifyEvent *) event;
 
541
 
 
542
                if (rd->w->syncAlarm == sa->alarm)
 
543
                    resizeUpdateWindowSize (d);
 
544
            }
 
545
        }
 
546
        break;
 
547
    }
 
548
 
 
549
    UNWRAP (rd, d, handleEvent);
 
550
    (*d->handleEvent) (d, event);
 
551
    WRAP (rd, d, handleEvent, resizeHandleEvent);
 
552
}
 
553
 
 
554
static Bool
 
555
resizeInitDisplay (CompPlugin  *p,
 
556
                   CompDisplay *d)
 
557
{
 
558
    ResizeDisplay *rd;
 
559
    int           i;
 
560
 
 
561
    rd = malloc (sizeof (ResizeDisplay));
 
562
    if (!rd)
 
563
        return FALSE;
 
564
 
 
565
    rd->screenPrivateIndex = allocateScreenPrivateIndex (d);
 
566
    if (rd->screenPrivateIndex < 0)
 
567
    {
 
568
        free (rd);
 
569
        return FALSE;
 
570
    }
 
571
 
 
572
    rd->w = 0;
 
573
 
 
574
    rd->releaseButton = 0;
 
575
 
 
576
    for (i = 0; i < NUM_KEYS; i++)
 
577
        rd->key[i] = XKeysymToKeycode (d->display,
 
578
                                       XStringToKeysym (rKeys[i].name));
 
579
 
 
580
    WRAP (rd, d, handleEvent, resizeHandleEvent);
 
581
 
 
582
    d->privates[displayPrivateIndex].ptr = rd;
 
583
 
 
584
    return TRUE;
 
585
}
 
586
 
 
587
static void
 
588
resizeFiniDisplay (CompPlugin  *p,
 
589
                   CompDisplay *d)
 
590
{
 
591
    RESIZE_DISPLAY (d);
 
592
 
 
593
    freeScreenPrivateIndex (d, rd->screenPrivateIndex);
 
594
 
 
595
    UNWRAP (rd, d, handleEvent);
 
596
 
 
597
    free (rd);
 
598
}
 
599
 
 
600
static Bool
 
601
resizeInitScreen (CompPlugin *p,
 
602
                  CompScreen *s)
 
603
{
 
604
    ResizeScreen *rs;
 
605
 
 
606
    RESIZE_DISPLAY (s->display);
 
607
 
 
608
    rs = malloc (sizeof (ResizeScreen));
 
609
    if (!rs)
 
610
        return FALSE;
 
611
 
 
612
    rs->grabIndex = 0;
 
613
 
 
614
    rs->prevPointerX = 0;
 
615
    rs->prevPointerY = 0;
 
616
 
 
617
    resizeScreenInitOptions (rs, s->display->display);
 
618
 
 
619
    rs->leftCursor      = XCreateFontCursor (s->display->display, XC_left_side);
 
620
    rs->rightCursor     = XCreateFontCursor (s->display->display, XC_right_side);
 
621
    rs->upCursor        = XCreateFontCursor (s->display->display,
 
622
                                             XC_top_side);
 
623
    rs->upLeftCursor    = XCreateFontCursor (s->display->display,
 
624
                                             XC_top_left_corner);
 
625
    rs->upRightCursor   = XCreateFontCursor (s->display->display,
 
626
                                             XC_top_right_corner);
 
627
    rs->downCursor      = XCreateFontCursor (s->display->display,
 
628
                                             XC_bottom_side);
 
629
    rs->downLeftCursor  = XCreateFontCursor (s->display->display,
 
630
                                             XC_bottom_left_corner);
 
631
    rs->downRightCursor = XCreateFontCursor (s->display->display,
 
632
                                             XC_bottom_right_corner);
 
633
 
 
634
    addScreenBinding (s, &rs->opt[RESIZE_SCREEN_OPTION_INITIATE].value.bind);
 
635
 
 
636
    s->privates[rd->screenPrivateIndex].ptr = rs;
 
637
 
 
638
    return TRUE;
 
639
}
 
640
 
 
641
static void
 
642
resizeFiniScreen (CompPlugin *p,
 
643
                  CompScreen *s)
 
644
{
 
645
    RESIZE_SCREEN (s);
 
646
 
 
647
    free (rs);
 
648
}
 
649
 
 
650
static Bool
 
651
resizeInit (CompPlugin *p)
 
652
{
 
653
    displayPrivateIndex = allocateDisplayPrivateIndex ();
 
654
    if (displayPrivateIndex < 0)
 
655
        return FALSE;
 
656
 
 
657
    return TRUE;
 
658
}
 
659
 
 
660
static void
 
661
resizeFini (CompPlugin *p)
 
662
{
 
663
    if (displayPrivateIndex >= 0)
 
664
        freeDisplayPrivateIndex (displayPrivateIndex);
 
665
}
 
666
 
 
667
CompPluginVTable resizeVTable = {
 
668
    "resize",
 
669
    "Resize Window",
 
670
    "Resize window",
 
671
    resizeInit,
 
672
    resizeFini,
 
673
    resizeInitDisplay,
 
674
    resizeFiniDisplay,
 
675
    resizeInitScreen,
 
676
    resizeFiniScreen,
 
677
    0, /* InitWindow */
 
678
    0, /* FiniWindow */
 
679
    0, /* GetDisplayOptions */
 
680
    0, /* SetDisplayOption */
 
681
    resizeGetScreenOptions,
 
682
    resizeSetScreenOption,
 
683
    NULL,
 
684
    0
 
685
};
 
686
 
 
687
CompPluginVTable *
 
688
getCompPluginInfo (void)
 
689
{
 
690
    return &resizeVTable;
 
691
}