home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume11 / saver < prev    next >
Text File  |  1987-09-25  |  14KB  |  550 lines

  1. Subject:  v11i077:  Small SUN screen-saver
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: gerolima@ford-wdl34.arpa (Mark Gerolimatos)
  7. Posting-number: Volume 11, Issue 77
  8. Archive-name: saver
  9.  
  10. Saver is a screen saver program that works not by writing on the screen,
  11. but rather by turning the frame buffer's output off, rather like a
  12. terminal's screen darkener. Saver hardly uses any CPU time (it selects on
  13. input), and does not need to be run in a windowing system.  There are two
  14. modes: dark on demand (DOD!), and daemon mode (real nice if you don't want
  15. have to remember to darken the screen).  In DOD mode, the screen will turn
  16. dark about five seconds from when the command is given. In daemon mode,
  17. the screen darkens automatically after a certain length of inactivity of
  18. both the keyboard and mouse.
  19.         -Mark
  20.  
  21. : ----------------------------- CUT HERE --------------------------- :
  22. export PATH || exec /bin/sh $0 $*
  23. : ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::':
  24. : This is a shell archive, meaning:
  25. : 1. Remove everything above the "export PATH ..." line.
  26. : 2. Save the resulting text in a file.
  27. : 3. Execute the file with /bin/sh (NOT csh) to create the files:
  28. :    Makefile
  29. :    saver.1
  30. :    saver.c
  31. : ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::':
  32. PATH="/bin:/usr/bin:/usr/lbin:/usr/ucb:$PATH"
  33. export PATH
  34. if test -f 'Makefile' -o -d 'Makefile'
  35. then
  36.     echo 'shar: "Makefile" exists; NOT overwritten'
  37. else
  38. echo 'x Makefile 79 bytes'
  39. sed -e 's/^X//' << 'EOF Makefile' > 'Makefile'
  40. X# Easy Makefile, Eh?
  41. XCFLAGS = -O
  42. Xsaver: saver.o
  43. X    cc $(CFLAGS) -o saver saver.o
  44. EOF Makefile
  45. if test 79 -ne "`wc -c < 'Makefile'`"
  46. then
  47.     echo 'shar: "Makefile" CORRUPTED (not 79 bytes)'
  48. fi
  49. fi ; : End of overwrite check
  50. if test -f 'saver.1' -o -d 'saver.1'
  51. then
  52.     echo 'shar: "saver.1" exists; NOT overwritten'
  53. else
  54. echo 'x saver.1 1959 bytes'
  55. sed -e 's/^X//' << 'EOF saver.1' > 'saver.1'
  56. X.TH SAVER 1 "18 September 1987"
  57. X.SH NAME
  58. Xsaver \- black out a Sun screen
  59. X.SH SYNOPSIS
  60. X.B saver
  61. X[ \fB\-d\fP ] 
  62. X[ \fB\-t \fP\fItime\fP ] 
  63. X.LP
  64. X.SH DESCRIPTION
  65. X\fIsaver\fP is a screen saver program that works not by writing on
  66. Xthe screen, but rather by turning the frame buffer's output off,
  67. Xrather like a terminal's screen darkener. \fISaver\fP hardly uses
  68. Xany CPU time (it selects on input), and does not need
  69. Xto be run in a windowing system.
  70. X.LP
  71. XThere are two modes: dark on demand (DOD!), and daemon mode (real
  72. Xnice if you don't want have to remember to darken the screen).
  73. XIn DOD mode, the screen will turn dark about five seconds from
  74. Xwhen the command is given. In daemon mode, the screen darkens 
  75. Xautomatically after a certain length of inactivity of both the 
  76. Xkeyboard and mouse.
  77. X.LP
  78. XIn both cases, the screen turns back on when something happens on
  79. Xthe keyboard or mouse (when in a windowing system), or the console
  80. X(when out of a windowing system). Not that when in most windowing
  81. Xsystems, merely moving the mouse, or hitting any key will turn
  82. Xthe screen back on. However, when out of a windowing system, the
  83. X<return> key must be hit (except when in raw mode).
  84. X.LP
  85. X.SH OPTIONS
  86. X.TP
  87. X\fB\-d\fP
  88. XDaemon mode: run (forever), darkening after an idle interval on the
  89. Xkeyboard or mouse or console (default 300 seconds...5 minutes).
  90. X.TP
  91. X\fB\-t\fP
  92. XTime: Set the time interval to darken the screen.
  93. X.LP
  94. X.SH EXAMPLES
  95. X.LP
  96. XTo run in daemon mode (interval of 10 minutes):
  97. X.RS
  98. X.IP "% \fBsaver -d -t 600\fP"
  99. X.RE
  100. X.LP
  101. XTo run in DOD mode:
  102. X.RS
  103. X.IP "% \fBsaver\fP (real hard, eh?)"
  104. X.RE
  105. X.LP
  106. X.SH BUGS
  107. X.LP
  108. XWhen out of a windowing system, \fIsaver\fP stats the console for
  109. Xmodify and access time. Difficulties can arise when nothing is reading
  110. Xthe console and echo is turned off.
  111. X.LP
  112. X\fISaver\fP must be run in the background when in daemon mode
  113. X(I don't do forks).
  114. X.LP
  115. X\fISaver\fP should be run by root in daemon mode to prevent any
  116. Xfunny ownership problems due to logout/login.
  117. EOF saver.1
  118. if test 1959 -ne "`wc -c < 'saver.1'`"
  119. then
  120.     echo 'shar: "saver.1" CORRUPTED (not 1959 bytes)'
  121. fi
  122. fi ; : End of overwrite check
  123. if test -f 'saver.c' -o -d 'saver.c'
  124. then
  125.     echo 'shar: "saver.c" exists; NOT overwritten'
  126. else
  127. echo 'x saver.c 8826 bytes'
  128. sed -e 's/^X//' << 'EOF saver.c' > 'saver.c'
  129. X/* You may do whatever you want with this program, so long as this
  130. X** header is left intact:
  131. X**    
  132. X**    saver, written by Mark Gerolimatos (gerolima@ford-wdl1.arpa)
  133. X**
  134. X**    This program is free, and totally devoid of any sort of warantee.
  135. X**    Neither the author nor Ford Aerospace assume any responsibility
  136. X**    for any damage or unpleasantness that might be caused by its use.
  137. X**
  138. X*/
  139. X
  140. X
  141. X
  142. X
  143. X
  144. X/*
  145. X**    (However, if you find any bugs, it would be nice if you reported
  146. X**    them to me).
  147. X*/
  148. X
  149. X
  150. X/* This here porgram opens up the frame buffer, sends it an "off"
  151. X** video call, and then sends it an "on" call (both very nicely 
  152. X** undocumented by sun) when the return key gets hit. A nice 
  153. X** screen-saver that won't let console messages
  154. X** screw it up.
  155. X**
  156. X** When in suntools or X, the screen my be relit by moving the
  157. X** mouse, or hitting any key on the keyboard.
  158. X**
  159. X** When in console mode, a <return> must be hit, unless you're in
  160. X** some kind of uncooked mode (like when playing rogue), in which
  161. X** case any character will do.
  162. X**
  163. X** Complaints to: Mark Gerolimatos, gerolima@ford-wdl1.arpa
  164. X**
  165. X**
  166. X** There is also a daemon option, which will turn off after so
  167. X** many seconds (default == 300) of nothing happening on the machine.
  168. X** To run it this way, use
  169. X**
  170. X**    saver -d -t some_number &
  171. X**
  172. X** It's good for root to do this, so that when /dev/console changes
  173. X** ownership, nothing funny happens.
  174. X**
  175. X** Bugs: 
  176. X**
  177. X** when /dev/console is not in direct mode (ie !raw), you
  178. X** have to hit a <return> to make the screen come back to life.
  179. X** Not only that, but the carriage-return must be read by someone
  180. X** or the screen will never darken (the select(2) will fall thru).
  181. X** So tail -f'ing somthing will defeat the darkener, as tail doesn't
  182. X** read the console. Oh, well.
  183. X**
  184. X** when not in suntools or X, (when the mouse puts out data in native
  185. X** mode), the mouse will not be used to figure out whether or not
  186. X** to turn the screen on/off. This is because you can't guarantee that
  187. X** the mouse will be read, resulting in the screen never darkening. 
  188. X** When not in suntools, this happens anytime you barely touch the mouse.
  189. X**
  190. X** However, when in suntools, or when not tail -f'ing (or anthing like that),
  191. X** it seems quite robust. I've had it in my /etc/rc file for quite a
  192. X** while, and nothing bad has happened.
  193. X*/
  194. X
  195. X#include    <sys/param.h>
  196. X#include    <sys/file.h>
  197. X#include    <sys/ioctl.h>
  198. X#include    <sun/fbio.h>
  199. X#include    <sys/types.h>
  200. X#include    <sys/stat.h>
  201. X#include    <sys/time.h>
  202. X#include    <sundev/vuid_event.h>
  203. X
  204. X#include    <stdio.h>
  205. X
  206. Xint kbd = NOFILE+500;    /* some impossible fd number */
  207. Xint mouse = NOFILE+500;
  208. Xint console = NOFILE+500;
  209. Xint    screen_fd;
  210. Xint    statfds;
  211. Xint    nfds;
  212. Xint    delay_time = 300;
  213. Xint    debug = 0;
  214. X
  215. X#define max(A,B)     (((A) > (B))?(A):(B))
  216. Xmain (argc,argv)
  217. Xint argc; char **argv;
  218. X{
  219. X
  220. X    char c;
  221. X    int i;
  222. X    int do_mouse = 0;
  223. X    int daemon = 0;
  224. X    int use_stdin = 0;
  225. X    if((screen_fd = open("/dev/fb",O_RDWR)) < 0)
  226. X    {
  227. X        Perror("open");
  228. X        exit(1);
  229. X    }
  230. X    kbd = open("/dev/kbd",O_RDONLY,0);
  231. X    mouse = -1;
  232. X    while (--argc > 0 && (*++argv)[0] == '-')
  233. X    {
  234. X        switch((*argv)[1])
  235. X        {
  236. X        case 'D':
  237. X            debug = 1;
  238. X            break;
  239. X        case 'd':
  240. X            daemon = 1;
  241. X            /* also must open mouse with daemon */
  242. X        case 'm':    /* this option is pretty useless */
  243. X            do_mouse = 1;
  244. X            break;
  245. X        case 't':
  246. X            argc--; argv++;
  247. X            if(argc <= 0)
  248. X            {
  249. X                fprintf(stderr,"time with no delay\n");
  250. X                fflush(stderr);
  251. X                exit(1);
  252. X            }
  253. X            i = atoi(*argv);
  254. X            if(i > 0) delay_time = i;
  255. X            break;
  256. X        default:
  257. X            break;
  258. X        }
  259. X    }
  260. X    /* now, check to see if mouse is in suntools mode */
  261. X    mouse = open("/dev/mouse",O_RDONLY,0);
  262. X    if(mouse >= 0)
  263. X    {
  264. X        if((ioctl(mouse,VUIDGFORMAT,&i)) < 0)
  265. X        {
  266. X            Perror("ioctl on mouse to get VUIDFORMAT");
  267. X            exit(1);
  268. X        }
  269. X        if(i == VUID_NATIVE && !do_mouse)    /* ignore the sucker */
  270. X        {
  271. X            close(mouse);
  272. X            mouse = -1;
  273. X        }
  274. X    }
  275. X
  276. X    console = open("/dev/console",O_RDONLY,0);
  277. X    /* mouse, kbd, and stdin */
  278. X    if(kbd >= 0) statfds |= (1 << kbd);
  279. X    if(mouse >= 0) statfds |= (1 << mouse);
  280. X    if(console >= 0) statfds |= (1 << console);
  281. X    /* if can't do this stuff, just do a getchar to block */
  282. X    if(!statfds)
  283. X    {
  284. X        int q;
  285. X        /* do a simple ioctl to see if operations on 0 fail */
  286. X        if((ioctl(0,TIOCGPGRP,&q)) < 0)
  287. X        {
  288. X            /* not a terminal, and you can't read kbd or mouse,
  289. X            ** so give up, right a way
  290. X            */
  291. X            fprintf(stderr,"Cannot get kbd, mouse, console, or stdin\n");
  292. X            fflush(stderr);
  293. X            return;
  294. X        }
  295. X    }
  296. X    sleep(5);    /* give the kbd and mouse a chance to flush */
  297. X    if(daemon)
  298. X    {
  299. X        run_daemon();
  300. X        exit(0);
  301. X    }
  302. X    video_off();
  303. X    delay(statfds); /* wait for some kind of input */
  304. X    video_on();
  305. X    exit(0);
  306. X}
  307. X
  308. X
  309. Xstruct stat sbuf;
  310. Xrun_daemon ()
  311. X{
  312. X    static time_t ktime = -1, catime = -1, cmtime = -1, mtime = -1;
  313. X    static time_t oktime = -1, ocatime = -1, ocmtime = -1, 
  314. X            omtime = -1;
  315. X    int t;
  316. X
  317. X    t = delay_time;
  318. X    while(1)
  319. X    {
  320. X
  321. X        if(debug)
  322. X        {
  323. X            fprintf(stderr,"Statting\n");
  324. X            fflush(stderr);
  325. X        }
  326. X        if(fstat(console,&sbuf) <0)
  327. X        {
  328. X            Perror("fstat, console");
  329. X            exit(1);
  330. X        }
  331. X        catime = sbuf.st_atime;
  332. X        cmtime = sbuf.st_mtime;
  333. X        if(fstat(kbd,&sbuf) <0)
  334. X        {
  335. X            Perror("fstat, kbd");
  336. X            exit(1);
  337. X        }
  338. X        ktime = sbuf.st_atime;
  339. X        if(fstat(mouse,&sbuf) <0)
  340. X        {
  341. X            Perror("fstat, mouse");
  342. X            exit(1);
  343. X        }
  344. X        mtime = sbuf.st_atime;
  345. X
  346. X        /**** HERE'S THE SLEEP ****/
  347. X        sleep(t);
  348. X
  349. X        if(fstat(kbd,&sbuf) <0)
  350. X        {
  351. X            Perror("fstat, kbd");
  352. X            exit(1);
  353. X        }
  354. X        oktime = sbuf.st_atime - ktime;
  355. X        if(fstat(mouse,&sbuf) <0)
  356. X        {
  357. X            Perror("fstat, mouse");
  358. X            exit(1);
  359. X        }
  360. X        omtime = sbuf.st_atime - mtime;
  361. X        if(fstat(console,&sbuf) <0)
  362. X        {
  363. X            Perror("fstat, console");
  364. X            exit(1);
  365. X        }
  366. X        ocatime = sbuf.st_atime - catime;
  367. X        ocmtime = sbuf.st_mtime - cmtime;
  368. X
  369. X        /* if none of the times changed 
  370. X        ** there was no access in the last t seconds. Turn
  371. X        ** off the screen.
  372. X        */
  373. X
  374. X        /* give 2 seconds leeway (that's a highway in Virginia) 
  375. X        ** for whatever */
  376. X        if(debug)
  377. X        {
  378. X            fprintf(stderr,"oktime = %d, omtime = %d, ocmtime = %d, ocatime = %d\n",
  379. X                oktime,omtime,ocmtime,ocatime);
  380. X            fflush(stderr);
  381. X        }
  382. X        if(oktime < 2 && omtime < 2 && ocmtime < 2 && ocatime < 2)
  383. X        {
  384. X            int i;
  385. X            int fds;
  386. X            /* mice are a special case: they aren't always read */
  387. X            /* now, we must check to see what mode the
  388. X            ** mouse is in. This is expensive, but only
  389. X            ** need be done every once in a while
  390. X            ** (delay time)
  391. X            */
  392. X            if((ioctl(mouse,VUIDGFORMAT,&i)) < 0)
  393. X            {
  394. X                Perror("ioctl on mouse to get VUIDFORMAT");
  395. X                exit(1);
  396. X            }
  397. X            if(i == VUID_NATIVE)    /* ignore the sucker */
  398. X                statfds &= ~(1 << mouse);
  399. X            else
  400. X                statfds |= (1 << mouse);
  401. X
  402. X            if(debug) 
  403. X            {
  404. X                if(!ready(statfds))
  405. X                    fprintf(stderr,"offing\n");
  406. X                else
  407. X                    fprintf(stderr,"would have offed\n");
  408. X                fflush(stderr);
  409. X            }
  410. X            else 
  411. X            {
  412. X                if(!ready(statfds))
  413. X                    video_off();
  414. X            }
  415. X            fds = delay(statfds);
  416. X
  417. X            video_on();
  418. X            t = delay_time;
  419. X            sleep(1);    /* more leeway for jerks who do -t 1*/
  420. X        }
  421. X        /* if you did not need to shut the screen off,
  422. X        ** wait delay_time from the last thing that was
  423. X        ** accessed last.
  424. X        */
  425. X        else
  426. X        {
  427. X            /** I'm not so sure this is correct. When in suntools,
  428. X            *** you read off of /dev/kbd. When out of suntools,
  429. X            *** /dev/console registers. Now, if octime is just
  430. X            *** so that oc%delay = 1, (but is in fact some huge
  431. X            *** number becuz console ain't been used since
  432. X            *** you brought up suntools) you will black out, right
  433. X            *** away. No, it looks like you'll have to take
  434. X            *** a hit, such that you will black out at the maximum
  435. X            *** time. Sigh.
  436. X            ***
  437. X            int    i = oktime%delay_time, 
  438. X                j = omtime%delay_time, 
  439. X                k = octime%delay_time;
  440. X            t = max(i,j);
  441. X            t = max(t,k);
  442. X            ****/
  443. X            t = max(oktime,omtime);
  444. X            t = max(t,ocatime);
  445. X            t = max(t,ocmtime);
  446. X            if(t == 0 || t > delay_time) t = delay_time;
  447. X            if(debug)
  448. X            {
  449. X                fprintf(stderr,"delay time = %d\n",t);
  450. X                fflush(stderr);
  451. X            }
  452. X        }
  453. X    }
  454. X}
  455. X
  456. Xlast_time (time,fd)
  457. X{
  458. X    struct stat sbuf;
  459. X    int retval;
  460. X    if(fstat(fd,&sbuf) <0)
  461. X    {
  462. X        Perror("fstat, last_time");
  463. X        exit(1);
  464. X    }
  465. X    retval = sbuf.st_atime - time;
  466. X    return(retval);
  467. X}
  468. X
  469. Xdelay (fds)
  470. X{
  471. X    if(!fds)
  472. X        return(getchar());
  473. X
  474. X    nfds = select(NOFILE,&fds,0,0,0);
  475. X    if(nfds < 0)
  476. X    {
  477. X        Perror("select");
  478. X    }
  479. X    return(fds);
  480. X}
  481. X
  482. Xstatic struct timeval timer;    /* zeroed out */
  483. Xready (fds)
  484. X{
  485. X    struct timeval t;
  486. X    t = timer;
  487. X    switch(select(NOFILE,&fds,0,0,&t))
  488. X    {
  489. X    case -1:
  490. X        Perror("select in ready");
  491. X        return(0);
  492. X    default:
  493. X        return(fds);
  494. X    }
  495. X}
  496. X
  497. X/* apparently, this is not always up-to-date...so ignore it! */
  498. Xget_video ()
  499. X{
  500. X    int i;
  501. X    int q;
  502. X    i = ioctl(screen_fd,FBIOGVIDEO,&q);
  503. X    return(q);
  504. X}
  505. X
  506. Xvideo_off ()
  507. X{
  508. X    int i;
  509. X    int q;
  510. X    q = FBVIDEO_OFF;
  511. X    i = ioctl(screen_fd,FBIOSVIDEO,&q);
  512. X    if(i < 0)
  513. X    {
  514. X        Perror("ioctl");
  515. X    }
  516. X    return(i);
  517. X}
  518. X
  519. Xvideo_on ()
  520. X{
  521. X    int i;
  522. X    int j;
  523. X    j = FBVIDEO_ON;
  524. X    i = ioctl(screen_fd,FBIOSVIDEO,&j);
  525. X    if(i < 0)
  526. X    {
  527. X        Perror("ioctl");
  528. X    }
  529. X    return(i);
  530. X}
  531. X
  532. X/* was originally when the fprintf went to a separate file */
  533. XPerror (string)
  534. Xchar *string;
  535. X{
  536. X    perror(string);
  537. X    /***
  538. X    fprintf(stderr,"%s\n",string);
  539. X    fflush(stderr);
  540. X    ***/
  541. X}
  542. EOF saver.c
  543. if test 8826 -ne "`wc -c < 'saver.c'`"
  544. then
  545.     echo 'shar: "saver.c" CORRUPTED (not 8826 bytes)'
  546. fi
  547. fi ; : End of overwrite check
  548. : End of shell archive
  549. exit 0
  550.