summaryrefslogtreecommitdiff
path: root/usr.sbin/screenblank/screenblank.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /usr.sbin/screenblank/screenblank.c
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/screenblank/screenblank.c')
-rw-r--r--usr.sbin/screenblank/screenblank.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/usr.sbin/screenblank/screenblank.c b/usr.sbin/screenblank/screenblank.c
new file mode 100644
index 00000000000..dcd5d59ad6c
--- /dev/null
+++ b/usr.sbin/screenblank/screenblank.c
@@ -0,0 +1,321 @@
+/* $NetBSD: screenblank.c,v 1.1 1995/07/12 04:57:51 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1995 Jason R. Thorpe.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Jason R. Thorpe.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Screensaver daemon for the Sun 3 and SPARC.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/queue.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <math.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <machine/fbio.h>
+
+#include "pathnames.h"
+
+struct dev_stat {
+ LIST_ENTRY(dev_stat) ds_link; /* linked list */
+ char *ds_path; /* path to device */
+ int ds_isfb; /* boolean; framebuffer? */
+ time_t ds_atime; /* time device last accessed */
+ time_t ds_mtime; /* time device last modified */
+};
+LIST_HEAD(ds_list, dev_stat) ds_list;
+
+extern char *__progname;
+
+static void add_dev __P((char *, int));
+static void change_state __P((int));
+static void cvt_arg __P((char *, struct timeval *));
+static void logpid __P((void));
+static void sighandler __P((int, int, struct sigcontext *));
+static void usage __P((void));
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct dev_stat *dsp;
+ struct timeval timo_on, timo_off, *tvp;
+ struct sigaction sa;
+ struct stat st;
+ int ch, change, fflag = 0, kflag = 0, mflag = 0, state;
+
+ LIST_INIT(&ds_list);
+
+ /*
+ * Set the default timeouts: 10 minutes on, .25 seconds off.
+ */
+ timo_on.tv_sec = 600;
+ timo_on.tv_usec = 0;
+ timo_off.tv_sec = 0;
+ timo_off.tv_usec = 250000;
+
+ while ((ch = getopt(argc, argv, "d:e:f:km")) != -1) {
+ switch (ch) {
+ case 'd':
+ cvt_arg(optarg, &timo_on);
+ break;
+
+ case 'e':
+ cvt_arg(optarg, &timo_off);
+ break;
+
+ case 'f':
+ fflag = 1;
+ add_dev(optarg, 1);
+ break;
+
+ case 'k':
+ if (mflag || kflag)
+ usage();
+ kflag = 1;
+ break;
+
+ case 'm':
+ if (kflag || mflag)
+ usage();
+ mflag = 1;
+ break;
+
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ if (argc)
+ usage();
+
+ /*
+ * Add the keyboard, mouse, and default framebuffer devices
+ * as necessary. We _always_ check the console device.
+ */
+ add_dev(_PATH_CONSOLE, 0);
+ if (!kflag)
+ add_dev(_PATH_KEYBOARD, 0);
+ if (!mflag)
+ add_dev(_PATH_MOUSE, 0);
+ if (!fflag)
+ add_dev(_PATH_FB, 1);
+
+ /* Ensure that the framebuffer is on. */
+ state = FBVIDEO_ON;
+ change_state(state);
+ tvp = &timo_on;
+
+ /*
+ * Make sure the framebuffer gets turned back on when we're
+ * killed.
+ */
+ sa.sa_handler = sighandler;
+ sa.sa_mask = 0;
+ sa.sa_flags = SA_NOCLDSTOP;
+ if (sigaction(SIGINT, &sa, NULL) || sigaction(SIGTERM, &sa, NULL) ||
+ sigaction(SIGHUP, &sa, NULL))
+ err(1, "sigaction");
+
+ /* Detach. */
+ if (daemon(0, 0))
+ err(1, "daemon");
+ logpid();
+
+ /* Start the state machine. */
+ for (;;) {
+ change = 0;
+ for (dsp = ds_list.lh_first; dsp != NULL;
+ dsp = dsp->ds_link.le_next) {
+ /* Don't check framebuffers. */
+ if (dsp->ds_isfb)
+ continue;
+ if (stat(dsp->ds_path, &st) < 0)
+ err(1, "stat: %s", dsp->ds_path);
+ if (st.st_atime > dsp->ds_atime) {
+ change = 1;
+ dsp->ds_atime = st.st_atime;
+ }
+ if (st.st_mtime > dsp->ds_mtime) {
+ change = 1;
+ dsp->ds_mtime = st.st_mtime;
+ }
+ }
+
+ switch (state) {
+ case FBVIDEO_ON:
+ if (!change) {
+ state = FBVIDEO_OFF;
+ change_state(state);
+ tvp = &timo_off;
+ }
+ break;
+
+ case FBVIDEO_OFF:
+ if (change) {
+ state = FBVIDEO_ON;
+ change_state(state);
+ tvp = &timo_on;
+ }
+ break;
+ }
+
+ if (select(0, NULL, NULL, NULL, tvp) < 0)
+ err(1, "select");
+ }
+ /* NOTREACHED */
+}
+
+static void
+add_dev(path, isfb)
+ char *path;
+ int isfb;
+{
+ struct dev_stat *dsp1, *dsp2;
+
+ /* Create the entry... */
+ dsp1 = malloc(sizeof(struct dev_stat));
+ if (dsp1 == NULL)
+ errx(1, "can't allocate memory for %s", path);
+ bzero(dsp1, sizeof(struct dev_stat));
+ dsp1->ds_path = path;
+ dsp1->ds_isfb = isfb;
+
+ /* ...and put it in the list. */
+ if (ds_list.lh_first == NULL) {
+ LIST_INSERT_HEAD(&ds_list, dsp1, ds_link);
+ } else {
+ for (dsp2 = ds_list.lh_first; dsp2->ds_link.le_next != NULL;
+ dsp2 = dsp2->ds_link.le_next)
+ /* Nothing. */ ;
+ LIST_INSERT_AFTER(dsp2, dsp1, ds_link);
+ }
+}
+
+/* ARGSUSED */
+static void
+sighandler(sig, code, context)
+ int sig, code;
+ struct sigcontext *context;
+{
+
+ /* Kill the pid file and re-enable the framebuffer before exit. */
+ (void)unlink(_PATH_SCREENBLANKPID);
+ change_state(FBVIDEO_ON);
+ exit(0);
+}
+
+static void
+change_state(state)
+ int state;
+{
+ struct dev_stat *dsp;
+ int fd;
+
+ for (dsp = ds_list.lh_first; dsp != NULL; dsp = dsp->ds_link.le_next) {
+ /* Don't change the state of non-framebuffers! */
+ if (dsp->ds_isfb == 0)
+ continue;
+ if ((fd = open(dsp->ds_path, O_RDWR, 0)) < 0) {
+ warn("open: %s", dsp->ds_path);
+ continue;
+ }
+ if (ioctl(fd, FBIOSVIDEO, &state) < 0)
+ warn("ioctl: %s", dsp->ds_path);
+ (void)close(fd);
+ }
+}
+
+static void
+cvt_arg(arg, tvp)
+ char *arg;
+ struct timeval *tvp;
+{
+ char *cp;
+ double seconds = 0.0, exponent = -1.0;
+ int period = 0;
+
+ for (cp = arg; *cp != '\0'; ++cp) {
+ if (*cp == '.') {
+ if (period)
+ errx(1, "invalid argument: %s", arg);
+ period = 1;
+ continue;
+ }
+
+ if (!isdigit(*cp))
+ errx(1, "invalid argument: %s", arg);
+
+ if (period) {
+ seconds = seconds + ((*cp - '0') * pow(10.0, exponent));
+ exponent -= 1.0;
+ } else
+ seconds = (seconds * 10.0) + (*cp - '0');
+ }
+
+ tvp->tv_sec = (long)seconds;
+ tvp->tv_usec = (long)((seconds - tvp->tv_sec) * 1000000);
+}
+
+static void
+logpid()
+{
+ FILE *fp;
+
+ if ((fp = fopen(_PATH_SCREENBLANKPID, "w")) != NULL) {
+ fprintf(fp, "%u\n", getpid());
+ (void)fclose(fp);
+ }
+}
+
+static void
+usage()
+{
+
+ fprintf(stderr, "usage: %s [-k | -m] [-d timeout] [-e timeout] %s\n",
+ __progname, "[-f framebuffer]");
+ exit(1);
+}