/* * Copyright © 2005 Novell, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Author: David Reveman */ #include #include #include #include #define FADE_SPEED_DEFAULT 7.0f #define FADE_SPEED_MIN 0.1f #define FADE_SPEED_MAX 10.0f #define FADE_SPEED_PRECISION 0.1f #define URGENT_SPEED_DEFAULT 15 #define URGENT_SPEED_MAX 50 #define URGENT_SPEED_MIN 5 #define URGENT_SPEED_O (fs->opt[FADE_SCREEN_OPTION_URGENT_SPEED].value.i*100) #define URGENT_COUNT_DEFAULT 5 #define URGENT_COUNT_MIN 0 #define URGENT_COUNT_MAX 15 #define URGENT_COUNT_O fs->opt[FADE_SCREEN_OPTION_URGENT_COUNT].value.i #define URGENT_CENTER_DEFAULT 70 #define URGENT_CENTER_MIN 0 #define URGENT_CENTER_MAX 100 #define URGENT_CENTER_O (fs->opt[FADE_SCREEN_OPTION_URGENT_CENTER].value.i/100.0) #define URGENT_SWING_DEFAULT 20 #define URGENT_SWING_MIN 0 #define URGENT_SWING_MAX 100 #define URGENT_SWING_O (fs->opt[FADE_SCREEN_OPTION_URGENT_SWING].value.i/100.0) #define URGENT_DEFAULT TRUE #define URGENT_O fs->opt[FADE_SCREEN_OPTION_URGENT].value.b #define FADE_VISUAL_BELL_DEFAULT FALSE #define FADE_FULLSCREEN_VISUAL_BELL_DEFAULT FALSE static int displayPrivateIndex; typedef struct _FadeDisplay { int screenPrivateIndex; } FadeDisplay; #define FADE_SCREEN_OPTION_FADE_SPEED 0 #define FADE_SCREEN_OPTION_NUM 1 typedef struct _FadeScreen { int windowPrivateIndex; int fadeTime; int msec; CompOption opt[FADE_SCREEN_OPTION_NUM]; PreparePaintScreenProc preparePaintScreen; PaintWindowProc paintWindow; } FadeScreen; typedef struct _FadeWindow { GLushort opacity; GLushort brightness; GLushort saturation; int animStep; int count; int steps; } FadeWindow; /* Steps is in fade window to make sure painting only happens once per step */ #define GET_FADE_DISPLAY(d) \ ((FadeDisplay *) (d)->privates[displayPrivateIndex].ptr) #define FADE_DISPLAY(d) \ FadeDisplay *fd = GET_FADE_DISPLAY (d) #define GET_FADE_SCREEN(s, fd) \ ((FadeScreen *) (s)->privates[(fd)->screenPrivateIndex].ptr) #define FADE_SCREEN(s) \ FadeScreen *fs = GET_FADE_SCREEN (s, GET_FADE_DISPLAY (s->display)) #define GET_FADE_WINDOW(w, fs) \ ((FadeWindow *) (w)->privates[(fs)->windowPrivateIndex].ptr) #define FADE_WINDOW(w) \ FadeWindow *fw = GET_FADE_WINDOW (w, \ GET_FADE_SCREEN (w->screen, \ GET_FADE_DISPLAY (w->screen->display))) #define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption)) static void fadeScreenInitOptions(FadeScreen * fs) { CompOption *o; o = &fs->opt[FADE_SCREEN_OPTION_FADE_SPEED]; o->advanced = False; o->name = "fade_speed"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Fade Speed"); o->longDesc = N_("How fast the windows Fade in and out."); o->type = CompOptionTypeFloat; o->value.f = FADE_SPEED_DEFAULT; o->rest.f.min = FADE_SPEED_MIN; o->rest.f.max = FADE_SPEED_MAX; o->rest.f.precision = FADE_SPEED_PRECISION; } static CompOption *fadeGetScreenOptions(CompScreen * screen, int *count) { if (screen) { FADE_SCREEN(screen); *count = NUM_OPTIONS(fs); return fs->opt; } else { FadeScreen *fs = malloc(sizeof(FadeScreen)); fadeScreenInitOptions(fs); *count = NUM_OPTIONS(fs); return fs->opt; } } static Bool fadeSetScreenOption(CompScreen * screen, char *name, CompOptionValue * value) { CompOption *o; int index; FADE_SCREEN(screen); o = compFindOption(fs->opt, NUM_OPTIONS(fs), name, &index); if (!o) return FALSE; switch (index) { case FADE_SCREEN_OPTION_FADE_SPEED: if (compSetFloatOption(o, value)) { fs->fadeTime = 1000.0f / o->value.f; return TRUE; } break; default: break; } return FALSE; } static void fadePreparePaintScreen(CompScreen * s, int msSinceLastPaint) { CompWindow *w; int steps; FADE_SCREEN(s); fs->msec = msSinceLastPaint; steps = (msSinceLastPaint * OPAQUE) / fs->fadeTime; if (steps < 12) steps = 12; for (w = s->windows; w; w = w->next) { GET_FADE_WINDOW(w, fs)->steps = steps; } UNWRAP(fs, s, preparePaintScreen); (*s->preparePaintScreen) (s, msSinceLastPaint); WRAP(fs, s, preparePaintScreen, fadePreparePaintScreen); } static Bool fadePaintWindow(CompWindow * w, const WindowPaintAttrib * attrib, Region region, unsigned int mask) { CompScreen *s = w->screen; Bool status; FADE_SCREEN(s); FADE_WINDOW(w); if (!w->screen->canDoSlightlySaturated) fw->saturation = attrib->saturation; if (fw->opacity != attrib->opacity || fw->brightness != attrib->brightness || fw->saturation != attrib->saturation) { GLint opacity; GLint brightness; GLint saturation; opacity = fw->opacity; if (attrib->opacity > fw->opacity) { opacity = fw->opacity + fw->steps; if (opacity > attrib->opacity) opacity = attrib->opacity; } else if (attrib->opacity < fw->opacity) { opacity = fw->opacity - fw->steps; if (opacity < attrib->opacity) opacity = attrib->opacity; } brightness = fw->brightness; if (attrib->brightness > fw->brightness) { brightness = fw->brightness + (fw->steps / 12); if (brightness > attrib->brightness) brightness = attrib->brightness; } else if (attrib->brightness < fw->brightness) { brightness = fw->brightness - (fw->steps / 12); if (brightness < attrib->brightness) brightness = attrib->brightness; } saturation = fw->saturation; if (attrib->saturation > fw->saturation) { saturation = fw->saturation + (fw->steps / 6); if (saturation > attrib->saturation) saturation = attrib->saturation; } else if (attrib->saturation < fw->saturation) { saturation = fw->saturation - (fw->steps / 6); if (saturation < attrib->saturation) saturation = attrib->saturation; } WindowPaintAttrib fAttrib = *attrib; fAttrib.opacity = opacity; fAttrib.brightness = brightness; fAttrib.saturation = saturation; UNWRAP(fs, s, paintWindow); status = (*s->paintWindow) (w, &fAttrib, region, mask); WRAP(fs, s, paintWindow, fadePaintWindow); fw->opacity = opacity; fw->brightness = brightness; fw->saturation = saturation; fw->steps = 0; if (opacity != attrib->opacity || brightness != attrib->brightness || saturation != attrib->saturation) addWindowDamage(w); } else { UNWRAP(fs, s, paintWindow); status = (*s->paintWindow) (w, attrib, region, mask); WRAP(fs, s, paintWindow, fadePaintWindow); } return status; } static Bool fadeInitDisplay(CompPlugin * p, CompDisplay * d) { FadeDisplay *fd; fd = malloc(sizeof(FadeDisplay)); if (!fd) return FALSE; fd->screenPrivateIndex = allocateScreenPrivateIndex(d); if (fd->screenPrivateIndex < 0) { free(fd); return FALSE; } d->privates[displayPrivateIndex].ptr = fd; return TRUE; } static void fadeFiniDisplay(CompPlugin * p, CompDisplay * d) { FADE_DISPLAY(d); freeScreenPrivateIndex(d, fd->screenPrivateIndex); free(fd); } static Bool fadeInitScreen(CompPlugin * p, CompScreen * s) { FadeScreen *fs; FADE_DISPLAY(s->display); fs = malloc(sizeof(FadeScreen)); if (!fs) return FALSE; fs->windowPrivateIndex = allocateWindowPrivateIndex(s); if (fs->windowPrivateIndex < 0) { free(fs); return FALSE; } fs->fadeTime = 1000.0f / FADE_SPEED_DEFAULT; fadeScreenInitOptions(fs); WRAP(fs, s, preparePaintScreen, fadePreparePaintScreen); WRAP(fs, s, paintWindow, fadePaintWindow); s->privates[fd->screenPrivateIndex].ptr = fs; return TRUE; } static void fadeFiniScreen(CompPlugin * p, CompScreen * s) { FADE_SCREEN(s); freeWindowPrivateIndex(s, fs->windowPrivateIndex); UNWRAP(fs, s, preparePaintScreen); UNWRAP(fs, s, paintWindow); free(fs); } static Bool fadeInitWindow(CompPlugin * p, CompWindow * w) { FadeWindow *fw; FADE_SCREEN(w->screen); fw = malloc(sizeof(FadeWindow)); if (!fw) return FALSE; fw->opacity = w->paint.opacity; fw->brightness = w->paint.brightness; fw->saturation = w->paint.saturation; w->privates[fs->windowPrivateIndex].ptr = fw; return TRUE; } static void fadeFiniWindow(CompPlugin * p, CompWindow * w) { FADE_WINDOW(w); free(fw); } static Bool fadeInit(CompPlugin * p) { displayPrivateIndex = allocateDisplayPrivateIndex(); if (displayPrivateIndex < 0) return FALSE; return TRUE; } static void fadeFini(CompPlugin * p) { if (displayPrivateIndex >= 0) freeDisplayPrivateIndex(displayPrivateIndex); } CompPluginDep fadeDeps[] = { {CompPluginRuleAfter, "animation"} , {CompPluginRuleAfter, "decoration"} , {CompPluginRuleAfter, "wobbly"} , }; static CompPluginVTable fadeVTable = { "fade", N_("Fading Windows"), N_("Fade in windows when mapped and fade out windows when unmapped"), fadeInit, fadeFini, fadeInitDisplay, fadeFiniDisplay, fadeInitScreen, fadeFiniScreen, fadeInitWindow, fadeFiniWindow, 0, /* GetDisplayOptions */ 0, /* SetDisplayOption */ fadeGetScreenOptions, fadeSetScreenOption, fadeDeps, sizeof(fadeDeps) / sizeof(fadeDeps[0]), 0, 0, BERYL_ABI_INFO, "beryl-plugins", "effects", 0, 0, True, }; CompPluginVTable *getCompPluginInfo(void) { return &fadeVTable; }