home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume18 / xalarm30 / part04 < prev    next >
Encoding:
Text File  |  1992-07-07  |  50.2 KB  |  1,863 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!darwin.sura.net!mips!msi!dcmartin
  3. From: Simon Marshall <S.Marshall@sequent.cc.hull.ac.uk>
  4. Subject: v18i005: Xalarm 3.04, Part04/05
  5. Message-ID: <1992Jul8.154525.20553@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. References: <csx-18i002-xalarm-3.04@uunet.UU.NET>
  10. Date: Wed, 8 Jul 1992 15:45:25 GMT
  11. Approved: dcmartin@msi.com
  12. Lines: 1849
  13.  
  14. Submitted-by: Simon Marshall <S.Marshall@sequent.cc.hull.ac.uk>
  15. Posting-number: Volume 18, Issue 5
  16. Archive-name: xalarm-3.04/part04
  17.  
  18. # this is part.04 (part 4 of a multipart archive)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file fns.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 4; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping fns.c'
  36. else
  37. echo 'x - continuing file fns.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'fns.c' &&
  39. X        exit (-1);
  40. X        }
  41. X    } else if ((STREQUAL (argv[i], DAEMONOPTION1)) or
  42. X         (STREQUAL (argv[i], DAEMONOPTION2))) {
  43. X        if (++i == last) {
  44. X        (void) fprintf (stderr, "No daemon date to parse alarm file with.\n");
  45. X        exit (-1);
  46. X        } else if (ISINVALID (*days = DaysTo (argv[i], instance = Daemon))) {
  47. X        (void) fprintf (stderr, "Can't use daemon date: %s", xalarm.errormessage);
  48. X        exit (-1);
  49. X        } else if (*days == 0) {
  50. X        (void) fprintf (stderr, "Zero days means daemon would not sleep!\n");
  51. X        exit (-1);
  52. X        }
  53. X    } else
  54. X        /* Just copy the option.
  55. X         */
  56. X        (*args)[(*argc)++] = XtNewString (argv[i]);
  57. X
  58. X    for (i=1; i<last; i++) {
  59. X    ch = argv[i];
  60. X    while (*ch != '\0')
  61. X        *(ch++) = ' ';
  62. X    }
  63. X
  64. X    return (instance);
  65. }
  66. X
  67. X
  68. X
  69. /* 
  70. X * Fork off an xalarm process which will repeatedly parse the
  71. X * alarm file.
  72. X */
  73. X
  74. void StartDaemon (days, argv, argc)
  75. X  String  *argv;
  76. X  int        days, argc;
  77. {
  78. X    Display    *display;
  79. X    String     displayname = DisplayName (argv, argc);
  80. X    int     pid, kids;
  81. X    time_t     abstime;
  82. X    struct tm  *now;
  83. X
  84. X    /* 
  85. X     * Fork off the daemon.
  86. X     */
  87. X
  88. X    switch (pid = (int) fork ()) {
  89. X     case -1:
  90. X    perror ("xalarm");
  91. X    exit (-1);
  92. X     case 0:
  93. X    (void) signal (SIGUSR1, SIG_IGN);
  94. X    (void) signal (SIGUSR2, (SIGRET (*)()) KillDaemon);
  95. X    break;
  96. X     default:
  97. X    (void) printf ("xalarm: Daemon started (%d).\n", pid);
  98. X    exit (0);
  99. X    }
  100. X
  101. X    /* 
  102. X     * Open the display for the daemon and parse & sleep until we 
  103. X     * loose the connection.
  104. X     */
  105. X
  106. X    if (NONNIL (Display *, (display = XOpenDisplay (displayname)))) {
  107. X    (void) time (&abstime);
  108. X    now = localtime (&abstime);
  109. X
  110. X    while (True) {
  111. X        /* 
  112. X         * Start any alarms in the alarm file, then wait for them 
  113. X         * to finish.
  114. X         */
  115. X        if (ISWEEKLYD (days))
  116. X        kids = ParseAlarmFile (7 - now->tm_wday, argv, argc);
  117. X        else
  118. X        kids = ParseAlarmFile (days - 1, argv, argc);
  119. X
  120. X        while (kids-- > 0)
  121. X        (void) wait ((int *) NULL);
  122. X
  123. X        /* 
  124. X         * Sleep until the next time, then test the connection.
  125. X         */
  126. X        (void) time (&abstime);
  127. X        now = localtime (&abstime);
  128. X        (void) sleep ((unsigned)
  129. X        (30 + ((ISWEEKLYD (days) ?
  130. X            (days = 7) - now->tm_wday + 1 : days) * SECSIN1DAY) -
  131. X         (now->tm_hour * SECSIN1HR) - (now->tm_min * SECSIN1MIN) - now->tm_sec));
  132. X
  133. X        XSync (display, False);
  134. X    }
  135. X    }
  136. }
  137. X
  138. X
  139. X
  140. /* 
  141. X * Signal handler for a daemon - it just kills the process.
  142. X */
  143. X
  144. static SIGRET KillDaemon (sig, code, scp, addr)
  145. X  int               sig, code;
  146. X  struct sigcontext  *scp;
  147. X  char              *addr;
  148. {
  149. X    (void) fprintf (stderr, "xalarm: Daemon killed (%d).\n", getpid ());
  150. X    exit (0);
  151. }
  152. X
  153. X
  154. X
  155. /* 
  156. X * Signal handler for a normal alarm - it just kills the process.
  157. X */
  158. X
  159. SIGRET KillAlarm (sig, code, scp, addr)
  160. X  int               sig, code;
  161. X  struct sigcontext  *scp;
  162. X  char              *addr;
  163. {
  164. X    Quit ((Widget) NULL, (XtPointer) NULL, (XtPointer) NULL);
  165. }
  166. X
  167. X
  168. X
  169. /* 
  170. X * We add the time outs for the alarm & warnings.
  171. X * The warnings are added only if there is time enuf to go.
  172. X * ie. if "-time +10 -warn 15" you will get nowt.
  173. X * "-time +10 -warn 9" will, however, give you a warning in 1 min.
  174. X */
  175. X
  176. void AddTimeOuts ()
  177. {
  178. X    unsigned long   timeout = SUMTIMEOUTS (xalarm.dateout, xalarm.timeout);
  179. X    int         i;
  180. X    
  181. X    xalarm.settime = (unsigned long) time ((time_t *) NULL);
  182. X    xalarm.offtime = xalarm.settime + (timeout / MSECSIN1SEC);
  183. X
  184. X    for (i=0; i<xalarm.numwarnings; i++)
  185. X    if (timeout > xalarm.warnings[i])
  186. X        xalarm.timeoutid[i] =
  187. X        XtAppAddTimeOut (xalarm.appcon,
  188. X                 TIMEOUT (timeout - xalarm.warnings[i]),
  189. X                 (XtTimerCallbackProc) Warning,
  190. X                 (XtPointer) (xalarm.warnings[i] / MSECSIN1MIN));
  191. X    xalarm.timeoutid[xalarm.numwarnings] =
  192. X    XtAppAddTimeOut (xalarm.appcon, TIMEOUT (timeout),
  193. X             (XtTimerCallbackProc) WakeUp, (XtPointer) NULL);
  194. }
  195. X  
  196. X   
  197. X
  198. /* 
  199. X * Set the window manager name of the given widget.
  200. X */
  201. X
  202. void SetWMName (widget, name)
  203. X  Widget   widget;
  204. X  String   name;
  205. {
  206. X    Display        *display = XtDisplay (xalarm.toplevel);
  207. X    String         wmname[1];
  208. X    XTextProperty   property;
  209. X
  210. X    if (not XtIsRealized (widget))
  211. X    XtRealizeWidget (widget);
  212. X
  213. X    wmname[0] = name;
  214. X    if (XStringListToTextProperty (wmname, 1, &property)) {
  215. X    XSetWMName (display, XtWindow (widget), &property);
  216. X    XSetWMIconName (display, XtWindow (widget), &property);
  217. X    XtFree (property.value);
  218. X    }
  219. }
  220. X
  221. X
  222. X
  223. /* 
  224. X * Reset the tracker so it calls itself.
  225. X */
  226. X
  227. XXtIntervalId ResetTracker (tracker, clientdata, triggered)
  228. X  XtTimerCallbackProc     tracker;
  229. X  XtPointer         clientdata;
  230. X  int             triggered;
  231. {
  232. X    time_t     now;
  233. X    struct tm  *clock;
  234. X
  235. X    (void) time (&now);
  236. X    clock = localtime (&now);
  237. X    /*
  238. X     * 60 seconds from when it triggered.
  239. X     */
  240. X    return (XtAppAddTimeOut (xalarm.appcon, 
  241. X                 TIMEOUT (MSECSIN1SEC * (60 - clock->tm_sec + triggered)),
  242. X                 tracker, clientdata));
  243. }
  244. X
  245. X
  246. X
  247. /* 
  248. X * Set the geometry of the given widget.
  249. X */
  250. X
  251. void SetGeometry (widget)
  252. X  Widget   widget;
  253. {
  254. X    Dimension     width, height, borderwidth;
  255. X        
  256. X    if (not XtIsRealized (widget))
  257. X    XtRealizeWidget (widget);
  258. X
  259. X    XtVaGetValues (widget, XtNwidth, &width, XtNheight, &height,
  260. X           XtNborderWidth, &borderwidth, NULL);
  261. X
  262. X    if (STREQUAL (xalarm.geometry, NOGEOMETRY))
  263. X    CentreWidgetUnderPointer (widget, width, height, borderwidth);
  264. X    else
  265. X    ParseGeometry (widget, width, height, borderwidth, xalarm.geometry);
  266. }
  267. X
  268. X
  269. X
  270. /* 
  271. X * Move the given widget so that it is directly underneath the pointer.
  272. X */
  273. X
  274. static void CentreWidgetUnderPointer (widget, width, height, borderwidth)
  275. X  Widget      widget;
  276. X  Dimension   width, height, borderwidth;
  277. {
  278. X    Window        root, child;
  279. X    int        x, y, dummy;
  280. X    unsigned int   mask;
  281. X
  282. X    width += (borderwidth * 2);
  283. X    height += (borderwidth * 2);
  284. X
  285. X    if (XQueryPointer (XtDisplay (widget), XtWindow (widget),
  286. X               &root, &child, &x, &y, &dummy, &dummy, &mask)) {
  287. X    x = MAX (0, MIN (x - ((int) width / 2),
  288. X             XWidthOfScreen (XtScreen (widget)) - (int) width));
  289. X    y = MAX (0, MIN (y - ((int) height / 2),
  290. X             XHeightOfScreen (XtScreen (widget)) - (int) height));
  291. X    XtVaSetValues (widget, XtNx, (XtArgVal) x, XtNy, (XtArgVal) y, NULL);
  292. X    }
  293. }
  294. X
  295. X
  296. X
  297. /* 
  298. X * Move +/ resize the given widget so that it has the given geometry.
  299. X */
  300. X
  301. static void ParseGeometry (widget, currentwidth, currentheight, borderwidth, geometry)
  302. X  Widget      widget;
  303. X  Dimension   currentwidth, currentheight, borderwidth;
  304. X  String      geometry;
  305. {
  306. X    unsigned int   width = (unsigned int) currentwidth,
  307. X           height = (unsigned int) currentheight;
  308. X    int        x = 0, y = 0, mask;
  309. X
  310. X    mask = XParseGeometry (geometry, &x, &y, &width, &height);
  311. X
  312. X    if (mask & WidthValue)
  313. X    XtVaSetValues (widget, XtNwidth, (XtArgVal) width, NULL);
  314. X    if (mask & HeightValue)
  315. X    XtVaSetValues (widget, XtNheight, (XtArgVal) height, NULL);
  316. X    if (mask & (WidthValue | HeightValue))
  317. X    XtVaSetValues (widget, XtNallowShellResize, (XtArgVal) False, NULL);
  318. X
  319. X    if (not (mask & (XValue | YValue)))
  320. X    CentreWidgetUnderPointer (widget, width, height, borderwidth);
  321. X    else {
  322. X    if (mask & XNegative)
  323. X        x = x + XWidthOfScreen (XtScreen (widget)) - (int) width;
  324. X    if (mask & YNegative)
  325. X        y = y + XHeightOfScreen (XtScreen (widget)) - (int) height;
  326. X    XtVaSetValues (widget, XtNx, (XtArgVal) x, XtNy, (XtArgVal) y, NULL);
  327. X    }
  328. }
  329. X
  330. X
  331. X
  332. /* 
  333. X * Make sure that the widget's right side is visible.
  334. X * For resizing popups.
  335. X */
  336. X
  337. void EnsureNotGrownOffScreen (widget)
  338. X  Widget   widget;
  339. {
  340. X    Position     x;
  341. X    Dimension     width, borderwidth, screenwidth = XWidthOfScreen (XtScreen (widget));
  342. X
  343. X    XtVaGetValues (widget, XtNx, &x, XtNwidth, &width, XtNborderWidth, &borderwidth,
  344. X           NULL);
  345. X    width += (borderwidth * 2);
  346. X    if (screenwidth > width)
  347. X    XtVaSetValues (widget, XtNx, (XtArgVal) MIN (x, screenwidth - width), NULL);
  348. }
  349. X
  350. X
  351. X
  352. /* 
  353. X * Pull out any display arg.
  354. X */
  355. X
  356. String DisplayName (argv, argc)
  357. X  String  *argv;
  358. X  int        argc;
  359. {
  360. X    String   displayname = (String) NULL;
  361. X    int      i;
  362. X
  363. X    for (i=1; i<argc; i++)
  364. X    if ((strcmp (argv[i], "-display") == 0) or (strcmp (argv[i], "-d") == 0))
  365. X        if (i < argc-1)
  366. X        displayname = argv[i+1];
  367. X        else {
  368. X        (void) printf ("xalarm: No display to open.\n");
  369. X        exit (-1);
  370. X        }
  371. X
  372. X    return (displayname);
  373. }
  374. X
  375. X
  376. X
  377. /* 
  378. X * Make a sound, if that's what's wanted.
  379. X */
  380. void Audio (sound)
  381. X  String   sound;
  382. {
  383. X    if ((STREQUAL (sound, BELL)) or (STREQUAL (sound, BEEP)))
  384. X    XBell (XtDisplay (xalarm.toplevel), xalarm.volume);
  385. X    else if (not STREQUAL (sound, QUIET))
  386. X    if (system (sound) != 0)
  387. X        perror (sound);
  388. }
  389. X
  390. X
  391. X
  392. /* 
  393. X * Returns a string concated from the given array of strings.
  394. X * Separates the strings with a newline.
  395. X *
  396. X * Hacked from various books on X & Xt.
  397. X */
  398. X
  399. String Concat (strings, n)
  400. X  String  *strings;
  401. X  int        n;
  402. {
  403. X    String        buffer;
  404. X    unsigned int   i, len = 0;
  405. X
  406. X    if (n <= 1)
  407. X    return ((String) NULL);
  408. X
  409. X    for (i=1; i<n; i++)
  410. X    len += strlen (strings[i]);
  411. X    len += (n-1);
  412. X
  413. X    buffer = XtMalloc (len+1);
  414. X    buffer[0] = '\0';
  415. X    for (i=1; i<n; i++) {
  416. X    if (i > 1)
  417. X        (void) strcat (buffer, "\n");
  418. X    (void) strcat (buffer, strings[i]);
  419. X    }
  420. X
  421. X    return (buffer);
  422. }
  423. X
  424. X
  425. X
  426. /* 
  427. X * Replace each newline by a space.  Returns the new string.
  428. X */
  429. X
  430. String ReplaceNewlines (str)
  431. X  String   str;
  432. {
  433. X    String   s, newstr = XtNewString (str);
  434. X
  435. X    if (NONNIL (String, s = newstr))
  436. X    do
  437. X        if (*s == '\n')
  438. X        *s = ' ';
  439. X    while (*(s++) != '\0');
  440. X
  441. X    return (newstr);
  442. }
  443. X
  444. X
  445. X
  446. /* 
  447. X * Return the next word in str, starting at position chpos in the 
  448. X * string.  The returned word is in lower case.
  449. X */
  450. X
  451. String NextWord (str, chpos)
  452. X  String   str;
  453. X  int       *chpos;
  454. {
  455. X    String   word;
  456. X    int      start, i;
  457. X
  458. X    while (isspace (str[*chpos]))
  459. X    (*chpos)++;
  460. X
  461. X    start = *chpos;
  462. X    while ((not isspace (str[*chpos])) and (str[*chpos] != '\0'))
  463. X    (*chpos)++;
  464. X
  465. X    if ((str[*chpos] == '\0') and (start == *chpos))
  466. X    return ("");
  467. X    else {
  468. X    word = XtMalloc (*chpos - start + 1);
  469. X    for (i=0; i<(*chpos-start); i++)
  470. X        word[i] = DOWNCASE (str[start+i]);
  471. X    word[*chpos-start] = '\0';
  472. X    
  473. X    return (word);
  474. X    }
  475. }
  476. X
  477. X
  478. X
  479. /* 
  480. X * Returns true iff the string contains a valid integer.
  481. X */
  482. X
  483. Boolean IsInteger (str)
  484. X  String   str;
  485. {
  486. X    if (*str == '+')
  487. X    str++;
  488. X    while (*str != '\0')
  489. X    if (not isdigit (*str++))
  490. X        return (False);
  491. X    return (True);
  492. }
  493. X
  494. X
  495. X
  496. /* 
  497. X * Return the user, users' home directory & host names.
  498. X */
  499. X
  500. String UserName ()
  501. {
  502. X    static String   name = (String) NULL;
  503. X
  504. X    if (NIL (String, name))
  505. #if defined (USEGETLOGIN)
  506. X    name = (String) getlogin ();
  507. #elif defined (USECUSERID)
  508. X    (void) cuserid (name = XtMalloc ((Cardinal) L_cuserid + 1));
  509. #elif defined (USEGETPWUID)
  510. X    name = XtNewString (getpwuid (getuid ())->pw_name);
  511. #else
  512. X    name = getenv ("USER");
  513. #endif
  514. X
  515. X    return ((NIL (String, name)) ? NOTKNOWN : name);
  516. }
  517. X
  518. X
  519. X
  520. String HomeDirectory ()
  521. {
  522. X    static String   name = (String) NULL;
  523. X
  524. X    if (NIL (String, name))
  525. #if defined (USEGETPWUID)
  526. X    name = XtNewString (getpwuid (getuid ())->pw_dir);
  527. #else
  528. X    name = getenv ("HOME");
  529. #endif
  530. X
  531. X    return ((NIL (String, name)) ? NOTKNOWN : name);
  532. }
  533. X
  534. X
  535. X
  536. String MachineName ()
  537. {
  538. #if defined (USEGETHOSTNAME)
  539. X    static char   name[TEXT];
  540. X
  541. X    return ((gethostname (name, TEXT) < 0) ? NOTKNOWN : name);
  542. #elif defined (USEUNAME)
  543. X    static struct utsname   name;
  544. X
  545. X    return ((uname (&name) < 0) ? NOTKNOWN : name.nodename);
  546. #else
  547. X    return (NOTKNOWN);
  548. #endif
  549. }
  550. X
  551. X
  552. X
  553. /* 
  554. X * This function generates a random number and stuffs it down the pipe.
  555. X */
  556. X
  557. void Quit (widget, clientdata, calldata)
  558. X  Widget      widget;
  559. X  XtPointer   clientdata, calldata;
  560. {
  561. X    XtDestroyApplicationContext (xalarm.appcon);
  562. X    exit (0);
  563. }
  564. SHAR_EOF
  565. echo 'File fns.c is complete' &&
  566. chmod 0644 fns.c ||
  567. echo 'restore of fns.c failed'
  568. Wc_c="`wc -c < 'fns.c'`"
  569. test 18097 -eq "$Wc_c" ||
  570.     echo 'fns.c: original size 18097, current size' "$Wc_c"
  571. rm -f _shar_wnt_.tmp
  572. fi
  573. # ============= fullpath ==============
  574. if test -f 'fullpath' -a X"$1" != X"-c"; then
  575.     echo 'x - skipping fullpath (File already exists)'
  576.     rm -f _shar_wnt_.tmp
  577. else
  578. > _shar_wnt_.tmp
  579. echo 'x - extracting fullpath (Text)'
  580. sed 's/^X//' << 'SHAR_EOF' > 'fullpath' &&
  581. #!/bin/sh
  582. X
  583. PATH="$PATH:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin:/usr/games:/usr/local/lib/emacs/etc:/usr/local/emacs/etc."
  584. export PATH
  585. X
  586. case $1 in
  587. X    -quick)    mode=-quick
  588. X        shift;;
  589. X    *)    mode=;;
  590. esac
  591. X
  592. loc=`which $1 2>/dev/null`
  593. case "$loc" in
  594. X    # For a Tek:
  595. X    "command is /"*)
  596. X        loc=`echo $loc | sed 's/command is //'`;;
  597. X    # For normal whiches:
  598. X    "$1"*|"no $1"*|"command is "*)
  599. X        loc=;;
  600. esac
  601. X
  602. if test ! "$loc" = "" -a "$mode" = "-quick"; then
  603. X    echo Assuming $1 is $loc. >&2
  604. else
  605. X    echo -n "Where is your \"$1\"? [$loc] " >&2
  606. X    read ans
  607. X
  608. X    if test ! "$ans" = ""; then
  609. X        loc=$ans
  610. X    fi
  611. X    if test "$loc" = ""; then
  612. X        loc=$1
  613. X    fi
  614. X    if test -d "$loc"; then
  615. X        case "$loc" in
  616. X            *"/")    loc=$loc$1;;
  617. X            *)    loc=$loc/$1;;
  618. X        esac
  619. X    fi
  620. X    if test ! -f "$loc"; then
  621. X        echo Warning: \"$loc\" does not exist. >&2
  622. X    fi
  623. fi
  624. X
  625. echo $loc
  626. SHAR_EOF
  627. chmod 0755 fullpath ||
  628. echo 'restore of fullpath failed'
  629. Wc_c="`wc -c < 'fullpath'`"
  630. test 850 -eq "$Wc_c" ||
  631.     echo 'fullpath: original size 850, current size' "$Wc_c"
  632. rm -f _shar_wnt_.tmp
  633. fi
  634. # ============= patchlevel.h ==============
  635. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  636.     echo 'x - skipping patchlevel.h (File already exists)'
  637.     rm -f _shar_wnt_.tmp
  638. else
  639. > _shar_wnt_.tmp
  640. echo 'x - extracting patchlevel.h (Text)'
  641. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  642. #define        XALARMVERSION    "3.04"
  643. SHAR_EOF
  644. chmod 0644 patchlevel.h ||
  645. echo 'restore of patchlevel.h failed'
  646. Wc_c="`wc -c < 'patchlevel.h'`"
  647. test 30 -eq "$Wc_c" ||
  648.     echo 'patchlevel.h: original size 30, current size' "$Wc_c"
  649. rm -f _shar_wnt_.tmp
  650. fi
  651. # ============= times.c ==============
  652. if test -f 'times.c' -a X"$1" != X"-c"; then
  653.     echo 'x - skipping times.c (File already exists)'
  654.     rm -f _shar_wnt_.tmp
  655. else
  656. > _shar_wnt_.tmp
  657. echo 'x - extracting times.c (Text)'
  658. sed 's/^X//' << 'SHAR_EOF' > 'times.c' &&
  659. /*
  660. X      Copyright (c) 1991, 1992 by Simon Marshall, University of Hull, UK
  661. X
  662. X           If you still end up late, don't blame me!
  663. X                       
  664. X  Permission to use, copy, modify, distribute, and sell this software and its
  665. X       documentation for any purpose and without fee is hereby granted,
  666. X    provided that the above copyright notice appear in all copies and that
  667. X    both that copyright notice and this permission notice appear in
  668. X               supporting documentation.
  669. X                       
  670. X  This software is provided AS IS with no warranties of any kind.  The author
  671. X    shall have no liability with respect to the infringement of copyrights,
  672. X     trade secrets or any patents by this file or any part thereof.  In no
  673. X      event will the author be liable for any lost revenue or profits or
  674. X          other special, indirect and consequential damages.
  675. */
  676. X
  677. /* 
  678. X * Parse times.
  679. X */
  680. X
  681. X
  682. X
  683. #include "xalarm.h"
  684. #include "dates.h"
  685. X
  686. #define        VALUE(ch)    ((int) (ch) - (int) '0')
  687. #define        INSTRING(ch, s)    (((ch) != '\0') and (index ((s), (ch))))
  688. X
  689. X
  690. long        TimeToMilliSeconds();
  691. Boolean        ParseTimeString();
  692. extern time_t    time();
  693. extern struct tm *localtime();
  694. X
  695. X
  696. X
  697. extern AlarmData xalarm;
  698. X
  699. X
  700. X
  701. /* 
  702. X * Convert the string into milliseconds, or INVALID if 
  703. X * not recognised.
  704. X * Recognises quite a lot, really, but doesn't like non absolute times 
  705. X * having "am" or "pm" etc.
  706. X */    
  707. X
  708. long TimeToMilliSeconds (timestr)
  709. X  String   timestr;
  710. {
  711. X    Boolean     in24hrformat;
  712. X    int     hours, minutes, seconds;
  713. X    time_t     abstime;
  714. X    struct tm  *now;
  715. X
  716. X    if (not ParseTimeString (timestr, &hours, &minutes, &in24hrformat))
  717. X    return ((long) INVALID);
  718. X
  719. X    if ((*timestr == '+') or (STREQUAL (timestr, NOW)))
  720. X    seconds = (hours * SECSIN1HR) + (minutes * SECSIN1MIN);
  721. X    else {
  722. X    (void) time (&abstime);
  723. X    now = localtime (&abstime);
  724. X    seconds = ((hours - now->tm_hour) * SECSIN1HR) +
  725. X        ((minutes - now->tm_min) * SECSIN1MIN) - now->tm_sec;
  726. X    if ((seconds < 0) and (not in24hrformat))
  727. X        seconds += (12 * SECSIN1HR);
  728. X    }
  729. X
  730. X    if ((xalarm.dateout > 0) or ((xalarm.dateout == 0) and (seconds >= 0)))
  731. X    return ((long) seconds * MSECSIN1SEC);
  732. X    else {
  733. X    ADDERROR (TIMEPASSED, (String) NULL);
  734. X    return ((long) INVALID);
  735. X    }
  736. }
  737. X
  738. X
  739. X
  740. /* 
  741. X * Parse that string.  Robbed and hacked from xcal (3.2) by Peter 
  742. X * Collinson et al.
  743. X */
  744. X
  745. Boolean ParseTimeString (str, hrs, mins, in24hrf)
  746. X  String    str;
  747. X  int        *hrs, *mins;
  748. X  Boolean  *in24hrf;
  749. {
  750. X    enum      {Hhmm, hHmm, hh_mm, hhMm, hhmM, AmPm, aMpM} state;
  751. X    Boolean   relative, finished = False;
  752. X    int       numdigits = 0;
  753. X    char     *s = str, badtime[TEXT];
  754. X              
  755. X    RESETERROR ();
  756. X
  757. X    if (relative = (*str == '+'))
  758. X    str++;
  759. X    else if (STREQUAL (str, NOW)) {
  760. X    *hrs = *mins = 0;
  761. X    return (True);
  762. X    } else if (STREQUAL (str, NOON)) {
  763. X    *hrs = 12;
  764. X    *mins = 0;
  765. X    return (*in24hrf = True);
  766. X    }
  767. X
  768. X    while (*s != '\0')
  769. X    if (isdigit (*s++))
  770. X        numdigits++;
  771. X
  772. X    if (relative)
  773. X    switch (numdigits) {
  774. X     case 1: state = hhmM; break;
  775. X     case 2: state = hhMm; break;
  776. X     case 3: state = hHmm; break;
  777. X     case 4: state = Hhmm; break;
  778. X     default:
  779. X        (void) sprintf (badtime, "just %d", numdigits);
  780. X        ADDERROR (WRONGNUMDIGITS, badtime);
  781. X        return (False);
  782. X    }
  783. X    else
  784. X    switch (numdigits) {
  785. X     case 1:
  786. X     case 2:
  787. X     case 4: state = Hhmm; break;
  788. X     case 3: state = hHmm; break;
  789. X     default:
  790. X        (void) sprintf (badtime, "just %d", numdigits);
  791. X        ADDERROR (WRONGNUMDIGITS, badtime);
  792. X        return (False);
  793. X    }
  794. X
  795. X    *hrs = *mins = 0;
  796. X    *in24hrf = False;
  797. X
  798. X    while (not finished)
  799. X    switch (state) {
  800. X     case Hhmm:
  801. X        if (isdigit (*str)) {
  802. X        *hrs = VALUE (*str++);
  803. X        state = hHmm;
  804. X        continue;
  805. X        } else {
  806. X        ADDERROR (UNRECOGNISED, str);
  807. X        return (False);
  808. X        }
  809. X     case hHmm:
  810. X        if (isdigit (*str)) {
  811. X        *hrs = *hrs*10 + VALUE (*str++);
  812. X        state = hh_mm;
  813. X        continue;
  814. X        }
  815. X     case hh_mm:
  816. X        if (INSTRING (*str, ".:-")) {
  817. X        state = hhMm;
  818. X        str++;
  819. X        continue;
  820. X        }
  821. X     case hhMm:
  822. X        if (isdigit (*str)) {
  823. X        *mins = VALUE (*str++);
  824. X        state = hhmM;
  825. X        continue;
  826. X        }
  827. X     case hhmM:
  828. X        if (isdigit (*str)) {
  829. X        *mins = *mins*10 + VALUE (*str++);
  830. X        state = AmPm;
  831. X        continue;
  832. X        }
  833. X     case AmPm:
  834. X        if (*str == '\0') {
  835. X        *in24hrf = (*hrs > 12) or ((*hrs < 10) and (numdigits % 2 == 0));
  836. X        finished = True;
  837. X        continue;
  838. X        } else if (relative) {
  839. X        ADDERROR (UNRECOGNISED, str);
  840. X        return (False);
  841. X        }
  842. X
  843. X        if (INSTRING (*str, "Aa")) {
  844. X        if (*hrs == 12)
  845. X            *hrs = 0;
  846. X        state = aMpM;
  847. X        continue;
  848. X        } else if (INSTRING (*str, "Pp")) {
  849. X            if (*hrs < 12)
  850. X            *hrs = *hrs + 12;
  851. X            state = aMpM;
  852. X            continue;
  853. X        }
  854. X        ADDERROR (EXPECTEDAMPM, str);
  855. X        return (False);
  856. X     case aMpM:
  857. X        str++;
  858. X        if (INSTRING (*str, "Mm")) {
  859. X        *in24hrf = finished = True;
  860. X        str++;
  861. X        } else {
  862. X        ADDERROR (EXPECTEDAMPM, str);
  863. X        return (False);
  864. X        }
  865. X    }
  866. X
  867. X    if ((*hrs < 24) and (*mins < 60) and (*str == '\0'))
  868. X    return (True);
  869. X    else {
  870. X    if (*hrs >= 24) {
  871. X        (void) sprintf (badtime, "%d", *hrs);
  872. X        ADDERROR (BADHOURS, badtime);
  873. X    } else if (*mins >= 60) {
  874. X        (void) sprintf (badtime, "%d", *mins);
  875. X        ADDERROR (BADMINUTES, badtime);
  876. X    } else {
  877. X        ADDERROR (UNRECOGNISED, str);
  878. X    }
  879. X    return (False);
  880. X    }
  881. }
  882. SHAR_EOF
  883. chmod 0644 times.c ||
  884. echo 'restore of times.c failed'
  885. Wc_c="`wc -c < 'times.c'`"
  886. test 5094 -eq "$Wc_c" ||
  887.     echo 'times.c: original size 5094, current size' "$Wc_c"
  888. rm -f _shar_wnt_.tmp
  889. fi
  890. # ============= warnings.c ==============
  891. if test -f 'warnings.c' -a X"$1" != X"-c"; then
  892.     echo 'x - skipping warnings.c (File already exists)'
  893.     rm -f _shar_wnt_.tmp
  894. else
  895. > _shar_wnt_.tmp
  896. echo 'x - extracting warnings.c (Text)'
  897. sed 's/^X//' << 'SHAR_EOF' > 'warnings.c' &&
  898. /*
  899. X      Copyright (c) 1991, 1992 by Simon Marshall, University of Hull, UK
  900. X
  901. X           If you still end up late, don't blame me!
  902. X                       
  903. X  Permission to use, copy, modify, distribute, and sell this software and its
  904. X       documentation for any purpose and without fee is hereby granted,
  905. X    provided that the above copyright notice appear in all copies and that
  906. X    both that copyright notice and this permission notice appear in
  907. X               supporting documentation.
  908. X                       
  909. X  This software is provided AS IS with no warranties of any kind.  The author
  910. X    shall have no liability with respect to the infringement of copyrights,
  911. X     trade secrets or any patents by this file or any part thereof.  In no
  912. X      event will the author be liable for any lost revenue or profits or
  913. X          other special, indirect and consequential damages.
  914. */
  915. X
  916. /* 
  917. X * The stuff for dealing with warnings; processing to get the times & 
  918. X * the fns for popping up the warnings themselves.
  919. X */
  920. X
  921. X
  922. X
  923. #include "xalarm.h"
  924. X
  925. #include <X11/Xaw/Form.h>
  926. #include <X11/Xaw/Command.h>
  927. X
  928. X
  929. #define        WARNINGFORMAT    "Warning!  (%d:%02d)"
  930. #define        WARNING        "Warning: %s due in "
  931. X
  932. X
  933. void        SetWarningTimes(), Warning(), QuitWarning();
  934. static void    TimeTracker(), Reset();
  935. extern XtIntervalId ResetTracker();
  936. extern SIGRET    ResetAlarm();
  937. extern long    TimeToMilliSeconds();
  938. extern void    SetGeometry(), SetWMName(), Audio(), Quit();
  939. extern time_t    time();
  940. extern struct tm *localtime();
  941. X
  942. X
  943. X
  944. extern AlarmData    xalarm;
  945. X
  946. X
  947. X
  948. /* 
  949. X * Process the string to extract warning times.  Currently just gives 
  950. X * a message if a warning time is invalid.
  951. X */
  952. X
  953. void SetWarningTimes (warnings)
  954. X  String   warnings;
  955. {
  956. X    String         warnstr = warnings;
  957. X    char         warning[TEXT];
  958. X    unsigned long   biggest;
  959. X    int         i, j, bigindex;
  960. X                
  961. X    xalarm.numwarnings = 0;
  962. X    while ((*warnstr != '\0') and (ISVALID (xalarm.numwarnings))) {
  963. X    warning[i=0] = '+';
  964. X    while ((*warnstr != ',') and (*warnstr != '\0'))
  965. X        warning[++i] = *warnstr++;
  966. X    warning[++i] = '\0';
  967. X
  968. X    switch (xalarm.warnings[xalarm.numwarnings] =
  969. X        (unsigned long) TimeToMilliSeconds (warning)) {
  970. X     case 0:
  971. X        break;
  972. X     case INVALID:
  973. X        xalarm.numwarnings = INVALID;
  974. X        break;
  975. X     default:
  976. X        xalarm.numwarnings++;
  977. X        break;
  978. X    }
  979. X
  980. X    while (*warnstr == ',')
  981. X        warnstr++;
  982. X    }
  983. X    if ((warnstr != warnings) and (*(warnstr-1) == ','))
  984. X    xalarm.numwarnings = INVALID;
  985. X
  986. X    /* 
  987. X     * Sort it, why not?
  988. X     */
  989. X    for (i=0; i<xalarm.numwarnings-1; i++) {
  990. X    biggest = xalarm.warnings[bigindex = i];
  991. X    for (j=i+1; j<xalarm.numwarnings; j++)
  992. X        if (xalarm.warnings[j] > biggest)
  993. X        biggest = xalarm.warnings[bigindex = j];
  994. X    xalarm.warnings[bigindex] = xalarm.warnings[i];
  995. X    xalarm.warnings[i] = biggest;
  996. X    }
  997. }
  998. X
  999. X
  1000. X
  1001. /* 
  1002. X * pop up a warning.  includes a dismiss & quit button.
  1003. X */
  1004. X
  1005. void Warning (clientdata, id)
  1006. X  XtPointer      clientdata;
  1007. X  XtIntervalId      id;
  1008. {
  1009. X    static Widget   popup = NONWIDGET;
  1010. X    Widget         warningbox, dismiss, reset, quit;
  1011. X
  1012. X    if (ISNONWIDGET (popup)) {
  1013. X    popup = XtVaCreatePopupShell ("Warning!", transientShellWidgetClass,
  1014. X                      xalarm.toplevel, NULL);
  1015. X    warningbox = XtVaCreateManagedWidget ("warning", formWidgetClass, popup, NULL);
  1016. X
  1017. X    CreateManagedButton (dismiss, "dismiss", warningbox, QuitWarning, popup);
  1018. X    xalarm.warningwidget = XtVaCreateManagedWidget ("message", labelWidgetClass,
  1019. X                            warningbox, NULL);
  1020. X    CreateManagedButton (reset, "reset", warningbox, Reset, popup);
  1021. X    CreateManagedButton (quit, "quit", warningbox, Quit, NULL);
  1022. X    }
  1023. X
  1024. X    if (ISNONID (xalarm.warningid))
  1025. X    TimeTracker ((XtPointer) popup, (XtIntervalId) NULL);
  1026. X    SetGeometry (popup);
  1027. X    Audio (xalarm.warningaudio);
  1028. X    XtPopup (popup, XtGrabNone);
  1029. X    XRaiseWindow (XtDisplay (popup), XtWindow (popup));
  1030. X    XFlush (XtDisplay (popup));
  1031. }
  1032. X  
  1033. X         
  1034. X
  1035. /* 
  1036. X * Track the time for this widget.  Puts a clock in the WM name, and 
  1037. X * keeps the warning message upto date.
  1038. X */
  1039. X
  1040. static void TimeTracker (clientdata, id)
  1041. X  XtPointer      clientdata;
  1042. X  XtIntervalId      id;
  1043. {
  1044. X    char     buf[TEXT], wmname[TEXT], warnmessage[TEXT], *wm = warnmessage;
  1045. X    int     mins, count;
  1046. X    time_t     now;
  1047. X    struct tm  *clock;
  1048. X    
  1049. X    (void) time (&now);
  1050. X    clock = localtime (&now);
  1051. X
  1052. X    if ((mins = (int) (((unsigned long) 59 + xalarm.offtime - (unsigned long) now)
  1053. X               / SECSIN1MIN)) == 0)
  1054. X    xalarm.warningid = NONID;
  1055. X    else {
  1056. X    (void) sprintf (wmname, WARNINGFORMAT, clock->tm_hour, clock->tm_min);
  1057. X    SetWMName ((Widget) clientdata, wmname);
  1058. X
  1059. X    if (xalarm.warningwords == 0)
  1060. X        (void) sprintf (buf, WARNING, xalarm.proggie+1);
  1061. X    else {
  1062. X        (void) sprintf (warnmessage, "`%s", xalarm.messagestr);
  1063. X        count = xalarm.warningwords;
  1064. X        while ((count-- > 0) and (*wm != '\0')) {
  1065. X        while (isspace (*wm))
  1066. X            *wm++ = ' ';
  1067. X        while (not isspace (*wm) and (*wm != '\0'))
  1068. X            wm++;
  1069. X        }
  1070. X        (void) sprintf (wm, "%s", (*wm == '\0') ? "' " : "...' ");
  1071. X        (void) sprintf (buf, WARNING, warnmessage);
  1072. X    }
  1073. X    MAKETIMESTRING (ENDOF (buf), mins);
  1074. X
  1075. X    XtVaSetValues (xalarm.warningwidget, XtNlabel, (XtArgVal) buf, NULL);
  1076. X
  1077. X    xalarm.warningid = ResetTracker (TimeTracker, clientdata,
  1078. X                     (int) (xalarm.offtime % 60));
  1079. X    }
  1080. }
  1081. X
  1082. X
  1083. X
  1084. /* 
  1085. X * Popdown the warning window & popup to reset the alarm.
  1086. X */
  1087. X
  1088. static void Reset (widget, clientdata, calldata)
  1089. X  Widget      widget;
  1090. X  XtPointer   clientdata, calldata;
  1091. {
  1092. X    QuitWarning (widget, clientdata, calldata);
  1093. X    (void) ResetAlarm ((int) NULL, (int) NULL, (struct sigcontext *) NULL,
  1094. X               (char *) NULL);
  1095. }
  1096. X
  1097. X
  1098. X
  1099. /* 
  1100. X * Popdown the warning window.
  1101. X */
  1102. X
  1103. void QuitWarning (widget, clientdata, calldata)
  1104. X  Widget      widget;
  1105. X  XtPointer   clientdata, calldata;
  1106. {
  1107. X    if (ISID (xalarm.warningid)) {
  1108. X    XtRemoveTimeOut (xalarm.warningid);
  1109. X    xalarm.warningid = NONID;
  1110. X    }
  1111. X    XtPopdown ((Widget) clientdata);
  1112. }
  1113. SHAR_EOF
  1114. chmod 0644 warnings.c ||
  1115. echo 'restore of warnings.c failed'
  1116. Wc_c="`wc -c < 'warnings.c'`"
  1117. test 5720 -eq "$Wc_c" ||
  1118.     echo 'warnings.c: original size 5720, current size' "$Wc_c"
  1119. rm -f _shar_wnt_.tmp
  1120. fi
  1121. # ============= when.c ==============
  1122. if test -f 'when.c' -a X"$1" != X"-c"; then
  1123.     echo 'x - skipping when.c (File already exists)'
  1124.     rm -f _shar_wnt_.tmp
  1125. else
  1126. > _shar_wnt_.tmp
  1127. echo 'x - extracting when.c (Text)'
  1128. sed 's/^X//' << 'SHAR_EOF' > 'when.c' &&
  1129. /*
  1130. X      Copyright (c) 1991, 1992 by Simon Marshall, University of Hull, UK
  1131. X
  1132. X           If you still end up late, don't blame me!
  1133. X                       
  1134. X  Permission to use, copy, modify, distribute, and sell this software and its
  1135. X       documentation for any purpose and without fee is hereby granted,
  1136. X    provided that the above copyright notice appear in all copies and that
  1137. X    both that copyright notice and this permission notice appear in
  1138. X               supporting documentation.
  1139. X                       
  1140. X  This software is provided AS IS with no warranties of any kind.  The author
  1141. X    shall have no liability with respect to the infringement of copyrights,
  1142. X     trade secrets or any patents by this file or any part thereof.  In no
  1143. X      event will the author be liable for any lost revenue or profits or
  1144. X          other special, indirect and consequential damages.
  1145. */
  1146. X
  1147. /* 
  1148. X * Stuff for getting the time the alarm is due to go off, and 
  1149. X * confirmation if needed.
  1150. X */
  1151. X
  1152. X
  1153. X
  1154. #include "xalarm.h"
  1155. #include "dates.h"
  1156. X
  1157. #include <X11/Xaw/Form.h>
  1158. #include <X11/Xaw/Dialog.h>
  1159. X
  1160. X
  1161. #define        TIMEINSTRUCTIONS    "Enter time (as [+]time[am/pm]):"
  1162. #define        DATEINSTRUCTIONS    "Enter date (as +days|date):"
  1163. #define        WARNINGINSTRUCTIONS    "Enter warnings (as time[,time...]):"
  1164. #define        CONFIRMFORMAT        "%s %s %d, %02d:%02d (in %d+%d:%02d), "
  1165. #define        WHENFORMAT        "When?  (%d:%02d)"
  1166. #define        EDITTIME        (0)
  1167. #define        EDITDATE        (1)
  1168. #define        EDITWARNINGS        (2)
  1169. #define        EDITED(str, widget)    (strcmp (str, XawDialogGetValueString (widget)))
  1170. #define        DIALOGVALUE(widget)    (XtNewString (XawDialogGetValueString (widget)))
  1171. #define        UPCASE(ch)        (((ch) >= 'a') and ((ch) <= 'z') ? \
  1172. X                     ((ch) - 'a' + 'A') : (ch))
  1173. X
  1174. X
  1175. X
  1176. void        PopupAndAsk(), EnteredTime(), EnteredDate(), EnteredWarnings(),
  1177. X        Confirmed(), MakeConfirmMessage(), EditedText();
  1178. static void    PopupAndConfirm(), Popup(), PopupNext(), Edit(), Cancel(), TimeTracker();
  1179. extern XtIntervalId ResetTracker();
  1180. extern String    HomeDirectory();
  1181. extern void    Quit(), AddTimeOuts(), SetWarningTimes(), SetGeometry(),
  1182. X        SaveAlarmSettings(), SetWMName(), EnsureNotGrownOffScreen();
  1183. extern long    TimeToMilliSeconds();
  1184. extern unsigned long DateToMilliSeconds();
  1185. extern time_t    time();
  1186. extern struct tm *localtime();
  1187. X
  1188. X
  1189. X
  1190. extern AlarmData    xalarm;
  1191. X
  1192. X
  1193. X
  1194. /* 
  1195. X * just pop up a dialog widget to get an at/in time.  won't pop down 
  1196. X * until a valid time is given.  EnteredTime() does this.
  1197. X */
  1198. X
  1199. void PopupAndAsk ()
  1200. {
  1201. X    static Widget   popup = NONWIDGET;
  1202. X    Widget         when, gettime, getdate, getwtime, confirm;
  1203. X
  1204. X    if (ISNONWIDGET (popup)) {
  1205. X    popup = XtVaCreatePopupShell ("When?", transientShellWidgetClass,
  1206. X                      xalarm.toplevel, NULL);
  1207. X    when = XtVaCreateManagedWidget ("when", formWidgetClass, popup, NULL);
  1208. X
  1209. X    /* 
  1210. X     * Widget for time input.
  1211. X     */
  1212. X    gettime = XtVaCreateManagedWidget ("time", dialogWidgetClass, when,
  1213. X                       XtNvalue, (XtArgVal) xalarm.timestr, NULL);
  1214. X    XawDialogAddButton (gettime, "ok", EnteredTime, (XtPointer) NULL);
  1215. X    XawDialogAddButton (gettime, "editdate", Edit, (XtPointer) EDITDATE);
  1216. X    XawDialogAddButton (gettime, "editwarnings", Edit, (XtPointer) EDITWARNINGS);
  1217. X    XawDialogAddButton (gettime, "quit", Quit, (XtPointer) NULL);
  1218. X
  1219. X    /* 
  1220. X     * Widget for date input.
  1221. X     */
  1222. X    getdate = XtVaCreateWidget ("date", dialogWidgetClass, when,
  1223. X                    XtNvalue, (XtArgVal) xalarm.datestr, NULL);
  1224. X    XawDialogAddButton (getdate, "ok", EnteredDate, (XtPointer) NULL);
  1225. X    XawDialogAddButton (getdate, "edittime", Edit, (XtPointer) EDITTIME);
  1226. X    XawDialogAddButton (getdate, "editwarnings", Edit, (XtPointer) EDITWARNINGS);
  1227. X    XawDialogAddButton (getdate, "quit", Quit, (XtPointer) NULL);
  1228. X
  1229. X    /* 
  1230. X     * Widget for warning times input.
  1231. X     */
  1232. X    getwtime = XtVaCreateWidget ("warnings", dialogWidgetClass, when,
  1233. X                     XtNvalue, (XtArgVal) xalarm.warningsstr, NULL);
  1234. X    XawDialogAddButton (getwtime, "ok", EnteredWarnings, (XtPointer) NULL);
  1235. X    XawDialogAddButton (getwtime, "edittime", Edit, (XtPointer) EDITTIME);
  1236. X    XawDialogAddButton (getwtime, "editdate", Edit, (XtPointer) EDITDATE);
  1237. X    XawDialogAddButton (getwtime, "quit", Quit, (XtPointer) NULL);
  1238. X
  1239. X    /* 
  1240. X     * Widget for confirmation.
  1241. X     */
  1242. X    confirm = XtVaCreateWidget ("confirm", dialogWidgetClass, when,
  1243. X                    XtNvalue, (XtArgVal) xalarm.messagestr, NULL);
  1244. X    XawDialogAddButton (confirm, "ok", Confirmed, (XtPointer) popup);
  1245. X    XawDialogAddButton (confirm, "cancel", Cancel, (XtPointer) NULL);
  1246. X    XawDialogAddButton (confirm, "save", SaveAlarmSettings, (XtPointer) NULL);
  1247. X    XawDialogAddButton (confirm, "quit", Quit, (XtPointer) NULL);
  1248. X
  1249. X    /* 
  1250. X     * Set the callback for the value widget in each Dialog.
  1251. X     */
  1252. X    AddValueCallback (xalarm.gettimewidget = gettime, EditedText, True);
  1253. X    AddValueCallback (xalarm.getdatewidget = getdate, EditedText, True);
  1254. X    AddValueCallback (xalarm.getwtimewidget = getwtime, EditedText, True);
  1255. X    AddValueCallback (xalarm.confirmwidget = confirm, EditedText, True);
  1256. X    xalarm.dialog = gettime;
  1257. X    xalarm.savebutton = XtNameToWidget (confirm, "save");
  1258. X    }
  1259. X
  1260. X    if (ISNONID (xalarm.whenid))
  1261. X    TimeTracker ((XtPointer) popup, (XtIntervalId) NULL);
  1262. X    SetGeometry (popup);
  1263. X    XtPopup (popup, XtGrabExclusive);
  1264. X    XRaiseWindow (XtDisplay (popup), XtWindow (popup));
  1265. X    PopupNext ();
  1266. X    XFlush (XtDisplay (popup));
  1267. }
  1268. X
  1269. X
  1270. X
  1271. /* 
  1272. X * Track the time for this widget.  Puts a clock in the WM name, and 
  1273. X * keeps the confirmation time message upto date.
  1274. X */
  1275. X
  1276. static void TimeTracker (clientdata, id)
  1277. X  XtPointer      clientdata;
  1278. X  XtIntervalId      id;
  1279. {
  1280. X    char     wmname[TEXT], buf[TEXT];
  1281. X    time_t     now;
  1282. X    struct tm  *clock;
  1283. X    
  1284. X    (void) time (&now);
  1285. X    clock = localtime (&now);
  1286. X
  1287. X    (void) sprintf (wmname, WHENFORMAT, clock->tm_hour, clock->tm_min);
  1288. X    SetWMName ((Widget) clientdata, wmname);
  1289. X
  1290. X    if (xalarm.dialog == xalarm.confirmwidget) {
  1291. X    /* 
  1292. X     * Make sure that the alarm is not now out of date.
  1293. X     */
  1294. X    xalarm.dateout = DateToMilliSeconds (xalarm.datestr);
  1295. X    xalarm.timeout = TimeToMilliSeconds (xalarm.timestr);
  1296. X    if ((xalarm.timeout == 0) and (xalarm.dateout == 0) and
  1297. X        (xalarm.timestr[0] != '+'))
  1298. X        Popup (xalarm.gettimewidget, TIMEINSTRUCTIONS);
  1299. X    else {
  1300. X        MakeConfirmMessage (buf);
  1301. X        if (not XtIsSensitive (xalarm.savebutton))
  1302. X        (void) sprintf (ENDOF (buf), "\nSaved in %s/%s",
  1303. X                HomeDirectory (), XALARMFILE);
  1304. X        XtVaSetValues (xalarm.confirmwidget, XtNlabel, (XtArgVal) buf, NULL);
  1305. X    }
  1306. X    }
  1307. X
  1308. X    xalarm.whenid = ResetTracker (TimeTracker, clientdata, 0);
  1309. }
  1310. X
  1311. X
  1312. X
  1313. /* 
  1314. X * Popup the next dialog, if more needs to be entered.
  1315. X */
  1316. X
  1317. static void PopupNext ()
  1318. {
  1319. X    if (ISINVALID (xalarm.timeout) or
  1320. X    EDITED (xalarm.timestr, xalarm.gettimewidget))
  1321. X    Popup (xalarm.gettimewidget, TIMEINSTRUCTIONS);
  1322. X    else if (ISINVALID (xalarm.dateout) or
  1323. X         EDITED (xalarm.datestr, xalarm.getdatewidget))
  1324. X    Popup (xalarm.getdatewidget, DATEINSTRUCTIONS);
  1325. X    else if (ISINVALID (xalarm.numwarnings) or
  1326. X         EDITED (xalarm.warningsstr, xalarm.getwtimewidget))
  1327. X    Popup (xalarm.getwtimewidget, WARNINGINSTRUCTIONS);
  1328. X    else
  1329. X    PopupAndConfirm ();
  1330. }
  1331. X
  1332. X
  1333. X
  1334. /* 
  1335. X * If invalid, stay.  Otherwise, get the rest, if any.
  1336. X */
  1337. X
  1338. void EnteredTime (widget, clientdata, calldata)
  1339. X  Widget      widget;
  1340. X  XtPointer   clientdata, calldata;
  1341. {
  1342. X    char   message[TEXT];
  1343. X
  1344. X    xalarm.timeout = TimeToMilliSeconds
  1345. X    (xalarm.timestr = DIALOGVALUE (xalarm.gettimewidget));
  1346. X
  1347. X    if (ISVALID (xalarm.timeout))
  1348. X    PopupNext ();
  1349. X    else {
  1350. X    (void) sprintf (message, "%s%s", xalarm.errormessage, TIMEINSTRUCTIONS);
  1351. X    XtVaSetValues (xalarm.gettimewidget, XtNlabel, (XtArgVal) message, NULL);
  1352. X    }
  1353. }
  1354. X
  1355. X
  1356. X
  1357. /* 
  1358. X * If invalid, stay.  Otherwise, get the rest, if any.
  1359. X */
  1360. X
  1361. void EnteredDate (widget, clientdata, calldata)
  1362. X  Widget      widget;
  1363. X  XtPointer   clientdata, calldata;
  1364. {
  1365. X    char   message[TEXT];
  1366. X
  1367. X    xalarm.dateout = DateToMilliSeconds
  1368. X    (xalarm.datestr = DIALOGVALUE (xalarm.getdatewidget));
  1369. X
  1370. X    if (ISVALID (xalarm.dateout))
  1371. X    PopupNext ();
  1372. X    else {
  1373. X    (void) sprintf (message, "%s%s", xalarm.errormessage, DATEINSTRUCTIONS);
  1374. X    XtVaSetValues (xalarm.getdatewidget, XtNlabel, (XtArgVal) message, NULL);
  1375. X    }
  1376. }
  1377. X
  1378. X
  1379. X
  1380. /* 
  1381. X * If invalid, stay.  Otherwise, get the rest, if any.
  1382. X */
  1383. X
  1384. void EnteredWarnings (widget, clientdata, calldata)
  1385. X  Widget      widget;
  1386. X  XtPointer   clientdata, calldata;
  1387. {
  1388. X    char   message[TEXT];
  1389. X
  1390. X    SetWarningTimes (xalarm.warningsstr = DIALOGVALUE (xalarm.getwtimewidget));
  1391. X
  1392. X    if (ISVALID (xalarm.numwarnings))
  1393. X    PopupNext ();
  1394. X    else {
  1395. X    (void) sprintf (message, "%s%s", xalarm.errormessage, WARNINGINSTRUCTIONS);
  1396. X    XtVaSetValues (xalarm.getwtimewidget, XtNlabel, (XtArgVal) message, NULL);
  1397. X    }
  1398. }
  1399. X
  1400. X
  1401. X
  1402. /* 
  1403. X * Just toggle whether i/t concerns alarm time/date/warning time(s).
  1404. X */
  1405. X
  1406. static void Edit (widget, clientdata, calldata)
  1407. X  Widget      widget;
  1408. X  XtPointer   clientdata, calldata;
  1409. {
  1410. X    switch ((int) clientdata) {
  1411. X     case EDITTIME:
  1412. X    Popup (xalarm.gettimewidget, TIMEINSTRUCTIONS);
  1413. X    break;
  1414. X     case EDITDATE:
  1415. X    Popup (xalarm.getdatewidget, DATEINSTRUCTIONS);
  1416. X    break;
  1417. X     case EDITWARNINGS:
  1418. X    Popup (xalarm.getwtimewidget, WARNINGINSTRUCTIONS);
  1419. X    break;
  1420. X    }
  1421. }
  1422. X
  1423. X
  1424. X
  1425. /* 
  1426. X * Set the sensitivity of the save button.
  1427. X */
  1428. X
  1429. void EditedText (widget, clientdata, calldata)
  1430. X  Widget      widget;
  1431. X  XtPointer   clientdata, calldata;
  1432. {
  1433. X    static Boolean   edited = True;
  1434. X
  1435. X    if (not (Boolean) clientdata)
  1436. X    XtSetSensitive (xalarm.savebutton, edited = False);
  1437. X    else if (not edited)
  1438. X    XtSetSensitive (xalarm.savebutton, edited = True);
  1439. }
  1440. X
  1441. X
  1442. X
  1443. /* 
  1444. X * Popup to confirm, showing the time which the alarm will trigger.
  1445. X */
  1446. X
  1447. static void PopupAndConfirm ()
  1448. {
  1449. X    char   message[TEXT];
  1450. X
  1451. X    MakeConfirmMessage (message);
  1452. X    Popup (xalarm.confirmwidget, message);
  1453. }
  1454. X
  1455. X
  1456. X
  1457. /* 
  1458. X * Make the message that should be displayed as the label in the 
  1459. X * confirmation window.
  1460. X */
  1461. X
  1462. void MakeConfirmMessage (message)
  1463. X  String   message;
  1464. {
  1465. X    static char     strings[][4] = {WEEKDAYS, MONTHS};
  1466. X    time_t         now;
  1467. X    struct tm        *alarmtime;
  1468. X    unsigned long   msecsout;
  1469. X    int         count = 0, i;
  1470. X
  1471. X    msecsout = SUMTIMEOUTS (DateToMilliSeconds (xalarm.datestr),
  1472. X                TimeToMilliSeconds (xalarm.timestr));
  1473. X    (void) time (&now);
  1474. X    now += (time_t) (msecsout / MSECSIN1SEC);
  1475. X    alarmtime = localtime (&now);
  1476. X
  1477. X    strings[alarmtime->tm_wday][0] = UPCASE (strings[alarmtime->tm_wday][0]);
  1478. X    strings[alarmtime->tm_mon+7][0] = UPCASE (strings[alarmtime->tm_mon+7][0]);
  1479. X    msecsout += (59 * MSECSIN1SEC);
  1480. X    (void) sprintf (message, CONFIRMFORMAT,
  1481. X            strings[alarmtime->tm_wday], strings[alarmtime->tm_mon+7],
  1482. X            alarmtime->tm_mday, alarmtime->tm_hour, alarmtime->tm_min,
  1483. X            msecsout / MSECSIN1DAY, (msecsout / MSECSIN1HR) % 24,
  1484. X            (msecsout / MSECSIN1MIN) % 60);
  1485. X    msecsout -= (59 * MSECSIN1SEC);
  1486. X
  1487. X    for (i=0; i<xalarm.numwarnings; i++)
  1488. X    if (msecsout > xalarm.warnings[i])
  1489. X        count++;
  1490. X
  1491. X    if (count == 0)
  1492. X    (void) sprintf (ENDOF (message), "no warnings:");
  1493. X    else 
  1494. X    (void) sprintf (ENDOF (message), "warning%s: ", PLURAL (count));
  1495. X
  1496. X    for (i=0; i<xalarm.numwarnings; i++)
  1497. X    if (xalarm.timeout > xalarm.warnings[i]) {
  1498. X        MAKETIME (ENDOF (message), xalarm.warnings[i] / MSECSIN1MIN);
  1499. X        if (--count > 0)
  1500. X        (void) strcat (message, ",");
  1501. X    }
  1502. }
  1503. X
  1504. X
  1505. X
  1506. /* 
  1507. X * Yow!  Let's go!
  1508. X */
  1509. X
  1510. void Confirmed (widget, clientdata, calldata)
  1511. X  Widget      widget;
  1512. X  XtPointer   clientdata, calldata;
  1513. {
  1514. X    String   message = DIALOGVALUE (xalarm.confirmwidget);
  1515. X
  1516. X    if (*message != '\0')
  1517. X    XtVaSetValues (xalarm.messagewidget,
  1518. X               XtNlabel, (XtArgVal) (xalarm.messagestr = message), NULL);
  1519. X
  1520. X    /* 
  1521. X     * Reset the timeout, since the gap between entering 
  1522. X     * and confirming may be significant.
  1523. X     */
  1524. X
  1525. X    xalarm.timeout = TimeToMilliSeconds (xalarm.timestr);
  1526. X    XtRemoveTimeOut (xalarm.whenid); 
  1527. X    xalarm.whenid = NONID;
  1528. X    AddTimeOuts ();
  1529. X
  1530. X    XtPopdown (XtParent (XtParent (xalarm.confirmwidget)));
  1531. }
  1532. X
  1533. X
  1534. X
  1535. /* 
  1536. X * Swap back to gettime widget & remove kbd focus.
  1537. X */
  1538. X
  1539. static void Cancel (widget, clientdata, calldata)
  1540. X  Widget      widget;
  1541. X  XtPointer   clientdata, calldata;
  1542. {
  1543. X    Popup (xalarm.gettimewidget, TIMEINSTRUCTIONS);
  1544. }
  1545. X
  1546. X
  1547. X
  1548. /* 
  1549. X * Show this widget, and set its label.
  1550. X * If there's not enough room for the new widget, move it.
  1551. X */
  1552. X
  1553. static void Popup (widget, label)
  1554. X  Widget   widget;
  1555. X  String   label;
  1556. {
  1557. X    Widget   form = XtParent (widget);
  1558. X
  1559. X    XtVaSetValues (widget, XtNlabel, (XtArgVal) label, NULL);
  1560. X
  1561. X    XawFormDoLayout (form, False);
  1562. X    if (xalarm.dialog != widget) {
  1563. X    XtManageChild (widget);
  1564. X    XtUnmanageChild (xalarm.dialog);
  1565. X    xalarm.dialog = widget;
  1566. X    }
  1567. X    XawFormDoLayout (form, True);
  1568. X
  1569. X    EnsureNotGrownOffScreen (XtParent (form));
  1570. }
  1571. SHAR_EOF
  1572. chmod 0644 when.c ||
  1573. echo 'restore of when.c failed'
  1574. Wc_c="`wc -c < 'when.c'`"
  1575. test 12351 -eq "$Wc_c" ||
  1576.     echo 'when.c: original size 12351, current size' "$Wc_c"
  1577. rm -f _shar_wnt_.tmp
  1578. fi
  1579. # ============= xalarm.c ==============
  1580. if test -f 'xalarm.c' -a X"$1" != X"-c"; then
  1581.     echo 'x - skipping xalarm.c (File already exists)'
  1582.     rm -f _shar_wnt_.tmp
  1583. else
  1584. > _shar_wnt_.tmp
  1585. echo 'x - extracting xalarm.c (Text)'
  1586. sed 's/^X//' << 'SHAR_EOF' > 'xalarm.c' &&
  1587. /*
  1588. X      Copyright (c) 1991, 1992 by Simon Marshall, University of Hull, UK
  1589. X
  1590. X           If you still end up late, don't blame me!
  1591. X                       
  1592. X  Permission to use, copy, modify, distribute, and sell this software and its
  1593. X       documentation for any purpose and without fee is hereby granted,
  1594. X    provided that the above copyright notice appear in all copies and that
  1595. X    both that copyright notice and this permission notice appear in
  1596. X               supporting documentation.
  1597. X                       
  1598. X  This software is provided AS IS with no warranties of any kind.  The author
  1599. X    shall have no liability with respect to the infringement of copyrights,
  1600. X     trade secrets or any patents by this file or any part thereof.  In no
  1601. X      event will the author be liable for any lost revenue or profits or
  1602. X          other special, indirect and consequential damages.
  1603. */
  1604. X
  1605. /* 
  1606. X * Main bit of prog, just deal with parsing command line options etc 
  1607. X * (well, letting XtAppInitialize() do it) & setting up stuff by 
  1608. X * calling out to other fns.
  1609. X */
  1610. X
  1611. X
  1612. X
  1613. #include "xalarm.h"
  1614. X
  1615. X
  1616. int        main();
  1617. void        DoAlarm();
  1618. static void    SetAlarm();
  1619. extern Instance    PreParseArgList();
  1620. extern String   Concat();
  1621. extern SIGRET    ResetAlarm(), KillAlarm();
  1622. extern void    Initialise(), StartDaemon(), CreateAlarmWidget(), PopupAndAsk(),
  1623. X        AddTimeOuts(), SetWarningTimes(), AlarmDying(), RestartDiedAlarms(),
  1624. X        EnteredTime(), EnteredDate(), EnteredWarnings(), Confirmed(),
  1625. X        ShowSnoozeValue(), ShowClickToZero(), Quit();
  1626. extern int    ParseAlarmFile();
  1627. extern long    TimeToMilliSeconds();
  1628. extern unsigned long DateToMilliSeconds();
  1629. X
  1630. X
  1631. X
  1632. static XtResource resources[] = {
  1633. X    {XtNtime,        XtCTime,    XtRString,        sizeof (String),
  1634. X     XtOffsetOf (ApplData, time),    XtRString,        (XtPointer) ""},
  1635. X    {XtNdate,        XtCDate,    XtRString,        sizeof (String),
  1636. X     XtOffsetOf (ApplData, date),    XtRString,        (XtPointer) ""},
  1637. X    {XtNwarnings,    XtCWarnings,    XtRString,        sizeof (String),
  1638. X     XtOffsetOf (ApplData, warnings),    XtRString,        (XtPointer) ""},
  1639. X    {XtNwarningwords,    XtCWarningwords,XtRInt,            sizeof (int),
  1640. X     XtOffsetOf (ApplData,warningwords),XtRImmediate,        (XtPointer) 0},
  1641. X    {XtNpester,        XtCPester,    XtRString,        sizeof (String),
  1642. X     XtOffsetOf (ApplData, pester),    XtRString,        (XtPointer) "0"},
  1643. X    {XtNsnooze,        XtCSnooze,    XtRString,        sizeof (String),
  1644. X     XtOffsetOf (ApplData, snooze),    XtRString,        (XtPointer) "0"},
  1645. X    {XtNconfirm,    XtCConfirm,    XtRBoolean,        sizeof (Boolean),
  1646. X     XtOffsetOf (ApplData, confirm),    XtRImmediate,        (XtPointer) True},
  1647. X    {XtNkill,        XtCKill,    XtRString,        sizeof (String),
  1648. X     XtOffsetOf (ApplData, kill),    XtRString,        (XtPointer) NULL},
  1649. X    {XtNreset,        XtCReset,    XtRString,        sizeof (String),
  1650. X     XtOffsetOf (ApplData, reset),    XtRString,        (XtPointer) NULL},
  1651. X    {XtNlist,        XtCList,    XtRBoolean,        sizeof (Boolean),
  1652. X     XtOffsetOf (ApplData, list),    XtRImmediate,        (XtPointer) False},
  1653. X    {XtNvolume,        XtCVolume,    XtRInt,            sizeof (int),
  1654. X     XtOffsetOf (ApplData, volume),    XtRImmediate,        (XtPointer) 50},
  1655. X    {XtNversion,    XtCVersion,    XtRBoolean,        sizeof (Boolean),
  1656. X     XtOffsetOf (ApplData, version),    XtRImmediate,        (XtPointer) False},
  1657. X    {XtNhelp,        XtCHelp,    XtRBoolean,        sizeof (Boolean),
  1658. X     XtOffsetOf (ApplData, help),    XtRImmediate,        (XtPointer) False},
  1659. X    {XtNname,        XtCName,    XtRString,        sizeof (String),
  1660. X     XtOffsetOf (ApplData, proggie),    XtRString,        (XtPointer) "xalarm"},
  1661. X    {XtNgeometry,    XtCGeometry,    XtRString,        sizeof (String),
  1662. X     XtOffsetOf (ApplData, geometry),    XtRString,        (XtPointer) NOGEOMETRY},
  1663. X    {XtNalarmaudio,    XtCAlarmaudio,    XtRString,        sizeof (String),
  1664. X     XtOffsetOf (ApplData, alarmaudio),    XtRString,        (XtPointer) ""},
  1665. X    {XtNwarnaudio,    XtCWarnaudio,    XtRString,        sizeof (String),
  1666. X     XtOffsetOf (ApplData, warnaudio),    XtRString,        (XtPointer) ""},
  1667. X    {XtNquiet,        XtCQuiet,    XtRBoolean,        sizeof (Boolean),
  1668. X     XtOffsetOf (ApplData, quiet),    XtRImmediate,        (XtPointer) False},
  1669. };
  1670. X        
  1671. X
  1672. X
  1673. static XrmOptionDescRec options[] = {
  1674. X    {"-time",        ".time",    XrmoptionSepArg,    (XtPointer) ""},
  1675. X    {"-t",        ".time",    XrmoptionSepArg,    (XtPointer) ""},
  1676. X    {"-date",        ".date",    XrmoptionSepArg,    (XtPointer) ""},
  1677. X    {"-warn",        ".warnings",    XrmoptionSepArg,    (XtPointer) NULL},
  1678. X    {"-w",        ".warnings",    XrmoptionSepArg,    (XtPointer) NULL},
  1679. X    {"-nowarn",        ".warnings",    XrmoptionNoArg,        (XtPointer) ""},
  1680. X    {"-nw",        ".warnings",    XrmoptionNoArg,        (XtPointer) ""},
  1681. X    {"-warnwords",    ".warningwords",XrmoptionSepArg,    (XtPointer) NULL},
  1682. X    {"-ww",        ".warningwords",XrmoptionSepArg,    (XtPointer) NULL},
  1683. X    {"-nowarnwords",    ".warningwords",XrmoptionNoArg,        (XtPointer) "0"},
  1684. X    {"-nww",        ".warningwords",XrmoptionNoArg,        (XtPointer) "0"},
  1685. X    {"-confirm",    ".confirm",    XrmoptionNoArg,        (XtPointer) "True"},
  1686. X    {"-c",        ".confirm",    XrmoptionNoArg,        (XtPointer) "True"},
  1687. X    {"-noconfirm",    ".confirm",    XrmoptionNoArg,        (XtPointer) "False"},
  1688. X    {"-nc",        ".confirm",    XrmoptionNoArg,        (XtPointer) "False"},
  1689. X    {"-pester",        ".pester",    XrmoptionSepArg,    (XtPointer) NULL},
  1690. X    {"-p",        ".pester",    XrmoptionSepArg,    (XtPointer) NULL},
  1691. X    {"-nopester",    ".pester",    XrmoptionNoArg,        (XtPointer) "0"},
  1692. X    {"-np",        ".pester",    XrmoptionNoArg,        (XtPointer) "0"},
  1693. X    {"-snooze",        ".snooze",    XrmoptionSepArg,    (XtPointer) NULL},
  1694. X    {"-s",        ".snooze",    XrmoptionSepArg,    (XtPointer) NULL},
  1695. X    {"-list",        ".list",    XrmoptionNoArg,        (XtPointer) "True"},
  1696. X    {"-l",        ".list",    XrmoptionNoArg,        (XtPointer) "True"},
  1697. X    {"-kill",        ".kill",    XrmoptionSepArg,    (XtPointer) NULL},
  1698. X    {"-reset",        ".reset",    XrmoptionSepArg,    (XtPointer) NULL},
  1699. X    {"-r",        ".reset",    XrmoptionSepArg,    (XtPointer) NULL},
  1700. X    {"-alarmaudio",    ".alarmaudio",    XrmoptionSepArg,    (XtPointer) NULL},
  1701. X    {"-aa",        ".alarmaudio",    XrmoptionSepArg,    (XtPointer) NULL},
  1702. X    {"-noalarmaudio",    ".alarmaudio",    XrmoptionNoArg,        (XtPointer) QUIET},
  1703. X    {"-naa",        ".alarmaudio",    XrmoptionNoArg,        (XtPointer) QUIET},
  1704. X    {"-warningaudio",    ".warningaudio",XrmoptionSepArg,    (XtPointer) NULL},
  1705. X    {"-warnaudio",    ".warningaudio",XrmoptionSepArg,    (XtPointer) NULL},
  1706. X    {"-wa",        ".warningaudio",XrmoptionSepArg,    (XtPointer) NULL},
  1707. X    {"-nowarningaudio",    ".warningaudio",XrmoptionNoArg,        (XtPointer) QUIET},
  1708. X    {"-nowarnaudio",    ".warningaudio",XrmoptionNoArg,        (XtPointer) QUIET},
  1709. X    {"-nwa",        ".warningaudio",XrmoptionNoArg,        (XtPointer) QUIET},
  1710. X    {"-quiet",        ".quiet",    XrmoptionNoArg,        (XtPointer) "True"},
  1711. X    {"-q",        ".quiet",    XrmoptionNoArg,        (XtPointer) "True"},
  1712. X    {"-volume",        ".volume",    XrmoptionSepArg,    (XtPointer) NULL},
  1713. X    {"-v",        ".volume",    XrmoptionSepArg,    (XtPointer) NULL},
  1714. X    {"-version",    ".version",    XrmoptionNoArg,        (XtPointer) "True"},
  1715. X    {"-help",        ".help",    XrmoptionNoArg,        (XtPointer) "True"},
  1716. X    {"-geometry",    ".geometry",    XrmoptionSepArg,    (XtPointer) NULL},
  1717. X    {"-geom",        ".geometry",    XrmoptionSepArg,    (XtPointer) NULL},
  1718. X    {"-g",        ".geometry",    XrmoptionSepArg,    (XtPointer) NULL},
  1719. X    {"-d",        ".display",    XrmoptionSepArg,    (XtPointer) NULL},
  1720. };
  1721. X
  1722. X
  1723. X
  1724. static XtActionsRec actions[] = {
  1725. X    {"Quit",        (XtActionProc) Quit},
  1726. X    {"EnteredTime",    (XtActionProc) EnteredTime},
  1727. X    {"EnteredDate",    (XtActionProc) EnteredDate},
  1728. X    {"EnteredWarnings",    (XtActionProc) EnteredWarnings},
  1729. X    {"Confirmed",    (XtActionProc) Confirmed},
  1730. X    {"ShowClickToZero",    (XtActionProc) ShowClickToZero},
  1731. X    {"ShowSnoozeValue",    (XtActionProc) ShowSnoozeValue}
  1732. };
  1733. X
  1734. X
  1735. X
  1736. AlarmData       xalarm;
  1737. X
  1738. X
  1739. X
  1740. /* 
  1741. X * The main entry.  DoAlarm() and StartDaemon() never return.
  1742. X */
  1743. X
  1744. int main (argc, argv)
  1745. X  int        argc;
  1746. X  String  *argv;
  1747. {
  1748. X    Instance   instance;
  1749. X    String    *args;
  1750. X    int        days;
  1751. X
  1752. X    instance = PreParseArgList (argv, &argc, &days, &args);
  1753. X
  1754. X    RestartDiedAlarms (args, argc);
  1755. X
  1756. X    switch (instance) {
  1757. X     case RestartOnly:
  1758. X    break;
  1759. X     case Alarm:
  1760. X    xalarm.saveonshutdown = True;
  1761. X    DoAlarm (args, argc);
  1762. X     case Daemon:
  1763. X    xalarm.saveonshutdown = False;
  1764. X    StartDaemon (days, args, argc);
  1765. X     case File:
  1766. X    xalarm.saveonshutdown = False;
  1767. X    (void) ParseAlarmFile (days, args, argc);
  1768. X    }
  1769. X
  1770. X    return (0);
  1771. }
  1772. X
  1773. X
  1774. X
  1775. /* 
  1776. X * Do the actual alarm as given.
  1777. X */
  1778. X
  1779. void DoAlarm (argv, argc)
  1780. X  String  *argv;
  1781. X  int        argc;
  1782. {
  1783. X    ApplData   data;
  1784. X
  1785. X    xalarm.toplevel = XtAppInitialize (&xalarm.appcon, "XAlarm",
  1786. X                       options, XtNumber (options), &argc, argv,
  1787. X                       (String *) NULL, (ArgList) NULL, 0);
  1788. X
  1789. X    XtGetApplicationResources (xalarm.toplevel, &data, resources, XtNumber (resources),
  1790. X                   (ArgList) NULL, 0);
  1791. X
  1792. X    XtAppAddActions (xalarm.appcon, actions, XtNumber (actions));
  1793. X
  1794. X    /* 
  1795. X     * First initialise; exit or fork.
  1796. X     * We have to make the alarm widget first, as SetAlarm() may popup 
  1797. X     * a dialog box which may need to know the alarm widget's label.
  1798. X     */
  1799. X
  1800. X    Initialise (*argv, &data);
  1801. X    CreateAlarmWidget (Concat (argv, argc));
  1802. X    SetAlarm (&data);
  1803. X
  1804. X    XtAppMainLoop (xalarm.appcon);
  1805. }       
  1806. X           
  1807. X           
  1808. X
  1809. /* 
  1810. X * If the time is not given, pop up and ask for it, otherwise add the 
  1811. X * time outs.  Get the warnings first, tho.
  1812. X */
  1813. X
  1814. static void SetAlarm (data)
  1815. X  ApplData  *data;
  1816. {
  1817. X    char   time[TEXT];
  1818. X
  1819. X    (void) sprintf (time, "+%s", data->pester);
  1820. X    xalarm.pester = (int) (TimeToMilliSeconds (time) / MSECSIN1MIN);
  1821. X    (void) sprintf (time, "+%s", data->snooze);
  1822. X    xalarm.snooze = (int) (TimeToMilliSeconds (time) / MSECSIN1MIN);
  1823. X
  1824. X    xalarm.warningwords = data->warningwords;
  1825. X    xalarm.confirm = data->confirm;
  1826. X    xalarm.proggie = data->proggie;
  1827. X    xalarm.geometry = data->geometry;
  1828. X    xalarm.volume = (data->volume - 50) * 2;
  1829. X    if (data->quiet)
  1830. X    xalarm.alarmaudio = xalarm.warningaudio = QUIET;
  1831. X    else {
  1832. X    xalarm.alarmaudio = data->alarmaudio;
  1833. X    xalarm.warningaudio = data->warnaudio;
  1834. X    }
  1835. X
  1836. X    xalarm.warningwidget = NONWIDGET;
  1837. X    xalarm.whenid = xalarm.warningid = xalarm.alarmid = xalarm.pesterid = NONID;
  1838. X
  1839. X    /* 
  1840. X     * Get the date & time from the date & time string,
  1841. X     * and the warnings from the warnings string...
  1842. X     */
  1843. X    xalarm.dateout = DateToMilliSeconds (xalarm.datestr = data->date);
  1844. X    xalarm.timeout = TimeToMilliSeconds (xalarm.timestr = data->time);
  1845. X    SetWarningTimes (xalarm.warningsstr = data->warnings);
  1846. X
  1847. X    /* 
  1848. X     * If ``invalid'' (may not have been given anyway), popup.
  1849. X     * If ok, but we want confirmation, popup to check.  (this is cheating!)
  1850. X     * There is no waiting for confirmation if the timeout is 0 - the user
  1851. SHAR_EOF
  1852. true || echo 'restore of xalarm.c failed'
  1853. fi
  1854. echo 'End of  part 4'
  1855. echo 'File xalarm.c is continued in part 5'
  1856. echo 5 > _shar_seq_.tmp
  1857. exit 0
  1858. -- 
  1859. --
  1860. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  1861. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  1862. Sunnyvale, California 94086            at&t: 408/522-9236
  1863.