/** * 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 #include #include #include #include #include #include #include #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; }