e16/src/fx.c

994 lines
24 KiB
C

/*
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#include "desktops.h"
#include "dialog.h"
#include "eimage.h"
#include "emodule.h"
#include "parse.h"
#include "timers.h"
#include "xwin.h"
#include <math.h>
/* FIXME - Needs cleaning up */
#ifndef M_PI_2
#define M_PI_2 (3.141592654 / 2)
#endif
#define FX_OP_START 1
#define FX_OP_STOP 2
#define FX_OP_TOGGLE 3
typedef struct
{
const char *name;
void (*init_func) (const char *name);
void (*desk_func) (void);
void (*quit_func) (void);
void (*pause_func) (void);
char enabled;
char paused;
}
FXHandler;
/****************************** RIPPLES *************************************/
#define fx_ripple_waterh 64
static Pixmap fx_ripple_above = None;
static Win fx_ripple_win = NoWin;
static int fx_ripple_count = 0;
static void
FX_ripple_timeout(int val __UNUSED__, void *data __UNUSED__)
{
static double incv = 0, inch = 0;
static GC gc1 = 0, gc = 0;
int y;
if (fx_ripple_above == None)
{
XGCValues gcv;
fx_ripple_win = DeskGetBackgroundWin(DesksGetCurrent());
fx_ripple_above =
ECreatePixmap(fx_ripple_win, VRoot.w, fx_ripple_waterh * 2, 0);
if (gc)
EXFreeGC(gc);
if (gc1)
EXFreeGC(gc1);
gcv.subwindow_mode = IncludeInferiors;
gc = EXCreateGC(WinGetXwin(fx_ripple_win), GCSubwindowMode, &gcv);
gc1 = EXCreateGC(WinGetXwin(fx_ripple_win), 0L, &gcv);
}
if (fx_ripple_count == 0)
XCopyArea(disp, EoGetXwin(DesksGetCurrent()), fx_ripple_above, gc, 0,
VRoot.h - (fx_ripple_waterh * 3), VRoot.w, fx_ripple_waterh * 2,
0, 0);
fx_ripple_count++;
if (fx_ripple_count > 32)
fx_ripple_count = 0;
incv += 0.40;
if (incv > (M_PI_2 * 4))
{
incv = 0;
}
inch += 0.32;
if (inch > (M_PI_2 * 4))
{
inch = 0;
}
for (y = 0; y < fx_ripple_waterh; y++)
{
double aa, a, p;
int yoff, off, yy;
p = (((double)(fx_ripple_waterh - y)) / ((double)fx_ripple_waterh));
a = p * p * 48 + incv;
yoff = y + (int)(sin(a) * 7) + 1;
yy = (fx_ripple_waterh * 2) - yoff;
aa = p * p * 64 + inch;
off = (int)(sin(aa) * 10 * (1 - p));
XCopyArea(disp, fx_ripple_above, WinGetXwin(fx_ripple_win), gc1, 0, yy,
VRoot.w, 1, off, VRoot.h - fx_ripple_waterh + y);
}
DoIn("FX_RIPPLE_TIMEOUT", 0.066, FX_ripple_timeout, 0, NULL);
}
static void
FX_Ripple_Init(const char *name __UNUSED__)
{
fx_ripple_count = 0;
DoIn("FX_RIPPLE_TIMEOUT", 0.066, FX_ripple_timeout, 0, NULL);
}
static void
FX_Ripple_Desk(void)
{
if (fx_ripple_above != None)
EFreePixmap(fx_ripple_above);
fx_ripple_count = 0;
fx_ripple_above = None;
}
static void
FX_Ripple_Quit(void)
{
RemoveTimerEvent("FX_RIPPLE_TIMEOUT");
EClearArea(fx_ripple_win, 0, VRoot.h - fx_ripple_waterh, VRoot.w,
fx_ripple_waterh, False);
}
static void
FX_Ripple_Pause(void)
{
static char paused = 0;
if (!paused)
{
FX_Ripple_Quit();
paused = 1;
}
else
{
FX_Ripple_Init(NULL);
paused = 0;
}
}
#ifdef E_FX_RAINDROPS /* FIXME - Requires eliminating use of PixImg */
/****************************** RAIN DROPS **********************************/
#define fx_raindrop_size 96
#define fx_raindrop_size2 (fx_raindrop_size / 2)
#define fx_raindrop_duration 32
#define fx_frequency 4
#define fx_amplitude 48
static Window fx_raindrops_win = None;
static int fx_raindrops_number = 4;
static PixImg *fx_raindrops_draw = NULL;
typedef struct
{
int x, y;
int count;
PixImg *buf;
}
DropContext;
static DropContext fx_raindrops[4];
static void
FX_raindrops_timeout(int val __UNUSED__, void *data __UNUSED__)
{
static GC gc1 = 0, gc = 0;
int i, x, y, xx, yy;
int percent_done;
static char first = 1;
static char sintab[256];
static unsigned char disttab[fx_raindrop_size][fx_raindrop_size];
if (fx_raindrops_win == None)
{
XGCValues gcv;
if (first)
{
int j;
first = 0;
for (i = 0; i < 256; i++)
sintab[i] =
(char)(sin(((double)i) * M_PI_2 * 4 / 256) * fx_amplitude);
for (j = 0; j < fx_raindrop_size; j++)
{
for (i = 0; i < fx_raindrop_size; i++)
{
xx = i - fx_raindrop_size2;
yy = j - fx_raindrop_size2;
disttab[i][j] =
(unsigned char)sqrt((double)((xx * xx) + (yy * yy)));
}
}
}
fx_raindrops_win = DeskGetBackgroundWin(DesksGetCurrent());
if (gc)
EXFreeGC(gc);
if (gc1)
EXFreeGC(gc1);
gcv.subwindow_mode = IncludeInferiors;
gc = EXCreateGC(fx_raindrops_win, GCSubwindowMode, &gcv);
gc1 = EXCreateGC(fx_raindrops_win, 0L, &gcv);
fx_raindrops_draw =
ECreatePixImg(fx_raindrops_win, fx_raindrop_size, fx_raindrop_size);
if (!fx_raindrops_draw)
return;
for (i = 0; i < fx_raindrops_number; i++)
{
fx_raindrops[i].buf =
ECreatePixImg(fx_raindrops_win, fx_raindrop_size,
fx_raindrop_size);
if (fx_raindrops[i].buf)
XShmGetImage(disp, fx_raindrops_win, fx_raindrops[i].buf->xim,
fx_raindrops[i].x, fx_raindrops[i].y, 0xffffffff);
if (!fx_raindrops[i].buf)
return;
}
}
for (i = 0; i < fx_raindrops_number; i++)
{
fx_raindrops[i].count++;
if (fx_raindrops[i].count == fx_raindrop_duration)
{
int j, count = 0;
char intersect = 1;
XClearArea(disp, fx_raindrops_win, fx_raindrops[i].x,
fx_raindrops[i].y, fx_raindrop_size, fx_raindrop_size,
False);
fx_raindrops[i].count = 0;
while (intersect)
{
count++;
if (count > 10240)
break;
intersect = 0;
for (j = 0; j < fx_raindrops_number; j++)
{
fx_raindrops[i].x =
rand() % (VRoot.w - fx_raindrop_size);
fx_raindrops[i].y =
rand() % (VRoot.h - fx_raindrop_size);
if (fx_raindrops[i].x < 0)
fx_raindrops[i].x = 0;
else if (fx_raindrops[i].x >
(VRoot.w - fx_raindrop_size))
fx_raindrops[i].x = VRoot.w - fx_raindrop_size;
if (fx_raindrops[i].y < 0)
fx_raindrops[i].y = 0;
else if (fx_raindrops[i].y >
(VRoot.h - fx_raindrop_size))
fx_raindrops[i].y = VRoot.h - fx_raindrop_size;
if (i != j)
{
if (((fx_raindrops[i].x >= fx_raindrops[j].x)
&& (fx_raindrops[i].x <
fx_raindrops[j].x + fx_raindrop_size)
&& (fx_raindrops[i].y >= fx_raindrops[j].y)
&& (fx_raindrops[i].y <
fx_raindrops[j].y + fx_raindrop_size))
||
((fx_raindrops
[i].x + fx_raindrop_size >= fx_raindrops[j].x)
&& (fx_raindrops[i].x + fx_raindrop_size <
fx_raindrops[j].x + fx_raindrop_size)
&& (fx_raindrops[i].y >= fx_raindrops[j].y)
&& (fx_raindrops[i].y <
fx_raindrops[j].y + fx_raindrop_size))
|| ((fx_raindrops[i].x >= fx_raindrops[j].x)
&& (fx_raindrops[i].x <
fx_raindrops[j].x + fx_raindrop_size)
&& (fx_raindrops[i].y + fx_raindrop_size >=
fx_raindrops[j].y)
&& (fx_raindrops[i].y + fx_raindrop_size <
fx_raindrops[j].y + fx_raindrop_size))
||
((fx_raindrops
[i].x + fx_raindrop_size >= fx_raindrops[j].x)
&& (fx_raindrops[i].x + fx_raindrop_size <
fx_raindrops[j].x + fx_raindrop_size)
&& (fx_raindrops[i].y + fx_raindrop_size >=
fx_raindrops[j].y)
&& (fx_raindrops[i].y + fx_raindrop_size <
fx_raindrops[j].y + fx_raindrop_size)))
intersect = 1;
}
}
}
XShmGetImage(disp, fx_raindrops_win, fx_raindrops[i].buf->xim,
fx_raindrops[i].x, fx_raindrops[i].y, 0xffffffff);
}
percent_done =
1 + ((fx_raindrops[i].count << 8) / fx_raindrop_duration);
for (y = 0; y < fx_raindrop_size; y++)
{
for (x = 0; x < fx_raindrop_size; x++)
{
int dist;
dist = disttab[x][y];
if (dist > fx_raindrop_size2)
XPutPixel(fx_raindrops_draw->xim, x, y,
XGetPixel(fx_raindrops[i].buf->xim, x, y));
else
{
int percent;
percent = 1 + ((dist << 8) / fx_raindrop_size2);
if (percent > percent_done)
XPutPixel(fx_raindrops_draw->xim, x, y,
XGetPixel(fx_raindrops[i].buf->xim, x, y));
else
{
int varx, vary;
int phase, divisor, multiplier;
phase =
((percent - percent_done) * fx_frequency) & 0xff;
xx = x - fx_raindrop_size2;
yy = y - fx_raindrop_size2;
divisor = 1 + (dist << 8);
multiplier =
(int)sintab[phase] * (256 - percent_done);
varx = ((-xx) * multiplier) / divisor;
vary = ((-yy) * multiplier) / divisor;
xx = x + varx;
yy = y + vary;
if (xx < 0)
xx = 0;
else if (xx >= fx_raindrop_size)
xx = fx_raindrop_size - 1;
if (yy < 0)
yy = 0;
else if (yy >= fx_raindrop_size)
yy = fx_raindrop_size - 1;
XPutPixel(fx_raindrops_draw->xim, x, y,
XGetPixel(fx_raindrops[i].buf->xim, xx,
yy));
}
}
}
}
XShmPutImage(disp, fx_raindrops_win, gc1, fx_raindrops_draw->xim, 0, 0,
fx_raindrops[i].x, fx_raindrops[i].y, fx_raindrop_size,
fx_raindrop_size, False);
ESync();
}
DoIn("FX_RAINDROPS_TIMEOUT", (0.066 /*/ (float)fx_raindrops_number */ ),
FX_raindrops_timeout, 0, NULL);
}
static void
FX_Raindrops_Init(const char *name __UNUSED__)
{
int i;
fx_raindrops_win = None;
for (i = 0; i < fx_raindrops_number; i++)
{
fx_raindrops[i].count = rand() % fx_raindrop_duration;
fx_raindrops[i].x = rand() % (VRoot.w - fx_raindrop_size);
fx_raindrops[i].y = rand() % (VRoot.h - fx_raindrop_size);
}
DoIn("FX_RAINDROPS_TIMEOUT", 0.066, FX_raindrops_timeout, 0, NULL);
}
static void
FX_Raindrops_Desk(void)
{
fx_raindrops_win = None;
}
static void
FX_Raindrops_Quit(void)
{
int i;
RemoveTimerEvent("FX_RAINDROPS_TIMEOUT");
for (i = 0; i < fx_raindrops_number; i++)
{
XClearArea(disp, fx_raindrops_win, fx_raindrops[i].x, fx_raindrops[i].y,
fx_raindrop_size, fx_raindrop_size, False);
if (fx_raindrops[i].buf)
EDestroyPixImg(fx_raindrops[i].buf);
fx_raindrops[i].buf = NULL;
}
if (fx_raindrops_draw)
EDestroyPixImg(fx_raindrops_draw);
fx_raindrops_draw = NULL;
fx_raindrops_win = None;
}
static void
FX_Raindrops_Pause(void)
{
static char paused = 0;
if (!paused)
{
FX_Raindrops_Quit();
paused = 1;
}
else
{
FX_Raindrops_Init(NULL);
paused = 0;
}
}
#endif /* E_FX_RAINDROPS */
/****************************** WAVES ***************************************/
/* by tsade :) */
/****************************************************************************/
#define FX_WAVE_WATERH 64
#define FX_WAVE_WATERW 64
#define FX_WAVE_DEPTH 10
#define FX_WAVE_GRABH (FX_WAVE_WATERH + FX_WAVE_DEPTH)
#define FX_WAVE_CROSSPERIOD 0.42
static Pixmap fx_wave_above = None;
static Win fx_wave_win = NoWin;
static int fx_wave_count = 0;
static void
FX_Wave_timeout(int val __UNUSED__, void *data __UNUSED__)
{
/* Variables */
static double incv = 0, inch = 0;
static double incx = 0;
double incx2;
static GC gc1 = 0, gc = 0;
int y;
/* Check to see if we need to create stuff */
if (!fx_wave_above)
{
XGCValues gcv;
fx_wave_win = DeskGetBackgroundWin(DesksGetCurrent());
fx_wave_above =
ECreatePixmap(fx_wave_win, VRoot.w, FX_WAVE_WATERH * 2, 0);
if (gc)
EXFreeGC(gc);
if (gc1)
EXFreeGC(gc1);
gcv.subwindow_mode = IncludeInferiors;
gc = EXCreateGC(WinGetXwin(fx_wave_win), GCSubwindowMode, &gcv);
gc1 = EXCreateGC(WinGetXwin(fx_wave_win), 0L, &gcv);
}
/* On the zero, grab the desktop again. */
if (fx_wave_count == 0)
{
XCopyArea(disp, EoGetXwin(DesksGetCurrent()), fx_wave_above, gc, 0,
VRoot.h - (FX_WAVE_WATERH * 3), VRoot.w, FX_WAVE_WATERH * 2,
0, 0);
}
/* Increment and roll the counter */
fx_wave_count++;
if (fx_wave_count > 32)
fx_wave_count = 0;
/* Increment and roll some other variables */
incv += 0.40;
if (incv > (M_PI_2 * 4))
incv = 0;
inch += 0.32;
if (inch > (M_PI_2 * 4))
inch = 0;
incx += 0.32;
if (incx > (M_PI_2 * 4))
incx = 0;
/* Copy the area to correct bugs */
if (fx_wave_count == 0)
{
XCopyArea(disp, fx_wave_above, WinGetXwin(fx_wave_win), gc1, 0,
VRoot.h - FX_WAVE_GRABH, VRoot.w, FX_WAVE_DEPTH * 2, 0,
VRoot.h - FX_WAVE_GRABH);
}
/* Go through the bottom couple (FX_WAVE_WATERH) lines of the window */
for (y = 0; y < FX_WAVE_WATERH; y++)
{
/* Variables */
double aa, a, p;
int yoff, off, yy;
int x;
/* Figure out the side-to-side movement */
p = (((double)(FX_WAVE_WATERH - y)) / ((double)FX_WAVE_WATERH));
a = p * p * 48 + incv;
yoff = y + (int)(sin(a) * 7) + 1;
yy = (FX_WAVE_WATERH * 2) - yoff;
aa = p * p * FX_WAVE_WATERH + inch;
off = (int)(sin(aa) * 10 * (1 - p));
/* Set up the next part */
incx2 = incx;
/* Go through the width of the screen, in block sizes */
for (x = 0; x < VRoot.w; x += FX_WAVE_WATERW)
{
/* Variables */
int sx;
/* Add something to incx2 and roll it */
incx2 += FX_WAVE_CROSSPERIOD;
if (incx2 > (M_PI_2 * 4))
incx2 = 0;
/* Figure it out */
sx = (int)(sin(incx2) * FX_WAVE_DEPTH);
/* Display this block */
XCopyArea(disp, fx_wave_above, WinGetXwin(fx_wave_win), gc1, x, yy, /* x, y */
FX_WAVE_WATERW, 1, /* w, h */
off + x, VRoot.h - FX_WAVE_WATERH + y + sx /* dx, dy */
);
}
}
/* Make noise */
DoIn("FX_WAVE_TIMEOUT", 0.066, FX_Wave_timeout, 0, NULL);
}
static void
FX_Waves_Init(const char *name __UNUSED__)
{
fx_wave_count = 0;
DoIn("FX_WAVE_TIMEOUT", 0.066, FX_Wave_timeout, 0, NULL);
}
static void
FX_Waves_Desk(void)
{
EFreePixmap(fx_wave_above);
fx_wave_count = 0;
fx_wave_above = 0;
}
static void
FX_Waves_Quit(void)
{
RemoveTimerEvent("FX_WAVE_TIMEOUT");
EClearArea(fx_wave_win, 0, VRoot.h - FX_WAVE_WATERH, VRoot.w,
FX_WAVE_WATERH, False);
}
static void
FX_Waves_Pause(void)
{
static char paused = 0;
if (!paused)
{
FX_Waves_Quit();
paused = 1;
}
else
{
FX_Waves_Init(NULL);
paused = 0;
}
}
#ifdef E_FX_IMAGESPINNER
/****************************** IMAGESPINNER ********************************/
static Window fx_imagespinner_win = None;
static int fx_imagespinner_count = 3;
static char *fx_imagespinner_params = NULL;
static void
FX_imagespinner_timeout(int val __UNUSED__, void *data __UNUSED__)
{
char *string = NULL;
if (fx_imagespinner_win == None)
{
fx_imagespinner_win = DeskGetBackgroundWin(DesksGetCurrent());
}
#if 0 /* Don't use getword */
/* do stuff here */
string = getword(fx_imagespinner_params, fx_imagespinner_count);
if (!string)
{
fx_imagespinner_count = 3;
string = getword(fx_imagespinner_params, fx_imagespinner_count);
}
#endif
fx_imagespinner_count++;
if (string)
{
EImage *im;
im = ThemeImageLoad(string);
if (im)
{
int x, y, w, h;
EImageGetSize(im, &w, &h);
sscanf(fx_imagespinner_params, "%*s %i %i ", &x, &y);
x = ((VRoot.w * x) >> 10) - ((w * x) >> 10);
y = ((VRoot.h * y) >> 10) - ((h * y) >> 10);
EImageRenderOnDrawable(im, fx_imagespinner_win, x, y, w, h, 0);
EImageFree(im);
}
Efree(string);
}
DoIn("FX_IMAGESPINNER_TIMEOUT", 0.066, FX_imagespinner_timeout, 0, NULL);
}
static void
FX_ImageSpinner_Init(const char *name)
{
fx_imagespinner_count = 3;
DoIn("FX_IMAGESPINNER_TIMEOUT", 0.066, FX_imagespinner_timeout, 0, NULL);
fx_imagespinner_params = Estrdup(name);
}
static void
FX_ImageSpinner_Desk(void)
{
fx_imagespinner_win = DeskGetBackgroundWin(DesksGetCurrent());
}
static void
FX_ImageSpinner_Quit(void)
{
RemoveTimerEvent("FX_IMAGESPINNER_TIMEOUT");
XClearArea(disp, fx_imagespinner_win, 0, 0, VRoot.w, VRoot.h, False);
if (fx_imagespinner_params)
Efree(fx_imagespinner_params);
fx_imagespinner_params = NULL;
fx_imagespinner_win = None;
}
static void
FX_ImageSpinner_Pause(void)
{
static char paused = 0;
if (!paused)
{
FX_ImageSpinner_Quit();
paused = 1;
}
else
{
FX_ImageSpinner_Init(NULL);
paused = 0;
}
}
#endif /* E_FX_IMAGESPINNER */
/****************************************************************************/
static FXHandler fx_handlers[] = {
{"ripples",
FX_Ripple_Init, FX_Ripple_Desk, FX_Ripple_Quit, FX_Ripple_Pause,
0, 0},
{"waves",
FX_Waves_Init, FX_Waves_Desk, FX_Waves_Quit, FX_Waves_Pause,
0, 0},
#ifdef E_FX_RAINDROPS /* FIXME */
{"raindrops",
FX_Raindrops_Init, FX_Raindrops_Desk, FX_Raindrops_Quit,
FX_Raindrops_Pause,
0, 0},
#endif
#ifdef E_FX_IMAGESPINNER
{"imagespinner",
FX_ImageSpinner_Init, FX_ImageSpinner_Desk, FX_ImageSpinner_Quit,
FX_ImageSpinner_Pause,
0, 0},
#endif
};
#define N_FX_HANDLERS (sizeof(fx_handlers)/sizeof(FXHandler))
/****************************** Effect handlers *****************************/
static FXHandler *
FX_Find(const char *name)
{
unsigned int i;
for (i = 0; i < N_FX_HANDLERS; i++)
if (!strcmp(fx_handlers[i].name, name))
return &fx_handlers[i];
return NULL;
}
static void
FX_Op(const char *name, int fx_op)
{
FXHandler *fxh;
fxh = FX_Find(name);
if (fxh == NULL)
return;
switch (fx_op)
{
case FX_OP_START:
if (fxh->enabled)
break;
do_start:
if (fxh->init_func)
fxh->init_func(name);
fxh->enabled = 1;
break;
case FX_OP_STOP:
if (!fxh->enabled)
break;
do_stop:
if (fxh->quit_func)
fxh->quit_func();
fxh->enabled = 0;
break;
case FX_OP_TOGGLE:
if (fxh->enabled)
goto do_stop;
else
goto do_start;
}
}
static void
FX_DeskChange(void)
{
unsigned int i;
for (i = 0; i < N_FX_HANDLERS; i++)
{
if (fx_handlers[i].enabled)
{
if (fx_handlers[i].desk_func)
fx_handlers[i].desk_func();
}
}
}
static void
FX_Pause(void)
{
unsigned int i;
for (i = 0; i < N_FX_HANDLERS; i++)
{
if (fx_handlers[i].enabled)
{
if (fx_handlers[i].paused)
{
if (fx_handlers[i].pause_func)
fx_handlers[i].pause_func();
fx_handlers[i].paused = 1;
}
else
{
if (fx_handlers[i].pause_func)
fx_handlers[i].pause_func();
fx_handlers[i].paused = 0;
}
}
}
}
static void
FX_StartAll(void)
{
unsigned int i;
FXHandler *fxh;
for (i = 0; i < N_FX_HANDLERS; i++)
{
fxh = &fx_handlers[i];
if (fxh->enabled && fxh->init_func)
fxh->init_func(fxh->name);
}
}
static int
FX_IsOn(const char *effect)
{
unsigned int i;
for (i = 0; i < N_FX_HANDLERS; i++)
{
if (!strcmp(fx_handlers[i].name, effect))
{
return fx_handlers[i].enabled;
}
}
return 0;
}
/****************************************************************************/
/*
* Fx Module
*/
static void
FxSighan(int sig, void *prm __UNUSED__)
{
switch (sig)
{
case ESIGNAL_START:
FX_StartAll();
break;
case ESIGNAL_AREA_SWITCH_START:
case ESIGNAL_DESK_SWITCH_START:
break;
case ESIGNAL_AREA_SWITCH_DONE:
case ESIGNAL_DESK_SWITCH_DONE:
FX_DeskChange();
break;
case ESIGNAL_ANIMATION_SUSPEND:
case ESIGNAL_ANIMATION_RESUME:
FX_Pause();
break;
}
}
static char tmp_effect_raindrops;
static char tmp_effect_ripples;
static char tmp_effect_waves;
static void
CB_ConfigureFX(Dialog * d __UNUSED__, int val, void *data __UNUSED__)
{
if (val < 2)
{
FX_Op("raindrops", tmp_effect_raindrops ? FX_OP_START : FX_OP_STOP);
FX_Op("ripples", tmp_effect_ripples ? FX_OP_START : FX_OP_STOP);
FX_Op("waves", tmp_effect_waves ? FX_OP_START : FX_OP_STOP);
}
autosave();
}
static void
_DlgFillFx(Dialog * d __UNUSED__, DItem * table, void *data __UNUSED__)
{
DItem *di;
tmp_effect_raindrops = FX_IsOn("raindrops");
tmp_effect_ripples = FX_IsOn("ripples");
tmp_effect_waves = FX_IsOn("waves");
DialogItemTableSetOptions(table, 1, 0, 0, 0);
/* Effects */
di = DialogAddItem(table, DITEM_TEXT);
DialogItemSetText(di, _("Effects"));
#if 0 /* Disabled */
di = DialogAddItem(table, DITEM_CHECKBUTTON);
DialogItemSetText(di, _("Enable Effect: Raindrops"));
DialogItemCheckButtonSetPtr(di, &tmp_effect_raindrops);
#endif
di = DialogAddItem(table, DITEM_CHECKBUTTON);
DialogItemSetText(di, _("Ripples"));
DialogItemCheckButtonSetPtr(di, &tmp_effect_ripples);
di = DialogAddItem(table, DITEM_CHECKBUTTON);
DialogItemSetText(di, _("Waves"));
DialogItemCheckButtonSetPtr(di, &tmp_effect_waves);
}
const DialogDef DlgFx = {
"CONFIGURE_FX",
N_("FX"),
N_("Special FX Settings"),
"SOUND_SETTINGS_FX",
"pix/fx.png",
N_("Enlightenment Special Effects\n" "Settings Dialog\n"),
_DlgFillFx,
DLG_OAC, CB_ConfigureFX,
};
static void
FxIpc(const char *params, Client * c __UNUSED__)
{
char word1[FILEPATH_LEN_MAX];
char word2[FILEPATH_LEN_MAX];
if (!params)
return;
word1[0] = '\0';
word2[0] = '\0';
word(params, 1, word1);
if (!strcmp(word1, "raindrops") || !strcmp(word1, "ripples") ||
!strcmp(word1, "waves"))
{
word(params, 2, word2);
if (!strcmp(word2, ""))
FX_Op(word1, FX_OP_TOGGLE);
else if (!strcmp(word2, "on"))
FX_Op(word1, FX_OP_START);
else if (!strcmp(word2, "off"))
FX_Op(word1, FX_OP_STOP);
else if (!strcmp(word2, "?"))
IpcPrintf("%s: %s", word1, FX_IsOn(word1) ? "on" : "off");
else
IpcPrintf("Error: unknown mode specified");
}
else if (!strncmp(word1, "cfg", 2))
{
DialogShowSimple(&DlgFx, NULL);
}
}
static const IpcItem FxIpcArray[] = {
{
FxIpc,
"fx", "fx",
"Toggle various effects on/off",
" fx cfg Configure effects\n"
" fx <effect> <mode> Set the mode of a particular effect\n"
" fx <effect> ?\" Get the current mode\n"
"the following effects are available\n"
" ripples <on/off> (ripples that act as a water effect on the screen)\n"
" waves <on/off> (waves that act as a water effect on the screen)\n"}
,
};
#define N_IPC_FUNCS (sizeof(FxIpcArray)/sizeof(IpcItem))
static const CfgItem FxCfgItems[] = {
CFR_ITEM_BOOL(fx_handlers[0].enabled, ripples.enabled, 0),
CFR_ITEM_BOOL(fx_handlers[1].enabled, waves.enabled, 0),
#ifdef E_FX_RAINDROPS /* FIXME */
CFR_ITEM_BOOL(fx_handlers[2].enabled, raindrops.enabled, 0),
#endif
};
#define N_CFG_ITEMS (sizeof(FxCfgItems)/sizeof(CfgItem))
/*
* Module descriptor
*/
const EModule ModEffects = {
"effects", "efx",
FxSighan,
{N_IPC_FUNCS, FxIpcArray},
{N_CFG_ITEMS, FxCfgItems}
};