e16-epplets/epplets/E-Xss.c

373 lines
9.5 KiB
C

/*
* Copyright (C) 1999-2000, Michael Jennings
*
* 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 <stdio.h>
#include <signal.h>
#include "config.h"
#include "epplet.h"
#if 0
#define D(x) do {printf("%10s | %7d: [debug] ", __FILE__, __LINE__); printf x; fflush(stdout);} while (0)
#else
#define D(x) ((void) 0)
#endif
#define BEGMATCH(a, b) (!strncasecmp((a), (b), (sizeof(b) - 1)))
#define NONULL(x) ((x) ? (x) : (""))
#define PREV_HACK() do {if (idx == 1) idx = hack_cnt - 1; else if (idx == 0) idx = hack_cnt - 2; else idx -= 2;} while (0)
#define CUR_HACK() ((idx == 0) ? (hack_cnt - 1) : (idx - 1))
#define NEXT_HACK() ((void) 0)
#define INC_HACK() do {idx++; if (idx == hack_cnt) idx = 0;} while (0)
#define DEC_HACK() do {if (idx == 0) idx = hack_cnt - 1; else idx--;} while (0)
static Epplet_gadget close_button, prev_button, next_button, zoom_button,
cfg_button, lock_button, draw_area;
static Epplet_gadget cfg_tb_delay, *cfg_tb_hacks;
static Window config_win = None;
static unsigned long idx = 0, hack_cnt = 0;
static double delay;
static char **hacks = NULL;
static pid_t hack_pid = -1;
static void child_cb(void *data, int pid, int exit_code);
static void
start_hack(char *hack)
{
char buff[1024];
Esnprintf(buff, sizeof(buff), "%s -window-id %ld", hack,
Epplet_get_drawingarea_window(draw_area));
Epplet_register_child_handler(child_cb, NULL);
hack_pid = Epplet_spawn_command(buff);
}
static void
stop_hack(void)
{
if (hack_pid != -1)
{
kill(hack_pid, SIGTERM);
}
hack_pid = -1;
}
static void
change_hack(void *data __UNUSED__)
{
stop_hack();
start_hack(hacks[idx]);
INC_HACK();
Epplet_timer(change_hack, NULL, delay, "CHANGE_HACK");
}
static void
child_cb(void *data __UNUSED__, int pid, int exit_code)
{
if (pid == hack_pid)
{
fprintf(stderr, "E-Xss: Child process exited with return code %d\n",
exit_code);
Epplet_remove_timer("CHANGE_HACK");
Epplet_timer(change_hack, NULL, 0.1, "CHANGE_HACK");
}
}
static void
close_cb(void *data __UNUSED__)
{
stop_hack();
Epplet_unremember();
Esync();
exit(0);
}
static void
zoom_cb(void *data __UNUSED__)
{
Epplet_spawn_command(hacks[CUR_HACK()]);
}
static void
play_cb(void *data)
{
int op = (int)(long)data;
switch (op)
{
case -1:
/* Previous hack */
PREV_HACK();
change_hack(NULL);
break;
case 1:
/* Next hack */
NEXT_HACK();
change_hack(NULL);
break;
default:
break;
}
}
static void
in_cb(void *data __UNUSED__, Window w)
{
if (w == Epplet_get_main_window())
{
/*Epplet_gadget_hide(draw_area); */
Epplet_gadget_show(close_button);
Epplet_gadget_show(zoom_button);
Epplet_gadget_show(prev_button);
Epplet_gadget_show(next_button);
Epplet_gadget_show(cfg_button);
Epplet_gadget_show(lock_button);
}
}
static void
out_cb(void *data __UNUSED__, Window w)
{
if (w == Epplet_get_main_window())
{
/*Epplet_gadget_show(draw_area); */
Epplet_gadget_hide(close_button);
Epplet_gadget_hide(zoom_button);
Epplet_gadget_hide(prev_button);
Epplet_gadget_hide(next_button);
Epplet_gadget_hide(cfg_button);
Epplet_gadget_hide(lock_button);
}
}
static int
delete_cb(void *data __UNUSED__, Window win __UNUSED__)
{
config_win = None;
return 1;
}
static void
apply_config(void)
{
const char *s;
char buff[1024];
unsigned long i, j;
strcpy(buff, Epplet_textbox_contents(cfg_tb_delay));
if ((delay = atof(buff)) != 0.0)
{
Epplet_modify_config("delay", buff);
}
else
{
delay = atof(Epplet_query_config_def("delay", "60.0"));
}
for (i = 0, j = 0; i < hack_cnt; i++)
{
s = Epplet_textbox_contents(cfg_tb_hacks[i]);
if (strlen(s))
{
Esnprintf(buff, sizeof(buff), "hack_%lu", j);
Epplet_modify_config(buff, s);
hacks[j++] = (char *)Epplet_query_config(buff);
}
}
hack_cnt = j;
if (idx >= hack_cnt)
{
idx = 0;
}
hacks = (char **)realloc(hacks, sizeof(char *) * (hack_cnt));
DEC_HACK();
change_hack(NULL);
}
static void
ok_cb(void *data __UNUSED__)
{
apply_config();
Epplet_save_config();
Epplet_window_destroy(config_win);
config_win = None;
free(cfg_tb_hacks);
}
static void
apply_cb(void *data __UNUSED__)
{
apply_config();
}
static void
cancel_cb(void *data __UNUSED__)
{
Epplet_window_destroy(config_win);
config_win = None;
free(cfg_tb_hacks);
}
static void
config_cb(void *data __UNUSED__)
{
char buff[128];
unsigned int h, y, i;
if (config_win)
return;
hacks = (char **)realloc(hacks, sizeof(char *) * (++hack_cnt));
cfg_tb_hacks = (Epplet_gadget *) malloc(sizeof(Epplet_gadget) * hack_cnt);
memset(cfg_tb_hacks, 0, sizeof(Epplet_gadget) * hack_cnt);
h = 70 + (hack_cnt * 41);
config_win =
Epplet_create_window_config(300, h, "E-Xss Configuration", ok_cb, NULL,
apply_cb, NULL, cancel_cb, NULL);
sprintf(buff, "%3.2f", delay);
Epplet_gadget_show(Epplet_create_label
(4, 4, "Delay between images (seconds):", 2));
Epplet_gadget_show(cfg_tb_delay =
Epplet_create_textbox(NULL, buff, 4, 18, 292, 20, 2, NULL,
NULL));
for (i = 0, y = 50; i < hack_cnt; i++)
{
Esnprintf(buff, sizeof(buff), "Hack #%d:", i);
Epplet_gadget_show(Epplet_create_label(4, y, buff, 2));
y += 14;
Epplet_gadget_show(cfg_tb_hacks[i] =
Epplet_create_textbox(NULL,
((i ==
hack_cnt -
1) ? NULL : hacks[i]), 4, y,
292, 20, 2, NULL, NULL));
y += 27;
}
Epplet_window_show(config_win);
Epplet_window_pop_context();
}
static void
lock_cb(void *data __UNUSED__)
{
Epplet_spawn_command("xscreensaver-command -lock");
}
static void
parse_config(void)
{
delay = atof(Epplet_query_config_def("delay", "60.0"));
hacks = (char **)malloc(sizeof(char *) * (hack_cnt + 1));
for (; 1; hack_cnt++)
{
const char *tmp;
char buff[40];
Esnprintf(buff, sizeof(buff), "hack_%lu", hack_cnt);
tmp = Epplet_query_config(buff);
if (!tmp)
{
break;
}
hacks = (char **)realloc(hacks, sizeof(char *) * (hack_cnt + 1));
hacks[hack_cnt] = (char *)tmp;
}
if (hack_cnt == 0)
{
hack_cnt = 3;
hacks = (char **)realloc(hacks, sizeof(char *) * (hack_cnt));
hacks[0] = (char *)"kaleidescope";
hacks[1] = (char *)"rorschach";
hacks[2] = (char *)"qix -solid -delay 0 -segments 100";
Epplet_add_config("hack_0", "kaleidescope");
Epplet_add_config("hack_1", "strange");
Epplet_add_config("hack_2", "qix -solid -delay 50 -segments 100");
Epplet_add_config("hack_3", "demon");
Epplet_add_config("hack_4", "bubbles");
Epplet_add_config("hack_5", "xflame");
Epplet_add_config("hack_6", "compass");
Epplet_add_config("hack_7", "drift");
Epplet_add_config("hack_8", "flow");
Epplet_add_config("hack_9", "galaxy");
Epplet_add_config("hack_10", "hypercube");
Epplet_add_config("hack_11", "ifs");
Epplet_add_config("hack_12", "kumppa -delay 20000");
Epplet_add_config("hack_13", "laser");
Epplet_add_config("hack_14", "swirl");
Epplet_add_config("hack_15", "t3d");
Epplet_add_config("hack_16", "triangle");
Epplet_add_config("hack_17", "worm");
}
}
int
main(int argc, char **argv)
{
Epplet_adjust_priority(10);
atexit(Epplet_cleanup);
Epplet_Init("E-Xss", "0.2", "Enlightenment Xscreensaver Epplet", 3, 3, argc,
argv, 0);
Epplet_load_config();
parse_config();
draw_area = Epplet_create_drawingarea(3, 3, 43, 43);
Epplet_gadget_show(draw_area);
close_button =
Epplet_create_button(NULL, NULL, 3, 3, 0, 0, "CLOSE", 0, NULL, close_cb,
NULL);
cfg_button = Epplet_create_std_button("CONFIGURE", 33, 3, config_cb, NULL);
lock_button =
Epplet_create_button("Lock", NULL, 2, 17, 44, 13, 0, 0, NULL, lock_cb,
NULL);
prev_button =
Epplet_create_button(NULL, NULL, 3, 33, 0, 0, "PREVIOUS", 0, NULL,
play_cb, (void *)(-1));
zoom_button =
Epplet_create_button(NULL, NULL, 18, 33, 0, 0, "EJECT", 0, NULL, zoom_cb,
NULL);
next_button =
Epplet_create_button(NULL, NULL, 33, 33, 0, 0, "NEXT", 0, NULL, play_cb,
(void *)(1));
Epplet_show();
Epplet_register_focus_in_handler(in_cb, NULL);
Epplet_register_focus_out_handler(out_cb, NULL);
Epplet_register_delete_event_handler(delete_cb, NULL);
change_hack(NULL);
Epplet_Loop();
return 0;
}