summaryrefslogtreecommitdiff
path: root/beryl-plugins/src/splash.c
diff options
context:
space:
mode:
authorquinn <quinn@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-09-27 23:19:52 +0000
committerquinn <quinn@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-09-27 23:19:52 +0000
commit4c9796dddab60529fff57638d3cb0d8ca830a3fe (patch)
tree1c54f385f71dc9897381c7b266ff1090137a74e1 /beryl-plugins/src/splash.c
parent6e36e85e06f7cf5edc75016bc2bb2612c0ee80c1 (diff)
downloadmarex-dev-4c9796dddab60529fff57638d3cb0d8ca830a3fe.tar.gz
marex-dev-4c9796dddab60529fff57638d3cb0d8ca830a3fe.tar.bz2
move in beryl-plugins
git-svn-id: file:///beryl/trunk@325 d7aaf104-2d23-0410-ae22-9d23157bf5a3
Diffstat (limited to 'beryl-plugins/src/splash.c')
-rw-r--r--beryl-plugins/src/splash.c800
1 files changed, 800 insertions, 0 deletions
diff --git a/beryl-plugins/src/splash.c b/beryl-plugins/src/splash.c
new file mode 100644
index 0000000..293e6c7
--- /dev/null
+++ b/beryl-plugins/src/splash.c
@@ -0,0 +1,800 @@
+/**
+ *
+ * Beryl splash plugin
+ *
+ * splash.c
+ *
+ * Copyright : (C) 2006 by Dennis Kasprzyk
+ * E-mail : dennis.kasprzyk@rwth-aachen.de
+ *
+ *
+ * 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>
+
+#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 "/logo_example.png"
+#define SPLASH_DISPLAY_OPTION_BACKGROUND_DEFAULT IMAGEDIR "/back_example.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;
+
+} 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)
+ fprintf (stderr,
+ "[SPLASH]: Could not load splash background image \"%s\" !\n",
+ sd->opt[SPLASH_DISPLAY_OPTION_BACKGROUND].value.s);
+ if (!ss->hasBack)
+ 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;
+ }
+ }
+ }
+
+ 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, unsigned int mask)
+{
+
+ SPLASH_SCREEN (s);
+ SPLASH_DISPLAY (s->display);
+
+ Bool status = TRUE;
+
+ if (ss->active)
+ s->disablePostprocessFX =
+ !sd->opt[SPLASH_DISPLAY_OPTION_DISABLE_UPDATE].value.b;
+
+
+ UNWRAP (ss, s, paintScreen);
+ status = (*s->paintScreen) (s, sa, region, mask);
+ WRAP (ss, s, paintScreen, splashPaintScreen);
+
+ if (!ss->active)
+ return status;
+
+ s->disablePostprocessFX = FALSE;
+
+ 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);
+
+ 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 = sd->opt[SPLASH_DISPLAY_OPTION_SATURATION].value.f / 100.0;
+
+ 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, 0, 0, 0, 0,
+ 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 (0, s->height);
+ glVertex2f (0, 0);
+ glTexCoord2f (0, 0);
+ glVertex2f (0, s->height);
+ glTexCoord2f (s->width, 0);
+ glVertex2f (s->width, s->height);
+ glTexCoord2f (s->width, s->height);
+ glVertex2f (s->width, 0);
+ 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 (0, 0);
+ glVertex2f (0, s->height);
+ glVertex2f (s->width, s->height);
+ glVertex2f (s->width, 0);
+ glEnd ();
+ }
+
+ if (sd->opt[SPLASH_DISPLAY_OPTION_DISABLE_UPDATE].value.b)
+ {
+
+ // save background
+ if (ss->doUpdate)
+ {
+ ss->doUpdate = FALSE;
+ glEnable (GL_TEXTURE_RECTANGLE_ARB);
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, ss->background.handle);
+ glCopyTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 0, 0,
+ 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, 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 (0, s->height);
+ glVertex2f (0, 0);
+ glTexCoord2f (0, 0);
+ glVertex2f (0, s->height);
+ glTexCoord2f (s->width, 0);
+ glVertex2f (s->width, s->height);
+ glTexCoord2f (s->width, s->height);
+ glVertex2f (s->width, 0);
+ 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;
+ 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);
+ 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 ();
+
+ 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 = (s->width - ss->logoSize[0]) / 2;
+ int 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;
+
+ return TRUE;
+}
+
+
+static void
+splashFiniScreen (CompPlugin * p, CompScreen * s)
+{
+
+ SPLASH_SCREEN (s);
+
+ //Restore the original function
+ UNWRAP (ss, s, paintScreen);
+ UNWRAP (ss, s, preparePaintScreen);
+ UNWRAP (ss, s, donePaintScreen);
+
+ //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, Display * display)
+{
+ CompOption *o;
+
+ o = &sd->opt[SPLASH_DISPLAY_OPTION_INITIATE];
+ o->name = "initiate";
+ o->shortDesc = "Initiate";
+ o->longDesc = "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 = CompBindingTypeKey;
+ o->value.action.state = CompActionStateInitKey;
+ o->value.action.key.modifiers = SPLASH_DISPLAY_OPTION_INITIATE_MOD;
+ o->value.action.key.keycode =
+ XKeysymToKeycode (display,
+ XStringToKeysym
+ (SPLASH_DISPLAY_OPTION_INITIATE_KEY));
+
+ o = &sd->opt[SPLASH_DISPLAY_OPTION_BACKGROUND];
+ o->name = "background_file";
+ 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->name = "logo_file";
+ 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->name = "fade_time";
+ 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->name = "display_time";
+ 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->name = "saturation";
+ 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->name = "brightness";
+ 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->name = "disable_update";
+ 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));
+ Display *d = XOpenDisplay (getenv ("DISPLAY"));
+ if (!d)
+ exit (1);
+ splashDisplayInitOptions (sd, d);
+ *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->display);
+ 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);
+}
+
+
+CompPluginVTable splashVTable = {
+ "splash",
+ "Splash",
+ "A simple splash plugin",
+ splashInit,
+ splashFini,
+ splashInitDisplay,
+ splashFiniDisplay,
+ splashInitScreen,
+ splashFiniScreen,
+ 0,
+ 0,
+ splashGetDisplayOptions,
+ splashSetDisplayOption,
+ 0,
+ 0,
+ 0,
+ 0,
+ BERYL_ABI_INFO
+};
+
+CompPluginVTable *
+getCompPluginInfo (void)
+{
+ return &splashVTable;
+}