1 #define _GNU_SOURCE
2 #include <string.h>
3 #include <stdlib.h>
4 #include <math.h>
5 
6 #include <compiz-core.h>
7 #include "compiz-animation.h"
8 
9 
10 typedef struct _WaveParam
11 {
12     float halfWidth;
13     float amp;
14     float pos;
15 } WaveParam;
16 
17 typedef enum
18 {
19     ZoomFromCenterOff = 0,
20     ZoomFromCenterMin,
21     ZoomFromCenterCreate,
22     ZoomFromCenterOn
23 } ZoomFromCenter;
24 #define LAST_ZOOM_FROM_CENTER 3
25 
26 //TODO remove #define RANDOM_EFFECT_OFFSET 2 /* skip None and Random */
27 
28 typedef struct _RestackInfo
29 {
30     CompWindow *wRestacked, *wStart, *wEnd, *wOldAbove;
31     Bool raised;
32 } RestackInfo;
33 
34 typedef struct _IdValuePair
35 {
36     const ExtensionPluginInfo *pluginInfo;
37     int optionId;
38     CompOptionValue value;
39 } IdValuePair;
40 
41 typedef struct _OptionSet
42 {
43     int nPairs;
44     IdValuePair *pairs;
45 } OptionSet;
46 
47 typedef struct _OptionSets
48 {
49     int nSets;
50     OptionSet *sets;
51 } OptionSets;
52 
53 typedef struct _EffectSet
54 {
55     int n;
56     AnimEffect *effects;
57 } EffectSet;
58 
59 extern int animDisplayPrivateIndex;
60 extern int animFunctionsPrivateIndex;
61 extern CompMetadata animMetadata;
62 
63 extern AnimEffect AnimEffectNone;
64 extern AnimEffect AnimEffectRandom;
65 extern AnimEffect AnimEffectCurvedFold;
66 extern AnimEffect AnimEffectDodge;
67 extern AnimEffect AnimEffectDream;
68 extern AnimEffect AnimEffectFade;
69 extern AnimEffect AnimEffectFocusFade;
70 extern AnimEffect AnimEffectGlide1;
71 extern AnimEffect AnimEffectGlide2;
72 extern AnimEffect AnimEffectHorizontalFolds;
73 extern AnimEffect AnimEffectMagicLamp;
74 extern AnimEffect AnimEffectRollUp;
75 extern AnimEffect AnimEffectSidekick;
76 extern AnimEffect AnimEffectVacuum;
77 extern AnimEffect AnimEffectWave;
78 extern AnimEffect AnimEffectZoom;
79 
80 #define NUM_EFFECTS 16
81 
82 extern int customOptionOptionIds[AnimEventNum];
83 
84 typedef enum _AnimDisplayOptions
85 {
86     ANIM_DISPLAY_OPTION_ABI,
87     ANIM_DISPLAY_OPTION_INDEX,
88     ANIM_DISPLAY_OPTION_NUM
89 } AnimDisplayOptions;
90 
91 typedef struct _AnimDisplay
92 {
93     int screenPrivateIndex;
94     HandleEventProc handleEvent;
95     HandleCompizEventProc handleCompizEvent;
96     int activeWindow;
97     CompMatch neverAnimateMatch;
98 
99     CompOption opt[ANIM_DISPLAY_OPTION_NUM];
100 } AnimDisplay;
101 
102 typedef struct _PluginEventInfo
103 {
104     char *pluginName;
105     char *activateEventName;
106 } PluginEventInfo;
107 
108 
109 #define NUM_SWITCHERS 6
110 #define NUM_WATCHED_PLUGINS (NUM_SWITCHERS + 2)
111 
112 typedef enum
113 {
114     // Event settings
115     ANIM_SCREEN_OPTION_OPEN_EFFECTS = 0,
116     ANIM_SCREEN_OPTION_OPEN_DURATIONS,
117     ANIM_SCREEN_OPTION_OPEN_MATCHES,
118     ANIM_SCREEN_OPTION_OPEN_OPTIONS,
119     ANIM_SCREEN_OPTION_OPEN_RANDOM_EFFECTS,
120     ANIM_SCREEN_OPTION_CLOSE_EFFECTS,
121     ANIM_SCREEN_OPTION_CLOSE_DURATIONS,
122     ANIM_SCREEN_OPTION_CLOSE_MATCHES,
123     ANIM_SCREEN_OPTION_CLOSE_OPTIONS,
124     ANIM_SCREEN_OPTION_CLOSE_RANDOM_EFFECTS,
125     ANIM_SCREEN_OPTION_MINIMIZE_EFFECTS,
126     ANIM_SCREEN_OPTION_MINIMIZE_DURATIONS,
127     ANIM_SCREEN_OPTION_MINIMIZE_MATCHES,
128     ANIM_SCREEN_OPTION_MINIMIZE_OPTIONS,
129     ANIM_SCREEN_OPTION_MINIMIZE_RANDOM_EFFECTS,
130     ANIM_SCREEN_OPTION_SHADE_EFFECTS,
131     ANIM_SCREEN_OPTION_SHADE_DURATIONS,
132     ANIM_SCREEN_OPTION_SHADE_MATCHES,
133     ANIM_SCREEN_OPTION_SHADE_OPTIONS,
134     ANIM_SCREEN_OPTION_SHADE_RANDOM_EFFECTS,
135     ANIM_SCREEN_OPTION_FOCUS_EFFECTS,
136     ANIM_SCREEN_OPTION_FOCUS_DURATIONS,
137     ANIM_SCREEN_OPTION_FOCUS_MATCHES,
138     ANIM_SCREEN_OPTION_FOCUS_OPTIONS,
139     // Misc. settings
140     ANIM_SCREEN_OPTION_ALL_RANDOM,
141     ANIM_SCREEN_OPTION_TIME_STEP,
142     // Effect settings
143     ANIM_SCREEN_OPTION_CURVED_FOLD_AMP_MULT,
144     ANIM_SCREEN_OPTION_CURVED_FOLD_Z2TOM,
145     ANIM_SCREEN_OPTION_DODGE_GAP_RATIO,
146     ANIM_SCREEN_OPTION_DREAM_Z2TOM,
147     ANIM_SCREEN_OPTION_GLIDE1_AWAY_POS,
148     ANIM_SCREEN_OPTION_GLIDE1_AWAY_ANGLE,
149     ANIM_SCREEN_OPTION_GLIDE1_Z2TOM,
150     ANIM_SCREEN_OPTION_GLIDE2_AWAY_POS,
151     ANIM_SCREEN_OPTION_GLIDE2_AWAY_ANGLE,
152     ANIM_SCREEN_OPTION_GLIDE2_Z2TOM,
153     ANIM_SCREEN_OPTION_HORIZONTAL_FOLDS_AMP_MULT,
154     ANIM_SCREEN_OPTION_HORIZONTAL_FOLDS_NUM_FOLDS,
155     ANIM_SCREEN_OPTION_HORIZONTAL_FOLDS_Z2TOM,
156     ANIM_SCREEN_OPTION_MAGIC_LAMP_MOVING_END,
157     ANIM_SCREEN_OPTION_MAGIC_LAMP_GRID_RES,
158     ANIM_SCREEN_OPTION_MAGIC_LAMP_MAX_WAVES,
159     ANIM_SCREEN_OPTION_MAGIC_LAMP_WAVE_AMP_MIN,
160     ANIM_SCREEN_OPTION_MAGIC_LAMP_WAVE_AMP_MAX,
161     ANIM_SCREEN_OPTION_MAGIC_LAMP_OPEN_START_WIDTH,
162     ANIM_SCREEN_OPTION_ROLLUP_FIXED_INTERIOR,
163     ANIM_SCREEN_OPTION_SIDEKICK_NUM_ROTATIONS,
164     ANIM_SCREEN_OPTION_SIDEKICK_SPRINGINESS,
165     ANIM_SCREEN_OPTION_SIDEKICK_ZOOM_FROM_CENTER,
166     ANIM_SCREEN_OPTION_VACUUM_MOVING_END,
167     ANIM_SCREEN_OPTION_VACUUM_GRID_RES,
168     ANIM_SCREEN_OPTION_VACUUM_OPEN_START_WIDTH,
169     ANIM_SCREEN_OPTION_WAVE_WIDTH,
170     ANIM_SCREEN_OPTION_WAVE_AMP_MULT,
171     ANIM_SCREEN_OPTION_ZOOM_FROM_CENTER,
172     ANIM_SCREEN_OPTION_ZOOM_SPRINGINESS,
173 
174     ANIM_SCREEN_OPTION_NUM
175 } AnimScreenOptions;
176 
177 // This must have the value of the first "effect setting" above
178 // in AnimScreenOptions
179 #define NUM_NONEFFECT_OPTIONS ANIM_SCREEN_OPTION_CURVED_FOLD_AMP_MULT
180 
181 
182 typedef struct _AnimScreen
183 {
184     int windowPrivateIndex;
185 
186     PreparePaintScreenProc preparePaintScreen;
187     DonePaintScreenProc donePaintScreen;
188     PaintOutputProc paintOutput;
189     PaintWindowProc paintWindow;
190     DamageWindowRectProc damageWindowRect;
191     AddWindowGeometryProc addWindowGeometry;
192     DrawWindowTextureProc drawWindowTexture;
193     InitWindowWalkerProc initWindowWalker;
194 
195     WindowResizeNotifyProc windowResizeNotify;
196     WindowMoveNotifyProc windowMoveNotify;
197     WindowGrabNotifyProc windowGrabNotify;
198     WindowUngrabNotifyProc windowUngrabNotify;
199 
200     CompOption opt[ANIM_SCREEN_OPTION_NUM];
201 
202     Bool aWinWasRestackedJustNow; // a window was restacked this paint round
203 
204     Bool pluginActive[NUM_WATCHED_PLUGINS];
205 
206     Window *lastClientListStacking; // to store last known stacking order
207     int nLastClientListStacking;
208     int startCountdown;
209     // to mark windows as "created" if they were opened before compiz
210     // was started and to prevent open animation happening for existing windows
211     // at compiz startup
212 
213     Bool animInProgress;
214 
215     int walkerAnimCount; // count of how many windows are currently involved in
216 			 // animations that require walker (dodge & focus fade)
217 
218     EffectSet randomEffects[AnimEventNum];
219 
220     OptionSets eventOptionSets[AnimEventNum];
221 
222     // Effect extensions
223     ExtensionPluginInfo **extensionPlugins;
224     unsigned int nExtensionPlugins;
225     unsigned int maxExtensionPlugins;
226 
227     // List of all possible effects for each event
228     AnimEffect *eventEffectsAllowed[AnimEventNum];
229     unsigned int nEventEffectsAllowed[AnimEventNum];
230     unsigned int maxEventEffectsAllowed[AnimEventNum];
231 
232     // List of chosen effects for each event
233     EffectSet eventEffects[AnimEventNum];
234 
235     CompOutput *output;
236 } AnimScreen;
237 
238 typedef struct _AnimWindow
239 {
240     AnimWindowCommon com;
241 
242     unsigned int state;
243     unsigned int newState;
244 
245     Bool animInitialized;	// whether the animation effect (not the window) is initialized
246     float remainderSteps;
247 
248     Bool nowShaded;
249     Bool grabbed;
250 
251     int unmapCnt;
252     int destroyCnt;
253 
254     Bool ignoreDamage;
255 
256     int curAnimSelectionRow;
257     int prevAnimSelectionRow;	// For the case when one event interrupts another
258 
259     Box BB;       // Bounding box for damage region calc. of CompTransform fx
260     Box lastBB;   // Last bounding box
261 
262     // for magic lamp
263     Bool minimizeToTop;
264     int magicLampWaveCount;
265     WaveParam *magicLampWaves;
266 
267     // for glide effect
268     float glideModRotAngle;	// The angle of rotation modulo 360
269 
270     // for zoom
271     float numZoomRotations;
272 
273     // for focus fade & dodge
274     RestackInfo *restackInfo;   // restack info if window was restacked this paint round
275     CompWindow *winToBePaintedBeforeThis; // Window which should be painted before this
276     CompWindow *winThisIsPaintedBefore; // the inverse relation of the above
277     CompWindow *moreToBePaintedPrev; // doubly linked list for windows underneath that
278     CompWindow *moreToBePaintedNext; //   raise together with this one
279     Bool created;
280     Bool configureNotified;     // was configureNotified before restack check
281     CompWindow *winPassingThrough; // win. passing through this one during focus effect
282 
283     // for dodge
284     Bool isDodgeSubject;	// TRUE if this window is the cause of dodging
285     Bool skipPostPrepareScreen;
286     CompWindow *dodgeSubjectWin;// The window being dodged
287     float dodgeMaxAmount;	/* max # pixels it should dodge
288 				   (neg. values dodge left) */
289     int dodgeOrder;		// dodge order (used temporarily)
290     Bool dodgeDirection;	// 0: up, down, left, right
291 
292     CompWindow *dodgeChainStart;// for the subject window
293     CompWindow *dodgeChainPrev;	// for dodging windows
294     CompWindow *dodgeChainNext;	// for dodging windows
295     Bool walkerOverNewCopy;     // whether walker is on the copy at the new pos.
296     unsigned int walkerVisitCount; // how many times walker has visited this window
297 } AnimWindow;
298 
299 #define GET_ANIM_DISPLAY(d)						\
300     ((AnimDisplay *) (d)->base.privates[animDisplayPrivateIndex].ptr)
301 
302 #define ANIM_DISPLAY(d)				\
303     AnimDisplay *ad = GET_ANIM_DISPLAY (d)
304 
305 #define GET_ANIM_SCREEN(s, ad)						\
306     ((AnimScreen *) (s)->base.privates[(ad)->screenPrivateIndex].ptr)
307 
308 #define ANIM_SCREEN(s)							\
309     AnimScreen *as = GET_ANIM_SCREEN (s, GET_ANIM_DISPLAY (s->display))
310 
311 #define GET_ANIM_WINDOW(w, as)						\
312     ((AnimWindow *) (w)->base.privates[(as)->windowPrivateIndex].ptr)
313 
314 #define ANIM_WINDOW(w)					     \
315     AnimWindow *aw = GET_ANIM_WINDOW (w,                     \
316 		     GET_ANIM_SCREEN (w->screen,             \
317 		     GET_ANIM_DISPLAY (w->screen->display)))
318 
319 // up, down, left, right
320 #define DODGE_AMOUNT(w, dw, dir)			\
321     ((dir) == 0 ? BORDER_Y(w) - (BORDER_Y(dw) + BORDER_H(dw)) :	\
322      (dir) == 1 ? (BORDER_Y(w) + BORDER_H(w)) - BORDER_Y(dw) :	\
323      (dir) == 2 ? BORDER_X(w) - (BORDER_X(dw) + BORDER_W(dw)) :	\
324      (BORDER_X(w) + BORDER_W(w)) - BORDER_X(dw))
325 
326 // up, down, left, right
327 #define DODGE_AMOUNT_BOX(box, dw, dir)				\
328     ((dir) == 0 ? (box).y - (BORDER_Y(dw) + BORDER_H(dw)) :		\
329      (dir) == 1 ? ((box).y + (box).height) - BORDER_Y(dw) :	\
330      (dir) == 2 ? (box).x - (BORDER_X(dw) + BORDER_W(dw)) :		\
331      ((box).x + (box).width) - BORDER_X(dw))
332 
333 // ratio of perceived length of animation compared to real duration
334 // to make it appear to have the same speed with other animation effects
335 
336 #define DREAM_PERCEIVED_T 0.6f
337 #define ROLLUP_PERCEIVED_T 0.6f
338 
339 
340 /*
341  * Function prototypes
342  *
343  */
344 
345 /* animation.c*/
346 
347 void
348 modelInitObjects (Model * model,
349 		  int x, int y,
350 		  int width, int height);
351 
352 void
353 postAnimationCleanup (CompWindow * w);
354 
355 float
356 defaultAnimProgress (CompWindow *w);
357 
358 float
359 sigmoidAnimProgress (CompWindow *w);
360 
361 float
362 decelerateProgressCustom (float progress,
363 			  float minx, float maxx);
364 
365 float
366 decelerateProgress (float progress);
367 
368 void
369 applyTransformToObject (Object *obj, GLfloat *mat);
370 
371 AnimDirection
372 getActualAnimDirection (CompWindow * w,
373 			AnimDirection dir,
374 			Bool openDir);
375 
376 void
377 defaultAnimStep (CompWindow * w,
378 		 float time);
379 
380 Bool
381 defaultAnimInit (CompWindow * w);
382 
383 void
384 defaultUpdateWindowTransform (CompWindow *w,
385 			      CompTransform *wTransform);
386 
387 Bool
388 animZoomToIcon (CompWindow *w);
389 
390 void
391 animDrawWindowGeometry(CompWindow * w);
392 
393 Bool
394 getMousePointerXY(CompScreen * s, short *x, short *y);
395 
396 void
397 expandBoxWithBox (Box *target, Box *source);
398 
399 void
400 expandBoxWithPoint (Box *target, float fx, float fy);
401 
402 void
403 updateBBWindow (CompOutput *output,
404 		CompWindow * w,
405 		Box *BB);
406 
407 void
408 updateBBScreen (CompOutput *output,
409 		CompWindow * w,
410 		Box *BB);
411 
412 void
413 compTransformUpdateBB (CompOutput *output,
414 		       CompWindow *w,
415 		       Box *BB);
416 
417 void
418 prepareTransform (CompScreen *s,
419 		  CompOutput *output,
420 		  CompTransform *resultTransform,
421 		  CompTransform *transform);
422 
423 void
424 perspectiveDistortAndResetZ (CompScreen *s,
425 			     CompTransform *wTransform);
426 
427 void
428 applyPerspectiveSkew (CompOutput *output,
429 		      CompTransform *transform,
430 		      Point *center);
431 
432 inline void
433 applyTransform (CompTransform *wTransform,
434 		CompTransform *transform);
435 
436 float
437 getProgressAndCenter (CompWindow *w,
438 		      Point *center);
439 
440 /* curvedfold.c */
441 
442 void
443 fxCurvedFoldModelStep (CompWindow *w,
444 		       float time);
445 
446 void
447 fxFoldUpdateWindowAttrib (CompWindow * w,
448 			  WindowPaintAttrib * wAttrib);
449 
450 Bool
451 fxCurvedFoldZoomToIcon (CompWindow *w);
452 
453 /* dodge.c */
454 
455 void
456 fxDodgePostPreparePaintScreen (CompWindow *w);
457 
458 void
459 fxDodgeUpdateWindowTransform (CompWindow *w,
460 			      CompTransform *wTransform);
461 
462 void
463 fxDodgeAnimStep (CompWindow *w,
464 		 float time);
465 
466 void
467 fxDodgeUpdateBB (CompOutput *output,
468 		 CompWindow * w,
469 		 Box *BB);
470 
471 /* dream.c */
472 
473 Bool
474 fxDreamAnimInit (CompWindow * w);
475 
476 void
477 fxDreamModelStep (CompWindow * w,
478 		  float time);
479 
480 void
481 fxDreamUpdateWindowAttrib (CompWindow * w,
482 			   WindowPaintAttrib * wAttrib);
483 
484 Bool
485 fxDreamZoomToIcon (CompWindow *w);
486 
487 /* fade.c */
488 
489 void
490 fxFadeUpdateWindowAttrib (CompWindow * w,
491 			  WindowPaintAttrib *wAttrib);
492 
493 
494 /* focusfade.c */
495 
496 void
497 fxFocusFadeUpdateWindowAttrib (CompWindow * w,
498 			       WindowPaintAttrib *wAttrib);
499 
500 /* glide.c */
501 
502 Bool
503 fxGlideInit (CompWindow *w);
504 
505 void
506 fxGlideUpdateWindowAttrib (CompWindow * w,
507 			   WindowPaintAttrib *wAttrib);
508 
509 void
510 fxGlideAnimStep (CompWindow *w,
511 		 float time);
512 
513 float
514 fxGlideAnimProgress (CompWindow *w);
515 
516 void
517 fxGlideUpdateWindowTransform (CompWindow *w,
518 			      CompTransform *wTransform);
519 
520 void
521 fxGlidePrePaintWindow (CompWindow * w);
522 
523 void
524 fxGlidePostPaintWindow (CompWindow * w);
525 
526 Bool
527 fxGlideZoomToIcon (CompWindow *w);
528 
529 /* horizontalfold.c */
530 
531 void
532 fxHorizontalFoldsModelStep (CompWindow *w,
533 			    float time);
534 
535 void
536 fxHorizontalFoldsInitGrid (CompWindow *w,
537 			   int *gridWidth,
538 			   int *gridHeight);
539 
540 Bool
541 fxHorizontalFoldsZoomToIcon (CompWindow *w);
542 
543 /* magiclamp.c */
544 
545 void
546 fxMagicLampInitGrid (CompWindow *w,
547 		     int *gridWidth,
548 		     int *gridHeight);
549 
550 void
551 fxVacuumInitGrid (CompWindow *w,
552 		  int *gridWidth,
553 		  int *gridHeight);
554 
555 Bool
556 fxMagicLampInit (CompWindow * w);
557 
558 void
559 fxMagicLampModelStep (CompWindow * w,
560 		      float time);
561 
562 /* options.c */
563 
564 void
565 updateOptionSets (CompScreen *s,
566 		  AnimEvent e);
567 
568 void
569 freeAllOptionSets (AnimScreen *as);
570 
571 CompOptionValue *
572 animGetPluginOptVal (CompWindow *w,
573 		     ExtensionPluginInfo *pluginInfo,
574 		     int optionId);
575 
576 OPTION_GETTERS_HDR
577 
578 /* rollup.c */
579 
580 void
581 fxRollUpModelStep (CompWindow *w,
582 		   float time);
583 
584 void fxRollUpInitGrid (CompWindow *w,
585 		       int *gridWidth,
586 		       int *gridHeight);
587 
588 Bool
589 fxRollUpAnimInit (CompWindow * w);
590 
591 /* wave.c */
592 
593 void
594 fxWaveModelStep (CompWindow * w,
595 		 float time);
596 
597 
598 /* zoomside.c */
599 
600 void
601 fxZoomUpdateWindowAttrib (CompWindow * w,
602 			  WindowPaintAttrib *wAttrib);
603 
604 void
605 fxZoomAnimProgress (CompWindow *w,
606 		    float *moveProgress,
607 		    float *scaleProgress,
608 		    Bool neverSpringy);
609 
610 Bool
611 fxSidekickInit (CompWindow *w);
612 
613 Bool
614 fxZoomInit (CompWindow * w);
615 
616 void
617 applyZoomTransform (CompWindow * w);
618 
619 void
620 getZoomCenterScale (CompWindow *w,
621 		    Point *pCurCenter, Point *pCurScale);
622 
623