Logo Search packages:      
Sourcecode: beryl-plugins version File versions

fade.c

/*
 * 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 <davidr@novell.com>
 */

#include <stdlib.h>
#include <string.h>

#include <beryl.h>

#include <math.h>

#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;
}

Generated by  Doxygen 1.6.0   Back to index