/**
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1