home *** CD-ROM | disk | FTP | other *** search
- Subject: v11i077: Small SUN screen-saver
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: gerolima@ford-wdl34.arpa (Mark Gerolimatos)
- Posting-number: Volume 11, Issue 77
- Archive-name: saver
-
- Saver is a screen saver program that works not by writing on the screen,
- but rather by turning the frame buffer's output off, rather like a
- terminal's screen darkener. Saver hardly uses any CPU time (it selects on
- input), and does not need to be run in a windowing system. There are two
- modes: dark on demand (DOD!), and daemon mode (real nice if you don't want
- have to remember to darken the screen). In DOD mode, the screen will turn
- dark about five seconds from when the command is given. In daemon mode,
- the screen darkens automatically after a certain length of inactivity of
- both the keyboard and mouse.
- -Mark
-
- : ----------------------------- CUT HERE --------------------------- :
- export PATH || exec /bin/sh $0 $*
- : ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::':
- : This is a shell archive, meaning:
- : 1. Remove everything above the "export PATH ..." line.
- : 2. Save the resulting text in a file.
- : 3. Execute the file with /bin/sh (NOT csh) to create the files:
- : Makefile
- : saver.1
- : saver.c
- : ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::':
- PATH="/bin:/usr/bin:/usr/lbin:/usr/ucb:$PATH"
- export PATH
- if test -f 'Makefile' -o -d 'Makefile'
- then
- echo 'shar: "Makefile" exists; NOT overwritten'
- else
- echo 'x Makefile 79 bytes'
- sed -e 's/^X//' << 'EOF Makefile' > 'Makefile'
- X# Easy Makefile, Eh?
- XCFLAGS = -O
- Xsaver: saver.o
- X cc $(CFLAGS) -o saver saver.o
- EOF Makefile
- if test 79 -ne "`wc -c < 'Makefile'`"
- then
- echo 'shar: "Makefile" CORRUPTED (not 79 bytes)'
- fi
- fi ; : End of overwrite check
- if test -f 'saver.1' -o -d 'saver.1'
- then
- echo 'shar: "saver.1" exists; NOT overwritten'
- else
- echo 'x saver.1 1959 bytes'
- sed -e 's/^X//' << 'EOF saver.1' > 'saver.1'
- X.TH SAVER 1 "18 September 1987"
- X.SH NAME
- Xsaver \- black out a Sun screen
- X.SH SYNOPSIS
- X.B saver
- X[ \fB\-d\fP ]
- X[ \fB\-t \fP\fItime\fP ]
- X.LP
- X.SH DESCRIPTION
- X\fIsaver\fP is a screen saver program that works not by writing on
- Xthe screen, but rather by turning the frame buffer's output off,
- Xrather like a terminal's screen darkener. \fISaver\fP hardly uses
- Xany CPU time (it selects on input), and does not need
- Xto be run in a windowing system.
- X.LP
- XThere are two modes: dark on demand (DOD!), and daemon mode (real
- Xnice if you don't want have to remember to darken the screen).
- XIn DOD mode, the screen will turn dark about five seconds from
- Xwhen the command is given. In daemon mode, the screen darkens
- Xautomatically after a certain length of inactivity of both the
- Xkeyboard and mouse.
- X.LP
- XIn both cases, the screen turns back on when something happens on
- Xthe keyboard or mouse (when in a windowing system), or the console
- X(when out of a windowing system). Not that when in most windowing
- Xsystems, merely moving the mouse, or hitting any key will turn
- Xthe screen back on. However, when out of a windowing system, the
- X<return> key must be hit (except when in raw mode).
- X.LP
- X.SH OPTIONS
- X.TP
- X\fB\-d\fP
- XDaemon mode: run (forever), darkening after an idle interval on the
- Xkeyboard or mouse or console (default 300 seconds...5 minutes).
- X.TP
- X\fB\-t\fP
- XTime: Set the time interval to darken the screen.
- X.LP
- X.SH EXAMPLES
- X.LP
- XTo run in daemon mode (interval of 10 minutes):
- X.RS
- X.IP "% \fBsaver -d -t 600\fP"
- X.RE
- X.LP
- XTo run in DOD mode:
- X.RS
- X.IP "% \fBsaver\fP (real hard, eh?)"
- X.RE
- X.LP
- X.SH BUGS
- X.LP
- XWhen out of a windowing system, \fIsaver\fP stats the console for
- Xmodify and access time. Difficulties can arise when nothing is reading
- Xthe console and echo is turned off.
- X.LP
- X\fISaver\fP must be run in the background when in daemon mode
- X(I don't do forks).
- X.LP
- X\fISaver\fP should be run by root in daemon mode to prevent any
- Xfunny ownership problems due to logout/login.
- EOF saver.1
- if test 1959 -ne "`wc -c < 'saver.1'`"
- then
- echo 'shar: "saver.1" CORRUPTED (not 1959 bytes)'
- fi
- fi ; : End of overwrite check
- if test -f 'saver.c' -o -d 'saver.c'
- then
- echo 'shar: "saver.c" exists; NOT overwritten'
- else
- echo 'x saver.c 8826 bytes'
- sed -e 's/^X//' << 'EOF saver.c' > 'saver.c'
- X/* You may do whatever you want with this program, so long as this
- X** header is left intact:
- X**
- X** saver, written by Mark Gerolimatos (gerolima@ford-wdl1.arpa)
- X**
- X** This program is free, and totally devoid of any sort of warantee.
- X** Neither the author nor Ford Aerospace assume any responsibility
- X** for any damage or unpleasantness that might be caused by its use.
- X**
- X*/
- X
- X
- X
- X
- X
- X/*
- X** (However, if you find any bugs, it would be nice if you reported
- X** them to me).
- X*/
- X
- X
- X/* This here porgram opens up the frame buffer, sends it an "off"
- X** video call, and then sends it an "on" call (both very nicely
- X** undocumented by sun) when the return key gets hit. A nice
- X** screen-saver that won't let console messages
- X** screw it up.
- X**
- X** When in suntools or X, the screen my be relit by moving the
- X** mouse, or hitting any key on the keyboard.
- X**
- X** When in console mode, a <return> must be hit, unless you're in
- X** some kind of uncooked mode (like when playing rogue), in which
- X** case any character will do.
- X**
- X** Complaints to: Mark Gerolimatos, gerolima@ford-wdl1.arpa
- X**
- X**
- X** There is also a daemon option, which will turn off after so
- X** many seconds (default == 300) of nothing happening on the machine.
- X** To run it this way, use
- X**
- X** saver -d -t some_number &
- X**
- X** It's good for root to do this, so that when /dev/console changes
- X** ownership, nothing funny happens.
- X**
- X** Bugs:
- X**
- X** when /dev/console is not in direct mode (ie !raw), you
- X** have to hit a <return> to make the screen come back to life.
- X** Not only that, but the carriage-return must be read by someone
- X** or the screen will never darken (the select(2) will fall thru).
- X** So tail -f'ing somthing will defeat the darkener, as tail doesn't
- X** read the console. Oh, well.
- X**
- X** when not in suntools or X, (when the mouse puts out data in native
- X** mode), the mouse will not be used to figure out whether or not
- X** to turn the screen on/off. This is because you can't guarantee that
- X** the mouse will be read, resulting in the screen never darkening.
- X** When not in suntools, this happens anytime you barely touch the mouse.
- X**
- X** However, when in suntools, or when not tail -f'ing (or anthing like that),
- X** it seems quite robust. I've had it in my /etc/rc file for quite a
- X** while, and nothing bad has happened.
- X*/
- X
- X#include <sys/param.h>
- X#include <sys/file.h>
- X#include <sys/ioctl.h>
- X#include <sun/fbio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <sundev/vuid_event.h>
- X
- X#include <stdio.h>
- X
- Xint kbd = NOFILE+500; /* some impossible fd number */
- Xint mouse = NOFILE+500;
- Xint console = NOFILE+500;
- Xint screen_fd;
- Xint statfds;
- Xint nfds;
- Xint delay_time = 300;
- Xint debug = 0;
- X
- X#define max(A,B) (((A) > (B))?(A):(B))
- Xmain (argc,argv)
- Xint argc; char **argv;
- X{
- X
- X char c;
- X int i;
- X int do_mouse = 0;
- X int daemon = 0;
- X int use_stdin = 0;
- X if((screen_fd = open("/dev/fb",O_RDWR)) < 0)
- X {
- X Perror("open");
- X exit(1);
- X }
- X kbd = open("/dev/kbd",O_RDONLY,0);
- X mouse = -1;
- X while (--argc > 0 && (*++argv)[0] == '-')
- X {
- X switch((*argv)[1])
- X {
- X case 'D':
- X debug = 1;
- X break;
- X case 'd':
- X daemon = 1;
- X /* also must open mouse with daemon */
- X case 'm': /* this option is pretty useless */
- X do_mouse = 1;
- X break;
- X case 't':
- X argc--; argv++;
- X if(argc <= 0)
- X {
- X fprintf(stderr,"time with no delay\n");
- X fflush(stderr);
- X exit(1);
- X }
- X i = atoi(*argv);
- X if(i > 0) delay_time = i;
- X break;
- X default:
- X break;
- X }
- X }
- X /* now, check to see if mouse is in suntools mode */
- X mouse = open("/dev/mouse",O_RDONLY,0);
- X if(mouse >= 0)
- X {
- X if((ioctl(mouse,VUIDGFORMAT,&i)) < 0)
- X {
- X Perror("ioctl on mouse to get VUIDFORMAT");
- X exit(1);
- X }
- X if(i == VUID_NATIVE && !do_mouse) /* ignore the sucker */
- X {
- X close(mouse);
- X mouse = -1;
- X }
- X }
- X
- X console = open("/dev/console",O_RDONLY,0);
- X /* mouse, kbd, and stdin */
- X if(kbd >= 0) statfds |= (1 << kbd);
- X if(mouse >= 0) statfds |= (1 << mouse);
- X if(console >= 0) statfds |= (1 << console);
- X /* if can't do this stuff, just do a getchar to block */
- X if(!statfds)
- X {
- X int q;
- X /* do a simple ioctl to see if operations on 0 fail */
- X if((ioctl(0,TIOCGPGRP,&q)) < 0)
- X {
- X /* not a terminal, and you can't read kbd or mouse,
- X ** so give up, right a way
- X */
- X fprintf(stderr,"Cannot get kbd, mouse, console, or stdin\n");
- X fflush(stderr);
- X return;
- X }
- X }
- X sleep(5); /* give the kbd and mouse a chance to flush */
- X if(daemon)
- X {
- X run_daemon();
- X exit(0);
- X }
- X video_off();
- X delay(statfds); /* wait for some kind of input */
- X video_on();
- X exit(0);
- X}
- X
- X
- Xstruct stat sbuf;
- Xrun_daemon ()
- X{
- X static time_t ktime = -1, catime = -1, cmtime = -1, mtime = -1;
- X static time_t oktime = -1, ocatime = -1, ocmtime = -1,
- X omtime = -1;
- X int t;
- X
- X t = delay_time;
- X while(1)
- X {
- X
- X if(debug)
- X {
- X fprintf(stderr,"Statting\n");
- X fflush(stderr);
- X }
- X if(fstat(console,&sbuf) <0)
- X {
- X Perror("fstat, console");
- X exit(1);
- X }
- X catime = sbuf.st_atime;
- X cmtime = sbuf.st_mtime;
- X if(fstat(kbd,&sbuf) <0)
- X {
- X Perror("fstat, kbd");
- X exit(1);
- X }
- X ktime = sbuf.st_atime;
- X if(fstat(mouse,&sbuf) <0)
- X {
- X Perror("fstat, mouse");
- X exit(1);
- X }
- X mtime = sbuf.st_atime;
- X
- X /**** HERE'S THE SLEEP ****/
- X sleep(t);
- X
- X if(fstat(kbd,&sbuf) <0)
- X {
- X Perror("fstat, kbd");
- X exit(1);
- X }
- X oktime = sbuf.st_atime - ktime;
- X if(fstat(mouse,&sbuf) <0)
- X {
- X Perror("fstat, mouse");
- X exit(1);
- X }
- X omtime = sbuf.st_atime - mtime;
- X if(fstat(console,&sbuf) <0)
- X {
- X Perror("fstat, console");
- X exit(1);
- X }
- X ocatime = sbuf.st_atime - catime;
- X ocmtime = sbuf.st_mtime - cmtime;
- X
- X /* if none of the times changed
- X ** there was no access in the last t seconds. Turn
- X ** off the screen.
- X */
- X
- X /* give 2 seconds leeway (that's a highway in Virginia)
- X ** for whatever */
- X if(debug)
- X {
- X fprintf(stderr,"oktime = %d, omtime = %d, ocmtime = %d, ocatime = %d\n",
- X oktime,omtime,ocmtime,ocatime);
- X fflush(stderr);
- X }
- X if(oktime < 2 && omtime < 2 && ocmtime < 2 && ocatime < 2)
- X {
- X int i;
- X int fds;
- X /* mice are a special case: they aren't always read */
- X /* now, we must check to see what mode the
- X ** mouse is in. This is expensive, but only
- X ** need be done every once in a while
- X ** (delay time)
- X */
- X if((ioctl(mouse,VUIDGFORMAT,&i)) < 0)
- X {
- X Perror("ioctl on mouse to get VUIDFORMAT");
- X exit(1);
- X }
- X if(i == VUID_NATIVE) /* ignore the sucker */
- X statfds &= ~(1 << mouse);
- X else
- X statfds |= (1 << mouse);
- X
- X if(debug)
- X {
- X if(!ready(statfds))
- X fprintf(stderr,"offing\n");
- X else
- X fprintf(stderr,"would have offed\n");
- X fflush(stderr);
- X }
- X else
- X {
- X if(!ready(statfds))
- X video_off();
- X }
- X fds = delay(statfds);
- X
- X video_on();
- X t = delay_time;
- X sleep(1); /* more leeway for jerks who do -t 1*/
- X }
- X /* if you did not need to shut the screen off,
- X ** wait delay_time from the last thing that was
- X ** accessed last.
- X */
- X else
- X {
- X /** I'm not so sure this is correct. When in suntools,
- X *** you read off of /dev/kbd. When out of suntools,
- X *** /dev/console registers. Now, if octime is just
- X *** so that oc%delay = 1, (but is in fact some huge
- X *** number becuz console ain't been used since
- X *** you brought up suntools) you will black out, right
- X *** away. No, it looks like you'll have to take
- X *** a hit, such that you will black out at the maximum
- X *** time. Sigh.
- X ***
- X int i = oktime%delay_time,
- X j = omtime%delay_time,
- X k = octime%delay_time;
- X t = max(i,j);
- X t = max(t,k);
- X ****/
- X t = max(oktime,omtime);
- X t = max(t,ocatime);
- X t = max(t,ocmtime);
- X if(t == 0 || t > delay_time) t = delay_time;
- X if(debug)
- X {
- X fprintf(stderr,"delay time = %d\n",t);
- X fflush(stderr);
- X }
- X }
- X }
- X}
- X
- Xlast_time (time,fd)
- X{
- X struct stat sbuf;
- X int retval;
- X if(fstat(fd,&sbuf) <0)
- X {
- X Perror("fstat, last_time");
- X exit(1);
- X }
- X retval = sbuf.st_atime - time;
- X return(retval);
- X}
- X
- Xdelay (fds)
- X{
- X if(!fds)
- X return(getchar());
- X
- X nfds = select(NOFILE,&fds,0,0,0);
- X if(nfds < 0)
- X {
- X Perror("select");
- X }
- X return(fds);
- X}
- X
- Xstatic struct timeval timer; /* zeroed out */
- Xready (fds)
- X{
- X struct timeval t;
- X t = timer;
- X switch(select(NOFILE,&fds,0,0,&t))
- X {
- X case -1:
- X Perror("select in ready");
- X return(0);
- X default:
- X return(fds);
- X }
- X}
- X
- X/* apparently, this is not always up-to-date...so ignore it! */
- Xget_video ()
- X{
- X int i;
- X int q;
- X i = ioctl(screen_fd,FBIOGVIDEO,&q);
- X return(q);
- X}
- X
- Xvideo_off ()
- X{
- X int i;
- X int q;
- X q = FBVIDEO_OFF;
- X i = ioctl(screen_fd,FBIOSVIDEO,&q);
- X if(i < 0)
- X {
- X Perror("ioctl");
- X }
- X return(i);
- X}
- X
- Xvideo_on ()
- X{
- X int i;
- X int j;
- X j = FBVIDEO_ON;
- X i = ioctl(screen_fd,FBIOSVIDEO,&j);
- X if(i < 0)
- X {
- X Perror("ioctl");
- X }
- X return(i);
- X}
- X
- X/* was originally when the fprintf went to a separate file */
- XPerror (string)
- Xchar *string;
- X{
- X perror(string);
- X /***
- X fprintf(stderr,"%s\n",string);
- X fflush(stderr);
- X ***/
- X}
- EOF saver.c
- if test 8826 -ne "`wc -c < 'saver.c'`"
- then
- echo 'shar: "saver.c" CORRUPTED (not 8826 bytes)'
- fi
- fi ; : End of overwrite check
- : End of shell archive
- exit 0
-