home *** CD-ROM | disk | FTP | other *** search
/ gatling.ikk.sztaki.hu / gatling.ikk.sztaki.hu.zip / gatling.ikk.sztaki.hu / pub / xbusy.diff < prev    next >
Text File  |  2003-02-06  |  24KB  |  887 lines

  1. diff -urw --new-file /tmp/xidle/Makefile ./Makefile
  2. --- /tmp/xidle/Makefile    Fri Aug  8 23:18:12 1997
  3. +++ ./Makefile    Tue Feb  4 15:26:24 2003
  4. @@ -4,15 +4,15 @@
  5.  #-DDEBUG=1
  6.  CFLAGS=-g -I/usr/X11R6/include -I/usr/X11R6/include/X11 
  7.  
  8. -xidle:    xidle.o
  9. -    $(CC) $(LDFLAGS) -o xidle xidle.o -L/usr/X11R6/lib $(LIBES)
  10. +xbusy:    xbusy.o
  11. +    $(CC) $(LDFLAGS) -o xbusy xbusy.o -L/usr/X11R6/lib $(LIBES)
  12.  
  13. -install:    xidle xidle.1
  14. -    rm -f $(BINDIR)/xidle
  15. -    mv xidle $(BINDIR)/xidle
  16. -    rm -f $(MANDIR)/man1/xidle.1
  17. -    cp xidle.1 $(MANDIR)/man1/xidle.1
  18. +#install:    xidle xidle.1
  19. +#    rm -f $(BINDIR)/xidle
  20. +#    mv xidle $(BINDIR)/xidle
  21. +#    rm -f $(MANDIR)/man1/xidle.1
  22. +#    cp xidle.1 $(MANDIR)/man1/xidle.1
  23.  
  24.  clean:
  25. -    -rm -f xidle
  26. +    -rm -f xbusy
  27.      -rm -f *.o
  28. diff -urw --new-file /tmp/xidle/xbusy.c ./xbusy.c
  29. --- /tmp/xidle/xbusy.c    Thu Jan  1 01:00:00 1970
  30. +++ ./xbusy.c    Wed Feb  5 14:58:27 2003
  31. @@ -0,0 +1,460 @@
  32. +/*
  33. + * This program is a hacked version of Bennet Yee's xidle.
  34. + * Modified by Gabor Kiss, 2003.
  35. + *
  36. + * Original copyright message follows:
  37. + */
  38. +/*
  39. + * Copyright (C) 1990, Bennet Yee.  You may freely distribute this code as long
  40. + * as this notice is intact.  If you make any modifications in your
  41. + * distribution, you must clearly document them.  If you distribute this code
  42. + * or any derivative thereof, it must be given at no charge to all parties
  43. + * on terms identical to those prescribed herein.  All distributions must
  44. + * contain source code.
  45. + *
  46. + * This software is provided with absolutely no warranty.
  47. + *
  48. + * If you have questions, you can contact me at bsy@cs.cmu.edu
  49. + */
  50. +#ifndef lint
  51. +    static char copyright[] = "\n\
  52. +Copyright (C) 1990, Bennet Yee.  You may freely distribute this code as long\n\
  53. +as this notice is intact.  If you make any modifications in your\n\
  54. +distribution, you must clearly document them.  If you distribute this code\n\
  55. +or any derivative thereof, it must be provided at no charge to all parties\n\
  56. +on terms identical to those prescribed herein.  All distributions must\n\
  57. +contain source code.\n\
  58. +\n\
  59. +This software is provided with absolutely no warranty.\n\
  60. +";
  61. +#endif /* lint */
  62. +
  63. +#include <X11/Xlib.h>
  64. +#include <X11/Xatom.h>
  65. +#include <X11/Xresource.h>
  66. +#include <X11/Xutil.h>
  67. +#include <X11/cursorfont.h>
  68. +#include <stdio.h>
  69. +#include <ctype.h>
  70. +#include <signal.h>
  71. +#include <errno.h>
  72. +#include <syslog.h>
  73. +#include <sys/param.h>
  74. +#include <sys/types.h>
  75. +#include <sys/file.h>
  76. +#include <sys/time.h>
  77. +
  78. +extern int    errno;
  79. +
  80. +#ifdef    DEBUG
  81. +#define    D(x)    fprintf x
  82. +#define    D2(x)    fprintf x
  83. +#define    D3(x)    fprintf x
  84. +#else
  85. +#define    D(x)
  86. +#define    D2(x)
  87. +#define    D3(x)
  88. +#endif
  89. +
  90. +#define    MAXDISPLAY        1024
  91. +#define    MAXNAME            1024
  92. +#define    MAXRESOURCE        1024
  93. +
  94. +#define    HIDE_POLL        50    /* < one minute */
  95. +#define    POLL            60
  96. +#define    MAX_ELAPSED_MSEC    (5*1000)
  97. +#define    UPDATE_CLOCK_IVL    (5*60*1000)
  98. +#define    UPDATE_WIN_IVL        (60*1000)
  99. +
  100. +long    poll = POLL;
  101. +Time    max_elapsed_msec = MAX_ELAPSED_MSEC,
  102. +    update_clock_ivl = UPDATE_CLOCK_IVL,
  103. +    update_win_ivl = UPDATE_WIN_IVL;
  104. +time_t    kezdes;                // kissg
  105. +int    kemeny_munka = 1;        // kissg
  106. +
  107. +XrmOptionDescRec tbl[] = {
  108. +{"-display",".display",XrmoptionSepArg, (caddr_t) ""},
  109. +{"-name",".name",XrmoptionSepArg, (caddr_t) "xbusy"},
  110. +// kissg {"-console",".console",XrmoptionSepArg, (caddr_t) "/dev/console"},
  111. +{"-poll",".poll",XrmoptionSepArg, (caddr_t) NULL},
  112. +{"-error",".error",XrmoptionSepArg, (caddr_t) NULL},
  113. +{"-sync",".sync",XrmoptionSepArg, (caddr_t) NULL},
  114. +{"-wcheck",".win",XrmoptionSepArg, (caddr_t) NULL},
  115. +{"-xrm",NULL,XrmoptionResArg, (caddr_t) NULL},
  116. +{"-nomouse",".nomouse",XrmoptionNoArg, (caddr_t) "on"},
  117. +{"-nodaemon",".nodaemon",XrmoptionNoArg, (caddr_t) "on"}
  118. +};
  119. +
  120. +// kissg char console[MAXPATHLEN] = "/dev/console";
  121. +
  122. +usage()
  123. +{
  124. +    fprintf(stderr,"Usage:  xbusy [-display dpy] [-name n] [-xrm rm] [-poll N] [-error N] [-sync N] [-wcheck N]\n");
  125. +    exit(1);
  126. +}
  127. +
  128. +#define    STATE_NORM    0
  129. +#define    STATE_HIDE    1
  130. +#define    STATE_BUSY    2
  131. +
  132. +int    state = STATE_NORM;
  133. +
  134. +void hide(int signum){ state = STATE_HIDE;}
  135. +void cont(int signum){ state = STATE_NORM;}
  136. +void fake(int signum){ state = STATE_BUSY;}
  137. +void kampec(int signum)    // kissg
  138. +{
  139. +    if (kemeny_munka) {
  140. +        time_t munkaido = time(NULL) - kezdes;
  141. +        syslog(LOG_INFO, "%d seconds of hard work confirmed", munkaido);
  142. +    }
  143. +    syslog(LOG_INFO, "exiting");
  144. +    exit(0);
  145. +}
  146. +
  147. +main(ac,av)
  148. +int    ac;
  149. +char    **av;
  150. +{
  151. +    Display            *dpy;
  152. +    XEvent            ev;
  153. +    XKeyPressedEvent    *kev = (XKeyPressedEvent *) &ev;
  154. +    XrmDatabase        db, rmdb;
  155. +    char            *type, display[MAXDISPLAY], name[MAXNAME];
  156. +    XrmValue        val;
  157. +    char            *tmp_string(), *Tmp_string();
  158. +    Atom            typeA;
  159. +    int            format;
  160. +    unsigned long        nitems, bytes;
  161. +    char            *prop;
  162. +    fd_set            in_fds, in_fd_init;
  163. +    int            Xfd;
  164. +    struct timeval        time_out, time_of_server_base, keytime;
  165. +    int            get_time, time_of_server_base_valid,
  166. +                orig_timeout;
  167. +    Time            current_time, key, server_base, elapsed,
  168. +                elapsed_mseconds, update_clock_mseconds,
  169. +                update_win_mseconds;
  170. +    int            ignore();
  171. +    int            nomouse = 0;
  172. +    int            nodaemon = 0;
  173. +// (*signal())();
  174. +
  175. +    openlog("xbusy",LOG_PID,LOG_DAEMON);
  176. +D3((stderr,"initializing RM\n"));
  177. +    XrmInitialize();
  178. +    db = (XrmDatabase) 0;
  179. +D3((stderr,"parsing cmds\n"));
  180. +    XrmParseCommand(&db,tbl,sizeof tbl/sizeof tbl[0],"xbusy",&ac,av);
  181. +D3((stderr,"db points to %X\n",db));
  182. +    if (ac != 1) {
  183. +        fprintf(stderr,"Option not understood: %s\n",av[1]);
  184. +        usage();
  185. +        exit(1);
  186. +    }
  187. +    strcpy(name,"xbusy");
  188. +
  189. +#define    RSRC(x,X) (XrmGetResource(db, \
  190. +                tmp_string(name,x), \
  191. +                Tmp_string(name,X), \
  192. +                &type, \
  193. +                &val))
  194. +#define    RSRCSTR(x,X) (RSRC(x,X) && !strcmp(type,"String"))
  195. +
  196. +    if (RSRCSTR(".name",".Name")) {
  197. +        strcpy(name,(char *)val.addr);
  198. +    }
  199. +    locase(name);
  200. +    strcpy(display,"");
  201. +    if (RSRCSTR(".display",".Display")) {
  202. +        strcpy(display,(char *)val.addr);
  203. +    }
  204. +    dpy = XOpenDisplay(display);
  205. +    if (!dpy) {
  206. +        fprintf(stderr,"No display\n");
  207. +        exit(1);
  208. +    }
  209. +
  210. +    /*
  211. +     * now that the display is open, we can merge in the
  212. +     * XA_RESOURCE_MANAGER rdb entry
  213. +     */
  214. +    if (XGetWindowProperty(dpy,
  215. +            RootWindow(dpy,DefaultScreen(dpy)),
  216. +            XA_RESOURCE_MANAGER,
  217. +            0,
  218. +            (int)(((unsigned)~0)>>1),
  219. +            0,
  220. +            XA_STRING,
  221. +            &typeA,
  222. +            &format,
  223. +            &nitems,
  224. +            &bytes,
  225. +            (unsigned char**)&prop) == Success && typeA != None) {
  226. +        if (format != 8) {
  227. +            fprintf(stderr,"xbusy: warning: your RESOURCE MANAGER property is not an 8-bit string!\n");
  228. +            goto cont_xdefault;
  229. +        }
  230. +        rmdb = XrmGetStringDatabase(prop);
  231. +        XrmMergeDatabases(db,&rmdb);
  232. +        XFree(prop);
  233. +        db = rmdb;
  234. +    }
  235. +cont_xdefault:
  236. +    {
  237. +        char        *getenv();
  238. +        char        *home = getenv("HOME");
  239. +        char        buf[MAXPATHLEN];
  240. +        XrmDatabase    xdefaults;
  241. +        if (home) {
  242. +            strcpy(buf,home);
  243. +            strcat(buf,"/.Xdefaults");
  244. +            xdefaults = XrmGetFileDatabase(buf);
  245. +            if (xdefaults) {
  246. +                XrmMergeDatabases(db,&xdefaults);
  247. +                db = xdefaults;
  248. +            }
  249. +        }
  250. +    }
  251. +//    if (RSRCSTR(".console",".Console")) {
  252. +//        strcpy(console,(char *)val.addr);
  253. +//    }
  254. +    if (RSRCSTR(".poll",".Poll")) {
  255. +        poll = atoi((char *)val.addr);
  256. +    }
  257. +    if (RSRCSTR(".error",".Error")) {
  258. +        max_elapsed_msec = 1000 * atoi((char *)val.addr);
  259. +    }
  260. +    if (RSRCSTR(".sync",".Sync")) {
  261. +        update_clock_ivl = 1000 * atoi((char *)val.addr);
  262. +    }
  263. +    if (RSRCSTR(".wcheck",".Wcheck")) {
  264. +        update_win_ivl = 1000 * atoi((char *)val.addr);
  265. +    }
  266. +    if (RSRC(".nomouse",".NoMouse")) {
  267. +        nomouse = 1;
  268. +D((stderr,"nomouse\n"));
  269. +    }
  270. +    if (RSRC(".nodaemon",".NoDaemon")) {
  271. +        nodaemon = 1;
  272. +D((stderr,"nodaemon\n"));
  273. +    }
  274. +
  275. +    if (!nodaemon) {
  276. +        if (-1 == daemon(0, 0)) {
  277. +            fprintf(stderr, "xbusy: cannot go background\n");
  278. +            exit(1);
  279. +        }
  280. +    }
  281. +    syslog(LOG_INFO, "starting");
  282. +
  283. +    XSetErrorHandler(ignore);
  284. +
  285. +    FD_ZERO(&in_fd_init);
  286. +    Xfd = ConnectionNumber(dpy);
  287. +    FD_SET(Xfd,&in_fd_init);
  288. +    recurse_win(dpy,RootWindow(dpy,DefaultScreen(dpy)),nomouse);
  289. +D((stderr,"looping\n"));
  290. +    elapsed_mseconds = 0;
  291. +    update_clock_mseconds = 0;
  292. +    update_win_mseconds = 0;
  293. +    get_time = 1;
  294. +    time_of_server_base_valid = 0;
  295. +    kezdes = time(NULL);
  296. +    (void) signal(SIGTSTP,hide);
  297. +    (void) signal(SIGCONT,cont);
  298. +    (void) signal(SIGUSR1,fake);
  299. +    (void) signal(SIGHUP,kampec);
  300. +    (void) signal(SIGINT,kampec);
  301. +    (void) signal(SIGTERM,kampec);
  302. +    for (;;) {
  303. +        in_fds = in_fd_init;
  304. +        if (state != STATE_HIDE) time_out.tv_sec = poll;
  305. +        else time_out.tv_sec = HIDE_POLL;
  306. +        time_out.tv_usec = 0;
  307. +        orig_timeout = time_out.tv_sec;
  308. +        errno = 0;
  309. +        if (select(Xfd+1,&in_fds,(fd_set *) 0, (fd_set *) 0,&time_out) == -1 && errno != EINTR) {
  310. +            perror("xbusy");
  311. +            fprintf(stderr,"xbusy: select failed\n");
  312. +            exit(1);
  313. +        }
  314. +        if (errno == EINTR) {
  315. +            get_time = 1;
  316. +            /*
  317. +             * Kernel may or may not modify the time_out value,
  318. +             * so we could lose time here.  This only happens
  319. +             * when we get a signal, however, so is not a big deal.
  320. +             */
  321. +            elapsed = 1000 * (orig_timeout - time_out.tv_sec);
  322. +            current_time += elapsed;
  323. +        } else if (FD_ISSET(Xfd,&in_fds)) {
  324. +D((stderr,"normal ev proc\n"));
  325. +            XNextEvent(dpy,&ev);
  326. +            /* check for more */
  327. +            while (XPending(dpy)) {
  328. +                XNextEvent(dpy,&ev);
  329. +            }
  330. +            key = kev->time;
  331. +            if (get_time) {
  332. +                get_time = 0;
  333. +                (void) gettimeofday(&time_of_server_base,(struct timezone *) 0);
  334. +                elapsed_mseconds = max_elapsed_msec + 1;
  335. +                /* force an update */
  336. +                current_time = key;
  337. +                server_base = current_time;
  338. +                time_of_server_base_valid = 1;
  339. +            }
  340. +            elapsed = key - current_time;
  341. +            current_time = key;
  342. +            if (!kemeny_munka) {
  343. +                kemeny_munka = 1;
  344. +                kezdes = time(NULL);
  345. +            }
  346. +        } else {
  347. +            elapsed = 1000 * orig_timeout;
  348. +            current_time += elapsed;
  349. +            if (kemeny_munka) {
  350. +                time_t munkaido = time(NULL) - kezdes  - orig_timeout;
  351. +                syslog(LOG_INFO,
  352. +                    "%d seconds of hard work confirmed",
  353. +                    munkaido);
  354. +                kemeny_munka = 0;
  355. +            }
  356. +        }
  357. +        /*
  358. +         * current_time == key iff got an keypress (poll>0)
  359. +         * otherwise, current_time > key
  360. +         */
  361. +
  362. +        /* update timers */
  363. +        elapsed_mseconds += elapsed;
  364. +        update_clock_mseconds += elapsed;
  365. +        update_win_mseconds += elapsed;
  366. +
  367. +        /* check expiration */
  368. +        if (update_win_mseconds > update_win_ivl) {
  369. +            update_win_mseconds = 0;
  370. +            recurse_win(dpy,RootWindow(dpy,DefaultScreen(dpy)),nomouse);
  371. +        }
  372. +        if (update_clock_mseconds > update_clock_ivl) {
  373. +            update_clock_mseconds = 0;
  374. +            get_time = 1;
  375. +        }
  376. +D((stderr,"elapsed_mseconds=%d,max_elapsed_msec=%d\n", elapsed_mseconds, max_elapsed_msec));
  377. +        if (elapsed_mseconds > max_elapsed_msec && time_of_server_base_valid) {
  378. +            elapsed_mseconds = 0;
  379. +            switch (state) {
  380. +            case STATE_NORM:
  381. +D((stderr,"current_time=%d,key=%d\n", current_time, key));
  382. +                if (current_time == key) {
  383. +                    keytime.tv_sec = (key - server_base)/1000 + time_of_server_base.tv_sec;
  384. +D((stderr,"keytime=%d\n", keytime.tv_sec));
  385. +                    keytime.tv_usec = 0;    /* ignore it */
  386. +// kissg                update(console,&keytime);
  387. +                }
  388. +                break;
  389. +            case STATE_BUSY:
  390. +                /*
  391. +                 * Presumably, we will not get any events
  392. +                 * from the server, so we can not periodically
  393. +                 * resynchronize our timers.  They still run
  394. +                 * and give us relative time, ....
  395. +                 */
  396. +                (void) gettimeofday(&keytime,(struct timezone *) 0);
  397. +                keytime.tv_usec = 0;    /* ignore it */
  398. +// kissg            update(console,&keytime);
  399. +                break;
  400. +            case STATE_HIDE:
  401. +                break;
  402. +            }
  403. +        }
  404. +    }
  405. +}
  406. +
  407. +/* since utimes has to go to the fs, we want to avoid it if poss. */
  408. +
  409. +#if 0 //kissg
  410. +update(file,now)
  411. +char        *file;
  412. +struct timeval    *now;
  413. +{
  414. +    struct timeval    t[2];
  415. +    t[1] = t[0] = *now;
  416. +    if (utimes(file,t) < 0) {
  417. +        perror(file);
  418. +    }
  419. +}
  420. +#endif
  421. +
  422. +recurse_win(dpy,w,nomouse)
  423. +Display    *dpy;
  424. +Window    w;
  425. +int    nomouse;
  426. +{
  427. +    Window            *child_list, root, parent;
  428. +    int            nchild;
  429. +    XWindowAttributes    attr;
  430. +    int            mask;
  431. +
  432. +    mask = KeyPressMask;
  433. +    if (!nomouse) {
  434. +        mask |= PointerMotionMask;
  435. +    }
  436. +    /*
  437. +     * if nobody else is interested in keypresses,
  438. +     * this may be a subwindow the keypresses of which should
  439. +     * propagate to a parent window where it is handled.
  440. +     */
  441. +    if (XGetWindowAttributes(dpy,w,&attr)) {
  442. +        if (attr.all_event_masks & mask) {
  443. +            XSelectInput(dpy,w,mask);
  444. +        } else D((stderr,"nobody interested in %d %X\n",w,w));
  445. +        if (XQueryTree(dpy,w,&root,&parent,&child_list,&nchild)) {
  446. +            while (--nchild >= 0) {
  447. +                recurse_win(dpy,child_list[nchild]);
  448. +            }
  449. +            XFree((char *) child_list);
  450. +        } else D((stderr,"can not query %d %X\n",w,w));
  451. +    }
  452. +    else D((stderr,"No attr for window %d %X\n",w,w));
  453. +}
  454. +
  455. +ignore(dpy,err_ev)
  456. +Display        *dpy;
  457. +XErrorEvent    *err_ev;
  458. +{
  459. +    ;
  460. +}
  461. +
  462. +locase(str)
  463. +char    *str;
  464. +{
  465. +    char    ch;
  466. +    while (ch = *str) {
  467. +        if (isupper(ch)) *str = ch + ('a'-(int)'A');
  468. +        ++str;
  469. +    }
  470. +}
  471. +
  472. +char *tmp_string(name,prop)
  473. +char    *name,*prop;
  474. +{
  475. +    static char    buf[MAXRESOURCE];
  476. +
  477. +    strcpy(buf,name);
  478. +    strcat(buf,prop);
  479. +    return buf;
  480. +}
  481. +
  482. +char *Tmp_string(name,prop)
  483. +char    *name,*prop;
  484. +{
  485. +    static char    buf[MAXRESOURCE];
  486. +
  487. +    strcpy(buf,name);
  488. +    strcat(buf,prop);
  489. +    buf[0] += 'A' - (int) 'a';
  490. +    return buf;
  491. +}
  492. diff -urw --new-file /tmp/xidle/xidle.c ./xidle.c
  493. --- /tmp/xidle/xidle.c    Fri Aug  8 23:07:53 1997
  494. +++ ./xidle.c    Thu Jan  1 01:00:00 1970
  495. @@ -1,391 +0,0 @@
  496. -/*
  497. - * Copyright (C) 1990, Bennet Yee.  You may freely distribute this code as long
  498. - * as this notice is intact.  If you make any modifications in your
  499. - * distribution, you must clearly document them.  If you distribute this code
  500. - * or any derivative thereof, it must be given at no charge to all parties
  501. - * on terms identical to those prescribed herein.  All distributions must
  502. - * contain source code.
  503. - *
  504. - * This software is provided with absolutely no warranty.
  505. - *
  506. - * If you have questions, you can contact me at bsy@cs.cmu.edu
  507. - */
  508. -#ifndef lint
  509. -    static char copyright[] = "\n\
  510. -Copyright (C) 1990, Bennet Yee.  You may freely distribute this code as long\n\
  511. -as this notice is intact.  If you make any modifications in your\n\
  512. -distribution, you must clearly document them.  If you distribute this code\n\
  513. -or any derivative thereof, it must be provided at no charge to all parties\n\
  514. -on terms identical to those prescribed herein.  All distributions must\n\
  515. -contain source code.\n\
  516. -\n\
  517. -This software is provided with absolutely no warranty.\n\
  518. -";
  519. -#endif /* lint */
  520. -
  521. -#include <X11/Xlib.h>
  522. -#include <X11/Xatom.h>
  523. -#include <X11/Xresource.h>
  524. -#include <X11/Xutil.h>
  525. -#include <X11/cursorfont.h>
  526. -#include <stdio.h>
  527. -#include <ctype.h>
  528. -#include <signal.h>
  529. -#include <errno.h>
  530. -#include <sys/param.h>
  531. -#include <sys/types.h>
  532. -#include <sys/file.h>
  533. -#include <sys/time.h>
  534. -
  535. -extern int    errno;
  536. -
  537. -#ifdef    DEBUG
  538. -#define    D(x)    fprintf x
  539. -#define    D2(x)    fprintf x
  540. -#define    D3(x)    fprintf x
  541. -#else
  542. -#define    D(x)
  543. -#define    D2(x)
  544. -#define    D3(x)
  545. -#endif
  546. -
  547. -#define    MAXDISPLAY        1024
  548. -#define    MAXNAME            1024
  549. -#define    MAXRESOURCE        1024
  550. -
  551. -#define    HIDE_POLL        50    /* < one minute */
  552. -#define    POLL            60
  553. -#define    MAX_ELAPSED_MSEC    (5*1000)
  554. -#define    UPDATE_CLOCK_IVL    (5*60*1000)
  555. -#define    UPDATE_WIN_IVL        (60*1000)
  556. -
  557. -long    poll = POLL;
  558. -Time    max_elapsed_msec = MAX_ELAPSED_MSEC,
  559. -    update_clock_ivl = UPDATE_CLOCK_IVL,
  560. -    update_win_ivl = UPDATE_WIN_IVL;
  561. -
  562. -XrmOptionDescRec tbl[] = {
  563. -{"-display",".display",XrmoptionSepArg, (caddr_t) ""},
  564. -{"-name",".name",XrmoptionSepArg, (caddr_t) "xidle"},
  565. -{"-console",".console",XrmoptionSepArg, (caddr_t) "/dev/console"},
  566. -{"-poll",".poll",XrmoptionSepArg, (caddr_t) NULL},
  567. -{"-error",".error",XrmoptionSepArg, (caddr_t) NULL},
  568. -{"-sync",".sync",XrmoptionSepArg, (caddr_t) NULL},
  569. -{"-wcheck",".win",XrmoptionSepArg, (caddr_t) NULL},
  570. -{"-xrm",NULL,XrmoptionResArg, (caddr_t) NULL},
  571. -{"-nomouse",".nomouse",XrmoptionNoArg, (caddr_t) "on"}
  572. -};
  573. -
  574. -char console[MAXPATHLEN] = "/dev/console";
  575. -
  576. -usage()
  577. -{
  578. -    fprintf(stderr,"Usage:  xidle [-display dpy] [-name n] [-xrm rm] [-poll N] [-error N] [-sync N] [-wcheck N]\n");
  579. -}
  580. -
  581. -#define    STATE_NORM    0
  582. -#define    STATE_HIDE    1
  583. -#define    STATE_BUSY    2
  584. -
  585. -int    state = STATE_NORM;
  586. -
  587. -hide(){    state = STATE_HIDE;}
  588. -cont(){    state = STATE_NORM;}
  589. -fake(){ state = STATE_BUSY;}
  590. -
  591. -main(ac,av)
  592. -int    ac;
  593. -char    **av;
  594. -{
  595. -    Display            *dpy;
  596. -    XEvent            ev;
  597. -    XKeyPressedEvent    *kev = (XKeyPressedEvent *) &ev;
  598. -    XrmDatabase        db, rmdb;
  599. -    char            *type, display[MAXDISPLAY], name[MAXNAME];
  600. -    XrmValue        val;
  601. -    char            *tmp_string(), *Tmp_string();
  602. -    Atom            typeA;
  603. -    int            format;
  604. -    unsigned long        nitems, bytes;
  605. -    char            *prop;
  606. -    fd_set            in_fds, in_fd_init;
  607. -    int            Xfd;
  608. -    struct timeval        time_out, time_of_server_base, keytime;
  609. -    int            get_time, time_of_server_base_valid,
  610. -                orig_timeout;
  611. -    Time            current_time, key, server_base, elapsed,
  612. -                elapsed_mseconds, update_clock_mseconds,
  613. -                update_win_mseconds;
  614. -    int            ignore();
  615. -    int            nomouse;
  616. -// (*signal())();
  617. -
  618. -D3((stderr,"initializing RM\n"));
  619. -    XrmInitialize();
  620. -    db = (XrmDatabase) 0;
  621. -D3((stderr,"parsing cmds\n"));
  622. -    XrmParseCommand(&db,tbl,sizeof tbl/sizeof tbl[0],"xidle",&ac,av);
  623. -D3((stderr,"db points to %X\n",db));
  624. -    if (ac != 1) {
  625. -        fprintf(stderr,"Option not understood: %s\n",av[1]);
  626. -        usage();
  627. -        exit(1);
  628. -    }
  629. -    strcpy(name,"xidle");
  630. -    if (XrmGetResource(db,tmp_string(name,".name"),Tmp_string(name,".Name"),&type,&val) && !strcmp(type,"String")) {
  631. -        strcpy(name,(char *)val.addr);
  632. -    }
  633. -    locase(name);
  634. -    strcpy(display,"");
  635. -    if (XrmGetResource(db,tmp_string(name,".display"),Tmp_string(name,".Display"),&type,&val) && !strcmp(type,"String")) {
  636. -        strcpy(display,(char *)val.addr);
  637. -    }
  638. -    dpy = XOpenDisplay(display);
  639. -    if (!dpy) {
  640. -        fprintf(stderr,"No display\n");
  641. -        exit(1);
  642. -    }
  643. -
  644. -    /*
  645. -     * now that the display is open, we can merge in the
  646. -     * XA_RESOURCE_MANAGER rdb entry
  647. -     */
  648. -    if (XGetWindowProperty(dpy,RootWindow(dpy,DefaultScreen(dpy)),XA_RESOURCE_MANAGER,0,(int)(((unsigned)~0)>>1),0,XA_STRING,&typeA,&format,&nitems,&bytes,&prop) == Success && typeA != None) {
  649. -        if (format != 8) {
  650. -            fprintf(stderr,"xidle: warning: your RESOURCE MANAGER property is not an 8-bit string!\n");
  651. -            goto cont_xdefault;
  652. -        }
  653. -        rmdb = XrmGetStringDatabase(prop);
  654. -        XrmMergeDatabases(db,&rmdb);
  655. -        XFree(prop);
  656. -        db = rmdb;
  657. -    }
  658. -cont_xdefault:
  659. -    {
  660. -        char        *getenv();
  661. -        char        *home = getenv("HOME");
  662. -        char        buf[MAXPATHLEN];
  663. -        XrmDatabase    xdefaults;
  664. -        if (home) {
  665. -            strcpy(buf,home);
  666. -            strcat(buf,"/.Xdefaults");
  667. -            xdefaults = XrmGetFileDatabase(buf);
  668. -            if (xdefaults) {
  669. -                XrmMergeDatabases(db,&xdefaults);
  670. -                db = xdefaults;
  671. -            }
  672. -        }
  673. -    }
  674. -    if (XrmGetResource(db,tmp_string(name,".console"),Tmp_string(name,".Console"),&type,&val) && !strcmp(type,"String")) {
  675. -        strcpy(console,(char *)val.addr);
  676. -    }
  677. -    if (XrmGetResource(db,tmp_string(name,".poll"),Tmp_string(name,".Poll"),&type,&val) && !strcmp(type,"String")) {
  678. -        poll = atoi((char *)val.addr);
  679. -    }
  680. -    if (XrmGetResource(db,tmp_string(name,".error"),Tmp_string(name,".Error"),&type,&val) && !strcmp(type,"String")) {
  681. -        max_elapsed_msec = 1000 * atoi((char *)val.addr);
  682. -    }
  683. -    if (XrmGetResource(db,tmp_string(name,".sync"),Tmp_string(name,".Sync"),&type,&val) && !strcmp(type,"String")) {
  684. -        update_clock_ivl = 1000 * atoi((char *)val.addr);
  685. -    }
  686. -    if (XrmGetResource(db,tmp_string(name,".wcheck"),Tmp_string(name,".Wcheck"),&type,&val) && !strcmp(type,"String")) {
  687. -        update_win_ivl = 1000 * atoi((char *)val.addr);
  688. -    }
  689. -    nomouse = 0;
  690. -    if (XrmGetResource(db,tmp_string(name,".nomouse"),Tmp_string(name,".NoMouse"),&type,&val)) {
  691. -        nomouse = 1;
  692. -D((stderr,"nomouse\n"));
  693. -    }
  694. -
  695. -    XSetErrorHandler(ignore);
  696. -
  697. -    FD_ZERO(&in_fd_init);
  698. -    Xfd = ConnectionNumber(dpy);
  699. -    FD_SET(Xfd,&in_fd_init);
  700. -    recurse_win(dpy,RootWindow(dpy,DefaultScreen(dpy)),nomouse);
  701. -D((stderr,"looping\n"));
  702. -    elapsed_mseconds = 0;
  703. -    update_clock_mseconds = 0;
  704. -    update_win_mseconds = 0;
  705. -    get_time = 1;
  706. -    time_of_server_base_valid = 0;
  707. -    (void) signal(SIGTSTP,hide);
  708. -    (void) signal(SIGCONT,cont);
  709. -    (void) signal(SIGUSR1,fake);
  710. -    for (;;) {
  711. -        in_fds = in_fd_init;
  712. -        if (state != STATE_HIDE) time_out.tv_sec = poll;
  713. -        else time_out.tv_sec = HIDE_POLL;
  714. -        time_out.tv_usec = 0;
  715. -        orig_timeout = time_out.tv_sec;
  716. -        errno = 0;
  717. -        if (select(Xfd+1,&in_fds,(fd_set *) 0, (fd_set *) 0,&time_out) == -1 && errno != EINTR) {
  718. -            perror("xidle");
  719. -            fprintf(stderr,"xidle: select failed\n");
  720. -            exit(1);
  721. -        }
  722. -        if (errno == EINTR) {
  723. -            get_time = 1;
  724. -            /*
  725. -             * Kernel may or may not modify the time_out value,
  726. -             * so we could lose time here.  This only happens
  727. -             * when we get a signal, however, so is not a big deal.
  728. -             */
  729. -            elapsed = 1000 * (orig_timeout - time_out.tv_sec);
  730. -            current_time += elapsed;
  731. -        } else if (FD_ISSET(Xfd,&in_fds)) {
  732. -D((stderr,"normal ev proc\n"));
  733. -            XNextEvent(dpy,&ev);
  734. -            /* check for more */
  735. -            while (XPending(dpy)) {
  736. -                XNextEvent(dpy,&ev);
  737. -            }
  738. -            key = kev->time;
  739. -            if (get_time) {
  740. -                get_time = 0;
  741. -                (void) gettimeofday(&time_of_server_base,(struct timezone *) 0);
  742. -                elapsed_mseconds = max_elapsed_msec + 1;
  743. -                /* force an update */
  744. -                current_time = key;
  745. -                server_base = current_time;
  746. -                time_of_server_base_valid = 1;
  747. -            }
  748. -            elapsed = key - current_time;
  749. -            current_time = key;
  750. -        } else {
  751. -            elapsed = 1000 * orig_timeout;
  752. -            current_time += elapsed;
  753. -        }
  754. -        /*
  755. -         * current_time == key iff got an keypress (poll>0)
  756. -         * otherwise, current_time > key
  757. -         */
  758. -
  759. -        /* update timers */
  760. -        elapsed_mseconds += elapsed;
  761. -        update_clock_mseconds += elapsed;
  762. -        update_win_mseconds += elapsed;
  763. -
  764. -        /* check expiration */
  765. -        if (update_win_mseconds > update_win_ivl) {
  766. -            update_win_mseconds = 0;
  767. -            recurse_win(dpy,RootWindow(dpy,DefaultScreen(dpy)),nomouse);
  768. -        }
  769. -        if (update_clock_mseconds > update_clock_ivl) {
  770. -            update_clock_mseconds = 0;
  771. -            get_time = 1;
  772. -        }
  773. -D((stderr,"elapsed_mseconds=%d,max_elapsed_msec=%d\n", elapsed_mseconds, max_elapsed_msec));
  774. -        if (elapsed_mseconds > max_elapsed_msec && time_of_server_base_valid) {
  775. -            elapsed_mseconds = 0;
  776. -            switch (state) {
  777. -            case STATE_NORM:
  778. -D((stderr,"current_time=%d,key=%d\n", current_time, key));
  779. -                if (current_time == key) {
  780. -                    keytime.tv_sec = (key - server_base)/1000 + time_of_server_base.tv_sec;
  781. -D((stderr,"keytime=%d\n", keytime.tv_sec));
  782. -                    keytime.tv_usec = 0;    /* ignore it */
  783. -                    update(console,&keytime);
  784. -                }
  785. -                break;
  786. -            case STATE_BUSY:
  787. -                /*
  788. -                 * Presumably, we will not get any events
  789. -                 * from the server, so we can not periodically
  790. -                 * resynchronize our timers.  They still run
  791. -                 * and give us relative time, ....
  792. -                 */
  793. -                (void) gettimeofday(&keytime.tv_sec,(struct timezone *) 0);
  794. -                keytime.tv_usec = 0;    /* ignore it */
  795. -                update(console,&keytime);
  796. -                break;
  797. -            case STATE_HIDE:
  798. -                break;
  799. -            }
  800. -        }
  801. -    }
  802. -}
  803. -
  804. -/* since utimes has to go to the fs, we want to avoid it if poss. */
  805. -
  806. -update(file,now)
  807. -char        *file;
  808. -struct timeval    *now;
  809. -{
  810. -    struct timeval    t[2];
  811. -    t[1] = t[0] = *now;
  812. -    if (utimes(file,t) < 0) {
  813. -        perror(file);
  814. -    }
  815. -}
  816. -
  817. -recurse_win(dpy,w,nomouse)
  818. -Display    *dpy;
  819. -Window    w;
  820. -int    nomouse;
  821. -{
  822. -    Window            *child_list, root, parent;
  823. -    int            nchild;
  824. -    XWindowAttributes    attr;
  825. -    int            mask;
  826. -
  827. -    mask = KeyPressMask;
  828. -    if (!nomouse) {
  829. -        mask |= PointerMotionMask;
  830. -    }
  831. -    /*
  832. -     * if nobody else is interested in keypresses,
  833. -     * this may be a subwindow the keypresses of which should
  834. -     * propagate to a parent window where it is handled.
  835. -     */
  836. -    if (XGetWindowAttributes(dpy,w,&attr)) {
  837. -        if (attr.all_event_masks & mask) {
  838. -            XSelectInput(dpy,w,mask);
  839. -        } else D((stderr,"nobody interested in %d %X\n",w,w));
  840. -        if (XQueryTree(dpy,w,&root,&parent,&child_list,&nchild)) {
  841. -            while (--nchild >= 0) {
  842. -                recurse_win(dpy,child_list[nchild]);
  843. -            }
  844. -            XFree((char *) child_list);
  845. -        } else D((stderr,"can not query %d %X\n",w,w));
  846. -    }
  847. -    else D((stderr,"No attr for window %d %X\n",w,w));
  848. -}
  849. -
  850. -ignore(dpy,err_ev)
  851. -Display        *dpy;
  852. -XErrorEvent    *err_ev;
  853. -{
  854. -    ;
  855. -}
  856. -
  857. -locase(str)
  858. -char    *str;
  859. -{
  860. -    char    ch;
  861. -    while (ch = *str) {
  862. -        if (isupper(ch)) *str = ch + ('a'-(int)'A');
  863. -        ++str;
  864. -    }
  865. -}
  866. -
  867. -char *tmp_string(name,prop)
  868. -char    *name,*prop;
  869. -{
  870. -    static char    buf[MAXRESOURCE];
  871. -
  872. -    strcpy(buf,name);
  873. -    strcat(buf,prop);
  874. -    return buf;
  875. -}
  876. -
  877. -char *Tmp_string(name,prop)
  878. -char    *name,*prop;
  879. -{
  880. -    static char    buf[MAXRESOURCE];
  881. -
  882. -    strcpy(buf,name);
  883. -    strcat(buf,prop);
  884. -    buf[0] += 'A' - (int) 'a';
  885. -    return buf;
  886. -}
  887.