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>
31
#define FADE_SPEED_DEFAULT 5.0f
32
#define FADE_SPEED_MIN 0.1f
33
#define FADE_SPEED_MAX 10.0f
34
#define FADE_SPEED_PRECISION 0.1f
36
static char *winType[] = {
47
#define N_WIN_TYPE (sizeof (winType) / sizeof (winType[0]))
49
static int displayPrivateIndex;
51
typedef struct _FadeDisplay {
52
int screenPrivateIndex;
53
HandleEventProc handleEvent;
57
#define FADE_SCREEN_OPTION_FADE_SPEED 0
58
#define FADE_SCREEN_OPTION_WINDOW_TYPE 1
59
#define FADE_SCREEN_OPTION_NUM 2
61
typedef struct _FadeScreen {
62
int windowPrivateIndex;
66
CompOption opt[FADE_SCREEN_OPTION_NUM];
68
PreparePaintScreenProc preparePaintScreen;
69
PaintWindowProc paintWindow;
70
DamageWindowRectProc damageWindowRect;
71
FocusWindowProc focusWindow;
76
typedef struct _FadeWindow {
87
#define GET_FADE_DISPLAY(d) \
88
((FadeDisplay *) (d)->privates[displayPrivateIndex].ptr)
90
#define FADE_DISPLAY(d) \
91
FadeDisplay *fd = GET_FADE_DISPLAY (d)
93
#define GET_FADE_SCREEN(s, fd) \
94
((FadeScreen *) (s)->privates[(fd)->screenPrivateIndex].ptr)
96
#define FADE_SCREEN(s) \
97
FadeScreen *fs = GET_FADE_SCREEN (s, GET_FADE_DISPLAY (s->display))
99
#define GET_FADE_WINDOW(w, fs) \
100
((FadeWindow *) (w)->privates[(fs)->windowPrivateIndex].ptr)
102
#define FADE_WINDOW(w) \
103
FadeWindow *fw = GET_FADE_WINDOW (w, \
104
GET_FADE_SCREEN (w->screen, \
105
GET_FADE_DISPLAY (w->screen->display)))
107
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
110
fadeGetScreenOptions (CompScreen *screen,
113
FADE_SCREEN (screen);
115
*count = NUM_OPTIONS (fs);
120
fadeSetScreenOption (CompScreen *screen,
122
CompOptionValue *value)
127
FADE_SCREEN (screen);
129
o = compFindOption (fs->opt, NUM_OPTIONS (fs), name, &index);
134
case FADE_SCREEN_OPTION_FADE_SPEED:
135
if (compSetFloatOption (o, value))
137
fs->fadeTime = 1000.0f / o->value.f;
141
case FADE_SCREEN_OPTION_WINDOW_TYPE:
142
if (compSetOptionList (o, value))
144
fs->wMask = compWindowTypeMaskFromStringList (&o->value);
145
fs->wMask &= ~CompWindowTypeDesktopMask;
156
fadeScreenInitOptions (FadeScreen *fs)
161
o = &fs->opt[FADE_SCREEN_OPTION_FADE_SPEED];
162
o->name = "fade_speed";
163
o->shortDesc = "Fade Speed";
164
o->longDesc = "Window fade speed";
165
o->type = CompOptionTypeFloat;
166
o->value.f = FADE_SPEED_DEFAULT;
167
o->rest.f.min = FADE_SPEED_MIN;
168
o->rest.f.max = FADE_SPEED_MAX;
169
o->rest.f.precision = FADE_SPEED_PRECISION;
171
o = &fs->opt[FADE_SCREEN_OPTION_WINDOW_TYPE];
172
o->name = "window_types";
173
o->shortDesc = "Window Types";
174
o->longDesc = "Window types that should be fading";
175
o->type = CompOptionTypeList;
176
o->value.list.type = CompOptionTypeString;
177
o->value.list.nValue = N_WIN_TYPE;
178
o->value.list.value = malloc (sizeof (CompOptionValue) * N_WIN_TYPE);
179
for (i = 0; i < N_WIN_TYPE; i++)
180
o->value.list.value[i].s = strdup (winType[i]);
181
o->rest.s.string = windowTypeString;
182
o->rest.s.nString = nWindowTypeString;
184
fs->wMask = compWindowTypeMaskFromStringList (&o->value);
188
fadePreparePaintScreen (CompScreen *s,
189
int msSinceLastPaint)
193
fs->steps = (msSinceLastPaint * OPAQUE) / fs->fadeTime;
197
UNWRAP (fs, s, preparePaintScreen);
198
(*s->preparePaintScreen) (s, msSinceLastPaint);
199
WRAP (fs, s, preparePaintScreen, fadePreparePaintScreen);
203
fadePaintWindow (CompWindow *w,
204
const WindowPaintAttrib *attrib,
208
CompScreen *s = w->screen;
214
if (!w->screen->canDoSlightlySaturated)
215
fw->saturation = attrib->saturation;
217
if (fw->opacity != attrib->opacity ||
218
fw->brightness != attrib->brightness ||
219
fw->saturation != attrib->saturation)
225
opacity = fw->opacity;
226
if (attrib->opacity > fw->opacity)
228
opacity = fw->opacity + fs->steps;
229
if (opacity > attrib->opacity)
230
opacity = attrib->opacity;
232
else if (attrib->opacity < fw->opacity)
234
if (w->type & CompWindowTypeUnknownMask)
235
opacity = fw->opacity - (fs->steps >> 1);
237
opacity = fw->opacity - fs->steps;
239
if (opacity < attrib->opacity)
240
opacity = attrib->opacity;
243
brightness = fw->brightness;
244
if (attrib->brightness > fw->brightness)
246
brightness = fw->brightness + (fs->steps / 12);
247
if (brightness > attrib->brightness)
248
brightness = attrib->brightness;
250
else if (attrib->brightness < fw->brightness)
252
brightness = fw->brightness - (fs->steps / 12);
253
if (brightness < attrib->brightness)
254
brightness = attrib->brightness;
257
saturation = fw->saturation;
258
if (attrib->saturation > fw->saturation)
260
saturation = fw->saturation + (fs->steps / 6);
261
if (saturation > attrib->saturation)
262
saturation = attrib->saturation;
264
else if (attrib->saturation < fw->saturation)
266
saturation = fw->saturation - (fs->steps / 6);
267
if (saturation < attrib->saturation)
268
saturation = attrib->saturation;
273
WindowPaintAttrib fAttrib = *attrib;
275
fAttrib.opacity = opacity;
276
fAttrib.brightness = brightness;
277
fAttrib.saturation = saturation;
279
UNWRAP (fs, s, paintWindow);
280
status = (*s->paintWindow) (w, &fAttrib, region, mask);
281
WRAP (fs, s, paintWindow, fadePaintWindow);
285
fw->opacity = opacity;
286
fw->brightness = brightness;
287
fw->saturation = saturation;
289
if (opacity != attrib->opacity ||
290
brightness != attrib->brightness ||
291
saturation != attrib->saturation)
305
while (fw->destroyCnt)
311
return (mask & PAINT_WINDOW_SOLID_MASK) ? FALSE : TRUE;
316
UNWRAP (fs, s, paintWindow);
317
status = (*s->paintWindow) (w, attrib, region, mask);
318
WRAP (fs, s, paintWindow, fadePaintWindow);
325
fadeAddDisplayModal (CompDisplay *d,
331
if (!(w->state & CompWindowStateDisplayModalMask))
340
if (fd->displayModals == 1)
344
for (s = d->screens; s; s = s->next)
346
for (w = s->windows; w; w = w->next)
353
w->paint.brightness = 0x8080;
354
w->paint.saturation = 0;
363
fadeRemoveDisplayModal (CompDisplay *d,
375
if (fd->displayModals == 0)
379
for (s = d->screens; s; s = s->next)
381
for (w = s->windows; w; w = w->next)
390
w->paint.brightness = w->brightness;
391
w->paint.saturation = w->saturation;
401
fadeHandleEvent (CompDisplay *d,
408
switch (event->type) {
410
w = findWindowAtDisplay (d, event->xdestroywindow.window);
413
FADE_SCREEN (w->screen);
415
if (w->texture.pixmap && (fs->wMask & w->type))
419
w->paint.opacity = 0;
427
fadeRemoveDisplayModal (d, w);
431
w = findWindowAtDisplay (d, event->xunmap.window);
434
FADE_SCREEN (w->screen);
436
if (w->texture.pixmap && (fs->wMask & w->type))
440
w->paint.opacity = 0;
448
fadeRemoveDisplayModal (d, w);
452
w = findWindowAtDisplay (d, event->xunmap.window);
457
if (!(w->type & CompWindowTypeDesktopMask))
458
w->paint.opacity = getWindowProp32 (d, w->id,
468
if (w->state & CompWindowStateDisplayModalMask)
469
fadeAddDisplayModal (d, w);
475
UNWRAP (fd, d, handleEvent);
476
(*d->handleEvent) (d, event);
477
WRAP (fd, d, handleEvent, fadeHandleEvent);
479
switch (event->type) {
481
if (event->xproperty.atom == d->winStateAtom)
483
w = findWindowAtDisplay (d, event->xproperty.window);
484
if (w && w->attrib.map_state == IsViewable)
486
if (w->state & CompWindowStateDisplayModalMask)
487
fadeAddDisplayModal (d, w);
489
fadeRemoveDisplayModal (d, w);
497
fadeDamageWindowRect (CompWindow *w,
503
FADE_SCREEN (w->screen);
509
if (fs->wMask & w->type)
512
fw->opacity = w->paint.opacity;
515
UNWRAP (fs, w->screen, damageWindowRect);
516
status = (*w->screen->damageWindowRect) (w, initial, rect);
517
WRAP (fs, w->screen, damageWindowRect, fadeDamageWindowRect);
523
fadeFocusWindow (CompWindow *w)
527
FADE_SCREEN (w->screen);
530
if (fw->destroyCnt || fw->unmapCnt)
533
UNWRAP (fs, w->screen, focusWindow);
534
status = (*w->screen->focusWindow) (w);
535
WRAP (fs, w->screen, focusWindow, fadeFocusWindow);
541
fadeInitDisplay (CompPlugin *p,
546
fd = malloc (sizeof (FadeDisplay));
550
fd->screenPrivateIndex = allocateScreenPrivateIndex (d);
551
if (fd->screenPrivateIndex < 0)
557
fd->displayModals = 0;
559
WRAP (fd, d, handleEvent, fadeHandleEvent);
561
d->privates[displayPrivateIndex].ptr = fd;
567
fadeFiniDisplay (CompPlugin *p,
572
freeScreenPrivateIndex (d, fd->screenPrivateIndex);
574
UNWRAP (fd, d, handleEvent);
580
fadeInitScreen (CompPlugin *p,
585
FADE_DISPLAY (s->display);
587
fs = malloc (sizeof (FadeScreen));
591
fs->windowPrivateIndex = allocateWindowPrivateIndex (s);
592
if (fs->windowPrivateIndex < 0)
599
fs->fadeTime = 1000.0f / FADE_SPEED_DEFAULT;
601
fadeScreenInitOptions (fs);
603
WRAP (fs, s, preparePaintScreen, fadePreparePaintScreen);
604
WRAP (fs, s, paintWindow, fadePaintWindow);
605
WRAP (fs, s, damageWindowRect, fadeDamageWindowRect);
606
WRAP (fs, s, focusWindow, fadeFocusWindow);
608
s->privates[fd->screenPrivateIndex].ptr = fs;
614
fadeFiniScreen (CompPlugin *p,
619
freeWindowPrivateIndex (s, fs->windowPrivateIndex);
621
UNWRAP (fs, s, preparePaintScreen);
622
UNWRAP (fs, s, paintWindow);
623
UNWRAP (fs, s, damageWindowRect);
624
UNWRAP (fs, s, focusWindow);
630
fadeInitWindow (CompPlugin *p,
635
FADE_SCREEN (w->screen);
637
fw = malloc (sizeof (FadeWindow));
641
fw->opacity = w->paint.opacity;
642
fw->brightness = w->paint.brightness;
643
fw->saturation = w->paint.saturation;
650
w->privates[fs->windowPrivateIndex].ptr = fw;
652
if (w->attrib.map_state == IsViewable)
654
if (w->state & CompWindowStateDisplayModalMask)
655
fadeAddDisplayModal (w->screen->display, w);
662
fadeFiniWindow (CompPlugin *p,
667
fadeRemoveDisplayModal (w->screen->display, w);
669
while (fw->unmapCnt--)
672
while (fw->destroyCnt--)
679
fadeInit (CompPlugin *p)
681
displayPrivateIndex = allocateDisplayPrivateIndex ();
682
if (displayPrivateIndex < 0)
689
fadeFini (CompPlugin *p)
691
if (displayPrivateIndex >= 0)
692
freeDisplayPrivateIndex (displayPrivateIndex);
695
CompPluginDep fadeDeps[] = {
696
{ CompPluginRuleBefore, "cube" },
697
{ CompPluginRuleBefore, "expose" }
700
static CompPluginVTable fadeVTable = {
703
"Fade in windows when mapped and fade out windows when unmapped",
712
0, /* GetDisplayOptions */
713
0, /* SetDisplayOption */
714
fadeGetScreenOptions,
717
sizeof (fadeDeps) / sizeof (fadeDeps[0])
721
getCompPluginInfo (void)