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