home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume17 / xautolck / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-06-28  |  54.2 KB

  1. Path: uunet!usc!cs.utexas.edu!swrinde!mips!msi!dcmartin
  2. From: eyckmans@imec.be
  3. Newsgroups: comp.sources.x
  4. Subject: v17i109: xautolock (patchlevel 8), Part01/01
  5. Message-ID: <1992Jun29.163106.9607@msi.com>
  6. Date: 29 Jun 92 16:31:06 GMT
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. Lines: 1926
  10. Approved: dcmartin@msi.com
  11. Originator: dcmartin@fascet
  12.  
  13. Submitted-by: eyckmans@imec.be
  14. Posting-number: Volume 17, Issue 109
  15. Archive-name: xautolock-8.0/part01
  16.  
  17. This is patchlevel 8 of xautolock, the program which monitors console
  18. activity, and starts up a program of  your choice if nothing  happens
  19. during a certain time interval.  
  20.  
  21. What's new?
  22. -----------
  23.  
  24.  - It supports multiheaded displays.
  25.  - It now uses the X resource database.
  26.  - The copyright notice has been changed considerably.
  27.  - The notification margin and bell percentage can be specified by
  28.    the user.
  29.  - It no longer steals events from windowmanagers that use a pseudo
  30.    root window.
  31.  - It no longer needs to get pointer events, so the chances of it
  32.    messing up event propagation have become even smaller.
  33.  - It can be disabled or activated by moving the pointer into one
  34.    of the corners of the display. This is highly customizable.
  35.  - It can be disabled (and re-enabled) by sending it a SIGHUP.
  36.  - By default, it now closes stdout and stderr, so you no longer
  37.    get zillions of error messages if you manually lock your display.
  38.  - The code is has become more foolproof (patchlevel 7 users
  39.    will have a hard time recognizing it :-).
  40.  
  41.  
  42. What hasn't been done yet?
  43. --------------------------
  44.  
  45.  - It still is contained in a single source file.
  46.  
  47.  
  48. Important
  49. ---------
  50.  
  51. Users of swm and tvtwm, (especially on Sparcs) are adviced to read
  52. the WARNING section in the README file.
  53.  
  54.  
  55.                           SDT & MCE
  56.  
  57. 8<------------------------------- CUT HERE ------------------------------------
  58. #! /bin/sh
  59. # This is a shell archive, meaning:
  60. # 1. Remove everything above the #! /bin/sh line.
  61. # 2. Save the resulting text in a file.
  62. # 3. Execute the file with /bin/sh (not csh) to create the files:
  63. #    Imakefile
  64. #    Makefile.std
  65. #    README
  66. #    patchlevel.h
  67. #    xautolock.c
  68. #    xautolock.man
  69. # This archive created: Fri May 15 17:56:28 1992
  70. export PATH; PATH=/bin:$PATH
  71. echo shar: extracting "'Imakefile'" '(498 characters)'
  72. if test -f 'Imakefile'
  73. then
  74.     echo shar: will not over-write existing file "'Imakefile'"
  75. else
  76. sed 's/^X//' << \SHAR_EOF > 'Imakefile'
  77. X#
  78. X#  Uncomment this if your compiler supports prototypes.
  79. X#
  80. X#  PROTOTYPES = -DHasPrototypes
  81. X
  82. X#ifdef HasVoidSignalReturn
  83. X   VOIDSIGNAL = -DHasVoidSignalReturn
  84. X#endif /* HasVoidSignalReturn */
  85. X
  86. X#if SunOSPlatform == YES
  87. X#
  88. X#  Circumvent a bug in the sun4 optimizer
  89. X#
  90. X  CDEBUGFLAGS = -g
  91. X#endif /* SunOSPlatform */
  92. X
  93. X      DEFINES = $(PROTOTYPES) $(VOIDSIGNAL) 
  94. XSYS_LIBRARIES = -lX11 
  95. X         HDRS = patchlevel.h 
  96. X         SRCS = xautolock.c 
  97. X         OBJS = xautolock.o 
  98. X
  99. XSimpleProgramTarget(xautolock)
  100. SHAR_EOF
  101. if test 498 -ne "`wc -c < 'Imakefile'`"
  102. then
  103.     echo shar: error transmitting "'Imakefile'" '(should have been 498 characters)'
  104. fi
  105. fi # end of overwriting check
  106. echo shar: extracting "'Makefile.std'" '(494 characters)'
  107. if test -f 'Makefile.std'
  108. then
  109.     echo shar: will not over-write existing file "'Makefile.std'"
  110. else
  111. sed 's/^X//' << \SHAR_EOF > 'Makefile.std'
  112. X#
  113. X#  Edit these to suit your needs.
  114. X#
  115. X#  SystemV is only used to select between fork and vfork. It doesn't hurt
  116. X#  to have it defined to YES, but if your system has vfork, it's more
  117. X#  efficient to comment this stuff out.
  118. X#
  119. XDEFINES = -DSystemV=YES
  120. X
  121. XRM      = /bin/rm -f
  122. XCC      = cc
  123. XHDRS    = patchlevel.h
  124. XSRCS    = xautolock.c
  125. XOBJS    = xautolock.o
  126. X
  127. XLIBS    = -lX11
  128. X
  129. Xall:: xautolock
  130. X
  131. Xxautolock: $(OBJS) 
  132. X    $(RM) $@
  133. X    $(CC) $(DEFINES) -o $@ $(OBJS) $(LIBS) 
  134. X
  135. Xclean:
  136. X    $(RM) xautolock $(OBJS) core
  137. SHAR_EOF
  138. if test 494 -ne "`wc -c < 'Makefile.std'`"
  139. then
  140.     echo shar: error transmitting "'Makefile.std'" '(should have been 494 characters)'
  141. fi
  142. fi # end of overwriting check
  143. echo shar: extracting "'README'" '(4557 characters)'
  144. if test -f 'README'
  145. then
  146.     echo shar: will not over-write existing file "'README'"
  147. else
  148. sed 's/^X//' << \SHAR_EOF > 'README'
  149. XPURPOSE
  150. X=======
  151. X
  152. XXautolock is a program which monitors console activity, and starts up
  153. Xa program of  your choice if  nothing  happens  during a certain time
  154. Xinterval.  You can use this to automatically start up a screen locker
  155. Xin case you tend  to forget to do so  manually before having a coffee
  156. Xbreak.
  157. X
  158. XHARDWARE PLATFORMS
  159. X==================
  160. X
  161. XWe have used  xautolock  on the following hardware without problems :
  162. X
  163. XDECstation 3100 to 5500
  164. XHP Apollo 9000/4xx (Sr10)
  165. XSony News 1800
  166. XSparc II
  167. XVAXen (Ultrix)
  168. X
  169. XOther people have reported that it should also work on :
  170. X
  171. XSun386
  172. XIBM RS/6000
  173. XVAXstation 3100 
  174. X
  175. XAn  earlier  version also ran on  the following machinery,  but we no
  176. Xlonger have those, so testing it was a bit difficult :-). 
  177. X
  178. XSun 3/60
  179. XApollo 3000 to 4500
  180. X
  181. XHOW TO USE IT
  182. X=============
  183. XJust read the man page, it's really simple.
  184. X
  185. X
  186. XHOW IT WORKS
  187. X============
  188. X
  189. XWhen  xautolock  starts  executing,  it  traverses  the  window tree, 
  190. Xselects  SubstructureNotify  on all windows and adds each window to a
  191. Xtemporary list.  About +- 30 seconds later,  it scans this list,  and
  192. Xnow  asks for KeyPress events.  However,  it takes care to  interfere 
  193. Xas litle as possible  with  the event propagation mechanism.  This is
  194. Xthe reason for the delay between the moment  xautolock learns about a
  195. Xnew window (and consequently asks for  SubstructureNotify events) and
  196. Xthe moment it asks for KeyPress.  Whenever a new window is created, a
  197. Xsimilar process takes place.
  198. X
  199. XIn addition, xautolock issues a  QueryPointer  request once a second,
  200. Xin order to find out wether the pointer has moved.
  201. X
  202. XIf nothing happens within a user-specified period of time,  xautolock
  203. Xwill fire up a program  which is supposed  to lock the screen.  While
  204. Xthis program is running, xautolock itself remains on the look-out for
  205. Xuser interaction.
  206. X
  207. XIn contradiction  to what many people  believe,  this scheme does not
  208. Xcause a noticeable overhead. 
  209. X
  210. X
  211. XCOMPILING XAUTOLOCK
  212. X===================
  213. X
  214. XXautolock  should  compile  straight  out of  the box.  Just  do  the
  215. Xfollowing :
  216. X
  217. X 1 : Type 
  218. X
  219. X      xmkmf 
  220. X      make
  221. X      make install
  222. X      make clean 
  223. X
  224. X 2 : Have fun.
  225. X
  226. XKNOWN BUGS
  227. X==========
  228. X
  229. XIf,  when creating  a window,  an application  waits for more than 30
  230. Xseconds before calling XSelectInput (),  xautolock may interfere with
  231. Xthe  event propagation  mechanism.  In order to minimize  the risk of
  232. Xthis happening,  an extra delay of 20 seconds  has been inserted into
  233. Xthe   xautolock  initialization  sequence.   This  was  done  because
  234. Xxautolock is most likely to be started automatically when a user logs
  235. Xin, and that process can be rather time-consuming.
  236. X
  237. XXautolock  does not check whether the screenlocker specified actually
  238. Xis available.
  239. X
  240. XThe xautolock resources have no resource class.
  241. X
  242. XIf you can find others, please send e-mail to one of the authors.
  243. X
  244. X
  245. XWARNING
  246. X=======
  247. X
  248. XThere  is  a  bug  in  the  event management code  of some  X servers
  249. X(amongst  which  both  X11R4  and X11R5  on Sparc).  If you are using 
  250. Xpatchlevel  7  of  xautolock,  it is best to reset  the server before
  251. Xswitching to patchlevel 8.  If you fail to do so, an old patchlevel 7
  252. Xbug may still show up.  (Some keybaord events were being  hijacked by
  253. Xpatchlevel 7 of xautolock, particularly when using tvtwm). 
  254. X
  255. X
  256. XCOPYRIGHT
  257. X=========
  258. XCopyright 1990, 1992 by S. De Troch and MCE.
  259. X
  260. XPermission to use, copy, modify and distribute this software and the
  261. Xsupporting documentation without fee is hereby granted, provided that :
  262. X
  263. X 1 : Both the above copyright notice and this permission notice
  264. X     appear in all copies of both the software and the supporting
  265. X     documentation.
  266. X 2 : You don't make a profit out of it.
  267. X
  268. XDISCLAIMER
  269. X==========
  270. X
  271. XTHE AUTHORS  DISCLAIM  ALL WARRANTIES  WITH  REGARD TO THIS SOFTWARE,
  272. XINCLUDING  ALL IMPLIED WARRANTIES OF MERCHANTABILITY  AND FITNESS, IN
  273. XNO  EVENT  SHALL THEY   BE  LIABLE  FOR   ANY  SPECIAL,  INDIRECT  OR
  274. XCONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS
  275. XOF  USE,  DATA  OR  PROFITS,   WHETHER  IN  AN  ACTION  OF  CONTRACT,
  276. XNEGLIGENCE  OR   OTHER   TORTIOUS  ACTION,   ARISING  OUT  OF  OR  IN
  277. XCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  278. X
  279. XAUTHORS
  280. X=======
  281. X
  282. XXautolock was conceived, written and performed by :
  283. X
  284. X Stefan De Troch             detroch@imec.be
  285. X Michel Eyckmans (MCE)       eyckmans@imec.be
  286. X
  287. X
  288. XACKNOWLEDGEMENTS
  289. X================
  290. X
  291. XSpecial thanks to :
  292. X
  293. X Kris Croes                  croes@imec.be
  294. X
  295. XAnd the patchlevel 8 beta testers :
  296. X
  297. X Paul D. Smith               paul_smith@dg.com
  298. X Brian                       brian@natinst.com
  299. SHAR_EOF
  300. if test 4557 -ne "`wc -c < 'README'`"
  301. then
  302.     echo shar: error transmitting "'README'" '(should have been 4557 characters)'
  303. fi
  304. fi # end of overwriting check
  305. echo shar: extracting "'patchlevel.h'" '(22 characters)'
  306. if test -f 'patchlevel.h'
  307. then
  308.     echo shar: will not over-write existing file "'patchlevel.h'"
  309. else
  310. sed 's/^X//' << \SHAR_EOF > 'patchlevel.h'
  311. X#define PATCHLEVEL  8
  312. SHAR_EOF
  313. if test 22 -ne "`wc -c < 'patchlevel.h'`"
  314. then
  315.     echo shar: error transmitting "'patchlevel.h'" '(should have been 22 characters)'
  316. fi
  317. fi # end of overwriting check
  318. echo shar: extracting "'xautolock.c'" '(37774 characters)'
  319. if test -f 'xautolock.c'
  320. then
  321.     echo shar: will not over-write existing file "'xautolock.c'"
  322. else
  323. sed 's/^X//' << \SHAR_EOF > 'xautolock.c'
  324. X/***************************************************************************
  325. X *
  326. X * xautolock
  327. X * =========
  328. X *
  329. X * Authors   :  S. De Troch (SDT)
  330. X *              M. Eyckmans (MCE)
  331. X *
  332. X * Date      :  22/07/90
  333. X *
  334. X * Comments  :
  335. X *
  336. X * Review    :  - 12/02/92 (MCE) :
  337. X *                . Hacked around a dxcalendar problem.
  338. X *              - 21/02/92 (MCE) :
  339. X *                . Major rewrite.
  340. X *              - 24/02/92 (MCE) :
  341. X *                . Removed an initialization bug.
  342. X *              - 25/02/92 (MCE) :
  343. X *                . Added code to detect multiple invocations.
  344. X *              - 06/03/92 (MCE) :
  345. X *                . Re-arranged the event loop in order to detect defunct
  346. X *                  children as soon as possible.
  347. X *              - 10/03/92 (SDT & MCE) :
  348. X *                . Added code to detect broken server connections.
  349. X *              - 24/03/92 (MCE) :
  350. X *                . Don't reset the time-out counter after receiving a
  351. X *                  synthetic or otherwise unexpected event.
  352. X *              - 15/04/92 (MCE) :
  353. X *                . Changed the default locker to "xlock 2>&- 1>&-".
  354. X *                . Fixed a couple of event mask bugs. (Thanks to
  355. X *                  jwz@lucid.com for running into these.)
  356. X *                . Corrected a property type bug in CheckConnection ().
  357. X *              - 20/04/92 (MCE) :
  358. X *                . Cut Main () into more managable pieces.
  359. X *                . Periodically call XQueryPointer ().
  360. X *              - 25/04/92 (MCE) :
  361. X *                . Added the `corners' feature. (Suggested by
  362. X *                  weisen@alw.nih.gov.)
  363. X *                . Fixed a problem with pseudo-root windows. (Thanks to
  364. X *                  sherman@unx.sas.com, nedwards@titan.trl.OZ.AU,
  365. X *                  dave@elxr.jpl.Nasa.Gov and tmcconne@sedona.intel.com
  366. X *                  for pointing out the problem and testing the patch.)
  367. X *                . Added `disable/enable on SIGHUP'. (Suggested by
  368. X *                  paul_smith@dg.com.)
  369. X *                . Added support for multiheaded displays. 
  370. X *              - 28/04/92 (MCE) :
  371. X *                . Use the X resource manager.
  372. X *              - 06/05/92 (MCE) :
  373. X *                . Fixed a few potential portability problems. (Thanks
  374. X *                  to paul_smith@dg.com again.)
  375. X *                . CheckConnection () now works properly on multiheaded
  376. X *                  displays. (Thanks to brian@natinst.com for testing
  377. X *                  the `multiheaded' feature.)
  378. X *                . Better version of Sleep().
  379. X *                . Recognize X resources for class "Xautolock".
  380. X *                . Don't update timer while sighupped.
  381. X *                . Switched to vfork () and execl ().
  382. X *                . New copyright notice.
  383. X *              - 11/05/92 (MCE) :
  384. X *                . Close stdout and stderr in stead of using "2>&- 1>&-".
  385. X *                  (Suggested by sinkwitz@ifi.unizh.ch.)
  386. X *                . Added "-noclose" for debugging. 
  387. X *
  388. X * -------------------------------------------------------------------------
  389. X *
  390. X * Please send bug reports to detroch@imec.be or eyckmans@imec.be.
  391. X *
  392. X * -------------------------------------------------------------------------
  393. X *
  394. X * Copyright 1990, 1992 by S. De Troch and MCE.
  395. X *
  396. X * Permission to use, copy, modify and distribute this software and the
  397. X * supporting documentation without fee is hereby granted, provided that :
  398. X *
  399. X *  1 : Both the above copyright notice and this permission notice
  400. X *      appear in all copies of both the software and the supporting
  401. X *      documentation.
  402. X *  2 : You don't make a profit out of it.
  403. X *
  404. X * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  405. X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
  406. X * EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  407. X * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
  408. X * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  409. X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  410. X * PERFORMANCE OF THIS SOFTWARE.
  411. X *
  412. X ***************************************************************************/
  413. X
  414. X
  415. X
  416. X/*
  417. X *  Have a guess what this does...
  418. X *  ==============================
  419. X *
  420. X *  Warning for swm & tvtwm users : xautolock should *not* be compiled
  421. X *  with vroot.h, because it needs to know the real root window.
  422. X */
  423. X#include <stdio.h>
  424. X#include <strings.h>
  425. X#include <X11/Xlib.h>
  426. X#include <X11/Xatom.h>
  427. X#include <X11/Xresource.h>
  428. X#include <sys/types.h>
  429. X#include <sys/wait.h>
  430. X#include <signal.h>
  431. X#include <memory.h>
  432. X#include <math.h>
  433. X
  434. X#ifdef AIXV3    
  435. X#include <sys/m_wait.h>
  436. X#endif /* AIXV3 */
  437. X
  438. X#if !defined (news1800) && !defined (sun386)
  439. X
  440. X#include <stdlib.h>
  441. X
  442. X#ifndef apollo
  443. X#include <malloc.h>
  444. X#include <unistd.h>
  445. X#endif /* apollo */
  446. X
  447. X#endif /* !news1800 && !sun386 */
  448. X
  449. X#include "patchlevel.h"
  450. X
  451. X
  452. X
  453. X
  454. X/*
  455. X *  Usefull macros and customization stuff
  456. X *  ======================================
  457. X */
  458. X#ifdef HasPrototypes
  459. X#define PP(x)                      x
  460. X#else /* HasPrototypes */
  461. X#define PP(x)                      ()
  462. X#endif /* HasPrototypes */
  463. X
  464. X
  465. X#define FALSE                      0       /* as it says                   */
  466. X#define TRUE                       1       /* as it says                   */
  467. X
  468. X#define ALL_OK                     0       /* for use by exit ()           */
  469. X#define PROBLEMS                   1       /* for use by exit ()           */
  470. X#define BELL_PERCENT               40      /* as is says                   */
  471. X#define MIN_MINUTES                1       /* minimum number of minutes
  472. X                          before firing up the locker  */
  473. X#define MINUTES                    10      /* default ...                  */
  474. X#define MAX_MINUTES                60      /* maximum ...                  */
  475. X#define INITIAL_SLEEP              20      /* for machines on which the
  476. X                             login sequence takes forever */
  477. X#define INCREMENTAL_SLEEP          1       /* time step in seconds         */
  478. X#define CREATION_DELAY             30      /* should be > 10 and
  479. X                           < min (45,(MIN_MINUTES*30))  */
  480. X#define CORNER_SIZE                10      /* size in pixels of the
  481. X                            force-lock areas             */
  482. X#define CORNER_DELAY               5       /* number of seconds to wait
  483. X                          before forcing a lock        */
  484. X#define LOCKER                     "xlock" /* NEVER use the -root option!  */
  485. X#define CLASS                      "Xautolock"
  486. X                            /* as it says                   */
  487. X
  488. X#if SystemV == YES
  489. X#define vfork                      fork
  490. X#endif /* SystemV == YES */
  491. X
  492. X#define Main                       main
  493. X#define Min(a,b)                   (a < b ? a : b)
  494. X#define forever                    for (;;)
  495. X#define Output0(str)               (Void) fprintf (stdout, str)
  496. X#define Output1(str,arg1)          (Void) fprintf (stdout, str, arg1)
  497. X#define Output2(str,arg1,arg2)     (Void) fprintf (stdout, str, arg1, arg2)
  498. X#define Error0(str)                (Void) fprintf (stderr, str)
  499. X#define Error1(str,arg1)           (Void) fprintf (stderr, str, arg1)
  500. X#define Error2(str,arg1,arg2)      (Void) fprintf (stderr, str, arg1, arg2)
  501. X#define UpdateTimer(new_val)       if (!sighupped) timer = new_val
  502. X
  503. Xstatic void*                       ch_ptr;  /* this is dirty */
  504. X#define Skeleton(t,s)              (ch_ptr = (Void*) malloc ((unsigned) s), \
  505. X                       ch_ptr == (Void*) NULL                \
  506. X                       ?   (Error0 ("Out of memory.\n"),       \
  507. X                        (Void) exit (PROBLEMS),              \
  508. X                        (t*) NULL                            \
  509. X                       )                                     \
  510. X                        : (t*) ch_ptr                           \
  511. X                               )                                        \
  512. X
  513. X#define New(type)                  Skeleton (type, sizeof (type))
  514. X#define NewArray(type,nof_elems)   Skeleton (type, sizeof (type) * nof_elems)
  515. X
  516. X
  517. X
  518. X
  519. X/*
  520. X *  New types
  521. X *  =========
  522. X */
  523. X#if defined (apollo) || defined (news1800)
  524. Xtypedef int                        (*XErrorHandler) PP((Display*,
  525. X                               XErrorEvent*));
  526. X#endif /* apollo || news1800 */
  527. X
  528. X#if defined (news1800) || defined (sun386)
  529. Xtypedef int                        pid_t;
  530. X#endif /* news1800  || sun386 */
  531. X
  532. X#define Void                       void     /* no typedef because of VAX */
  533. Xtypedef int                        Int;
  534. Xtypedef char                       Char;
  535. Xtypedef char*                      String;
  536. Xtypedef int                        Boolean;
  537. Xtypedef caddr_t                    Caddrt;
  538. Xtypedef unsigned long              Huge;
  539. X
  540. X#ifdef HasVoidSignalReturn
  541. X#define SigRet                     Void     /* no typedef because of VAX */
  542. X#else /* HasVoidSignalReturn */
  543. Xtypedef Int                        SigRet;
  544. X#endif /* HasVoidSignalReturn */
  545. X
  546. Xtypedef SigRet                     (*SigHandler) PP((/* OS dependent */));
  547. Xtypedef Boolean                    (*OptAction)  PP((Display*, String,
  548. X                             String));
  549. Xtypedef Void                       (*OptChecker) PP((Display*));
  550. X
  551. Xtypedef enum
  552. X    {
  553. X      IGNORE,                                 /* ignore this corner  */
  554. X      DONT_LOCK,                              /* never lock          */
  555. X      FORCE_LOCK,                             /* lock immediately    */
  556. X    } CornerAction;
  557. X
  558. Xtypedef struct QueueItem_
  559. X    {
  560. X      Window                   window;        /* as it says          */
  561. X      Time                     creationtime;  /* as it says          */
  562. X      struct QueueItem_*       next;          /* as it says          */
  563. X      struct QueueItem_*       prev;          /* as it says          */
  564. X    } aQueueItem, *QueueItem;
  565. X
  566. Xtypedef struct Queue_
  567. X    {
  568. X      struct QueueItem_*       head;          /* as it says          */
  569. X      struct QueueItem_*       tail;          /* as it says          */
  570. X    } aQueue, *Queue;
  571. X
  572. Xtypedef struct Opt_
  573. X    {
  574. X      String                   name;          /* as it says          */
  575. X      XrmOptionKind            kind;          /* as it says          */
  576. X      Caddrt                   value;         /* XrmOptionNoArg only */
  577. X      OptAction                action;        /* as it says          */
  578. X      OptChecker               checker;       /* as it says          */
  579. X    } anOpt, *Opt;
  580. X
  581. X
  582. X
  583. X
  584. X/*
  585. X *  Function declarations
  586. X *  =====================
  587. X */
  588. X#ifdef news1800
  589. Xextern Void*    malloc             PP((unsigned int));
  590. X#endif /* news1800 */
  591. Xstatic Void     Usage              PP((String, Int));
  592. Xstatic Void     Sleep              PP((Void));
  593. Xstatic Void     EvaluateCounter    PP((Display*));
  594. Xstatic Void     QueryPointer       PP((Display*));
  595. Xstatic Void     ProcessEvents      PP((Display*, Queue));
  596. Xstatic Queue    NewQueue           PP((Void));
  597. Xstatic Void     AddToQueue         PP((Queue, Window));
  598. Xstatic Void     ProcessQueue       PP((Queue, Display*, Time));
  599. Xstatic Void     SelectEvents       PP((Display*, Window, Boolean));
  600. Xstatic Void     CheckConnection    PP((Display*, String));
  601. Xstatic Int      FetchFalseAlarm    PP((Display*, XEvent));
  602. Xstatic Void     ProcessOpts        PP((Display*, Int, String*));
  603. Xstatic Boolean  TimeAction         PP((Display*, String, String));
  604. Xstatic Boolean  LockerAction       PP((Display*, String, String));
  605. Xstatic Boolean  CornersAction      PP((Display*, String, String));
  606. Xstatic Boolean  CornerSizeAction   PP((Display*, String, String));
  607. Xstatic Boolean  CornerDelayAction  PP((Display*, String, String));
  608. Xstatic Boolean  NotifyAction       PP((Display*, String, String));
  609. Xstatic Boolean  BellAction         PP((Display*, String, String));
  610. Xstatic Boolean  NoCloseAction      PP((Display*, String, String));
  611. Xstatic Boolean  HelpAction         PP((Display*, String, String));
  612. Xstatic Boolean  VersionAction      PP((Display*, String, String));
  613. Xstatic Boolean  GetPositive        PP((String, Int*));
  614. Xstatic Void     TimeChecker        PP((Display*));
  615. Xstatic Void     NotifyChecker      PP((Display*));
  616. Xstatic Void     CornerSizeChecker  PP((Display*));
  617. Xstatic Void     BellChecker        PP((Display*));
  618. Xstatic SigRet   DisableBySignal    PP((Void));
  619. X
  620. X
  621. X
  622. X
  623. X/*
  624. X *  Global variables
  625. X *  ================
  626. X */
  627. Xstatic Time          now = 0;               /* number of sleeps since we
  628. X                               started (not `Int')        */
  629. Xstatic Int           timer = 0;             /* as it says (not `Time')    */
  630. Xstatic String        locker = LOCKER;       /* as it says                 */
  631. Xstatic Int           time_limit = MINUTES;  /* as it says (not `Time')    */
  632. Xstatic Int           notify_margin;         /* as it says (not `Time')    */
  633. Xstatic Int           bell_percent = BELL_PERCENT;
  634. X                        /* as it says                 */
  635. Xstatic Int           corner_size = CORNER_SIZE;
  636. X                        /* as it says                 */
  637. Xstatic Int           corner_delay = CORNER_DELAY;
  638. X                        /* as it says (not `Time')    */
  639. Xstatic Boolean       sighupped = FALSE;     /* whether to ignore all
  640. X                           time-outs                  */
  641. Xstatic Boolean       notify_lock = FALSE;   /* whether to notify the user
  642. X                               before locking             */
  643. Xstatic CornerAction  corners[4] = { IGNORE, IGNORE, IGNORE, IGNORE };
  644. X                                        /* default CornerActions      */
  645. Xstatic Boolean       close_output = TRUE;   /* whether to close stdout
  646. X                                               and stderr                 */
  647. Xstatic anOpt         options[] = 
  648. X                  {
  649. X                      {"help"       , XrmoptionNoArg   ,
  650. X                    (Caddrt) ""  , HelpAction       , (OptChecker) NULL},
  651. X                      {"version"    , XrmoptionNoArg   ,
  652. X                    (Caddrt) ""  , VersionAction    , (OptChecker) NULL},
  653. X                      {"locker"     , XrmoptionSepArg  ,
  654. X                    (Caddrt) NULL, LockerAction     , (OptChecker) NULL},
  655. X                      {"corners"    , XrmoptionSepArg  ,
  656. X                    (Caddrt) NULL, CornersAction    , (OptChecker) NULL},
  657. X                      {"cornersize" , XrmoptionSepArg  ,
  658. X                    (Caddrt) NULL, CornerSizeAction , CornerSizeChecker},
  659. X                      {"cornerdelay", XrmoptionSepArg  ,
  660. X                    (Caddrt) NULL, CornerDelayAction, (OptChecker) NULL},
  661. X                      {"time"       , XrmoptionSepArg  ,
  662. X                    (Caddrt) NULL, TimeAction       , TimeChecker      },
  663. X                      {"notify"     , XrmoptionSepArg  ,
  664. X                    (Caddrt) NULL, NotifyAction     , NotifyChecker    },
  665. X                      {"bell"       , XrmoptionSepArg  ,
  666. X                    (Caddrt) NULL, BellAction       , BellChecker      },
  667. X                      {"noclose"    , XrmoptionNoArg   ,
  668. X                    (Caddrt) ""  , NoCloseAction    , (OptChecker) NULL},
  669. X                  };                     /* as it says, the order is
  670. X                           important                  */
  671. X
  672. X
  673. X
  674. X
  675. X/*
  676. X *  Command line argument related functions
  677. X *  =======================================
  678. X *
  679. X *  Support functions
  680. X *  -----------------
  681. X */
  682. Xstatic Boolean  GetPositive (arg, pos)
  683. XString  arg;  /* string to scan                  */
  684. XInt*    pos;  /* adress where to store the stuff */
  685. X
  686. X{
  687. X  Char  c;           /* dummy            */
  688. X  Int   old = *pos;  /* backup old value */
  689. X
  690. X
  691. X  if (   sscanf (arg, "%d%c", pos, &c) == 1
  692. X      && *pos >= 0
  693. X     )
  694. X  {
  695. X    return TRUE;
  696. X  }
  697. X  else
  698. X  {
  699. X    *pos = old;
  700. X    return FALSE;
  701. X  }
  702. X}
  703. X
  704. X
  705. X
  706. X/*
  707. X *  Action functions
  708. X *  ----------------
  709. X */
  710. X/*ARGSUSED*/
  711. Xstatic Boolean  HelpAction (d, name, arg)
  712. XDisplay*  d;     /* display pointer */
  713. XString    name;  /* program name    */
  714. XString    arg;   /* argument value  */
  715. X
  716. X{
  717. X  Usage (name, ALL_OK);
  718. X
  719. X  return TRUE;  /* for lint and gcc */
  720. X}
  721. X
  722. X
  723. X/*ARGSUSED*/
  724. Xstatic Boolean  VersionAction (d, name, arg)
  725. XDisplay*  d;     /* display pointer */
  726. XString    name;  /* program name    */
  727. XString    arg;   /* argument value  */
  728. X
  729. X{
  730. X  Error2 ("%s : patchlevel %d\n", name, PATCHLEVEL);
  731. X  (Void) exit (ALL_OK);
  732. X
  733. X  return TRUE;  /* for lint and gcc */
  734. X}
  735. X
  736. X
  737. X/*ARGSUSED*/
  738. Xstatic Boolean  CornerSizeAction (d, name, arg)
  739. XDisplay*  d;     /* display pointer */
  740. XString    name;  /* program name    */
  741. XString    arg;   /* argument value  */
  742. X
  743. X{
  744. X  return GetPositive (arg, &corner_size);
  745. X}
  746. X
  747. X
  748. X/*ARGSUSED*/
  749. Xstatic Boolean  CornerDelayAction (d, name, arg)
  750. XDisplay*  d;     /* display pointer */
  751. XString    name;  /* program name    */
  752. XString    arg;   /* argument value  */
  753. X
  754. X{
  755. X  return GetPositive (arg, &corner_delay);
  756. X}
  757. X
  758. X
  759. X/*ARGSUSED*/
  760. Xstatic Boolean  TimeAction (d, name, arg)
  761. XDisplay*  d;     /* display pointer */
  762. XString    name;  /* program name    */
  763. XString    arg;   /* argument value  */
  764. X
  765. X{
  766. X  return GetPositive (arg, &time_limit);
  767. X}
  768. X
  769. X
  770. X/*ARGSUSED*/
  771. Xstatic Boolean  NotifyAction (d, name, arg)
  772. XDisplay*  d;     /* display pointer */
  773. XString    name;  /* program name    */
  774. XString    arg;   /* argument value  */
  775. X
  776. X{
  777. X  return notify_lock = GetPositive (arg, ¬ify_margin);
  778. X}
  779. X
  780. X
  781. X/*ARGSUSED*/
  782. Xstatic Boolean  BellAction (d, name, arg)
  783. XDisplay*  d;     /* display pointer */
  784. XString    name;  /* program name    */
  785. XString    arg;   /* argument value  */
  786. X
  787. X{
  788. X  return GetPositive (arg, &bell_percent);
  789. X}
  790. X
  791. X
  792. X/*ARGSUSED*/
  793. Xstatic Boolean  NoCloseAction (d, name, arg)
  794. XDisplay*  d;     /* display pointer */
  795. XString    name;  /* program name    */
  796. XString    arg;   /* argument value  */
  797. X
  798. X{
  799. X  close_output = FALSE;
  800. X  return TRUE;
  801. X}
  802. X
  803. X
  804. X/*ARGSUSED*/
  805. Xstatic Boolean  LockerAction (d, name, arg)
  806. XDisplay*  d;     /* display pointer */
  807. XString    name;  /* program name    */
  808. XString    arg;   /* argument value  */
  809. X
  810. X{
  811. X  locker = arg;
  812. X  return TRUE;
  813. X}
  814. X
  815. X
  816. X/*ARGSUSED*/
  817. Xstatic Boolean  CornersAction (d, name, arg)
  818. XDisplay*  d;     /* display pointer */
  819. XString    name;  /* program name    */
  820. XString    arg;   /* argument value  */
  821. X
  822. X{
  823. X  Int  c;  /* loop counter */
  824. X
  825. X
  826. X  if (strlen (arg) == 4)
  827. X  {
  828. X    for (c = -1; ++c < 4; )
  829. X    {
  830. X      switch (arg[c])
  831. X      {
  832. X    case '0' :
  833. X      corners[c] = IGNORE;
  834. X      continue;
  835. X
  836. X    case '-' :
  837. X      corners[c] = DONT_LOCK;
  838. X      continue;
  839. X
  840. X    case '+' :
  841. X      corners[c] = FORCE_LOCK;
  842. X      continue;
  843. X
  844. X    default :
  845. X      return FALSE;
  846. X      }
  847. X    }
  848. X
  849. X    return TRUE;
  850. X  }
  851. X  else
  852. X  {
  853. X    return FALSE;
  854. X  }
  855. X}
  856. X
  857. X
  858. X
  859. X/*
  860. X *  Consistency checkers
  861. X *  --------------------
  862. X */
  863. X/*ARGSUSED*/
  864. Xstatic Void  TimeChecker (d)
  865. XDisplay*  d;  /* display pointer */
  866. X
  867. X{
  868. X  if (time_limit < MIN_MINUTES)
  869. X  {
  870. X    Error1 ("Setting time to minimum value of %d minute(s).\n",
  871. X            time_limit = MIN_MINUTES);
  872. X  }
  873. X  else if (time_limit > MAX_MINUTES)
  874. X  {
  875. X    Error1 ("Setting time to maximum value of %d minute(s).\n",
  876. X            time_limit = MAX_MINUTES);
  877. X  }
  878. X
  879. X  time_limit *= 60; /* convert to seconds */
  880. X}
  881. X
  882. X
  883. X/*ARGSUSED*/
  884. Xstatic Void  NotifyChecker (d)
  885. XDisplay*  d;  /* display pointer */
  886. X
  887. X{
  888. X  if (   notify_lock
  889. X      && notify_margin >= time_limit / 2
  890. X     )
  891. X  {
  892. X    Error1 ("Notification time set to %d seconds.\n",
  893. X            notify_margin = time_limit / 2);
  894. X  }
  895. X}
  896. X
  897. X
  898. X/*ARGSUSED*/
  899. Xstatic Void  BellChecker (d)
  900. XDisplay*  d;  /* display pointer */
  901. X
  902. X{
  903. X  if (   bell_percent < 1
  904. X      || bell_percent > 100
  905. X     )
  906. X  {
  907. X    Error1 ("Bell percentage set to %d%%.\n",
  908. X        bell_percent = BELL_PERCENT);
  909. X  }
  910. X}
  911. X
  912. X
  913. X/*ARGSUSED*/
  914. Xstatic Void  CornerSizeChecker (d)
  915. XDisplay*  d;  /* display pointer */
  916. X
  917. X{
  918. X  Int      s;                /* screen index   */
  919. X  Screen*  scr;              /* screen pointer */
  920. X  Int      max_corner_size;  /* as it says     */
  921. X  
  922. X
  923. X  for (max_corner_size = 32000, s = -1; ++s < ScreenCount (d); )
  924. X  {
  925. X    scr = ScreenOfDisplay (d, s);
  926. X
  927. X    if (   max_corner_size > WidthOfScreen (scr) / 4
  928. X    || max_corner_size > HeightOfScreen (scr) / 4
  929. X       )
  930. X    {
  931. X      max_corner_size = Min (WidthOfScreen (scr), HeightOfScreen (scr)) / 4;
  932. X    }
  933. X  }
  934. X
  935. X  if (corner_size > max_corner_size)
  936. X  {
  937. X    Error1 ("Corner size set to %d pixels.\n",
  938. X        corner_size = max_corner_size);
  939. X  }
  940. X}
  941. X
  942. X
  943. X
  944. X/*
  945. X *  Function for informing the user about syntax errors
  946. X *  ---------------------------------------------------
  947. X */
  948. Xstatic Void  Usage (prog_name, exit_code)
  949. XString  prog_name;  /* as it says */
  950. XInt     exit_code;  /* as it says */
  951. X
  952. X{
  953. X  String  blanks;  /* string full of blanks */
  954. X  size_t  len;     /* number of blanks      */
  955. X
  956. X
  957. X /*
  958. X  *  The relative overhead is enormous here, but who cares.
  959. X  *  I'm a perfectionist and Usage () doesn't return anyway.
  960. X  */
  961. X  len = strlen ("Usage : ") + strlen (prog_name) + 1;
  962. X  (Void) memset (blanks = NewArray (Char, len + 1), ' ', len);
  963. X  blanks[len] = '\0';
  964. X
  965. X
  966. X /*
  967. X  *  This is where the actual work gets done...
  968. X  */
  969. X  Error0 ("\n");
  970. X  Error1 ("Usage : %s ", prog_name);
  971. X  Error0 ("[-help][-version][-time minutes][-locker locker]\n");
  972. X  Error0 (blanks);
  973. X  Error0 ("[-notify margin][-bell percent][-corners xxxx]\n");
  974. X  Error0 (blanks);
  975. X  Error0 ("[-cornerdelay secs][-cornersize pixels][-noclose]\n");
  976. X
  977. X  Error0 ("\n");
  978. X  Error0 (" -help              : print this message and exit.\n");
  979. X  Error0 (" -version           : print version number and exit.\n");
  980. X  Error2 (" -time minutes      : time to lock screen [%d < minutes < %d].\n",
  981. X                             MIN_MINUTES, MAX_MINUTES);
  982. X  Error0 (" -locker locker     : program used to lock.\n");
  983. X  Error0 (" -notify margin     : beep this many seconds before locking.\n");
  984. X  Error0 (" -bell percent      : loudness of the beep.\n");
  985. X  Error0 (" -corners xxxx      : corner actions (0, +, -) in this order :\n");
  986. X  Error0 ("                      topleft topright bottomleft bottomright\n");
  987. X  Error0 (" -cornerdelay secs  : time to lock screen in a `+' corner.\n");
  988. X  Error0 (" -cornersize pixels : size of corner areas.\n");
  989. X  Error0 (" -noclose           : do not close stdout and stderr.\n");
  990. X
  991. X  Error0 ("\n");
  992. X  Error0 ("Defaults :\n");
  993. X
  994. X  Error0 ("\n");
  995. X  Error1 ("  time        : %d minutes\n"  , MINUTES     );
  996. X  Error1 ("  locker      : %s\n"          , LOCKER      );
  997. X  Error0 ("  notify      : don't beep\n"                );
  998. X  Error0 ("  bell        : 40%%\n"                      );
  999. X  Error0 ("  corners     : 0000\n"                      );
  1000. X  Error1 ("  cornerdelay : %d seconds\n"  , CORNER_DELAY);
  1001. X  Error1 ("  cornersize  : %d pixels\n"   , CORNER_SIZE );
  1002. X
  1003. X  Error0 ("\n");
  1004. X
  1005. X  exit (exit_code);
  1006. X}
  1007. X
  1008. X
  1009. X
  1010. X/*
  1011. X *  Function for processing command line arguments
  1012. X *  ----------------------------------------------
  1013. X */
  1014. Xstatic Void  ProcessOpts (d, argc, argv)
  1015. XDisplay*  d;       /* display pointer     */
  1016. XInt       argc;    /* number of arguments */
  1017. XString    argv[];  /* array of arguments  */
  1018. X
  1019. X{
  1020. X  Int                nof_options = sizeof (options) / sizeof (anOpt);
  1021. X                              /* number of supported options   */
  1022. X  Int                j;           /* loop counter                  */
  1023. X  Int                l;           /* temporary storage             */
  1024. X  Char*              ptr;         /* temporary storage             */
  1025. X  Char               buffer[80];  /* as it says                    */
  1026. X  Char*              dummy;       /* as it says                    */
  1027. X  XrmValue           value;       /* resource value container      */
  1028. X  XrmOptionDescList  xoptions;    /* optionslist in Xlib format    */
  1029. X  XrmDatabase        db = (XrmDatabase) NULL;
  1030. X                  /* command line options database */
  1031. X
  1032. X
  1033. X /*
  1034. X  *  Beautify argv[0].
  1035. X  */
  1036. X  for (ptr = argv[0] + strlen (argv[0]) - 1; ptr >= argv[0]; ptr--)
  1037. X  {
  1038. X    if (*ptr == '/')
  1039. X    {
  1040. X      break;
  1041. X    }
  1042. X  }
  1043. X
  1044. X  argv[0] = ptr + 1;
  1045. X
  1046. X
  1047. X /*
  1048. X  *  Calling XGetDefault () on a dummy resource is the easiest 
  1049. X  *  way to get both Xrm and d->db initialized.
  1050. X  */
  1051. X  (Void) XGetDefault (d, argv[0], "dummy");
  1052. X
  1053. X
  1054. X /*
  1055. X  *  Parse the command line options into a resource database. (The
  1056. X  *  command line database and the resource file database are not
  1057. X  *  merged, because we want to know where exactly each resource
  1058. X  *  value came from.)
  1059. X  */
  1060. X  xoptions = NewArray (XrmOptionDescRec, nof_options);
  1061. X
  1062. X  for (j = -1; ++j < nof_options; )
  1063. X  {
  1064. X    l = strlen (options[j].name);
  1065. X
  1066. X    (Void) sprintf (xoptions[j].option = NewArray (Char, l + 2),
  1067. X                "-%s", options[j].name);
  1068. X    (Void) sprintf (xoptions[j].specifier = NewArray (Char, l + 2),
  1069. X                ".%s", options[j].name);
  1070. X    xoptions[j].argKind = options[j].kind;
  1071. X    xoptions[j].value = options[j].value;
  1072. X  }
  1073. X
  1074. X  XrmParseCommand (&db, xoptions, nof_options, argv[0], &argc, argv);
  1075. X
  1076. X  if (--argc)
  1077. X  {
  1078. X    Usage (argv[0], PROBLEMS);
  1079. X  }
  1080. X
  1081. X  for (j = -1; ++j < nof_options; )
  1082. X  {
  1083. X    free (xoptions[j].option);
  1084. X    free (xoptions[j].specifier);
  1085. X  }
  1086. X
  1087. X  free (xoptions);
  1088. X
  1089. X
  1090. X /*
  1091. X  *  Call the action functions.
  1092. X  */
  1093. X  for (j = -1; ++j < nof_options; )
  1094. X  {
  1095. X    (Void) sprintf (buffer, "%s%s", argv[0], xoptions[j].specifier);
  1096. X
  1097. X    if (XrmGetResource (db, buffer, (String) NULL, &dummy, &value))
  1098. X    {
  1099. X      if (!(*(options[j].action)) (d, argv[0], value.addr))
  1100. X      {
  1101. X        Usage (argv[0], PROBLEMS); 
  1102. X      }
  1103. X    }
  1104. X    else if (XrmGetResource (d->db, buffer, (String) NULL, &dummy, &value))
  1105. X    {
  1106. X      if (!(*(options[j].action)) (d, argv[0], value.addr))
  1107. X      {
  1108. X        Error2 ("Can't interprete \"%s\" for \"%s\", using default.\n", 
  1109. X            value.addr, buffer);
  1110. X      }
  1111. X    }
  1112. X    else
  1113. X    {
  1114. X      (Void) sprintf (buffer, "%s%s", CLASS, xoptions[j].specifier);
  1115. X
  1116. X      if (   XrmGetResource (d->db, buffer, (String) NULL, &dummy, &value)
  1117. X          && !(*(options[j].action)) (d, argv[0], value.addr)
  1118. X         )
  1119. X      {
  1120. X        Error2 ("Can't interprete \"%s\" for \"%s\", using default.\n", 
  1121. X            value.addr, buffer);
  1122. X      }
  1123. X    }
  1124. X  }
  1125. X
  1126. X
  1127. X
  1128. X /*
  1129. X  *  Call the consistency checkers.
  1130. X  */
  1131. X  for (j = -1; ++j < nof_options; )
  1132. X  {
  1133. X    if (options[j].checker != (OptChecker) NULL)
  1134. X    {
  1135. X      (*(options[j].checker)) (d);
  1136. X    }
  1137. X  }
  1138. X}
  1139. X
  1140. X
  1141. X
  1142. X
  1143. X/*
  1144. X *  Functions related to the window queue
  1145. X *  =====================================
  1146. X *
  1147. X *  Function for creating a new queue
  1148. X *  ---------------------------------
  1149. X */
  1150. Xstatic Queue  NewQueue ()
  1151. X
  1152. X{
  1153. X  Queue  queue;  /* return value */
  1154. X
  1155. X
  1156. X  queue = New (aQueue);
  1157. X  queue->tail = New (aQueueItem);
  1158. X  queue->head = New (aQueueItem);
  1159. X
  1160. X  queue->tail->next = queue->head;
  1161. X  queue->head->prev = queue->tail;
  1162. X  queue->tail->prev = queue->head->next = (QueueItem) NULL;
  1163. X
  1164. X  return queue;
  1165. X}
  1166. X
  1167. X
  1168. X
  1169. X/*
  1170. X *  Function for adding an item to a queue
  1171. X *  --------------------------------------
  1172. X */
  1173. Xstatic Void  AddToQueue (queue, window)
  1174. XQueue   queue;   /* as it says */
  1175. XWindow  window;  /* as it says */
  1176. X
  1177. X{
  1178. X  QueueItem  new;  /* new item */
  1179. X
  1180. X
  1181. X  new = New (aQueueItem);
  1182. X
  1183. X  new->window = window;
  1184. X  new->creationtime = now;
  1185. X  new->next = queue->tail->next;
  1186. X  new->prev = queue->tail;
  1187. X  queue->tail->next->prev = new;
  1188. X  queue->tail->next = new;
  1189. X}
  1190. X
  1191. X
  1192. X
  1193. X/*
  1194. X *  Function for processing those entries that are old enough
  1195. X *  ---------------------------------------------------------
  1196. X */
  1197. Xstatic Void  ProcessQueue (queue, d, age)
  1198. XQueue     queue;  /* as it says      */
  1199. XDisplay*  d;      /* display pointer */
  1200. XTime      age;    /* required age    */
  1201. X
  1202. X{
  1203. X  QueueItem  current;  /* as it says */
  1204. X
  1205. X
  1206. X  if (now > age)
  1207. X  {
  1208. X    current = queue->head->prev;
  1209. X
  1210. X    while (   current->prev
  1211. X       && current->creationtime + age < now
  1212. X      )
  1213. X    {
  1214. X      SelectEvents (d, current->window, False);
  1215. X      current = current->prev;
  1216. X      free (current->next);
  1217. X    }
  1218. X
  1219. X    current->next = queue->head;
  1220. X    queue->head->prev = current;
  1221. X  }
  1222. X}
  1223. X
  1224. X
  1225. X
  1226. X
  1227. X/*
  1228. X *  Functions related to (the lack of) user activity
  1229. X *  ================================================
  1230. X *
  1231. X *  Function for processing the event queue
  1232. X *  ---------------------------------------
  1233. X */
  1234. Xstatic Void  ProcessEvents (d, queue)
  1235. XDisplay*  d;      /* display pointer */
  1236. XQueue     queue;  /* as it says      */
  1237. X
  1238. X{
  1239. X  XEvent  event;  /* as it says */
  1240. X
  1241. X
  1242. X /*
  1243. X  *  Read whatever is available for reading.
  1244. X  */
  1245. X  while (XPending (d))
  1246. X  {
  1247. X    if (XCheckMaskEvent (d, SubstructureNotifyMask, &event))
  1248. X    {
  1249. X      if (event.type == CreateNotify)
  1250. X      {
  1251. X    AddToQueue (queue, event.xcreatewindow.window);
  1252. X      }
  1253. X    }
  1254. X    else
  1255. X    {
  1256. X      XNextEvent (d, &event);
  1257. X    }
  1258. X
  1259. X
  1260. X   /*
  1261. X    *  Reset the counter if and only if the event is of one of
  1262. X    *  the types we are expecting to get *and* was not generated by
  1263. X    *  XSendEvent ().
  1264. X    */
  1265. X    if (   event.type == KeyPress
  1266. X    && !event.xany.send_event
  1267. X       )
  1268. X    {
  1269. X      UpdateTimer (0);
  1270. X    }
  1271. X  }
  1272. X
  1273. X
  1274. X /*
  1275. X  *  Check the window queue for entries that are older than
  1276. X  *  CREATION_DELAY seconds.
  1277. X  */
  1278. X  ProcessQueue (queue, d, (Time) CREATION_DELAY);
  1279. X}
  1280. X
  1281. X
  1282. X
  1283. X/*
  1284. X *  Function for monitoring pointer movements
  1285. X *  -----------------------------------------
  1286. X */
  1287. Xstatic Void  QueryPointer (d)
  1288. XDisplay*  d;  /* display pointer */
  1289. X
  1290. X{
  1291. X  Window          dummy_w;            /* as it says                    */
  1292. X  Int             dummy_c;            /* as it says                    */
  1293. X  Mask            dummy_m;            /* as it says                    */
  1294. X  Int             root_x;             /* as it says                    */
  1295. X  Int             root_y;             /* as it says                    */
  1296. X  Int             corner;             /* corner index                  */
  1297. X  Int             i;                  /* loop counter                  */
  1298. X  static Window   root;               /* root window the pointer is on */
  1299. X  static Screen*  screen;             /* screen the pointer is on      */
  1300. X  static Int      prev_root_x = -1;   /* as it says                    */
  1301. X  static Int      prev_root_y = -1;   /* as it says                    */
  1302. X  static Boolean  first_call = TRUE;  /* as it says                    */
  1303. X
  1304. X
  1305. X /*
  1306. X  *  Have a guess...
  1307. X  */
  1308. X  if (first_call)
  1309. X  {
  1310. X    first_call = FALSE;
  1311. X    root = DefaultRootWindow (d);
  1312. X    screen = ScreenOfDisplay (d, DefaultScreen (d));
  1313. X  }
  1314. X
  1315. X
  1316. X /*
  1317. X  *  Find out whether the pointer has moved. Using XQueryPointer for this
  1318. X  *  is gross, but it also is the only way never to mess up propagation
  1319. X  *  of pointer events.
  1320. X  *
  1321. X  *  Remark : Unlike XNextEvent(), XPending () doesn't notice if the
  1322. X  *           connection to the server is lost. For this reason, earlier
  1323. X  *           versions of xautolock periodically called XNoOp (). But
  1324. X  *           why not let XQueryPointer () do the job for us, since
  1325. X  *           we now call it every INCREMENTAL_SLEEP seconds anyway?
  1326. X  */
  1327. X  if (!XQueryPointer (d, root, &root, &dummy_w, &root_x, &root_y,
  1328. X              &dummy_c, &dummy_c, &dummy_m))
  1329. X  {
  1330. X   /*
  1331. X    *  Pointer has moved to another screen, so let's find out which one.
  1332. X    */
  1333. X    for (i = -1; ++i < ScreenCount (d); ) 
  1334. X    {
  1335. X      if (root == RootWindow (d, i)) 
  1336. X      {
  1337. X        screen = ScreenOfDisplay (d, i);
  1338. X    break;
  1339. X      }
  1340. X    }
  1341. X  }
  1342. X
  1343. X  if (   root_x == prev_root_x
  1344. X      && root_y == prev_root_y
  1345. X     )
  1346. X  {
  1347. X   /*
  1348. X    *  If the pointer has not moved since the previous call and 
  1349. X    *  is inside one of the 4 corners, we act according to the
  1350. X    *  contents of the "corners" array.
  1351. X    */
  1352. X    if (   (corner = 0,
  1353. X           root_x <= corner_size
  1354. X        && root_y <= corner_size
  1355. X       )
  1356. X    || (corner++,
  1357. X           root_x >= WidthOfScreen  (screen) - corner_size - 1
  1358. X        && root_y <= corner_size
  1359. X       )
  1360. X    || (corner++,
  1361. X           root_x <= corner_size
  1362. X        && root_y >= HeightOfScreen (screen) - corner_size - 1
  1363. X       )
  1364. X    || (corner++,
  1365. X           root_x >= WidthOfScreen  (screen) - corner_size - 1
  1366. X        && root_y >= HeightOfScreen (screen) - corner_size - 1
  1367. X       )
  1368. X       )
  1369. X    {
  1370. X      switch (corners[corner])
  1371. X      {
  1372. X    case FORCE_LOCK :
  1373. X      if (timer < time_limit - corner_delay + 2)
  1374. X      {
  1375. X        UpdateTimer (time_limit - corner_delay + 2);
  1376. X      }
  1377. X      break;
  1378. X
  1379. X    case DONT_LOCK :
  1380. X      UpdateTimer (0);
  1381. X      }
  1382. X    }
  1383. X  }
  1384. X  else
  1385. X  {
  1386. X    prev_root_x = root_x;
  1387. X    prev_root_y = root_y;
  1388. X    UpdateTimer (0);
  1389. X  }
  1390. X}
  1391. X
  1392. X
  1393. X
  1394. X/*
  1395. X *  Function for deciding whether to lock
  1396. X *  -------------------------------------
  1397. X */
  1398. Xstatic Void  EvaluateCounter (d)
  1399. XDisplay*  d;  /* display pointer */
  1400. X
  1401. X{
  1402. X  static pid_t  locker_pid = 0;  /* child pid  */
  1403. X  static Time   prev_bell = 0;   /* as it says */
  1404. X
  1405. X
  1406. X /*
  1407. X  *  Find out whether we should do something special. This can
  1408. X  *  be one (or more) of the following :
  1409. X  *
  1410. X  *   - Wait for the previous locker (if any).
  1411. X  *   - Ring the bell, if we were asked to and are about to lock.
  1412. X  *   - Start up a new locker if the time limit has been reached.
  1413. X  */
  1414. X  if (locker_pid)
  1415. X  {
  1416. X    union wait  status;  /* childs process status */
  1417. X
  1418. X
  1419. X    if (!wait3 (&status, WNOHANG, (struct rusage*) NULL))
  1420. X    {
  1421. X      UpdateTimer (0);
  1422. X    }
  1423. X    else
  1424. X    {
  1425. X      locker_pid = 0;
  1426. X    }
  1427. X  }
  1428. X
  1429. X  if (   notify_lock
  1430. X      && timer + notify_margin > time_limit
  1431. X      && prev_bell < now - notify_margin - 1
  1432. X     )
  1433. X  {
  1434. X    prev_bell = now;
  1435. X    XBell (d, bell_percent);
  1436. X    XSync (d, 0);
  1437. X  }
  1438. X
  1439. X  if (timer > time_limit)
  1440. X  {
  1441. X    if (!locker_pid)
  1442. X    {
  1443. X      switch (locker_pid = vfork ())
  1444. X      {
  1445. X    case -1 :
  1446. X      locker_pid = 0;
  1447. X      break;
  1448. X
  1449. X    case 0 :
  1450. X      (Void) close (ConnectionNumber (d));
  1451. X      (Void) execl ("/bin/sh", "sh", "-c", locker, (String) NULL);
  1452. X      (Void) _exit (PROBLEMS);
  1453. X
  1454. X    default :
  1455. X      UpdateTimer (0);
  1456. X      }
  1457. X    }
  1458. X  }
  1459. X}
  1460. X
  1461. X
  1462. X
  1463. X
  1464. X/*
  1465. X *  Miscellaneous functions
  1466. X *  =======================
  1467. X *
  1468. X *  X Error handler
  1469. X *  ---------------
  1470. X */
  1471. X/*ARGSUSED*/
  1472. Xstatic Int  FetchFalseAlarm (d, event)
  1473. XDisplay*  d;      /* display pointer */
  1474. XXEvent    event;  /* error event     */
  1475. X
  1476. X{
  1477. X  return 0;
  1478. X}
  1479. X
  1480. X
  1481. X
  1482. X/*
  1483. X *  SIGHUP signal handler
  1484. X *  ---------------------
  1485. X */
  1486. Xstatic SigRet  DisableBySignal ()
  1487. X
  1488. X{
  1489. X /*
  1490. X  *  The order in which things are done is rather important here.
  1491. X  */
  1492. X  UpdateTimer (0);
  1493. X  sighupped = !sighupped;
  1494. X  (Void) signal (SIGHUP, (SigHandler) DisableBySignal);
  1495. X
  1496. X#ifndef HasVoidSignalReturn 
  1497. X  return 0;
  1498. X#endif /* HasVoidSignalReturn */
  1499. X}
  1500. X
  1501. X
  1502. X
  1503. X/*
  1504. X *  Lazy function
  1505. X *  -------------
  1506. X */
  1507. Xstatic Void  Sleep ()
  1508. X
  1509. X{
  1510. X  Int  i;  /* loop counter */
  1511. X
  1512. X
  1513. X  for (i = -1; ++i < INCREMENTAL_SLEEP; )
  1514. X  {
  1515. X    (Void) sleep (1);
  1516. X    UpdateTimer (timer + 1);
  1517. X    now++;
  1518. X  }
  1519. X}
  1520. X
  1521. X
  1522. X
  1523. X/*
  1524. X *  Function for finding out whether another xautolock is already running
  1525. X *  ---------------------------------------------------------------------
  1526. X */
  1527. Xstatic Void  CheckConnection (d, prog_name)
  1528. XDisplay*  d;          /* display pointer */
  1529. XString    prog_name;  /* as it says      */
  1530. X
  1531. X{
  1532. X  pid_t   pid;        /* as it says              */
  1533. X  Int     kill_val;   /* return value of kill () */
  1534. X  Window  r;          /* root window             */
  1535. X  Atom    property;   /* property atom           */
  1536. X  Atom    type;       /* property type atom      */
  1537. X  Int     format;     /* property format         */
  1538. X  Huge    nof_items;  /* actual number of items  */
  1539. X  Huge    after;      /* dummy                   */
  1540. X  pid_t*  contents;   /* actual property value   */
  1541. X
  1542. X
  1543. X  r = RootWindowOfScreen (ScreenOfDisplay (d, 0));
  1544. X  property = XInternAtom (d, "XAUTOLOCK_SEMAPHORE_PID", False);
  1545. X
  1546. X  XGrabServer (d);
  1547. X  XGetWindowProperty (d, r, property, 0L, 2L, False, AnyPropertyType,
  1548. X              &type, &format, &nof_items, &after,
  1549. X              (unsigned char**) &contents);
  1550. X
  1551. X  if (type == XA_INTEGER)
  1552. X  {
  1553. X   /*
  1554. X    *  This breaks if the other xautolock is not 
  1555. X    *  running on the same machine.
  1556. X    */
  1557. X    kill_val = kill (*contents, 0);
  1558. X
  1559. X    if (kill_val == 0)
  1560. X    {
  1561. X      Error2 ("%s is already running (PID %d).\n",
  1562. X          prog_name, *contents);
  1563. X      (Void) exit (PROBLEMS);
  1564. X    }
  1565. X  }
  1566. X
  1567. X  pid = getpid ();
  1568. X  XChangeProperty (d, r, property, XA_INTEGER, 8,
  1569. X               PropModeReplace, (Char*) &pid, sizeof (pid));
  1570. X  XUngrabServer (d);
  1571. X
  1572. X  XFree ((Char*) contents);
  1573. X}
  1574. X
  1575. X
  1576. X
  1577. X/*
  1578. X *  Function for selecting events on a tree of windows
  1579. X *  --------------------------------------------------
  1580. X */
  1581. Xstatic Void  SelectEvents (d, window, substructure_only)
  1582. XDisplay*  d;                  /* display pointer   */
  1583. XWindow    window;             /* window            */
  1584. XBoolean   substructure_only;  /* as it says        */
  1585. X
  1586. X{
  1587. X  Window             root;              /* root window of this window */
  1588. X  Window             parent;            /* parent of this window      */
  1589. X  Window*            children;          /* children of this window    */
  1590. X  Int                nof_children = 0;  /* number of children         */
  1591. X  Int                i;                 /* loop counter               */
  1592. X  XWindowAttributes  attribs;           /* attributes of the window   */
  1593. X
  1594. X
  1595. X /*
  1596. X  *  Start by querying the server about parent and child windows.
  1597. X  */
  1598. X  if (!XQueryTree (d, window, &root, &parent, &children, &nof_children))
  1599. X  {
  1600. X    return;
  1601. X  }
  1602. X
  1603. X
  1604. X /*
  1605. X  *  Build the appropriate event mask. The basic idea is that we don't
  1606. X  *  want to interfere with the normal event propagation mechanism if
  1607. X  *  we don't have to.
  1608. X  */
  1609. X  if (substructure_only)
  1610. X  {
  1611. X    XSelectInput (d, window, SubstructureNotifyMask);
  1612. X  }
  1613. X  else
  1614. X  {
  1615. X    if (parent == None)  /* the *real* rootwindow */
  1616. X    {
  1617. X      attribs.all_event_masks = 
  1618. X      attribs.do_not_propagate_mask = KeyPressMask;
  1619. X    }
  1620. X    else if (XGetWindowAttributes (d, window, &attribs) == 0)
  1621. X    {
  1622. X      return;
  1623. X    }
  1624. X
  1625. X    XSelectInput (d, window,   SubstructureNotifyMask
  1626. X                     | (  (  attribs.all_event_masks
  1627. X                   | attribs.do_not_propagate_mask)
  1628. X                & KeyPressMask));
  1629. X  }
  1630. X
  1631. X
  1632. X /*
  1633. X  *  Now do the same thing for all children.
  1634. X  */
  1635. X  for (i = -1; ++i < nof_children; )
  1636. X  {
  1637. X    SelectEvents (d, children[i], substructure_only);
  1638. X  }
  1639. X
  1640. X  if (nof_children != 0)
  1641. X  {
  1642. X    XFree ((Char*) children);
  1643. X  }
  1644. X}
  1645. X
  1646. X
  1647. X
  1648. X/*
  1649. X *  Main function
  1650. X *  -------------
  1651. X */
  1652. XInt  Main (argc, argv)
  1653. XInt     argc;    /* number of arguments */
  1654. XString  argv[];  /* array of arguments  */
  1655. X
  1656. X{
  1657. X  Display*  d;      /* display pointer */
  1658. X  Window    r;      /* root window     */
  1659. X  Int       s;      /* screen index    */
  1660. X  Queue     queue;  /* as it says      */
  1661. X
  1662. X
  1663. X /*
  1664. X  *  Find out whether there actually is a server on the other side...
  1665. X  */
  1666. X  if (   (d = XOpenDisplay ((String) NULL))
  1667. X      == (Display*) NULL
  1668. X     )
  1669. X  {
  1670. X    (Void) exit (PROBLEMS);
  1671. X  }
  1672. X
  1673. X
  1674. X /*
  1675. X  *  Some initializations.
  1676. X  */
  1677. X  ProcessOpts (d, argc, argv);
  1678. X
  1679. X  XSetErrorHandler ((XErrorHandler) FetchFalseAlarm);
  1680. X  CheckConnection (d, argv[0]);
  1681. X  (Void) signal (SIGHUP, (SigHandler) DisableBySignal);
  1682. X
  1683. X  XSync (d, 0);
  1684. X  (Void) sleep (INITIAL_SLEEP);
  1685. X
  1686. X  queue = NewQueue ();
  1687. X
  1688. X  for (s = -1; ++s < ScreenCount (d); )
  1689. X  {
  1690. X    AddToQueue (queue, r = RootWindowOfScreen (ScreenOfDisplay (d, s)));
  1691. X    SelectEvents (d, r, True);
  1692. X  }
  1693. X
  1694. X  if (close_output)
  1695. X  {
  1696. X    (Void) fclose (stdout);
  1697. X    (Void) fclose (stderr);
  1698. X  }
  1699. X
  1700. X
  1701. X /*
  1702. X  *  Main event loop.
  1703. X  */
  1704. X  forever
  1705. X  {
  1706. X    Sleep ();
  1707. X    ProcessEvents (d, queue);
  1708. X    QueryPointer (d);
  1709. X    EvaluateCounter (d);
  1710. X  }
  1711. X}
  1712. SHAR_EOF
  1713. if test 37774 -ne "`wc -c < 'xautolock.c'`"
  1714. then
  1715.     echo shar: error transmitting "'xautolock.c'" '(should have been 37774 characters)'
  1716. fi
  1717. fi # end of overwriting check
  1718. echo shar: extracting "'xautolock.man'" '(5718 characters)'
  1719. if test -f 'xautolock.man'
  1720. then
  1721.     echo shar: will not over-write existing file "'xautolock.man'"
  1722. else
  1723. sed 's/^X//' << \SHAR_EOF > 'xautolock.man'
  1724. X.TH xautolock l
  1725. X
  1726. X
  1727. X.SH NAME
  1728. X
  1729. Xxautolock \- locks X display after a period of inactivity
  1730. X
  1731. X
  1732. X.SH SYNOPSIS 
  1733. X
  1734. X\fBxautolock\fR [\fB\-help\fR] [\fB\-version\fR] 
  1735. X[\fB\-time\fR \fIminutes\fR] [\fB\-locker\fR \fIlocker\fR]
  1736. X          [\fB\-notify \fImargin\fR] [\fB\-bell \fIpercent\fR]
  1737. X[\fB\-corners\fR \fIxxxx\fR]
  1738. X          [\fB\-cornerdelay\fR \fIsecs\fR]
  1739. X[\fB\-cornersize\fR \fIpixels\fR] [\fB\-noclose\fR]
  1740. X.br 
  1741. X
  1742. X
  1743. X.SH DESCRIPTION 
  1744. X
  1745. XWhen xautolock is started, it monitors the user activity on the
  1746. Xworkstation. When no activity is detected within \fIminutes\fR
  1747. Xminutes, the screen is automatically locked, using the screen
  1748. Xlocker specified with the \fI\-locker\fR option. xautolock is
  1749. Xcapable of managing multiheaded displays.
  1750. X
  1751. XIn the presence of the \fI\-notify\fR option, a warning signal will
  1752. Xbe issued \fImargin\fR seconds before starting the locker. The
  1753. X\fI\-bell\fR option specifies the loudness of the signal in
  1754. X\fIpercent\fR.
  1755. X
  1756. XYou can tell xautolock to take special actions when you move
  1757. Xthe mouse into one of the corners of the display and leave it
  1758. Xthere, by using the \fI\-corners\fR,
  1759. X\fI\-cornerdelay\fR and \fI\-cornersize\fR
  1760. Xoptions. This works as follows :
  1761. X
  1762. XThe \fIxxxx\fR argument to the \fI\-corners\fR option must consist
  1763. Xof exactly 4 characters from the following set : '0', '+', '-'.
  1764. XEach one of these specifies what xautolock should do when the mouse
  1765. Xenters a small square area located in each of the corners of the
  1766. Xscreen. The corners are considered in the
  1767. Xfollowing order : top left, top right, bottom left, bottom right.
  1768. XA '0' indicates that xautolock should ignore the corner.
  1769. XA '+' indicates that xautolock should start the \fIlocker\fR 
  1770. Xafter \fIsecs\fR seconds, unless the mouse is moved, or keyboard
  1771. Xinput is received. A '-' indicates that xautolock not start the
  1772. X\fIlocker\fR at all. The \fIpixels\fR argument specifies the
  1773. Xsize in pixels of the corner areas.
  1774. X
  1775. XBy default xautolock closes stdout and stderr. This prevents the
  1776. Xscreenlocker from writing error messages to these files in case
  1777. Xyou manually lock your display. The \fI\-noclose\fR option causes
  1778. Xxautolock not to close stdout and stderr. This can be used for
  1779. Xdebugging.
  1780. X
  1781. XYou can also disable xautolock by sending it a SIGHUP
  1782. Xsignal. When disabled, it will not attempt to start the
  1783. Xscreenlocker. To re-enable it, send it another SIGHUP. This 
  1784. Xmethod is preferable to using SIGSTOP and SIGCONT, because
  1785. Xwhile SIGHUPped, xautolock will still be emptying its 
  1786. Xevent queue.
  1787. X
  1788. X
  1789. X.SH OPTIONS
  1790. X
  1791. X.TP 14
  1792. X\fB\-help\fR
  1793. XPrint a help message and exit.
  1794. X.TP 
  1795. X\fB\-version\fR
  1796. XPrint the version number and exit.
  1797. X.TP 
  1798. X\fB\-time\fR
  1799. XSpecifies the time-out interval. The default is 10 minutes,
  1800. Xthe minimum is 1 minute and the maximum is 1 hour.
  1801. X.TP 
  1802. X\fB\-locker\fR
  1803. XSpecifies the screen locker to be used. The default is
  1804. X"xlock 2>&- 1>&-". Your PATH is used to locate the program.
  1805. XNotice that if \fIlocker\fR contains several words, it must
  1806. Xbe specified between quotes.
  1807. X.TP 
  1808. X\fB\-notify\fR
  1809. XWarn the user \fImargin\fR seconds before locking. The
  1810. Xdefault is not to warn the user.
  1811. X.TP
  1812. X\fB\-bell\fR
  1813. XSpecifies the loudness of the notification signal. The default
  1814. Xis 40 percent. This option is only usefull in conjunction with
  1815. X\fI\-notify\fR.
  1816. X.TP 
  1817. X\fB\-corners\fR
  1818. XDefine special actions to be taken when the mouse
  1819. Xenters one of the corners of the display. The default is 0000,
  1820. Xwhich means that no special actions are taken.
  1821. X.TP 
  1822. X\fB\-cornerdelay\fR
  1823. XSpecifies the number of seconds to wait
  1824. Xbefore reacting to a '+' corner. The default is 5 seonds.
  1825. X.TP 
  1826. X\fB\-cornersize\fR
  1827. XSpecifies the size in pixels of the corner areas. The default is
  1828. X10 pixels.
  1829. X.TP 
  1830. X\fB\-noclose\fR
  1831. XDon't close stdout and stderr.
  1832. X
  1833. X
  1834. X.SH RESOURCES
  1835. X
  1836. X.TP 14
  1837. X.B time 
  1838. XSpecifies the time out period.
  1839. X.TP 14
  1840. X.B locker 
  1841. XSpecifies the screen locker. No quotes are needed, even if
  1842. Xyour screen locker command contains several words.
  1843. X.TP 14
  1844. X.B notify 
  1845. XSpecifies the notification margin.
  1846. X.TP 14
  1847. X.B bell 
  1848. XSpecifies the notification loudness.
  1849. X.TP 14
  1850. X.B corners 
  1851. XSpecifies the corner behaviour.
  1852. X.TP 14
  1853. X.B cornersize 
  1854. XSpecifies the size of the corner areas.
  1855. X.TP 14
  1856. X.B cornerdelay 
  1857. XSpecifies the delay of a '+' corner.
  1858. X.TP 14
  1859. X.B noclose 
  1860. XDon't close stdout and stderr.
  1861. X
  1862. X.TP 0
  1863. XResources can be specified in your \fI~/.Xdefaults\fR file either
  1864. Xfor class \fIXautolock\fR, or for whatever name you renamed
  1865. Xxautolock to. For example : if you have two copies of xautolock,
  1866. Xone called "xfreeze", and one called "xmonitor", then both will
  1867. Xunderstand the following :
  1868. X
  1869. X  Xautolock.corners: ++++
  1870. X
  1871. XIn addition, "xfreeze" will understand :
  1872. X
  1873. X  xfreeze.cornersize: 10
  1874. X
  1875. Xwhile "xmonitor" will understand :
  1876. X
  1877. X  xmonitor.cornersize: 5
  1878. X
  1879. X
  1880. X.SH KNOWN\ BUGS 
  1881. X
  1882. Xxautolock does not check whether \fIlocker\fR is available.
  1883. X
  1884. XThe xautolock resources have no resource class. 
  1885. X
  1886. X
  1887. X.SH COPYRIGHT
  1888. X
  1889. XCopyright 1990, 1992 by S. De Troch and MCE.
  1890. X
  1891. XPermission to use, copy, modify and distribute this software and the
  1892. Xsupporting documentation without fee is hereby granted, provided that :
  1893. X
  1894. X 1 : Both the above copyright notice and this permission notice
  1895. X     appear in all copies of both the software and the supporting
  1896. X     documentation.
  1897. X 2 : You don't make a profit out of it.
  1898. X
  1899. XTHE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  1900. XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
  1901. XEVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  1902. XDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
  1903. XOR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  1904. XTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  1905. XPERFORMANCE OF THIS SOFTWARE.
  1906. X
  1907. X
  1908. X.SH AUTHORS   
  1909. X
  1910. XStefan De Troch (detroch@imec.be),
  1911. XMichel Eyckmans (eyckmans@imec.be).
  1912. X
  1913. X
  1914. X.SH SPECIAL\ THANKS\ TO
  1915. X
  1916. XKris Croes (croes@imec.be).
  1917. SHAR_EOF
  1918. if test 5718 -ne "`wc -c < 'xautolock.man'`"
  1919. then
  1920.     echo shar: error transmitting "'xautolock.man'" '(should have been 5718 characters)'
  1921. fi
  1922. fi # end of overwriting check
  1923. #    End of shell archive
  1924. exit 0
  1925. -- 
  1926. --
  1927. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  1928. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  1929. Sunnyvale, California 94086            at&t: 408/522-9236
  1930.