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

splash.c

/**
 * Beryl splash plugin
 *
 * splash.c
 *
 * Copyright : (C) 2006 by Dennis Kasprzyk
 * E-mail    : onestone@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 <stdio.h>
#include <math.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xrender.h>
#include <beryl.h>
#include <beryl_ipcs.h>

#define GET_SPLASH_DISPLAY(d)                                  \
    ((SplashDisplay *) (d)->privates[displayPrivateIndex].ptr)

#define SPLASH_DISPLAY(d)                      \
    SplashDisplay *sd = GET_SPLASH_DISPLAY (d)

#define GET_SPLASH_SCREEN(s, sd)                                   \
    ((SplashScreen *) (s)->privates[(sd)->screenPrivateIndex].ptr)

#define SPLASH_SCREEN(s)                                                      \
    SplashScreen *ss = GET_SPLASH_SCREEN (s, GET_SPLASH_DISPLAY (s->display))

#define SPLASH_DISPLAY_OPTION_INITIATE                       0
#define SPLASH_DISPLAY_OPTION_LOGO                           1
#define SPLASH_DISPLAY_OPTION_BACKGROUND                     2
#define SPLASH_DISPLAY_OPTION_SATURATION                     3
#define SPLASH_DISPLAY_OPTION_BRIGHTNESS                     4
#define SPLASH_DISPLAY_OPTION_FADE_TIME                      5
#define SPLASH_DISPLAY_OPTION_DISPLAY_TIME                   6
#define SPLASH_DISPLAY_OPTION_DISABLE_UPDATE                 7
#define SPLASH_DISPLAY_OPTION_NUM                            8

#define SPLASH_DISPLAY_OPTION_LOGO_DEFAULT                   IMAGEDIR "/splash_logo.png"
#define SPLASH_DISPLAY_OPTION_BACKGROUND_DEFAULT             IMAGEDIR "/splash_background.png"
#define SPLASH_DISPLAY_OPTION_SATURATION_DEFAULT             50.0
#define SPLASH_DISPLAY_OPTION_BRIGHTNESS_DEFAULT             50.0
#define SPLASH_DISPLAY_OPTION_FADE_TIME_DEFAULT              1.0
#define SPLASH_DISPLAY_OPTION_DISPLAY_TIME_DEFAULT           2.0
#define SPLASH_DISPLAY_OPTION_DISABLE_UPDATE_DEFAULT         TRUE

#define SPLASH_DISPLAY_OPTION_INITIATE_KEY                   "F11"
#define SPLASH_DISPLAY_OPTION_INITIATE_MOD                   CompSuperMask

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

static int displayPrivateIndex = 0;

// our texture container
typedef struct _SplashTexture
{
      int width;
      int height;
      unsigned int handle;
} SplashTexture;

typedef struct _SplashDisplay
{
      int screenPrivateIndex;

      CompOption opt[SPLASH_DISPLAY_OPTION_NUM];
} SplashDisplay;

#define MESH_W 16
#define MESH_H 16

typedef struct _SplashScreen
{
      PreparePaintScreenProc preparePaintScreen;
      DonePaintScreenProc donePaintScreen;
      PaintScreenProc paintScreen;

      int fade_in;
      int fade_out;
      int time;

      SplashTexture background;
      CompTexture back_img, logo_img;
      unsigned int backSize[2], logoSize[2];
      Bool hasInit, hasLogo, hasBack;

      float mesh[MESH_W][MESH_H][2];
      float mMove;

      Bool initiate;

      Bool active;
      Bool doUpdate;

      int ipcs_active_atom;

} SplashScreen;

static void genTexture(SplashTexture * tex, int width, int height)
{
      //Enable texturing
      glEnable(GL_TEXTURE_RECTANGLE_ARB);
      //Generate the OpenGL textures
      if (!tex->handle)
            glGenTextures(1, &tex->handle);
      //Write important info into the structure
      tex->width = width;
      tex->height = height;
      //Bind the texture
      glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex->handle);
      //Load the parameters
      glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
                              GL_LINEAR);
      glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                              GL_LINEAR);
      glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);

      glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0,
                         GL_RGB, GL_UNSIGNED_BYTE, NULL);
      glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
      glDisable(GL_TEXTURE_RECTANGLE_ARB);

}

static void splashPreparePaintScreen(CompScreen * s, int ms)
{
      SPLASH_SCREEN(s);
      SPLASH_DISPLAY(s->display);

      Bool lastShot = FALSE;


      ss->fade_in -= ms;
      if (ss->fade_in < 0)
      {
            ss->time += ss->fade_in;
            ss->fade_in = 0;
            if (ss->time < 0)
            {
                  if (ss->fade_out > 0 && ss->fade_out <= ms)
                        lastShot = TRUE;
                  ss->fade_out += ss->time;
                  ss->time = 0;
                  if (ss->fade_out < 0)
                        ss->fade_out = 0;
            }
      }

      if (ss->initiate)
      {
            ss->fade_in = ss->fade_out =
                        sd->opt[SPLASH_DISPLAY_OPTION_FADE_TIME].value.f * 1000.0;
            ss->time =
                        sd->opt[SPLASH_DISPLAY_OPTION_DISPLAY_TIME].value.f * 1000.0;
            ss->initiate = FALSE;
      }

      if (ss->fade_in || ss->fade_out || ss->time || lastShot)
      {
            ss->active = TRUE;
            ss->mMove += ms / 500.0;
            if (!ss->hasInit)
            {
                  ss->hasInit = TRUE;
                  ss->doUpdate = TRUE;
                  ss->mMove = 0.0;
                  genTexture(&ss->background, s->width, s->height);
                  ss->hasBack =
                              readImageToTexture(s, &ss->back_img,
                                                         sd->
                                                         opt
                                                         [SPLASH_DISPLAY_OPTION_BACKGROUND].
                                                         value.s, &ss->backSize[0],
                                                         &ss->backSize[1]);
                  ss->hasLogo =
                              readImageToTexture(s, &ss->logo_img,
                                                         sd->
                                                         opt
                                                         [SPLASH_DISPLAY_OPTION_LOGO].
                                                         value.s, &ss->logoSize[0],
                                                         &ss->logoSize[1]);
                  if (!ss->hasBack)
                  {
                        ss->hasBack =
                                    readImageToTexture(s, &ss->back_img,
                                                               SPLASH_DISPLAY_OPTION_BACKGROUND_DEFAULT,
                                                               &ss->backSize[0],
                                                               &ss->backSize[1]);
                        if (ss->hasBack)
                        {
                              fprintf(stderr,
                                          "[SPLASH]: Could not load splash background image \"%s\" using default!\n",
                                          sd->
                                          opt[SPLASH_DISPLAY_OPTION_BACKGROUND].value.s);
                        }
                  }
                  if (!ss->hasLogo)
                  {
                        ss->hasLogo =
                                    readImageToTexture(s, &ss->logo_img,
                                                               SPLASH_DISPLAY_OPTION_LOGO_DEFAULT,
                                                               &ss->logoSize[0],
                                                               &ss->logoSize[1]);
                        if (ss->hasLogo)
                        {
                              fprintf(stderr,
                                          "[SPLASH]: Could not load splash logo image \"%s\" using default!\n",
                                          sd->opt[SPLASH_DISPLAY_OPTION_LOGO].value.s);
                        }
                  }
                  if (!ss->hasBack)
                        fprintf(stderr,
                                    "[SPLASH]: Could not load splash background image \"%s\" !\n",
                                    sd->opt[SPLASH_DISPLAY_OPTION_BACKGROUND].value.s);
                  if (!ss->hasLogo)
                        fprintf(stderr,
                                    "[SPLASH]: Could not load splash logo image \"%s\" !\n",
                                    sd->opt[SPLASH_DISPLAY_OPTION_LOGO].value.s);
            }
      }
      else
      {
            ss->active = FALSE;
            ss->doUpdate = TRUE;
            if (ss->hasInit)
            {
                  ss->hasInit = FALSE;
                  glDeleteTextures(1, &ss->background.handle);
                  ss->background.handle = 0;
                  if (ss->hasBack)
                  {
                        glDeleteTextures(1, &ss->back_img.name);
                        ss->back_img.name = 0;
                        ss->hasBack = FALSE;
                  }
                  if (ss->hasLogo)
                  {
                        glDeleteTextures(1, &ss->logo_img.name);
                        ss->logo_img.name = 0;
                        ss->hasLogo = FALSE;
                  }
            }
      }

      if (ss->active)
      {
            IPCS_SetBool(IPCS_OBJECT(s), ss->ipcs_active_atom, TRUE);
      }
      else
      {
            IPCS_SetBool(IPCS_OBJECT(s), ss->ipcs_active_atom, FALSE);
      }

      UNWRAP(ss, s, preparePaintScreen);
      (*s->preparePaintScreen) (s, ms);
      WRAP(ss, s, preparePaintScreen, splashPreparePaintScreen);

}

static void splashDonePaintScreen(CompScreen * s)
{
      SPLASH_SCREEN(s);

      if (ss->fade_in || ss->fade_out || ss->time)
            damageScreen(s);

      UNWRAP(ss, s, donePaintScreen);
      (*s->donePaintScreen) (s);
      WRAP(ss, s, donePaintScreen, splashDonePaintScreen);
}


static Bool
splashPaintScreen(CompScreen * s, const ScreenPaintAttrib * sa,
                          Region region, int output, unsigned int mask)
{

      SPLASH_SCREEN(s);
      SPLASH_DISPLAY(s->display);

      Bool status = TRUE;
      XRectangle outputRect;

      UNWRAP(ss, s, paintScreen);
      status = (*s->paintScreen) (s, sa, region, output, mask);
      WRAP(ss, s, paintScreen, splashPaintScreen);

      screenGetOutputDevRect(s, output, &outputRect);
      int s_x = outputRect.x;
      int s_y = outputRect.y;
      int s_width = outputRect.width;
      int s_height = outputRect.height;

      if (!ss->active)
            return status;

      glPushMatrix();
      glLoadIdentity();
      prepareXCoords(s, output, -DEFAULT_Z_CAMERA);

      float alpha =
                  (1.0 -
                   (ss->fade_in /
                    (sd->opt[SPLASH_DISPLAY_OPTION_FADE_TIME].value.f *
                     1000.0))) * (ss->fade_out /
                                          (sd->opt[SPLASH_DISPLAY_OPTION_FADE_TIME].
                                           value.f * 1000.0));
      float darken =
                  1.0 - (sd->opt[SPLASH_DISPLAY_OPTION_BRIGHTNESS].value.f / 100.0);
      float sat =
                  1.0 - (sd->opt[SPLASH_DISPLAY_OPTION_SATURATION].value.f / 100.0);
      if (sat == 1.0)
            sat = 0.9999;

      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

      if (sat < 1.0 && s->canDoSaturated && ss->doUpdate)
      {
            glEnable(GL_TEXTURE_RECTANGLE_ARB);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ss->background.handle);
            glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, s_x,
                                          s->height - s_height - s_y, s_x,
                                          s->height - s_height - s_y, s_width, s_height);

            GLfloat constant[4];

            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

            glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);

            glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

            glColor4f(1.0f, 1.0f, 1.0f, 0.5f);

            s->activeTexture(GL_TEXTURE1_ARB);

            glEnable(GL_TEXTURE_RECTANGLE_ARB);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ss->background.handle);

            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

            glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

            glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

            constant[3] =
                        (sd->opt[SPLASH_DISPLAY_OPTION_DISABLE_UPDATE].value.
                         b) ? sat : alpha * sat;

            constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT;
            constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT;
            constant[2] = 0.5f + 0.5f * BLUE_SATURATION_WEIGHT;

            glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);

            glBegin(GL_QUADS);
            glTexCoord2f(s_x, s->height - s_y);
            glVertex2f(s_x, s_y);
            glTexCoord2f(s_x, s->height - s_height - s_y);
            glVertex2f(s_x, s_y + s_height);
            glTexCoord2f(s_x + s_width, s->height - s_height - s_y);
            glVertex2f(s_x + s_width, s_y + s_height);
            glTexCoord2f(s_x + s_width, s->height - s_y);
            glVertex2f(s_x + s_width, s_y);
            glEnd();

            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
            glDisable(GL_TEXTURE_RECTANGLE_ARB);
            s->activeTexture(GL_TEXTURE0_ARB);
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
            glDisable(GL_TEXTURE_RECTANGLE_ARB);
      }

      if (darken > 0 && ss->doUpdate)
      {
            glColor4f(0, 0, 0,
                          (sd->opt[SPLASH_DISPLAY_OPTION_DISABLE_UPDATE].
                           value.b) ? darken : alpha * darken);
            glBegin(GL_QUADS);
            glVertex2f(s_x, s_y);
            glVertex2f(s_x, s_y + s_height);
            glVertex2f(s_x + s_width, s_y + s_height);
            glVertex2f(s_x + s_width, s_y);
            glEnd();
      }

      if (sd->opt[SPLASH_DISPLAY_OPTION_DISABLE_UPDATE].value.b)
      {

            // save background
            if (ss->doUpdate)
            {
                  if (output + 1 == s->nOutputDev)
                        ss->doUpdate = FALSE;
                  glEnable(GL_TEXTURE_RECTANGLE_ARB);
                  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ss->background.handle);
                  glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
                                                s_x,
                                                s->height - s_height - s_y,
                                                s_x,
                                                s->height - s_height - s_y,
                                                s_width, s_height);
                  glDisable(GL_TEXTURE_RECTANGLE_ARB);
                  glPopMatrix();
                  glDisable(GL_BLEND);
                  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
                  UNWRAP(ss, s, paintScreen);
                  status = (*s->paintScreen) (s, sa, region, output, mask);
                  WRAP(ss, s, paintScreen, splashPaintScreen);
                  glPushMatrix();
                  glLoadIdentity();
                  glTranslatef(-0.5f, -0.5f, -DEFAULT_Z_CAMERA);
                  glScalef(1.0f / s->width, -1.0f / s->height, 1.0f);
                  glTranslatef(0.0f, -s->height, 0.0f);
                  glEnable(GL_BLEND);
                  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            }

            glEnable(GL_TEXTURE_RECTANGLE_ARB);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ss->background.handle);
            glColor4f(1.0, 1.0, 1.0, alpha);
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
            glBegin(GL_QUADS);
            glTexCoord2f(s_x, s->height - s_y);
            glVertex2f(s_x, s_y);
            glTexCoord2f(s_x, s->height - s_height - s_y);
            glVertex2f(s_x, s_y + s_height);
            glTexCoord2f(s_x + s_width, s->height - s_height - s_y);
            glVertex2f(s_x + s_width, s_y + s_height);
            glTexCoord2f(s_x + s_width, s->height - s_y);
            glVertex2f(s_x + s_width, s_y);
            glEnd();

            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
            glDisable(GL_TEXTURE_RECTANGLE_ARB);

      }

      glColor4f(1.0, 1.0, 1.0, alpha);
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

      if (ss->hasBack)
      {
            int x, y, head;

            for (x = 0; x < MESH_W; x++)
            {
                  for (y = 0; y < MESH_H; y++)
                  {
                        ss->mesh[x][y][0] =
                                    (x / (MESH_W - 1.0)) +
                                    (0.02 * sin((y / (MESH_H - 1.0) * 8) + ss->mMove));
                        ss->mesh[x][y][1] =
                                    (y / (MESH_H - 1.0)) +
                                    (0.02 * sin((ss->mesh[x][y][0] * 8) + ss->mMove));;
                  }
            }

            enableTexture(s, &ss->back_img, COMP_TEXTURE_FILTER_GOOD);

            if (s->nOutputDev > 1)
            {
                  XRectangle headOutputRect;

                  head = screenGetCurrentOutputDev(s);
                  screenGetOutputDevRect(s, head, &headOutputRect);
                  x = (headOutputRect.width - ss->backSize[0]) / 2;
                  y = (headOutputRect.height - ss->backSize[1]) / 2;

                  x += headOutputRect.x;
                  y += headOutputRect.y;
            }
            else
            {
                  x = (s->width - ss->backSize[0]) / 2;
                  y = (s->height - ss->backSize[1]) / 2;
            }
            CompMatrix mat = ss->back_img.matrix;

            glTranslatef(x, y, 0);

            float cx1, cx2, cy1, cy2;

            glBegin(GL_QUADS);
            for (x = 0; x < MESH_W - 1; x++)
            {
                  for (y = 0; y < MESH_H - 1; y++)
                  {
                        cx1 = (x / (MESH_W - 1.0)) * ss->backSize[0];
                        cx2 = ((x + 1) / (MESH_W - 1.0)) * ss->backSize[0];
                        cy1 = (y / (MESH_H - 1.0)) * ss->backSize[1];
                        cy2 = ((y + 1) / (MESH_H - 1.0)) * ss->backSize[1];

                        glTexCoord2f(COMP_TEX_COORD_X(&mat, cx1),
                                           COMP_TEX_COORD_Y(&mat, cy1));
                        glVertex2f(ss->mesh[x][y][0] *
                                       ss->backSize[0],
                                       ss->mesh[x][y][1] * ss->backSize[1]);
                        glTexCoord2f(COMP_TEX_COORD_X(&mat, cx1),
                                           COMP_TEX_COORD_Y(&mat, cy2));
                        glVertex2f(ss->mesh[x][y + 1][0] *
                                       ss->backSize[0],
                                       ss->mesh[x][y + 1][1] * ss->backSize[1]);
                        glTexCoord2f(COMP_TEX_COORD_X(&mat, cx2),
                                           COMP_TEX_COORD_Y(&mat, cy2));
                        glVertex2f(ss->mesh[x + 1][y + 1][0] *
                                       ss->backSize[0],
                                       ss->mesh[x + 1][y + 1][1] * ss->backSize[1]);
                        glTexCoord2f(COMP_TEX_COORD_X(&mat, cx2),
                                           COMP_TEX_COORD_Y(&mat, cy1));
                        glVertex2f(ss->mesh[x + 1][y][0] *
                                       ss->backSize[0],
                                       ss->mesh[x + 1][y][1] * ss->backSize[1]);
                  }
            }
            glEnd();

            if (s->nOutputDev > 1)
            {
                  XRectangle headOutputRect;

                  head = screenGetCurrentOutputDev(s);
                  screenGetOutputDevRect(s, head, &headOutputRect);
                  x = (headOutputRect.width - ss->backSize[0]) / 2;
                  y = (headOutputRect.height - ss->backSize[1]) / 2;

                  x += headOutputRect.x;
                  y += headOutputRect.y;
            }
            else
            {
                  x = (s->width - ss->backSize[0]) / 2;
                  y = (s->height - ss->backSize[1]) / 2;
            }
            glTranslatef(-x, -y, 0);

            disableTexture(s, &ss->back_img);
      }

      if (ss->hasLogo)
      {
            enableTexture(s, &ss->logo_img, COMP_TEXTURE_FILTER_GOOD);
            int x, y, head;

            if (s->nOutputDev > 1)
            {
                  XRectangle headOutputRect;

                  head = screenGetCurrentOutputDev(s);
                  screenGetOutputDevRect(s, head, &headOutputRect);
                  x = (headOutputRect.width - ss->logoSize[0]) / 2;
                  y = (headOutputRect.height - ss->logoSize[1]) / 2;

                  x += headOutputRect.x;
                  y += headOutputRect.y;
            }
            else
            {
                  x = (s->width - ss->logoSize[0]) / 2;
                  y = (s->height - ss->logoSize[1]) / 2;
            }

            CompMatrix mat = ss->logo_img.matrix;

            glTranslatef(x, y, 0);

            glBegin(GL_QUADS);
            glTexCoord2f(COMP_TEX_COORD_X(&mat, 0), COMP_TEX_COORD_Y(&mat, 0));
            glVertex2f(0, 0);
            glTexCoord2f(COMP_TEX_COORD_X(&mat, 0),
                               COMP_TEX_COORD_Y(&mat, ss->logoSize[1]));
            glVertex2f(0, ss->logoSize[1]);
            glTexCoord2f(COMP_TEX_COORD_X(&mat, ss->logoSize[0]),
                               COMP_TEX_COORD_Y(&mat, ss->logoSize[1]));
            glVertex2f(ss->logoSize[0], ss->logoSize[1]);
            glTexCoord2f(COMP_TEX_COORD_X(&mat, ss->logoSize[0]),
                               COMP_TEX_COORD_Y(&mat, 0));
            glVertex2f(ss->logoSize[0], 0);
            glEnd();

            glTranslatef(-x, -y, 0);

            disableTexture(s, &ss->logo_img);
      }

      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
      glDisable(GL_BLEND);
      glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
      glPopMatrix();
      return status;
}

static Bool splashInitScreen(CompPlugin * p, CompScreen * s)
{

      SPLASH_DISPLAY(s->display);

      SplashScreen *ss = (SplashScreen *) calloc(1, sizeof(SplashScreen));

      s->privates[sd->screenPrivateIndex].ptr = ss;

      WRAP(ss, s, paintScreen, splashPaintScreen);
      WRAP(ss, s, preparePaintScreen, splashPreparePaintScreen);
      WRAP(ss, s, donePaintScreen, splashDonePaintScreen);

      addScreenAction(s, &sd->opt[SPLASH_DISPLAY_OPTION_INITIATE].value.action);

      ss->initiate = FALSE;

      ss->ipcs_active_atom =
                  IPCS_GetAtom(IPCS_OBJECT(s), IPCS_BOOL, "SPLASH_IS_ACTIVE", TRUE);

      return TRUE;
}


static void splashFiniScreen(CompPlugin * p, CompScreen * s)
{

      SPLASH_SCREEN(s);
      SPLASH_DISPLAY(s->display);

      //Restore the original function
      UNWRAP(ss, s, paintScreen);
      UNWRAP(ss, s, preparePaintScreen);
      UNWRAP(ss, s, donePaintScreen);

      removeScreenAction(s,
                                 &sd->opt[SPLASH_DISPLAY_OPTION_INITIATE].value.action);

      //Free the pointer
      free(ss);
}

static Bool
splashSetDisplayOption(CompDisplay * display, char *name,
                                 CompOptionValue * value)
{
      CompOption *o;
      int index;

      SPLASH_DISPLAY(display);

      o = compFindOption(sd->opt, NUM_OPTIONS(sd), name, &index);
      if (!o)
            return FALSE;

      switch (index)
      {
      case SPLASH_DISPLAY_OPTION_INITIATE:
            if (setDisplayAction(display, o, value))
                  return TRUE;
            break;
      case SPLASH_DISPLAY_OPTION_SATURATION:
      case SPLASH_DISPLAY_OPTION_BRIGHTNESS:
      case SPLASH_DISPLAY_OPTION_FADE_TIME:
      case SPLASH_DISPLAY_OPTION_DISPLAY_TIME:
            if (compSetFloatOption(o, value))
                  return TRUE;
            break;
      case SPLASH_DISPLAY_OPTION_LOGO:
      case SPLASH_DISPLAY_OPTION_BACKGROUND:
            if (compSetStringOption(o, value))
                  return TRUE;
            break;
      case SPLASH_DISPLAY_OPTION_DISABLE_UPDATE:
            if (compSetBoolOption(o, value))
                  return TRUE;
            break;
      default:
            break;
      }

      return FALSE;
}

static Bool
splashInitiate(CompDisplay * d, CompAction * ac, CompActionState state,
                     CompOption * option, int nOption)
{
      CompScreen *s;

      s = findScreenAtDisplay(d, getIntOptionNamed(option, nOption, "root", 0));
      if (s)
      {
            SPLASH_SCREEN(s);
            ss->initiate = TRUE;
            damageScreen(s);
      }
      return FALSE;
}

static void splashDisplayInitOptions(SplashDisplay * sd)
{
      CompOption *o;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_INITIATE];
      o->advanced = False;
      o->name = "initiate";
      o->group = N_("Binding");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Initiate Splash");
      o->longDesc = N_("Start Splash.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = splashInitiate;
      o->value.action.terminate = 0;
      o->value.action.bell = FALSE;
      o->value.action.edgeMask = 0;
      o->value.action.type = 0;
      //o->value.action.type |= CompBindingTypeKey;
      o->value.action.state = CompActionStateInitKey;
      o->value.action.key.modifiers = SPLASH_DISPLAY_OPTION_INITIATE_MOD;
      o->value.action.key.keysym =
                  XStringToKeysym(SPLASH_DISPLAY_OPTION_INITIATE_KEY);

      o = &sd->opt[SPLASH_DISPLAY_OPTION_BACKGROUND];
      o->advanced = False;
      o->name = "background_file";
      o->group = N_("Images");
      o->subGroup = N_("");
      o->displayHints = "file;image;pngonly;";
      o->shortDesc = N_("Background File");
      o->longDesc = N_("Background image File.");
      o->type = CompOptionTypeString;
      o->value.s = strdup(SPLASH_DISPLAY_OPTION_BACKGROUND_DEFAULT);
      o->rest.s.string = 0;
      o->rest.s.nString = 0;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_LOGO];
      o->advanced = False;
      o->name = "logo_file";
      o->group = N_("Images");
      o->subGroup = N_("");
      o->displayHints = "file;image;pngonly;";
      o->shortDesc = N_("Logo File");
      o->longDesc = N_("Logo image File.");
      o->type = CompOptionTypeString;
      o->value.s = strdup(SPLASH_DISPLAY_OPTION_LOGO_DEFAULT);
      o->rest.s.string = 0;
      o->rest.s.nString = 0;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_FADE_TIME];
      o->advanced = False;
      o->name = "fade_time";
      o->group = N_("Appearance");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Fade Time");
      o->longDesc = N_("Fade In/Out Time.");
      o->type = CompOptionTypeFloat;
      o->value.f = SPLASH_DISPLAY_OPTION_FADE_TIME_DEFAULT;
      o->rest.f.min = 0.0;
      o->rest.f.max = 100.0;
      o->rest.f.precision = 0.1;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_DISPLAY_TIME];
      o->advanced = False;
      o->name = "display_time";
      o->group = N_("Appearance");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Display Time");
      o->longDesc = N_("Display Time.");
      o->type = CompOptionTypeFloat;
      o->value.f = SPLASH_DISPLAY_OPTION_DISPLAY_TIME_DEFAULT;
      o->rest.f.min = 0.0;
      o->rest.f.max = 100.0;
      o->rest.f.precision = 0.1;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_SATURATION];
      o->advanced = False;
      o->name = "saturation";
      o->group = N_("Appearance");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Saturation");
      o->longDesc = N_("Background Saturation.");
      o->type = CompOptionTypeFloat;
      o->value.f = SPLASH_DISPLAY_OPTION_SATURATION_DEFAULT;
      o->rest.f.min = 0.0;
      o->rest.f.max = 100.0;
      o->rest.f.precision = 0.1;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_BRIGHTNESS];
      o->advanced = False;
      o->name = "brightness";
      o->group = N_("Appearance");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Brightness");
      o->longDesc = N_("Background Brightness.");
      o->type = CompOptionTypeFloat;
      o->value.f = SPLASH_DISPLAY_OPTION_BRIGHTNESS_DEFAULT;
      o->rest.f.min = 0.0;
      o->rest.f.max = 100.0;
      o->rest.f.precision = 0.1;

      o = &sd->opt[SPLASH_DISPLAY_OPTION_DISABLE_UPDATE];
      o->advanced = False;
      o->name = "disable_update";
      o->group = N_("Behaviour");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Disable Updates");
      o->longDesc = N_("Disable Updates of Background.");
      o->type = CompOptionTypeBool;
      o->value.b = SPLASH_DISPLAY_OPTION_DISABLE_UPDATE_DEFAULT;
}

static CompOption *splashGetDisplayOptions(CompDisplay * display, int *count)
{
      if (display)
      {
            SPLASH_DISPLAY(display);

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

            splashDisplayInitOptions(sd);
            *count = NUM_OPTIONS(sd);
            return sd->opt;
      }
}



static Bool splashInitDisplay(CompPlugin * p, CompDisplay * d)
{
      //Generate a splash display
      SplashDisplay *sd = (SplashDisplay *) malloc(sizeof(SplashDisplay));

      //Allocate a private index
      sd->screenPrivateIndex = allocateScreenPrivateIndex(d);
      //Check if its valid
      if (sd->screenPrivateIndex < 0)
      {
            //Its invalid so free memory and return
            free(sd);
            return FALSE;
      }
      splashDisplayInitOptions(sd);
      d->privates[displayPrivateIndex].ptr = sd;
      return TRUE;
}

static void splashFiniDisplay(CompPlugin * p, CompDisplay * d)
{
      SPLASH_DISPLAY(d);
      //Free the private index
      freeScreenPrivateIndex(d, sd->screenPrivateIndex);
      //Free the pointer
      free(sd);
}



static Bool splashInit(CompPlugin * p)
{
      displayPrivateIndex = allocateDisplayPrivateIndex();

      if (displayPrivateIndex < 0)
            return FALSE;

      return TRUE;
}

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

CompPluginDep splashDeps[] = {
      {CompPluginRuleAfterCategory, "imageloader"}
      ,
      {CompPluginRuleEnd, ""}
};

CompPluginVTable splashVTable = {
      "splash",
      N_("Splash"),
      N_("A simple splash plugin"),
      splashInit,
      splashFini,
      splashInitDisplay,
      splashFiniDisplay,
      splashInitScreen,
      splashFiniScreen,
      0,
      0,
      splashGetDisplayOptions,
      splashSetDisplayOption,
      0,
      0,
      splashDeps,
      sizeof(splashDeps) / sizeof(splashDeps[0]),
      0,
      0,
      BERYL_ABI_INFO,
      "beryl-plugins",
      "misc",
      0,
      0,
      False,
};

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

Generated by  Doxygen 1.6.0   Back to index