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

fadedesktop.c

/**
 *
 * Beryl fade to desktop plugin
 *
 * fadedesktop.c
 *
 * Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
 *
 * 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.
 *
 **/

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

#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>

#define FD_INITIATE_KEY_DEFAULT "F6"
#define FD_INITIATE_MODIFIERS_DEFAULT CompSuperMask
#define FD_INITIATE_EDGE_DEFAULT 0

#define FD_SPEED_DEFAULT 20
#define FD_SPEED_MIN     1
#define FD_SPEED_MAX     100


#define FD_DISPLAY_OPTION_INITIATE 0
#define FD_DISPLAY_OPTION_NUM 1

#define FD_SCREEN_OPTION_SPEED 0
#define FD_SCREEN_OPTION_NUM 1



typedef struct _FadeDesktopDisplay
{
      int screenPrivateIndex;
      CompOption opt[FD_DISPLAY_OPTION_NUM];
} FadeDesktopDisplay;

typedef struct _FadeDesktopScreen
{
      int windowPrivateIndex;

      PreparePaintScreenProc preparePaintScreen;
      DonePaintScreenProc donePaintScreen;
      
      CompOption opt[FD_SCREEN_OPTION_NUM];

      Bool showingDesktop;
      Bool reverting;
} FadeDesktopScreen;

typedef struct _FadeDesktopWindow
{
      Bool isHidden;
} FadeDesktopWindow;



#define GET_FADEDESKTOP_DISPLAY(d)                         \
    ((FadeDesktopDisplay *) (d)->privates[displayPrivateIndex].ptr)

#define FD_DISPLAY(d)                  \
    FadeDesktopDisplay *fd = GET_FADEDESKTOP_DISPLAY (d)

#define GET_FADEDESKTOP_SCREEN(s, fd)                              \
    ((FadeDesktopScreen *) (s)->privates[(fd)->screenPrivateIndex].ptr)

#define FD_SCREEN(s)                                        \
    FadeDesktopScreen *fs = GET_FADEDESKTOP_SCREEN (s, GET_FADEDESKTOP_DISPLAY (s->display))

#define GET_FADEDESKTOP_WINDOW(w, fs)                              \
    ((FadeDesktopWindow *) (w)->privates[(fs)->windowPrivateIndex].ptr)

#define FD_WINDOW(w)                                        \
    FadeDesktopWindow *fw = GET_FADEDESKTOP_WINDOW(w, \
                              GET_FADEDESKTOP_SCREEN (w->screen, GET_FADEDESKTOP_DISPLAY (w->screen->display)))


static int displayPrivateIndex;


