2
* Copyright © 2005 Novell, Inc.
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
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.
23
* Author: David Reveman <davidr@novell.com>
32
#include <X11/Xatom.h>
33
#include <X11/Xproto.h>
37
#define ROTATE_POINTER_INVERT_Y_DEFAULT FALSE
39
#define ROTATE_POINTER_SENSITIVITY_DEFAULT 1.0f
40
#define ROTATE_POINTER_SENSITIVITY_MIN 0.01f
41
#define ROTATE_POINTER_SENSITIVITY_MAX 100.0f
42
#define ROTATE_POINTER_SENSITIVITY_PRECISION 0.01f
44
#define ROTATE_POINTER_SENSITIVITY_FACTOR 0.05f
46
#define ROTATE_ACCELERATION_DEFAULT 4.0f
47
#define ROTATE_ACCELERATION_MIN 1.0f
48
#define ROTATE_ACCELERATION_MAX 20.0f
49
#define ROTATE_ACCELERATION_PRECISION 0.1f
51
#define ROTATE_INITIATE_BUTTON_DEFAULT Button1
52
#define ROTATE_INITIATE_MODIFIERS_DEFAULT \
53
(CompPressMask | ControlMask | CompAltMask)
55
#define ROTATE_TERMINATE_BUTTON_DEFAULT Button1
56
#define ROTATE_TERMINATE_MODIFIERS_DEFAULT CompReleaseMask
58
#define ROTATE_LEFT_KEY_DEFAULT "Left"
59
#define ROTATE_LEFT_MODIFIERS_DEFAULT \
60
(CompPressMask | ControlMask | CompAltMask)
62
#define ROTATE_RIGHT_KEY_DEFAULT "Right"
63
#define ROTATE_RIGHT_MODIFIERS_DEFAULT \
64
(CompPressMask | ControlMask | CompAltMask)
66
#define ROTATE_LEFT_WINDOW_KEY_DEFAULT "Left"
67
#define ROTATE_LEFT_WINDOW_MODIFIERS_DEFAULT \
68
(CompPressMask | ShiftMask | ControlMask | CompAltMask)
70
#define ROTATE_RIGHT_WINDOW_KEY_DEFAULT "Right"
71
#define ROTATE_RIGHT_WINDOW_MODIFIERS_DEFAULT \
72
(CompPressMask | ShiftMask | ControlMask | CompAltMask)
74
#define ROTATE_SNAP_TOP_DEFAULT FALSE
76
#define ROTATE_SPEED_DEFAULT 1.5f
77
#define ROTATE_SPEED_MIN 0.1f
78
#define ROTATE_SPEED_MAX 50.0f
79
#define ROTATE_SPEED_PRECISION 0.1f
81
#define ROTATE_TIMESTEP_DEFAULT 1.2f
82
#define ROTATE_TIMESTEP_MIN 0.1f
83
#define ROTATE_TIMESTEP_MAX 50.0f
84
#define ROTATE_TIMESTEP_PRECISION 0.1f
86
static int displayPrivateIndex;
88
typedef struct _RotateDisplay {
89
int screenPrivateIndex;
90
HandleEventProc handleEvent;
93
#define ROTATE_SCREEN_OPTION_POINTER_INVERT_Y 0
94
#define ROTATE_SCREEN_OPTION_POINTER_SENSITIVITY 1
95
#define ROTATE_SCREEN_OPTION_ACCELERATION 2
96
#define ROTATE_SCREEN_OPTION_INITIATE 3
97
#define ROTATE_SCREEN_OPTION_TERMINATE 4
98
#define ROTATE_SCREEN_OPTION_LEFT 5
99
#define ROTATE_SCREEN_OPTION_RIGHT 6
100
#define ROTATE_SCREEN_OPTION_LEFT_WINDOW 7
101
#define ROTATE_SCREEN_OPTION_RIGHT_WINDOW 8
102
#define ROTATE_SCREEN_OPTION_SNAP_TOP 9
103
#define ROTATE_SCREEN_OPTION_SPEED 10
104
#define ROTATE_SCREEN_OPTION_TIMESTEP 11
105
#define ROTATE_SCREEN_OPTION_NUM 12
107
typedef struct _RotateScreen {
108
PreparePaintScreenProc preparePaintScreen;
109
DonePaintScreenProc donePaintScreen;
110
PaintScreenProc paintScreen;
111
SetScreenOptionForPluginProc setScreenOptionForPlugin;
113
CompOption opt[ROTATE_SCREEN_OPTION_NUM];
116
float pointerSensitivity;
125
GLfloat xrot, xVelocity;
126
GLfloat yrot, yVelocity;
144
#define GET_ROTATE_DISPLAY(d) \
145
((RotateDisplay *) (d)->privates[displayPrivateIndex].ptr)
147
#define ROTATE_DISPLAY(d) \
148
RotateDisplay *rd = GET_ROTATE_DISPLAY (d)
150
#define GET_ROTATE_SCREEN(s, rd) \
151
((RotateScreen *) (s)->privates[(rd)->screenPrivateIndex].ptr)
153
#define ROTATE_SCREEN(s) \
154
RotateScreen *rs = GET_ROTATE_SCREEN (s, GET_ROTATE_DISPLAY (s->display))
156
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
159
rotateGetScreenOptions (CompScreen *screen,
162
ROTATE_SCREEN (screen);
164
*count = NUM_OPTIONS (rs);
169
rotateSetScreenOption (CompScreen *screen,
171
CompOptionValue *value)
176
ROTATE_SCREEN (screen);
178
o = compFindOption (rs->opt, NUM_OPTIONS (rs), name, &index);
183
case ROTATE_SCREEN_OPTION_POINTER_INVERT_Y:
184
if (compSetBoolOption (o, value))
186
rs->pointerInvertY = o->value.b;
190
case ROTATE_SCREEN_OPTION_POINTER_SENSITIVITY:
191
if (compSetFloatOption (o, value))
193
rs->pointerSensitivity = o->value.f *
194
ROTATE_POINTER_SENSITIVITY_FACTOR;
198
case ROTATE_SCREEN_OPTION_ACCELERATION:
199
if (compSetFloatOption (o, value))
201
rs->acceleration = o->value.f;
205
case ROTATE_SCREEN_OPTION_INITIATE:
206
case ROTATE_SCREEN_OPTION_LEFT:
207
case ROTATE_SCREEN_OPTION_RIGHT:
208
case ROTATE_SCREEN_OPTION_LEFT_WINDOW:
209
case ROTATE_SCREEN_OPTION_RIGHT_WINDOW:
210
if (addScreenBinding (screen, &value->bind))
212
removeScreenBinding (screen, &o->value.bind);
214
if (compSetBindingOption (o, value))
218
case ROTATE_SCREEN_OPTION_TERMINATE:
219
if (compSetBindingOption (o, value))
222
case ROTATE_SCREEN_OPTION_SNAP_TOP:
223
if (compSetBoolOption (o, value))
225
rs->snapTop = o->value.b;
229
case ROTATE_SCREEN_OPTION_SPEED:
230
if (compSetFloatOption (o, value))
232
rs->speed = o->value.f;
236
case ROTATE_SCREEN_OPTION_TIMESTEP:
237
if (compSetFloatOption (o, value))
239
rs->timestep = o->value.f;
251
rotateScreenInitOptions (RotateScreen *rs,
256
o = &rs->opt[ROTATE_SCREEN_OPTION_POINTER_INVERT_Y];
257
o->name = "invert_y";
258
o->shortDesc = "Pointer Invert Y";
259
o->longDesc = "Invert Y axis for pointer movement";
260
o->type = CompOptionTypeBool;
261
o->value.b = ROTATE_POINTER_INVERT_Y_DEFAULT;
263
o = &rs->opt[ROTATE_SCREEN_OPTION_POINTER_SENSITIVITY];
264
o->name = "sensitivity";
265
o->shortDesc = "Pointer Sensitivity";
266
o->longDesc = "Sensitivity of pointer movement";
267
o->type = CompOptionTypeFloat;
268
o->value.f = ROTATE_POINTER_SENSITIVITY_DEFAULT;
269
o->rest.f.min = ROTATE_POINTER_SENSITIVITY_MIN;
270
o->rest.f.max = ROTATE_POINTER_SENSITIVITY_MAX;
271
o->rest.f.precision = ROTATE_POINTER_SENSITIVITY_PRECISION;
273
o = &rs->opt[ROTATE_SCREEN_OPTION_ACCELERATION];
274
o->name = "acceleration";
275
o->shortDesc = "Acceleration";
276
o->longDesc = "Rotation Acceleration";
277
o->type = CompOptionTypeFloat;
278
o->value.f = ROTATE_ACCELERATION_DEFAULT;
279
o->rest.f.min = ROTATE_ACCELERATION_MIN;
280
o->rest.f.max = ROTATE_ACCELERATION_MAX;
281
o->rest.f.precision = ROTATE_ACCELERATION_PRECISION;
283
o = &rs->opt[ROTATE_SCREEN_OPTION_INITIATE];
284
o->name = "initiate";
285
o->shortDesc = "Initiate";
286
o->longDesc = "Start Rotation";
287
o->type = CompOptionTypeBinding;
288
o->value.bind.type = CompBindingTypeButton;
289
o->value.bind.u.button.modifiers = ROTATE_INITIATE_MODIFIERS_DEFAULT;
290
o->value.bind.u.button.button = ROTATE_INITIATE_BUTTON_DEFAULT;
292
o = &rs->opt[ROTATE_SCREEN_OPTION_TERMINATE];
293
o->name = "terminate";
294
o->shortDesc = "Terminate";
295
o->longDesc = "Stop Rotation";
296
o->type = CompOptionTypeBinding;
297
o->value.bind.type = CompBindingTypeButton;
298
o->value.bind.u.button.modifiers = ROTATE_TERMINATE_MODIFIERS_DEFAULT;
299
o->value.bind.u.button.button = ROTATE_TERMINATE_BUTTON_DEFAULT;
301
o = &rs->opt[ROTATE_SCREEN_OPTION_LEFT];
302
o->name = "rotate_left";
303
o->shortDesc = "Rotate Left";
304
o->longDesc = "Rotate left";
305
o->type = CompOptionTypeBinding;
306
o->value.bind.type = CompBindingTypeKey;
307
o->value.bind.u.key.modifiers = ROTATE_LEFT_MODIFIERS_DEFAULT;
308
o->value.bind.u.key.keycode =
309
XKeysymToKeycode (display,
310
XStringToKeysym (ROTATE_LEFT_KEY_DEFAULT));
312
o = &rs->opt[ROTATE_SCREEN_OPTION_RIGHT];
313
o->name = "rotate_right";
314
o->shortDesc = "Rotate Right";
315
o->longDesc = "Rotate right";
316
o->type = CompOptionTypeBinding;
317
o->value.bind.type = CompBindingTypeKey;
318
o->value.bind.u.key.modifiers = ROTATE_RIGHT_MODIFIERS_DEFAULT;
319
o->value.bind.u.key.keycode =
320
XKeysymToKeycode (display,
321
XStringToKeysym (ROTATE_RIGHT_KEY_DEFAULT));
323
o = &rs->opt[ROTATE_SCREEN_OPTION_LEFT_WINDOW];
324
o->name = "rotate_left_window";
325
o->shortDesc = "Rotate Left with Window";
326
o->longDesc = "Rotate left and bring active window "
328
o->type = CompOptionTypeBinding;
329
o->value.bind.type = CompBindingTypeKey;
330
o->value.bind.u.key.modifiers = ROTATE_LEFT_WINDOW_MODIFIERS_DEFAULT;
331
o->value.bind.u.key.keycode =
332
XKeysymToKeycode (display,
333
XStringToKeysym (ROTATE_LEFT_WINDOW_KEY_DEFAULT));
335
o = &rs->opt[ROTATE_SCREEN_OPTION_RIGHT_WINDOW];
336
o->name = "rotate_right_window";
337
o->shortDesc = "Rotate Right with Window";
338
o->longDesc = "Rotate right and bring active window "
340
o->type = CompOptionTypeBinding;
341
o->value.bind.type = CompBindingTypeKey;
342
o->value.bind.u.key.modifiers = ROTATE_RIGHT_WINDOW_MODIFIERS_DEFAULT;
343
o->value.bind.u.key.keycode =
344
XKeysymToKeycode (display,
345
XStringToKeysym (ROTATE_RIGHT_WINDOW_KEY_DEFAULT));
347
o = &rs->opt[ROTATE_SCREEN_OPTION_SNAP_TOP];
348
o->name = "snap_top";
349
o->shortDesc = "Snap To Top Face";
350
o->longDesc = "Snap Cube Rotation to Top Face";
351
o->type = CompOptionTypeBool;
352
o->value.b = ROTATE_SNAP_TOP_DEFAULT;
354
o = &rs->opt[ROTATE_SCREEN_OPTION_SPEED];
356
o->shortDesc = "Speed";
357
o->longDesc = "Rotation Speed";
358
o->type = CompOptionTypeFloat;
359
o->value.f = ROTATE_SPEED_DEFAULT;
360
o->rest.f.min = ROTATE_SPEED_MIN;
361
o->rest.f.max = ROTATE_SPEED_MAX;
362
o->rest.f.precision = ROTATE_SPEED_PRECISION;
364
o = &rs->opt[ROTATE_SCREEN_OPTION_TIMESTEP];
365
o->name = "timestep";
366
o->shortDesc = "Timestep";
367
o->longDesc = "Rotation Timestep";
368
o->type = CompOptionTypeFloat;
369
o->value.f = ROTATE_TIMESTEP_DEFAULT;
370
o->rest.f.min = ROTATE_TIMESTEP_MIN;
371
o->rest.f.max = ROTATE_TIMESTEP_MAX;
372
o->rest.f.precision = ROTATE_TIMESTEP_PRECISION;
376
adjustVelocity (RotateScreen *rs,
379
float xrot, yrot, adjust, amount;
383
xrot = rs->moveTo + (rs->xrot + rs->baseXrot);
388
if (rs->xrot < -180.0f / size)
389
xrot = 360.0f / size + rs->xrot;
390
else if (rs->xrot > 180.0f / size)
391
xrot = rs->xrot - 360.0f / size;
394
adjust = -xrot * 0.05f * rs->acceleration;
395
amount = fabs (xrot);
398
else if (amount > 30.0f)
401
rs->xVelocity = (amount * rs->xVelocity + adjust) / (amount + 2.0f);
403
if (rs->snapTop && rs->yrot > 50.0f)
404
yrot = -(90.f - rs->yrot);
408
adjust = -yrot * 0.05f * rs->acceleration;
409
amount = fabs (rs->yrot);
412
else if (amount > 30.0f)
415
rs->yVelocity = (amount * rs->yVelocity + adjust) / (amount + 2.0f);
417
return (fabs (xrot) < 0.1f && fabs (rs->xVelocity) < 0.2f &&
418
fabs (yrot) < 0.1f && fabs (rs->yVelocity) < 0.2f);
422
rotatePreparePaintScreen (CompScreen *s,
423
int msSinceLastPaint)
432
amount = msSinceLastPaint * 0.05f * rs->speed;
433
steps = amount / (0.5f * rs->timestep);
434
if (!steps) steps = 1;
435
chunk = amount / (float) steps;
439
rs->xrot += rs->xVelocity * chunk;
440
rs->yrot += rs->yVelocity * chunk;
442
if (rs->xrot > 360.0f / s->size)
444
rs->baseXrot += 360.0f / s->size;
445
rs->xrot -= 360.0f / s->size;
447
else if (rs->xrot < 0.0f)
449
rs->baseXrot -= 360.0f / s->size;
450
rs->xrot += 360.0f / s->size;
453
if (rs->invert == -1)
455
if (rs->yrot > 45.0f)
457
rs->yVelocity = 0.0f;
460
else if (rs->yrot < -45.0f)
462
rs->yVelocity = 0.0f;
468
if (rs->yrot > 100.0f)
470
rs->yVelocity = 0.0f;
473
else if (rs->yrot < -100.0f)
475
rs->yVelocity = 0.0f;
482
rs->xVelocity /= 1.25f;
483
rs->yVelocity /= 1.25f;
485
if (fabs (rs->xVelocity) < 0.01f)
486
rs->xVelocity = 0.0f;
487
if (fabs (rs->yVelocity) < 0.01f)
488
rs->yVelocity = 0.0f;
490
else if (adjustVelocity (rs, s->size))
492
rs->xVelocity = 0.0f;
493
rs->yVelocity = 0.0f;
495
if (fabs (rs->yrot) < 0.1f)
500
xrot = rs->baseXrot + rs->xrot;
502
tx = (s->size * xrot / 360.0f) - 0.5f;
504
tx = (s->size * xrot / 360.0f) + 0.5f;
506
moveScreenViewport (s, tx, TRUE);
510
rs->baseXrot = rs->moveTo = 0.0f;
513
removeScreenGrab (s, rs->grabIndex, &rs->savedPointer);
520
w = findWindowAtScreen (s, rs->moveWindow);
523
moveWindow (w, w->attrib.x - rs->moveWindowX, 0,
525
syncWindowPosition (w);
529
focusDefaultWindow (s->display);
541
w = findWindowAtScreen (s, rs->moveWindow);
544
float xrot = (s->size * (rs->baseXrot + rs->xrot)) / 360.0f;
546
moveWindowToViewportPosition (w,
547
rs->moveWindowX - xrot * s->width,
553
UNWRAP (rs, s, preparePaintScreen);
554
(*s->preparePaintScreen) (s, msSinceLastPaint);
555
WRAP (rs, s, preparePaintScreen, rotatePreparePaintScreen);
559
rotateDonePaintScreen (CompScreen *s)
565
if ((!rs->grabbed && !rs->snapTop) || rs->xVelocity || rs->yVelocity)
569
UNWRAP (rs, s, donePaintScreen);
570
(*s->donePaintScreen) (s);
571
WRAP (rs, s, donePaintScreen, rotateDonePaintScreen);
575
rotatePaintScreen (CompScreen *s,
576
const ScreenPaintAttrib *sAttrib,
586
ScreenPaintAttrib sa = *sAttrib;
588
sa.xRotate += rs->baseXrot + rs->xrot;
589
sa.vRotate += rs->yrot;
591
mask &= ~PAINT_SCREEN_REGION_MASK;
592
mask |= PAINT_SCREEN_TRANSFORMED_MASK;
594
UNWRAP (rs, s, paintScreen);
595
status = (*s->paintScreen) (s, &sa, region, mask);
596
WRAP (rs, s, paintScreen, rotatePaintScreen);
600
UNWRAP (rs, s, paintScreen);
601
status = (*s->paintScreen) (s, sAttrib, region, mask);
602
WRAP (rs, s, paintScreen, rotatePaintScreen);
609
rotateInitiate (CompScreen *s,
615
rs->prevPointerX = x;
616
rs->prevPointerY = y;
620
/* some other plugin have already grabbed the screen */
621
if (s->maxGrab - rs->grabIndex)
626
rs->grabIndex = pushScreenGrab (s, s->invisibleCursor);
629
rs->savedPointer.x = rs->prevPointerX;
630
rs->savedPointer.y = rs->prevPointerY;
637
rs->snapTop = rs->opt[ROTATE_SCREEN_OPTION_SNAP_TOP].value.b;
642
rotate (CompScreen *s,
650
rotateInitiate (s, x, y);
655
rs->moveTo += (360.0f / s->size) * direction;
663
rotateWithWindow (CompScreen *s,
674
for (w = s->windows; w; w = w->next)
675
if (s->display->activeWindow == w->id)
681
if (w->type & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
684
if (w->state & CompWindowStateStickyMask)
687
rotateInitiate (s, x, y);
689
rs->moveWindow = w->id;
690
rs->moveWindowX = w->attrib.x;
696
rs->moveTo += (360.0f / s->size) * direction;
704
rotateTerminate (CompScreen *s)
716
rotateHandleEvent (CompDisplay *d,
723
switch (event->type) {
726
s = findScreenAtDisplay (d, event->xkey.root);
731
if (EV_KEY (&rs->opt[ROTATE_SCREEN_OPTION_INITIATE], event))
732
rotateInitiate (s, event->xkey.x_root, event->xkey.y_root);
734
if (EV_KEY (&rs->opt[ROTATE_SCREEN_OPTION_LEFT_WINDOW], event))
735
rotateWithWindow (s, event->xkey.x_root, event->xkey.y_root, -1);
736
else if (EV_KEY (&rs->opt[ROTATE_SCREEN_OPTION_LEFT], event))
737
rotate (s, event->xkey.x_root, event->xkey.y_root, -1);
739
if (EV_KEY (&rs->opt[ROTATE_SCREEN_OPTION_RIGHT_WINDOW], event))
740
rotateWithWindow (s, event->xkey.x_root, event->xkey.y_root, 1);
741
else if (EV_KEY (&rs->opt[ROTATE_SCREEN_OPTION_RIGHT], event))
742
rotate (s, event->xkey.x_root, event->xkey.y_root, 1);
744
if (EV_KEY (&rs->opt[ROTATE_SCREEN_OPTION_TERMINATE], event))
747
if (event->type == KeyPress &&
748
event->xkey.keycode == s->escapeKeyCode)
757
s = findScreenAtDisplay (d, event->xbutton.root);
762
if (EV_BUTTON (&rs->opt[ROTATE_SCREEN_OPTION_INITIATE], event))
764
event->xbutton.x_root,
765
event->xbutton.y_root);
767
if (EV_BUTTON (&rs->opt[ROTATE_SCREEN_OPTION_LEFT_WINDOW], event))
768
rotateWithWindow (s, event->xbutton.x_root,
769
event->xbutton.y_root, -1);
770
else if (EV_BUTTON (&rs->opt[ROTATE_SCREEN_OPTION_LEFT], event))
771
rotate (s, event->xbutton.x_root, event->xbutton.y_root, -1);
773
if (EV_BUTTON (&rs->opt[ROTATE_SCREEN_OPTION_RIGHT_WINDOW], event))
774
rotateWithWindow (s, event->xbutton.x_root,
775
event->xbutton.y_root, 1);
776
else if (EV_BUTTON (&rs->opt[ROTATE_SCREEN_OPTION_RIGHT], event))
777
rotate (s, event->xbutton.x_root, event->xbutton.y_root, 1);
779
if (EV_BUTTON (&rs->opt[ROTATE_SCREEN_OPTION_TERMINATE], event))
784
s = findScreenAtDisplay (d, event->xmotion.root);
789
if (rs->grabIndex && rs->grabbed)
794
pointerDx = event->xmotion.x_root - rs->prevPointerX;
795
pointerDy = event->xmotion.y_root - rs->prevPointerY;
796
rs->prevPointerX = event->xmotion.x_root;
797
rs->prevPointerY = event->xmotion.y_root;
799
if (event->xmotion.x_root < 50 ||
800
event->xmotion.y_root < 50 ||
801
event->xmotion.x_root > s->width - 50 ||
802
event->xmotion.y_root > s->height - 50)
804
rs->prevPointerX = s->width / 2;
805
rs->prevPointerY = s->height / 2;
807
XWarpPointer (d->display, None, s->root, 0, 0, 0, 0,
808
rs->prevPointerX, rs->prevPointerY);
811
if (rs->pointerInvertY)
812
pointerDy = -pointerDy;
814
rs->xVelocity += pointerDx * rs->pointerSensitivity * rs->invert;
815
rs->yVelocity += pointerDy * rs->pointerSensitivity;
824
if (event->xclient.message_type == d->winActiveAtom)
828
w = findWindowAtDisplay (d, event->xclient.window);
833
if (w->attrib.x >= s->width || w->attrib.x + w->width <= 0)
839
XQueryPointer (d->display, s->root,
840
&win, &win, &x, &y, &i, &i, &ui);
842
if (w->attrib.x >= s->width)
843
dx = w->attrib.x / s->width;
845
dx = ((w->attrib.x + w->width) / s->width) - 1;
847
if (dx > (s->size + 1) / 2)
849
else if (dx < -(s->size + 1) / 2)
852
rotate (s, x, y, dx);
856
else if (event->xclient.message_type == d->desktopViewportAtom)
858
s = findScreenAtDisplay (d, event->xclient.window);
863
dx = event->xclient.data.l[0] / s->width - s->x;
870
XQueryPointer (d->display, s->root,
871
&win, &win, &x, &y, &i, &i, &ui);
873
if (dx > (s->size + 1) / 2)
875
else if (dx < -(s->size + 1) / 2)
878
rotate (s, x, y, dx);
886
UNWRAP (rd, d, handleEvent);
887
(*d->handleEvent) (d, event);
888
WRAP (rd, d, handleEvent, rotateHandleEvent);
892
rotateUpdateCubeOptions (CompScreen *s)
898
p = findActivePlugin ("cube");
899
if (p && p->vTable->getScreenOptions)
901
CompOption *options, *option;
904
options = (*p->vTable->getScreenOptions) (s, &nOptions);
905
option = compFindOption (options, nOptions, "in", 0);
907
rs->invert = option->value.b ? -1 : 1;
912
rotateSetScreenOptionForPlugin (CompScreen *s,
915
CompOptionValue *value)
921
UNWRAP (rs, s, setScreenOptionForPlugin);
922
status = (*s->setScreenOptionForPlugin) (s, plugin, name, value);
923
WRAP (rs, s, setScreenOptionForPlugin, rotateSetScreenOptionForPlugin);
925
if (status && strcmp (plugin, "cube") == 0 && strcmp (name, "in") == 0)
926
rotateUpdateCubeOptions (s);
932
rotateInitDisplay (CompPlugin *p,
937
rd = malloc (sizeof (RotateDisplay));
941
rd->screenPrivateIndex = allocateScreenPrivateIndex (d);
942
if (rd->screenPrivateIndex < 0)
948
WRAP (rd, d, handleEvent, rotateHandleEvent);
950
d->privates[displayPrivateIndex].ptr = rd;
956
rotateFiniDisplay (CompPlugin *p,
961
freeScreenPrivateIndex (d, rd->screenPrivateIndex);
963
UNWRAP (rd, d, handleEvent);
969
rotateInitScreen (CompPlugin *p,
974
ROTATE_DISPLAY (s->display);
976
rs = malloc (sizeof (RotateScreen));
983
rs->xVelocity = 0.0f;
985
rs->yVelocity = 0.0f;
994
rs->savedPointer.x = 0;
995
rs->savedPointer.y = 0;
996
rs->prevPointerX = 0;
997
rs->prevPointerY = 0;
1000
rs->snapTop = FALSE;
1002
rs->acceleration = ROTATE_ACCELERATION_DEFAULT;
1004
rs->pointerInvertY = ROTATE_POINTER_INVERT_Y_DEFAULT;
1005
rs->pointerSensitivity = ROTATE_POINTER_SENSITIVITY_DEFAULT *
1006
ROTATE_POINTER_SENSITIVITY_FACTOR;
1008
rs->speed = ROTATE_SPEED_DEFAULT;
1009
rs->timestep = ROTATE_TIMESTEP_DEFAULT;
1011
rotateScreenInitOptions (rs, s->display->display);
1013
addScreenBinding (s, &rs->opt[ROTATE_SCREEN_OPTION_INITIATE].value.bind);
1014
addScreenBinding (s, &rs->opt[ROTATE_SCREEN_OPTION_LEFT].value.bind);
1015
addScreenBinding (s, &rs->opt[ROTATE_SCREEN_OPTION_RIGHT].value.bind);
1016
addScreenBinding (s,
1017
&rs->opt[ROTATE_SCREEN_OPTION_LEFT_WINDOW].value.bind);
1018
addScreenBinding (s,
1019
&rs->opt[ROTATE_SCREEN_OPTION_RIGHT_WINDOW].value.bind);
1021
WRAP (rs, s, preparePaintScreen, rotatePreparePaintScreen);
1022
WRAP (rs, s, donePaintScreen, rotateDonePaintScreen);
1023
WRAP (rs, s, paintScreen, rotatePaintScreen);
1024
WRAP (rs, s, setScreenOptionForPlugin, rotateSetScreenOptionForPlugin);
1026
s->privates[rd->screenPrivateIndex].ptr = rs;
1028
rotateUpdateCubeOptions (s);
1034
rotateFiniScreen (CompPlugin *p,
1039
UNWRAP (rs, s, preparePaintScreen);
1040
UNWRAP (rs, s, donePaintScreen);
1041
UNWRAP (rs, s, paintScreen);
1042
UNWRAP (rs, s, setScreenOptionForPlugin);
1048
rotateInit (CompPlugin *p)
1050
displayPrivateIndex = allocateDisplayPrivateIndex ();
1051
if (displayPrivateIndex < 0)
1058
rotateFini (CompPlugin *p)
1060
if (displayPrivateIndex >= 0)
1061
freeDisplayPrivateIndex (displayPrivateIndex);
1064
CompPluginDep rotateDeps[] = {
1065
{ CompPluginRuleAfter, "cube" }
1068
CompPluginVTable rotateVTable = {
1071
"Rotate desktop cube",
1080
0, /* GetDisplayOptions */
1081
0, /* SetDisplayOption */
1082
rotateGetScreenOptions,
1083
rotateSetScreenOption,
1085
sizeof (rotateDeps) / sizeof (rotateDeps[0])
1089
getCompPluginInfo (void)
1091
return &rotateVTable;