/* * noblank.c: * a wrapper for (full screen) applications and/or games that * lack support for xscreensaver. deactivates every 60 seconds * by default, tunable with the NOBLANK_INTERVAL env variable. * * Compiling: * gcc noblank.c -o noblank * * Usage: * noblank quake3 +disconnect +set fs_game arena * noblank nwn * * Related: * http://www.jwz.org/xscreensaver/faq.html#dvd * * Mike Hokenson */ #include #include #include #include #include #include #include #include #include static int interval = 60; /* deactivate once a minute */ static int do_deactivate = 0; static int do_exit = 0; void sighandler(int sig) { switch (sig) { case SIGALRM: do_deactivate = 1; break; case SIGCHLD: do_exit = 1; break; default: break; } } int main(int argc, char *argv[]) { char *args[argc - 1], *e; pid_t pid; int i; if (argc < 2) { fprintf(stderr, "Usage: %s [ ]\n", argv[0]); exit(1); } if ((e = getenv("NOBLANK_INTERVAL")) && *e) { int n = atoi(e); if (n > 0) interval = n; } for (i = 1; i < argc; i++) args[i-1] = argv[i]; args[argc-1] = NULL; pid = fork(); switch (pid) { case 0: /* child */ if (execvp(args[0], args) == -1) { fprintf(stderr, "Failed to execute '%s': %s\n", args[0], strerror(errno)); _exit(1); } _exit(0); case -1: /* error */ fprintf(stderr, "Failed to create new process: %s\n", strerror(errno)); exit(1); default: /* parent */ break; } signal(SIGALRM, sighandler); signal(SIGCHLD, sighandler); alarm(interval); while (1) { struct timeval tv; if (do_exit) break; if (do_deactivate) { signal(SIGCHLD, SIG_IGN); system("xscreensaver-command -deactivate > /dev/null 2>&1"); signal(SIGCHLD, sighandler); do_deactivate = 0; alarm(interval); /* XXX: xscreensaver-command: no response to command */ if (kill(pid, 0)) break; } tv.tv_sec = 0; tv.tv_usec = 25000; select(0, 0, NULL, NULL, &tv); } alarm(0); wait(NULL); exit(0); }