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