static Bool isFDWin(CompWindow *w)
{
      //w->screen->focusWindow ?
      if (w->state & CompWindowStateOffscreenMask)
            return FALSE;

    if (w->wmType & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
            return FALSE;

      if (w->type & (CompWindowTypeNormalMask | CompWindowTypeDialogMask ) )
      {
            return TRUE;
      }
      return FALSE;
}

static Bool
fadeDesktopTerminate(CompDisplay *d, CompAction * action, CompActionState state, CompOption *option, int nOption)
{
      CompScreen *s;
      Window xid;

      xid = getIntOptionNamed(option,nOption,"root",0);
      s = findScreenAtDisplay(d,xid);


      if (s)
      {
            FD_SCREEN(s);
            fs->reverting = TRUE;
            CompWindow *w;
            for (w=s->windows; w; w=w->next)
            {
                  FD_WINDOW(w);
                  if (fw->isHidden && (w->state & CompWindowStateOffscreenMask))
                  {
                        moveWindowOnscreen(w);
                  }
                  fw->isHidden = FALSE;
            }
            
      }

      return TRUE;

}


static Bool 
fadeDesktopInitiate(CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption)
{
      CompScreen *s;
      Window xid;
      xid = getIntOptionNamed(option,nOption,"root",0);
      s = findScreenAtDisplay(d,xid);
      
      
      
      if (s)
      {
            FD_SCREEN(s);
            
            if (fs->showingDesktop)
            {
                  fs->showingDesktop = FALSE;
                  fadeDesktopTerminate(d, action, state, option,  nOption);
                  return TRUE;
            }
            else if (fs->reverting)
            {
                  fs->reverting = FALSE;
            }
            fs->showingDesktop = TRUE;

            unsigned long data = 0;
            XChangeProperty(s->display->display, s->root,
                              s->display->showingDesktopAtom,
                              XA_CARDINAL, 32, PropModeReplace,
                              (unsigned char *)&data, 1);
            
      }
      return TRUE;
      
}

static void 
fadeDesktopPreparePaintScreen(CompScreen *s, int msSinceLastPaint)
{
      FD_SCREEN(s);
      #define SPEED ((fs->opt[FD_SCREEN_OPTION_SPEED].value.i ? fs->opt[FD_SCREEN_OPTION_SPEED].value.i : 1))
      
      int numWins=0;
      int numReverts=0;

      CompWindow *w;
      for (w=s->windows; w; w=w->next)
      {
            if (isFDWin(w))
            {
                  if (fs->showingDesktop)
                  {
                        if (w->paint.opacity > OPAQUE/SPEED)
                        {
                              setWindowOpacity(w,w->paint.opacity-OPAQUE/SPEED,PL_TEMP_HELLO);
                        }
                        else if (w->paint.opacity != 0)
                        {
                              FD_WINDOW(w);

                              moveWindowOffscreen(w);
                              fw->isHidden = TRUE;
                        }
                  }

                  if (fs->reverting)
                  {
                        if (w->paint.opacity + OPAQUE/SPEED <= w->opacity)
                        {
                              setWindowOpacity(w,w->paint.opacity + OPAQUE/SPEED,PL_TEMP_HELLO);
                        }
                        else 
                        {
                              resetWindowOpacity(w, PL_TEMP_HELLO);
                              numReverts++;
                        }
                        
                  }
                  numWins++;
                  
                  
      
            }
      }
      if (numWins == numReverts)
      {
            fs->reverting = FALSE;
            unsigned long data = 0;
            XChangeProperty(s->display->display, s->root,
                              s->display->showingDesktopAtom,
                              XA_CARDINAL, 32, PropModeReplace,
                              (unsigned char *)&data, 1);
      }

      UNWRAP(fs,s,preparePaintScreen);
      (*s->preparePaintScreen) (s,msSinceLastPaint);
      WRAP(fs,s,preparePaintScreen,fadeDesktopPreparePaintScreen);


}

static void fadeDesktopDonePaintScreen(CompScreen *s)
{
      FD_SCREEN(s);
      if (fs->showingDesktop || fs->reverting)
      {
            damageScreen(s);
      }
      UNWRAP(fs,s,donePaintScreen);
      (*s->donePaintScreen)(s);
      WRAP(fs,s,donePaintScreen,fadeDesktopDonePaintScreen);
}

static void
fadeDesktopDisplayInitOptions(FadeDesktopDisplay *fd)
{
      CompOption *o;
      o = &fd->opt[FD_DISPLAY_OPTION_INITIATE];
      o->advanced = False;
      o->name = "initiate";
      o->group = N_("Misc. Options");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Initiate Fade to Desktop");
      o->longDesc = N_("Initiate Fade to Desktop mode.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate= fadeDesktopInitiate;
      o->value.action.terminate = fadeDesktopTerminate;
      o->value.action.bell = FALSE;
      o->value.action.edgeMask = FD_INITIATE_EDGE_DEFAULT;
      o->value.action.type = CompBindingTypeKey;
      o->value.action.state = CompActionStateInitKey;
      o->value.action.state |= CompActionStateInitEdge;
      o->value.action.key.modifiers = FD_INITIATE_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(FD_INITIATE_KEY_DEFAULT);
}

static void fadeDesktopScreenInitOptions(FadeDesktopScreen * fs)
{
      CompOption *o;
      o = &fs->opt[FD_SCREEN_OPTION_SPEED];
      o->advanced = False;
      o->name = "speed";
      o->group = N_("Misc. Options");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Time to Fade");
      o->longDesc = N_("Time to Fade.");
      o->type = CompOptionTypeInt;
      o->value.i = FD_SPEED_DEFAULT;
      o->rest.i.min = FD_SPEED_MIN;
      o->rest.i.max = FD_SPEED_MAX;
}

static Bool fadeDesktopInit(CompPlugin *p)
{
      displayPrivateIndex = allocateDisplayPrivateIndex();
      if (displayPrivateIndex < 0)
            return FALSE;
      
      return TRUE;
}


static void fadeDesktopFini(CompPlugin *p)
{
      if (displayPrivateIndex >= 0)
            freeDisplayPrivateIndex(displayPrivateIndex);
}

static Bool fadeDesktopInitDisplay(CompPlugin *p, CompDisplay *d)
{
      FadeDesktopDisplay *fd;
      fd = malloc(sizeof(FadeDesktopDisplay));
      if (!fd)
            return FALSE;
      fd->screenPrivateIndex = allocateScreenPrivateIndex(d);
      if (fd->screenPrivateIndex < 0)
      {
            free(fd);
            return FALSE;
      }
      fadeDesktopDisplayInitOptions(fd);
      
      d->privates[displayPrivateIndex].ptr = fd;
      return TRUE;
}

static void fadeDesktopFiniDisplay(CompPlugin *p, CompDisplay *d)
{
      FD_DISPLAY(d);
      freeScreenPrivateIndex(d, fd->screenPrivateIndex);
      free(fd);
}

static Bool fadeDesktopInitScreen(CompPlugin *p, CompScreen *s)
{
      FadeDesktopScreen *fs;
      FD_DISPLAY(s->display);

      fs = malloc(sizeof(FadeDesktopScreen));
      if (!fs)
            return FALSE;

      fs->windowPrivateIndex = allocateWindowPrivateIndex(s);     
      if (fs->windowPrivateIndex < 0)
      {
            free(fs);
            return FALSE;
      }

      fadeDesktopScreenInitOptions(fs);

      fs->showingDesktop = FALSE;
      
      addScreenAction(s, &fd->opt[FD_DISPLAY_OPTION_INITIATE].value.action);
      
      WRAP(fs,s,preparePaintScreen,fadeDesktopPreparePaintScreen);
      WRAP(fs,s,donePaintScreen,fadeDesktopDonePaintScreen);

      s->privates[fd->screenPrivateIndex].ptr = fs;

      return TRUE;
      
}

static void fadeDesktopFiniScreen(CompPlugin *p, CompScreen *s)
{
      FD_SCREEN(s);
      FD_DISPLAY(s->display);
      
      UNWRAP(fs,s,preparePaintScreen);
      UNWRAP(fs,s,donePaintScreen);
      
      removeScreenAction(s, &fd->opt[FD_DISPLAY_OPTION_INITIATE].value.action);

      freeWindowPrivateIndex(s, fs->windowPrivateIndex);
      
      free (fs);
}

static Bool fadeDesktopInitWindow(CompPlugin *p, CompWindow *w)
{
      FadeDesktopWindow *fw;
      FD_SCREEN(w->screen);

      fw = malloc(sizeof(FadeDesktopWindow));
      if (!fw)
            return FALSE;

      fw->isHidden = FALSE;
      
      w->privates[fs->windowPrivateIndex].ptr = fw;

      return TRUE;
      
}

static void fadeDesktopFiniWindow(CompPlugin *p, CompWindow *w)
{
      FD_WINDOW(w);
      FD_SCREEN(w->screen);
      
      free (fw);
}


#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))

static CompOption *fadeDesktopGetDisplayOptions(CompDisplay *display, int *count)
{
      if (display)
      {
            FD_DISPLAY(display);

            *count = NUM_OPTIONS(fd);
            return fd->opt;
      }
      else
      {
            FadeDesktopDisplay *fd = malloc(sizeof(FadeDesktopDisplay));

            fadeDesktopDisplayInitOptions(fd);
            *count = NUM_OPTIONS(fd);
            return fd->opt;
      }
}

static Bool 
fadeDesktopSetDisplayOption(CompDisplay *display, char * name, CompOptionValue *value)
{

      FD_DISPLAY(display);
      CompOption *o;
      int index;
      o = compFindOption(fd->opt,FD_DISPLAY_OPTION_NUM,name,&index);

      if (!o)
            return FALSE;
      
      switch (index)
      {
            case FD_DISPLAY_OPTION_INITIATE:
                  if (setDisplayAction(display,o,value))
                        return TRUE;      
            default:
                  break;
      }
      return FALSE;
}

static CompOption *fadeDesktopGetScreenOptions(CompScreen * screen,
                                                                     int *count)
{
      if (screen)
      {
            FD_SCREEN(screen);

            *count = FD_SCREEN_OPTION_NUM;
            return fs->opt;
      }
      else
      {
            FadeDesktopScreen *fs = malloc(sizeof(FadeDesktopScreen));

            fadeDesktopScreenInitOptions(fs);
            *count = FD_SCREEN_OPTION_NUM;
            return fs->opt;
      }
}

static Bool 
fadeDesktopSetScreenOption(CompScreen *screen, char *name, CompOptionValue *value)
{
      CompOption *o;
      int index;
      FD_SCREEN(screen);
      o = compFindOption(fs->opt,FD_SCREEN_OPTION_NUM,name,&index);
      
      if (!o)
            return FALSE;

      switch (index)
      {
            case FD_SCREEN_OPTION_SPEED:
            if (compSetIntOption(o,value))
            {
                  return TRUE;
            }
            break;
      }
      return FALSE;
}

CompPluginFeature fdFeatures[] = {
      {"showdesktop"}
      ,
};

static CompPluginVTable fadeDesktopVTable = {
      "fadeDesktop",
      N_("Fade to Desktop"),
      N_("Easily access your desktop"),
      fadeDesktopInit,
      fadeDesktopFini,
      fadeDesktopInitDisplay,
      fadeDesktopFiniDisplay,
      fadeDesktopInitScreen,
      fadeDesktopFiniScreen,
      fadeDesktopInitWindow,
      fadeDesktopFiniWindow,
      fadeDesktopGetDisplayOptions,
      fadeDesktopSetDisplayOption,
      fadeDesktopGetScreenOptions,
      fadeDesktopSetScreenOption,
      0,
      0,
      fdFeatures,
      sizeof(fdFeatures) / sizeof(fdFeatures[0]),
      BERYL_ABI_INFO,
      "beryl-plugins",
      "desktop",
      0,
      0,
      True,
};

CompPluginVTable * getCompPluginInfo(void)
{
      return &fadeDesktopVTable;
}

Generated by  Doxygen 1.6.0   Back to index