home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume21 / xcal / part07 < prev    next >
Encoding:
Text File  |  1993-12-22  |  46.2 KB  |  1,875 lines

  1. Newsgroups: comp.sources.x
  2. From: pc@hillside.co.uk (Peter Collinson)
  3. Subject: v21i082:  xcal - A calendar program for X, Part07/08
  4. Message-ID: <1993Dec21.161826.22276@sparky.sterling.com>
  5. X-Md4-Signature: 4538a4bed324629e0653d811e1d9fc7d
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Hillside Systems, 61 Hillside Avenue, Canterbury, Kent CT2 8HA
  8. Date: Tue, 21 Dec 1993 16:18:26 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: pc@hillside.co.uk (Peter Collinson)
  12. Posting-number: Volume 21, Issue 82
  13. Archive-name: xcal/part07
  14. Environment: X11
  15. Supersedes: xcal: Volume 12, Issue 101
  16.  
  17. Xcal is a calendar program. For more details see Part 1 of this posting
  18.  
  19. Part 7 of 8
  20. --shar starts here--
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then unpack
  23. # it by saving it into a file and typing "sh file".  To overwrite existing
  24. # files, type "sh file -c".  You can also feed this as standard input via
  25. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  26. # will see the following message at the end:
  27. #        "End of archive 7 (of 8)."
  28. # Contents:  xcal.c xcal_alarm.c
  29. # Wrapped by pc@hillside on Wed Nov 17 11:24:37 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'xcal.c' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'xcal.c'\"
  33. else
  34. echo shar: Extracting \"'xcal.c'\" \(23399 characters\)
  35. sed "s/^X//" >'xcal.c' <<'END_OF_FILE'
  36. X#ifndef lint
  37. Xstatic char    *sccsid = "@(#)xcal.c    3.50 (Hillside Systems) 11/17/93";
  38. Xstatic char    *copyright = "@(#)Copyright 1989,1990,1993 Peter Collinson, Hillside Systems";
  39. X#endif                /* lint */
  40. X/***
  41. X
  42. X* program name:
  43. X    xcal.c
  44. X* function:
  45. X    display the current calendar date
  46. X    if pressed as a button go into strip calendar mode
  47. X* switches:
  48. X    -format str    use str as a main display format
  49. X    -debug        run quickly incrementing time - 1 day per sec
  50. X    -alarmscan    print alarm debug info
  51. X    -format        Set date format of top level box
  52. X    -stripfmt    Set date format of strip
  53. X    -editfmt    Set date format of edit boxes
  54. X    -clocktick    Set clock tick rate.
  55. X    -u        Look at another user's calendar
  56. X* libraries used:
  57. X    libXaw.a, libXmu.a libXt.a libX11.a
  58. X* compile time parameters:
  59. X    standard
  60. X* history:
  61. X    Written November 1989
  62. X    Hacked again October 1993
  63. X    Peter Collinson
  64. X    Hillside Systems
  65. X* (C) Copyright: 1989 Hillside Systems/Peter Collinson
  66. X    
  67. X    Permission to use, copy, modify, and distribute this software
  68. X    and its documentation for any purpose is hereby granted to
  69. X    anyone, provided that the above copyright notice appear
  70. X    in all copies and that both that copyright notice and this
  71. X    permission notice appear in supporting documentation, and that
  72. X    the name of Peter Collinson not be used in advertising or
  73. X    publicity pertaining to distribution of the software without
  74. X    specific, written prior permission.  Hillside Systems makes no
  75. X    representations about the suitability of this software for any
  76. X    purpose.  It is provided "as is" without express or implied
  77. X    warranty.
  78. X    
  79. X    Peter Collinson DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  80. X    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  81. X    AND FITNESS, IN NO EVENT SHALL Peter Collinson BE LIABLE FOR
  82. X    ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  83. X    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  84. X    WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  85. X    ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  86. X    PERFORMANCE OF THIS SOFTWARE.
  87. X
  88. X***/
  89. X#include <stdio.h>
  90. X#include <ctype.h>
  91. X#include <time.h>
  92. X#include <X11/Intrinsic.h>
  93. X#include <X11/Xos.h>
  94. X#include <X11/StringDefs.h>
  95. X#include <X11/Shell.h>
  96. X#include <X11/Xaw/Command.h>
  97. X#include <X11/Xaw/Label.h>
  98. X#include <X11/Xaw/Form.h>
  99. X#include "xcal.h"
  100. X
  101. Xchar            date_area[BUFSIZ];
  102. X
  103. X/* command line options specific to the application */
  104. Xstatic XrmOptionDescRec Options[] = {
  105. X    {"-debug", "debug", XrmoptionNoArg, (caddr_t) "TRUE"},
  106. X    {"-alarmscan", "alarmScan", XrmoptionNoArg, (caddr_t) "TRUE"},
  107. X    {"-format", "format", XrmoptionSepArg, NULL},
  108. X    {"-stripfmt", "stripFmt", XrmoptionSepArg, NULL},
  109. X    {"-editfmt", "editFmt", XrmoptionSepArg, NULL},
  110. X    {"-clocktick", "clockTick", XrmoptionSepArg, NULL},
  111. X    {"-u", "otherUser", XrmoptionSepArg, NULL},
  112. X};
  113. X
  114. Xstruct resources appResources;
  115. X
  116. XPixmap          HelpPix;
  117. XPixmap          HelpPressPix;
  118. XPixmap          IconPix;
  119. XPixmap          MouseOnPix;
  120. XPixmap          MouseOffPix;
  121. X
  122. XXtAppContext    appContext;
  123. X
  124. X#define offset(field) XtOffset(struct resources *, field)
  125. X
  126. Xstatic XtResource Resources[] = {
  127. X    {"debug", "Debug", XtRBoolean, sizeof(Boolean),
  128. X    offset(debug), XtRString, "False"},
  129. X        {"otherUser", "OtherUser", XtRString, sizeof(String),
  130. X        offset(otheruser), XtRString, NULL},
  131. X    {"alarmScan", "AlarmScan", XtRBoolean, sizeof(Boolean),
  132. X    offset(alarmScan), XtRString, "False"},
  133. X    {"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
  134. X    offset(reverseVideo), XtRString, "False"},
  135. X    {"xcalendarCompat", "XcalendarCompat", XtRBoolean, sizeof(Boolean),
  136. X    offset(calCompat), XtRString, "False"},
  137. X    {"giveHelp", "GiveHelp", XtRBoolean, sizeof(Boolean),
  138. X    offset(giveHelp), XtRString, "True"},
  139. X    {"helpFromFile", "HelpFromFile", XtRBoolean, sizeof(Boolean),
  140. X    offset(helpFromFile), XtRString, "True"},
  141. X        {"helpFile", "HelpFile", XtRString, sizeof(String),
  142. X        offset(helpfile), XtRString, "/usr/lib/X11/app-defaults/XCal.help"},
  143. X    {"useMemo", "UseMemo", XtRBoolean, sizeof(Boolean),
  144. X    offset(useMemo), XtRString, "True"},
  145. X    {"memoLeft", "MemoLeft", XtRBoolean, sizeof(Boolean),
  146. X    offset(memoLeft), XtRString, "True"},
  147. X    {"initialCalendar", "InitialCalendar", XtRBoolean, sizeof(Boolean),
  148. X    offset(initialCalendar), XtRString, "False"},
  149. X    {"initialEdit", "InitialEdit", XtRBoolean, sizeof(Boolean),
  150. X    offset(initialEdit), XtRString, "False"},
  151. X    {"initialMemo", "InitialMemo", XtRBoolean, sizeof(Boolean),
  152. X    offset(initialMemo), XtRString, "False"},
  153. X        {"format", "Format", XtRString, sizeof(String),
  154. X        offset(format), XtRString, "%A %d %B %Y"},
  155. X        {"stripFmt", "StripFmt", XtRString, sizeof(String),
  156. X        offset(stripfmt), XtRString, "%B %Y"},
  157. X        {"editFmt", "EditFmt", XtRString, sizeof(String),
  158. X        offset(editfmt), XtRString, "%A %d %B %Y"},
  159. X    {"clockTick", "ClockTick", XtRInt, sizeof(int),
  160. X    offset(clocktick), XtRString, "0"},
  161. X    {"markToday", "MarkToday", XtRBoolean, sizeof(Boolean),
  162. X    offset(markToday), XtRString, "True"},
  163. X    {"fontToday", "FontToday", XtRFontStruct, sizeof(XFontStruct *),
  164. X    offset(fontToday), XtRString, "XtDefaultFont"},
  165. X    {"todayForeground", "TodayForeground", XtRPixel, sizeof(Pixel),
  166. X    offset(today.fg), XtRString, "White"},
  167. X    {"todayBackground", "TodayBackground", XtRPixel, sizeof(Pixel),
  168. X    offset(today.bg), XtRString, "Black"},
  169. X    {"directory", "Directory", XtRString, sizeof(String),
  170. X    offset(directory), XtRString, "Calendar"},
  171. X    {"textBufferSize", "TextBufferSize", XtRInt, sizeof(int),
  172. X    offset(textbufsz), XtRString, "2048"},
  173. X    {"useWmTitle", "UseWmTitle", XtRBoolean, sizeof(Boolean),
  174. X    offset(useWmTitle), XtRString, "True"},
  175. X    {"minStripWidth", "MinStripWidth", XtRDimension, sizeof(Dimension),
  176. X    offset(minstripwidth), XtRString, "0"},
  177. X    /* set to screen size in the code */
  178. X    {"maxStripHeight", "MinStripHeight", XtRDimension, sizeof(Dimension),
  179. X    offset(maxstripheight), XtRString, "0"},
  180. X    {"january", "January", XtRString, sizeof(String),
  181. X    offset(mon[0]), XtRString, "January"},
  182. X    {"february", "February", XtRString, sizeof(String),
  183. X    offset(mon[1]), XtRString, "February"},
  184. X    {"march", "March", XtRString, sizeof(String),
  185. X    offset(mon[2]), XtRString, "March"},
  186. X    {"april", "April", XtRString, sizeof(String),
  187. X    offset(mon[3]), XtRString, "April"},
  188. X    {"may", "May", XtRString, sizeof(String),
  189. X    offset(mon[4]), XtRString, "May"},
  190. X    {"june", "June", XtRString, sizeof(String),
  191. X    offset(mon[5]), XtRString, "June"},
  192. X    {"july", "July", XtRString, sizeof(String),
  193. X    offset(mon[6]), XtRString, "July"},
  194. X    {"august", "August", XtRString, sizeof(String),
  195. X    offset(mon[7]), XtRString, "August"},
  196. X    {"september", "September", XtRString, sizeof(String),
  197. X    offset(mon[8]), XtRString, "September"},
  198. X    {"october", "October", XtRString, sizeof(String),
  199. X    offset(mon[9]), XtRString, "October"},
  200. X    {"november", "November", XtRString, sizeof(String),
  201. X    offset(mon[10]), XtRString, "November"},
  202. X    {"december", "December", XtRString, sizeof(String),
  203. X    offset(mon[11]), XtRString, "December"},
  204. X    {"jan", "Jan", XtRString, sizeof(String),
  205. X    offset(smon[0]), XtRString, "Jan"},
  206. X    {"feb", "Feb", XtRString, sizeof(String),
  207. X    offset(smon[1]), XtRString, "Feb"},
  208. X    {"mar", "Mar", XtRString, sizeof(String),
  209. X    offset(smon[2]), XtRString, "Mar"},
  210. X    {"apr", "Apr", XtRString, sizeof(String),
  211. X    offset(smon[3]), XtRString, "Apr"},
  212. X    {"may", "May", XtRString, sizeof(String),
  213. X    offset(smon[4]), XtRString, "May"},
  214. X    {"jun", "Jun", XtRString, sizeof(String),
  215. X    offset(smon[5]), XtRString, "Jun"},
  216. X    {"jul", "Jul", XtRString, sizeof(String),
  217. X    offset(smon[6]), XtRString, "Jul"},
  218. X    {"aug", "Aug", XtRString, sizeof(String),
  219. X    offset(smon[7]), XtRString, "Aug"},
  220. X    {"sep", "Sep", XtRString, sizeof(String),
  221. X    offset(smon[8]), XtRString, "Sep"},
  222. X    {"oct", "Oct", XtRString, sizeof(String),
  223. X    offset(smon[9]), XtRString, "Oct"},
  224. X    {"nov", "Nov", XtRString, sizeof(String),
  225. X    offset(smon[10]), XtRString, "Nov"},
  226. X    {"dec", "Dec", XtRString, sizeof(String),
  227. X    offset(smon[11]), XtRString, "Dec"},
  228. X    {"sunday", "Sunday", XtRString, sizeof(String),
  229. X    offset(day[0]), XtRString, "Sunday"},
  230. X    {"monday", "Monday", XtRString, sizeof(String),
  231. X    offset(day[1]), XtRString, "Monday"},
  232. X    {"tuesday", "Tuesday", XtRString, sizeof(String),
  233. X    offset(day[2]), XtRString, "Tuesday"},
  234. X    {"wednesday", "Wednesday", XtRString, sizeof(String),
  235. X    offset(day[3]), XtRString, "Wednesday"},
  236. X    {"thursday", "Thursday", XtRString, sizeof(String),
  237. X    offset(day[4]), XtRString, "Thursday"},
  238. X    {"friday", "Friday", XtRString, sizeof(String),
  239. X    offset(day[5]), XtRString, "Friday"},
  240. X    {"saturday", "Saturday", XtRString, sizeof(String),
  241. X    offset(day[6]), XtRString, "Saturday"},
  242. X    {"sun", "Sun", XtRString, sizeof(String),
  243. X    offset(sday[0]), XtRString, "Sun"},
  244. X    {"mon", "Mon", XtRString, sizeof(String),
  245. X    offset(sday[1]), XtRString, "Mon"},
  246. X    {"tue", "Tue", XtRString, sizeof(String),
  247. X    offset(sday[2]), XtRString, "Tue"},
  248. X    {"wed", "Wed", XtRString, sizeof(String),
  249. X    offset(sday[3]), XtRString, "Wed"},
  250. X    {"thu", "Thu", XtRString, sizeof(String),
  251. X    offset(sday[4]), XtRString, "Thu"},
  252. X    {"fri", "Fri", XtRString, sizeof(String),
  253. X    offset(sday[5]), XtRString, "Fri"},
  254. X    {"sat", "Sat", XtRString, sizeof(String),
  255. X    offset(sday[6]), XtRString, "Sat"},
  256. X    {"weekly", "Weekly", XtRString, sizeof(String),
  257. X    offset(weekly), XtRString, "Weekly"},
  258. X    {"alarms", "Alarms", XtRBoolean, sizeof(Boolean),
  259. X    offset(alarms), XtRString, "True"},
  260. X    {"execAlarms", "ExecAlarms", XtRBoolean, sizeof(Boolean),
  261. X     offset(execalarms), XtRString, "True"},
  262. X    {"alarmWarp", "AlarmWarp", XtRBoolean, sizeof(Boolean),
  263. X    offset(alarmWarp), XtRString, "False"},
  264. X    {"minAlarmWarp", "MinAlarmWarp", XtRInt, sizeof(int),
  265. X    offset(minAlarmWarp), XtRString, "7"},
  266. X    {"update", "Update", XtRInt, sizeof(int),
  267. X    offset(update), XtRString, "0"},
  268. X    {"volume", "Volume", XtRInt, sizeof(int),
  269. X    offset(volume), XtRString, "50"},
  270. X    {"nbeeps", "Nbeeps", XtRInt, sizeof(int),
  271. X    offset(nbeeps), XtRString, "3"},
  272. X    {"cmd", "Cmd", XtRString, sizeof(String),
  273. X    offset(cmd), XtRString, NULL},
  274. X    {"countdown", "Countdown", XtRString, sizeof(String),
  275. X    offset(countdown), XtRString, "10,0"},
  276. X    {"autoquit", "Autoquit", XtRInt, sizeof(int),
  277. X    offset(autoquit), XtRString, "120"},
  278. X    {"alarmleft", "Alarmleft", XtRString, sizeof(String),
  279. X    offset(alarmleft), XtRString, "%d minutes before..."},
  280. X    {"alarmnow", "Alarmnow", XtRString, sizeof(String),
  281. X    offset(alarmnow), XtRString, "Time is now..."},
  282. X    {"private", "Private", XtRString, sizeof(String),
  283. X    offset(private), XtRString, "Private calendar entry"},
  284. X    {"already", "Already", XtRString, sizeof(String),
  285. X    offset(already), XtRString, "Already editing %d %B %Y"},
  286. X    {"alreadyWeekly", "AlreadyWeekly", XtRString, sizeof(String),
  287. X    offset(alreadyWeekly), XtRString, "Already editing %A"},
  288. X    {"memoFile", "MemoFile", XtRString, sizeof(String),
  289. X    offset(memoFile), XtRString, "memo"},
  290. X    {"maxDisplayLines", "MaxDisplayLines", XtRInt, sizeof(int),
  291. X    offset(maxDisplayLines), XtRString, "5"},
  292. X};
  293. X
  294. Xstatic XtCallbackRec callbacks[] = {
  295. X    {NULL, NULL},
  296. X    {NULL, NULL},
  297. X};
  298. X#define ClearCallbacks() memset((caddr_t)callbacks, '\0', sizeof (callbacks))
  299. X
  300. Xstatic XtActionsRec appActions[] = {
  301. X    {"setdate", SetDate},
  302. X    {"leave", AskLeave},
  303. X    {"SetDateAction", TextCal},
  304. X    {"LoadDateAction", LoadDateStrip },
  305. X};
  306. X
  307. Xstatic String   defTranslations =
  308. X"<Btn2Down>: set()\n\
  309. X    <Btn2Up>:setdate() unset()\n\
  310. X    <Btn3Down>: set()\n\
  311. X    <Btn3Up>: leave() unset()";
  312. X
  313. XWidget          toplevel;
  314. X
  315. XWidget          mHelp;        /* popup help widget */
  316. X
  317. XDate            today;
  318. X
  319. Xint        updatefreq;    /* clock tick on the top level widget */
  320. X
  321. X/*
  322. X * external routines
  323. X */
  324. Xextern void     MainHelp();
  325. X
  326. X/*
  327. X * Forward routines local to this file
  328. X */
  329. Xvoid        AlterTitles();
  330. Xstatic void    ConvDate();
  331. Xstatic void     MkDate();
  332. Xstatic void     DebugMkDate();
  333. Xstatic void     PixInit();
  334. Xstatic int    CycleDays();
  335. Xstatic int    CycleMonths();
  336. Xstatic void    SetUpdateFreq();
  337. Xstatic int    UpdateFreq();
  338. Xstatic void    AdjustHeights();
  339. X
  340. X/*
  341. X *    Create the three components of the date strip
  342. X */
  343. Xstatic Widget    MemoWidget();
  344. Xstatic Widget    DateWidget();
  345. Xstatic Widget    HelpWidget();
  346. X
  347. X/*
  348. X * Your compiler may complain about the fact that some of the
  349. X * characters in these bitmaps are eight bits.
  350. X * If this worries you 
  351. X * #define UNSIGNED unsigned
  352. X */
  353. X#define UNSIGNED
  354. X
  355. X#include "calendar.bm"
  356. X#include "help.bm"
  357. X#include "help_press.bm"
  358. X#include "mouse.bm"
  359. X#include "mouseaway.bm"
  360. X#undef UNSIGNED
  361. X
  362. X/* defines fallbackResources */
  363. X#include "xcal_ad.h"
  364. X
  365. Xvoid
  366. Xmain(argc, argv)
  367. X    int            argc;
  368. X    char           *argv[];
  369. X{
  370. X
  371. X    Widget          parent;
  372. X    Widget          memo;
  373. X    Widget          lab;
  374. X    static Arg      iconArg[] = {
  375. X        {XtNiconPixmap, (XtArgVal) NULL},
  376. X    };
  377. X
  378. X
  379. X    toplevel = XtAppInitialize(&appContext, "XCal",
  380. X                Options, XtNumber(Options), &argc, argv,
  381. X                fallbackResources, NULL, 0);
  382. X
  383. X    PixInit(toplevel);
  384. X    iconArg[0].value = IconPix;
  385. X    XtSetValues(toplevel, iconArg, XtNumber(iconArg));
  386. X
  387. X    if (argc != 1)
  388. X        fprintf(stderr, "%s: Error in arguments\n", argv[0]);
  389. X
  390. X    XtGetApplicationResources(toplevel, (caddr_t) & appResources, Resources,
  391. X                  XtNumber(Resources), (ArgList) NULL, 0);
  392. X
  393. X    /*
  394. X     * If reverse video invert default colour settings
  395. X     */
  396. X    if (appResources.reverseVideo) {
  397. X        Colour          old;
  398. X        old = appResources.today;
  399. X        appResources.today.fg = old.bg;
  400. X        appResources.today.bg = old.fg;
  401. X    }
  402. X    
  403. X    if (!MyCalendar)
  404. X        AlterTitles();
  405. X    
  406. X    InitMonthEntries();
  407. X
  408. X    /* get a maximum initial size of the box */
  409. X    DoTemplate(date_area, sizeof(date_area), appResources.format);
  410. X
  411. X    parent = XtVaCreateManagedWidget("form", formWidgetClass, toplevel,
  412. X                       XtNborderWidth, 0,
  413. X                       XtNdefaultDistance, 0,
  414. X                      NULL);
  415. X    if (appResources.useMemo) {
  416. X        if (appResources.memoLeft) {
  417. X            memo = MemoWidget(parent, NULL);
  418. X            lab = DateWidget(parent, memo);
  419. X            if (appResources.giveHelp)
  420. X                mHelp = HelpWidget(parent, lab);
  421. X        } else {
  422. X            lab = DateWidget(parent, NULL);
  423. X            memo = MemoWidget(parent, lab);
  424. X            if (appResources.giveHelp)
  425. X                mHelp = HelpWidget(parent, memo);
  426. X        }
  427. X    } else {
  428. X        lab = DateWidget(parent, NULL);
  429. X        if (appResources.giveHelp)
  430. X            mHelp = HelpWidget(parent, lab);
  431. X    }
  432. X
  433. X    AdjustHeights(appResources.useMemo ? memo : NULL,
  434. X              lab,
  435. X              appResources.giveHelp ? mHelp : NULL);    
  436. X
  437. X    XtSetMappedWhenManaged(toplevel, False);
  438. X
  439. X    XtRealizeWidget(toplevel);    /* set the default geometry */
  440. X
  441. X    SetUpdateFreq(appResources.format);
  442. X
  443. X    if (appResources.debug) {
  444. X        fprintf(stderr, "Debug ON\n");
  445. X        DebugMkDate(lab);
  446. X    } else
  447. X        MkDate(lab);
  448. X
  449. X    XtAppAddActions(appContext, appActions, 4);    /* register actions */
  450. X    XtAugmentTranslations(lab, XtParseTranslationTable(defTranslations));
  451. X
  452. X    XtMapWidget(toplevel);
  453. X
  454. X    if (appResources.initialCalendar)
  455. X        DoCalendar(lab, NULL, NULL);
  456. X
  457. X    if (appResources.initialEdit) {
  458. X        MonthEntry     *me;
  459. X
  460. X        me = GetMonthEntry(today.year, today.month);
  461. X        if (me->me_have[today.day])
  462. X            StartEditing(lab, &today, NULL);
  463. X    }
  464. X    if (appResources.useMemo && appResources.initialMemo)
  465. X        DoMemo(memo, NULL, NULL);
  466. X
  467. X    InitAlarms();
  468. X
  469. X    XtAppMainLoop(appContext);
  470. X    exit(0);
  471. X}
  472. X
  473. X/*
  474. X *    Make three widgets for the main strip
  475. X */
  476. Xstatic Widget
  477. XMemoWidget(parent, horiz)
  478. X    Widget parent;
  479. X    Widget horiz;
  480. X{
  481. X    Widget ret;
  482. X    
  483. X    callbacks[0].callback = DoMemo;
  484. X    ret = XtVaCreateManagedWidget("today", commandWidgetClass, parent,
  485. X                XtNcallback, (XtArgVal) callbacks,
  486. X                XtNfromHoriz, horiz,
  487. X                XtNleft, XtChainLeft,
  488. X                XtNright, XtRubber,
  489. X                XtNborderWidth, 0,
  490. X                XtNbitmap, MouseOnPix,
  491. X                NULL);
  492. X    ClearCallbacks();
  493. X    return ret;
  494. X}
  495. X
  496. Xstatic Widget
  497. XDateWidget(parent, horiz)
  498. X    Widget    parent, horiz;
  499. X{
  500. X    Widget    ret;
  501. X
  502. X    callbacks[0].callback = DoCalendar;
  503. X    ret = XtVaCreateManagedWidget("date", commandWidgetClass, parent,
  504. X                XtNlabel, (XtArgVal) date_area,
  505. X                XtNcallback, (XtArgVal) callbacks,
  506. X                XtNfromHoriz, horiz,
  507. X                XtNleft, XtChainLeft,
  508. X                XtNright, XtRubber,
  509. X                XtNborderWidth, 0,
  510. X                NULL);
  511. X    ClearCallbacks();
  512. X    return ret;
  513. X}
  514. X
  515. Xstatic Widget
  516. XHelpWidget(parent, horiz)
  517. X    Widget    parent, horiz;
  518. X{
  519. X    Widget    ret;
  520. X
  521. X    callbacks[0].callback = MainHelp;
  522. X    ret = XtVaCreateManagedWidget("mainHelp", commandWidgetClass, parent,
  523. X                XtNcallback, (XtArgVal) callbacks,
  524. X                XtNfromHoriz, horiz,
  525. X                XtNleft, XtRubber,
  526. X                XtNright, XtChainRight,
  527. X                XtNborderWidth, 0,
  528. X                XtNbitmap, HelpPix,
  529. X                NULL);
  530. X    ClearCallbacks();
  531. X    return ret;
  532. X}
  533. X        
  534. X/*
  535. X * Initialise Pixmaps
  536. X */
  537. Xstatic void
  538. XPixInit(toplevel)
  539. X    Widget          toplevel;
  540. X{
  541. X    Display        *theDisplay = XtDisplay(toplevel);
  542. X
  543. X    HelpPix = XCreateBitmapFromData(theDisplay,
  544. X                    DefaultRootWindow(theDisplay),
  545. X                    help_bits, help_width, help_height);
  546. X    HelpPressPix = XCreateBitmapFromData(theDisplay,
  547. X                         DefaultRootWindow(theDisplay),
  548. X              help_press_bits, help_press_width, help_press_height);
  549. X    IconPix = XCreateBitmapFromData(theDisplay,
  550. X                    DefaultRootWindow(theDisplay),
  551. X                    cal_bits, cal_width, cal_height);
  552. X    MouseOnPix = XCreateBitmapFromData(theDisplay,
  553. X                       DefaultRootWindow(theDisplay),
  554. X                (char *) mouse_bits, mouse_width, mouse_height);
  555. X    MouseOffPix = XCreateBitmapFromData(theDisplay,
  556. X                        DefaultRootWindow(theDisplay),
  557. X        (char *) mouseaway_bits, mouseaway_width, mouseaway_height);
  558. X}
  559. X
  560. X/*
  561. X *    Adjust height of the command box
  562. X */
  563. Xstatic void
  564. XAdjustHeights(memo, date, help)
  565. X    Widget    memo;
  566. X    Widget    date;
  567. X    Widget    help;
  568. X{
  569. X    Dimension hm, hd, hh, max;
  570. X
  571. X    hm = memo ? wHeight(memo): 0;
  572. X    hd = date ? wHeight(date): 0;
  573. X    hh = help ? wHeight(help): 0;
  574. X    
  575. X    max = hm;
  576. X    max = (hd > max) ? hd : max;
  577. X    max = (hh > max) ? hh : max;
  578. X
  579. X    if (hm && hm < max)
  580. X        SetWidgetHeightMax(memo, hm, max);
  581. X    if (hd && hd < max)
  582. X        SetWidgetHeightMax(date, hd, max);
  583. X    if (hh && hh < max)
  584. X        SetWidgetHeightMax(help, hh, max);
  585. X}
  586. X
  587. Xvoid
  588. XSetWidgetHeightMax(w, h, max)
  589. X    Widget        w;
  590. X    Dimension     h;
  591. X    Dimension     max;
  592. X{
  593. X    Arg    args[3];
  594. X    int    adj;
  595. X
  596. X    adj = ((int)max - (int)h)/2;
  597. X    if (adj > 0) {
  598. X        XtSetArg(args[0], XtNvertDistance, adj);
  599. X        XtSetArg(args[1], XtNfromVert, NULL);
  600. X        XtSetValues(w, args, 2);
  601. X    }
  602. X}
  603. X
  604. X/*
  605. X * If we are not dealing with our calendar entries add
  606. X * (user-name)
  607. X * to the end of the date format strings
  608. X */
  609. Xvoid
  610. XAlterTitles()
  611. X{
  612. X    char    us[16];
  613. X    char    fmt[256];
  614. X
  615. X    (void) sprintf(us, " (%s)", appResources.otheruser);
  616. X
  617. X    /* I am unsure whether it is safe to free these strings */
  618. X#define cstr(v) { strcpy(fmt, v); strcat(fmt, us); v = XtNewString(fmt); }
  619. X    cstr(appResources.format);
  620. X    cstr(appResources.stripfmt);
  621. X    cstr(appResources.editfmt);
  622. X#undef cstr
  623. X}
  624. X    
  625. X/*
  626. X * Flip mouse state
  627. X */
  628. Xvoid
  629. XMouseShow(w, OnOff)
  630. X    Widget          w;
  631. X    Boolean         OnOff;
  632. X{
  633. X    Arg             arg[1];
  634. X
  635. X    XtSetArg(arg[0], XtNbitmap, OnOff ? MouseOnPix : MouseOffPix);
  636. X    XtSetValues(w, arg, 1);
  637. X}
  638. X
  639. X/*
  640. X * Flip help state
  641. X */
  642. Xvoid
  643. XHelpShow(w, Pressed)
  644. X    Widget          w;
  645. X    Boolean         Pressed;
  646. X{
  647. X    Arg             arg[1];
  648. X
  649. X    XtSetArg(arg[0], XtNbitmap, Pressed ? HelpPressPix : HelpPix);
  650. X    XtSetValues(w, arg, 1);
  651. X}
  652. X
  653. X
  654. X/*
  655. X * Exit routine
  656. X */
  657. Xvoid
  658. XLeave(retval)
  659. X    int             retval;
  660. X{
  661. X    exit(retval);
  662. X}
  663. X
  664. X/************************************************************************/
  665. X/*                                    */
  666. X/*                                    */
  667. X/*      This deals with the top level date `icon'            */
  668. X/*                                    */
  669. X/*                                    */
  670. X/************************************************************************/
  671. X/*
  672. X * Time management code
  673. X * Set up a Date structure from today's information
  674. X */
  675. Xstatic void
  676. XConvDate(tm, dp)
  677. X        struct tm      *tm;
  678. X        Date           *dp;
  679. X{
  680. X        dp->day = tm->tm_mday;
  681. X        dp->month = tm->tm_mon;
  682. X        dp->year = tm->tm_year + 1900;
  683. X        dp->wday = tm->tm_wday;
  684. X}
  685. X
  686. Xvoid
  687. XFmtTime(tm, buf, len, fmt)
  688. X    struct tm     *tm;
  689. X    char        *buf;
  690. X    int         len;
  691. X    char        *fmt;
  692. X    
  693. X{
  694. X    if (strftime(buf, len, fmt, tm) == 0) {
  695. X        strftime(buf, len, "%A %e %B %Y", tm);
  696. X    }
  697. X}
  698. X
  699. Xvoid
  700. XFmtDate(da, buf, len, fmt)
  701. X    Date    *da;
  702. X    char    *buf;
  703. X    int    len;
  704. X    char    *fmt;
  705. X{
  706. X    if (strfdate(buf, len, fmt, da) == 0) {
  707. X        strfdate(buf, len, "%A %e %B %Y", da);
  708. X    }
  709. X}
  710. X    
  711. Xstatic void
  712. XDebugMkDate(w)
  713. X    Widget          w;
  714. X{
  715. X    static long     ti;
  716. X    struct tm      *tm;
  717. X    Date            yesterday;
  718. X    static        firsttime;
  719. X
  720. X    yesterday = today;
  721. X
  722. X    if (ti == 0)
  723. X        (void) time(&ti);
  724. X    else 
  725. X        ti += updatefreq;
  726. X    tm = localtime(&ti);
  727. X
  728. X        ConvDate(tm, &today);
  729. X
  730. X    FmtTime(tm, date_area, sizeof(date_area), appResources.format);
  731. X
  732. X    XtVaSetValues(w, XtNlabel, (XtArgVal) date_area, NULL);
  733. X
  734. X    if (firsttime != 0) {
  735. X        if (yesterday.day != today.day) {
  736. X            ChangeHighlight(&yesterday, &today);
  737. X            AlarmFilePoll(tm);
  738. X        }
  739. X        UpdateMemo();
  740. X    }
  741. X    firsttime = 1;
  742. X    XtAppAddTimeOut(appContext, (updatefreq < 60) ? 25 : 500, DebugMkDate, (caddr_t) w);
  743. X}
  744. X
  745. Xstatic void
  746. XMkDate(w)
  747. X    Widget          w;
  748. X{
  749. X    long            ti;
  750. X    struct tm      *tm;
  751. X    Date            yesterday;
  752. X    static        firsttime;
  753. X
  754. X    yesterday = today;
  755. X
  756. X    (void) time(&ti);
  757. X    tm = localtime(&ti);
  758. X
  759. X        ConvDate(tm, &today);
  760. X
  761. X    FmtTime(tm, date_area, sizeof(date_area), appResources.format);
  762. X
  763. X    XtVaSetValues(w, XtNlabel, (XtArgVal) date_area, NULL);
  764. X
  765. X    if (firsttime != 0) {
  766. X        if (yesterday.day != today.day) {
  767. X            ChangeHighlight(&yesterday, &today);
  768. X            AlarmFilePoll(tm);
  769. X        }
  770. X        UpdateMemo();
  771. X    }
  772. X    firsttime = 1;
  773. X    
  774. X    ti = ClockSync(tm, updatefreq);
  775. X    XtAppAddTimeOut(appContext, ti * 1000, MkDate, (caddr_t) w);
  776. X}
  777. X
  778. X/*
  779. X * Given a time structure and a frequency in secs
  780. X * return no of secs to hit that interval
  781. X */
  782. Xlong
  783. XClockSync(tm, freq)
  784. X    struct    tm     *tm;
  785. X    long        freq;
  786. X{
  787. X    long    ti;
  788. X
  789. X    ti = freq;
  790. X    if (ti > 1 && ti < 60)
  791. X        ti -= tm->tm_sec%freq;
  792. X    else
  793. X    if (ti >= 60 && ti < 3600)
  794. X        ti -= (tm->tm_min*60 + tm->tm_sec)%freq;
  795. X    else
  796. X    if (ti >= 3600)
  797. X        ti -= (tm->tm_hour*60*60 + tm->tm_min*60 + tm->tm_sec)%freq;
  798. X    return ti;
  799. X}
  800. X
  801. X/*
  802. X * DoTemplate
  803. X * place an initial string into the date area so that the label
  804. X * box will always be big enough
  805. X */
  806. Xvoid
  807. XDoTemplate(buf, len, fmt)
  808. X    char    *buf;
  809. X    size_t    len;
  810. X    char    *fmt;
  811. X{
  812. X    Tm     *tm;
  813. X    Tm      tml;    
  814. X    time_t    ti;
  815. X    
  816. X    time(&ti);
  817. X    tm = localtime(&ti);
  818. X
  819. X    tml = *tm;    /* it seems that Solaris is unhappy when you */
  820. X    tm = &tml;    /* poke values into its own structure */
  821. X            /* but is OK if you have your own */
  822. X    /* generate a maximal structure */
  823. X    tm->tm_sec = 59;
  824. X    tm->tm_min = 59;
  825. X    tm->tm_hour = 23;
  826. X    tm->tm_mday = 27;
  827. X    tm->tm_mon = CycleMonths();
  828. X    tm->tm_year = 93;
  829. X    tm->tm_wday = CycleDays();
  830. X    FmtTime(tm, buf, len, fmt);
  831. X}
  832. X
  833. Xstatic int
  834. XCycleDays()
  835. X{
  836. X    int    max = 0;
  837. X    int    maxday = 0;
  838. X    char    buf[BUFSIZ];
  839. X    struct tm tm;
  840. X    int    d;
  841. X    int    len;
  842. X
  843. X    for (d = 0; d < 7; d++) {
  844. X        tm.tm_wday = d;
  845. X        len = strftime(buf, sizeof buf, "%A", &tm);
  846. X        if (len > max) {
  847. X            maxday = d;
  848. X            max = len;
  849. X        }
  850. X    }
  851. X    return maxday;
  852. X}
  853. X
  854. Xstatic int
  855. XCycleMonths()
  856. X{
  857. X    int    max = 0;
  858. X    int    maxmon = 0;
  859. X    char    buf[BUFSIZ];
  860. X    struct tm tm;
  861. X    int    d;
  862. X    int    len;
  863. X
  864. X    for (d = 0; d < 11; d++) {
  865. X        tm.tm_mon = d;
  866. X        len = strftime(buf, sizeof buf, "%B", &tm);
  867. X        if (len > max) {
  868. X            maxmon = d;
  869. X            max = len;
  870. X        }
  871. X    }
  872. X    return maxmon;
  873. X}
  874. X
  875. X/*
  876. X * Look to see if we need to do something more than poll daily to change
  877. X * the main toplevel strip
  878. X */
  879. Xstatic void
  880. XSetUpdateFreq(fmt)
  881. X    char    *fmt;
  882. X{    
  883. X    updatefreq = UpdateFreq(fmt);
  884. X    if (appResources.clocktick && updatefreq && 
  885. X        updatefreq < appResources.clocktick)
  886. X        updatefreq = appResources.clocktick;
  887. X    if (updatefreq == 0)
  888. X        updatefreq = 24*60*60;
  889. X}
  890. X
  891. X
  892. X/*
  893. X * Scan the time format string looking for an update frequency
  894. X */
  895. Xstatic int
  896. XUpdateFreq(fmt)
  897. X    char *fmt;
  898. X{
  899. X    int    update = 0;
  900. X#define    minu(v)    update = (update == 0 ? v : ((update < v) ? update : v))
  901. X
  902. X    for(;*fmt; ++fmt) {
  903. X        if (*fmt == '%')
  904. X            switch(*++fmt) {
  905. X            case '\0':
  906. X                --fmt;
  907. X                break;
  908. X            case 'C':
  909. X            case 'c':
  910. X            case 'r':
  911. X            case 'S':
  912. X            case 's':
  913. X            case 'T':
  914. X            case 'X':
  915. X                minu(1);    /* every second */
  916. X                break;
  917. X            case 'M':
  918. X            case 'R':
  919. X                minu(60);    /* every minute */
  920. X                break;
  921. X            case 'H':
  922. X            case 'h':
  923. X            case 'I':
  924. X            case 'k':
  925. X            case 'l':
  926. X                minu(3600);    /* every hour */
  927. X                break;
  928. X            case 'p':
  929. X            case 'P':
  930. X                minu(43200);    /* AM/PM */
  931. X                break;
  932. X            }
  933. X    }
  934. X    return update;
  935. X}
  936. END_OF_FILE
  937. if test 23399 -ne `wc -c <'xcal.c'`; then
  938.     echo shar: \"'xcal.c'\" unpacked with wrong size!
  939. fi
  940. # end of 'xcal.c'
  941. fi
  942. if test -f 'xcal_alarm.c' -a "${1}" != "-c" ; then 
  943.   echo shar: Will not clobber existing file \"'xcal_alarm.c'\"
  944. else
  945. echo shar: Extracting \"'xcal_alarm.c'\" \(19473 characters\)
  946. sed "s/^X//" >'xcal_alarm.c' <<'END_OF_FILE'
  947. X#ifndef lint
  948. Xstatic char    *sccsid = "@(#)xcal_alarm.c    1.24 (Hillside Systems) 10/29/93";
  949. Xstatic char    *copyright = "@(#)Copyright 1989,1990,1993 Mark Majhor, Peter Collinson";
  950. X#endif                /* lint */
  951. X/***
  952. X
  953. X* module name:
  954. X    xcal_alarm.c
  955. X* function:
  956. X    Deal with editable days
  957. X    This is derived from xcalendar's view of how to store things
  958. X* history:
  959. X    Original idea and code from
  960. X    Mark Majhor, Sequent written August 1990, received Sept 1990
  961. X    I have reworked most of the code and algorithms
  962. X    Peter Collinson
  963. X    Hillside Systems
  964. X
  965. X* (C) Copyright: 1989/1990 Hillside Systems/Peter Collinson/Mark Majhor
  966. X    
  967. X    For full permissions and copyright notice - see xcal.c
  968. X    
  969. X***/
  970. X#include <X11/IntrinsicP.h>    /* for toolkit stuff */
  971. X#include <X11/Intrinsic.h>
  972. X#include <X11/Xos.h>
  973. X#include <X11/StringDefs.h>    /* for useful atom names */
  974. X#include <X11/Shell.h>
  975. X#include <X11/Xaw/AsciiText.h>
  976. X#include <X11/Xaw/Text.h>
  977. X#include <X11/Xaw/Command.h>
  978. X#include <X11/Xaw/Label.h>
  979. X#include <X11/Xaw/Form.h>
  980. X#include <X11/Xaw/Paned.h>
  981. X#include <stdio.h>        /* for printing error messages */
  982. X#include <ctype.h>
  983. X#include <sys/stat.h>        /* for stat() */
  984. X#include <pwd.h>        /* for getting username */
  985. X#include <errno.h>
  986. X#include "xcal.h"
  987. X
  988. X#ifndef wordBreak
  989. X#define wordBreak    0x01
  990. X#define scrollVertical    0x02
  991. X#endif
  992. X
  993. Xstatic char    *LocalMapStem;
  994. Xstatic int    LocalMapStemMade;    /* day when LocalMapStem made last */
  995. Xstatic struct stat localstat;
  996. Xstatic char    *TodayFile;
  997. Xstatic struct stat todaystat;
  998. Xstatic Alarm    head;
  999. Xstatic int     *countDown;
  1000. Xstatic int      countDownCt;
  1001. X
  1002. Xstatic XtCallbackRec callbacks[] = {
  1003. X    {NULL, NULL},
  1004. X    {NULL, NULL}
  1005. X};
  1006. X
  1007. X#define    dprintf    if (appResources.alarmScan) printf
  1008. X
  1009. X#define    MINUTES(hr, mn)    ((hr)*60 + (mn))
  1010. X
  1011. X#define argLD(N,V) { XtSetArg(args[nargs], N, V); nargs++; }
  1012. X
  1013. X/*
  1014. X * Local routines
  1015. X */
  1016. Xstatic void     AlarmScan();
  1017. Xstatic void     FreeAlarmList();
  1018. Xstatic void     setCall();
  1019. Xstatic void     beep();
  1020. Xstatic void     AddAlarm();
  1021. Xstatic void     DisplayAlarmWindow();
  1022. Xstatic void     DestroyAlarm();
  1023. Xstatic void     HoldAlarm();
  1024. Xstatic void     AutoDestroy();
  1025. Xstatic void    AlarmEvent();
  1026. Xstatic void    ClockTick();
  1027. Xstatic void    AlarmsOff();
  1028. Xstatic int      readDataLine();
  1029. Xstatic String    CreateCommand();
  1030. Xstatic int    ReloadAlarms();
  1031. X
  1032. X/*
  1033. X * Initialise variables for the alarm mechanism
  1034. X */
  1035. Xvoid
  1036. XInitAlarms()
  1037. X{
  1038. X    register char  *str;
  1039. X    register char  *wk;
  1040. X    register        ct;
  1041. X    register int   *p;
  1042. X    char           *XtMalloc();
  1043. X
  1044. X    if (!MyCalendar)
  1045. X        return;
  1046. X
  1047. X    if (appResources.alarms == False) {
  1048. X        dprintf("Alarms not enabled\n");
  1049. X        return;
  1050. X    }
  1051. X    dprintf("Alarms on\n");
  1052. X    /*
  1053. X     * Interpret the countDown string established
  1054. X     * by user - turn this into a vector
  1055. X     * countDown -> points to a vector of integers
  1056. X     *    indicating the number of mins each alarm will be set
  1057. X     * countDownCt - the number of integers in the vector
  1058. X     */
  1059. X    if (str = appResources.countdown) {
  1060. X        for (wk = str, ct = 0; *wk; wk++)
  1061. X            if (*wk == ',')
  1062. X                ct++;
  1063. X        ct++;        /* no of things to store */
  1064. X
  1065. X        countDown = (int *) XtMalloc(sizeof(int) * (ct + 2));
  1066. X
  1067. X        p = countDown;
  1068. X        while (*str)
  1069. X            if (!isdigit(*str))
  1070. X                str++;
  1071. X            else
  1072. X                break;
  1073. X        while (*str) {
  1074. X            *p = 0;
  1075. X            ct = 0;
  1076. X            while (isdigit(*str))
  1077. X                ct = ct * 10 + *str++ - '0';
  1078. X            *p++ = ct;
  1079. X            countDownCt++;
  1080. X            while (*str && !isdigit(*str))
  1081. X                str++;
  1082. X        }
  1083. X    }
  1084. X    if (appResources.update)
  1085. X        ClockTick(0, 0);
  1086. X    else
  1087. X        AlarmFilePoll(0);
  1088. X}
  1089. X
  1090. X
  1091. X/*
  1092. X * ClockTick is polled every minute (update) to see if the data file has
  1093. X * altered - if so then a new data list is built
  1094. X */
  1095. Xstatic void
  1096. XClockTick(client_data, id)
  1097. X    caddr_t         client_data;
  1098. X    XtIntervalId   *id;
  1099. X{
  1100. X    long            secs;
  1101. X    time_t          ti;
  1102. X    struct tm      *tm;
  1103. X
  1104. X
  1105. X    ti = time(0);
  1106. X    tm = localtime(&ti);
  1107. X
  1108. X    dprintf("ClockTick %d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
  1109. X
  1110. X    secs = ClockSync(tm, appResources.update);
  1111. X    (void) XtAppAddTimeOut(appContext, secs * 1000,
  1112. X                (XtTimerCallbackProc) ClockTick,
  1113. X                (caddr_t) NULL);
  1114. X    AlarmFilePoll(tm);
  1115. X    MemoPoll();
  1116. X}
  1117. X
  1118. Xvoid
  1119. XAlarmFilePoll(tm)
  1120. X    struct tm      *tm;
  1121. X{
  1122. X    time_t          ti;
  1123. X    int        mnow;
  1124. X    int             files, changed;
  1125. X    struct stat    oldstat;
  1126. X    char           *home;
  1127. X    char            buf[256];
  1128. X    Alarm        *old;
  1129. X
  1130. X    if (appResources.alarms == False)
  1131. X        return;
  1132. X
  1133. X    if (tm == NULL) {
  1134. X        ti = time(0);
  1135. X        tm = localtime(&ti);
  1136. X    }
  1137. X    /*
  1138. X     * Create the name of the data file in a cache to save energy
  1139. X     */
  1140. X    if (LocalMapStemMade != tm->tm_mday) {
  1141. X        LocalMapStemMade = tm->tm_mday;
  1142. X        if (appResources.calCompat == False) {
  1143. X            (void) sprintf(buf, "%s/xy%d/xc%d%s%d",
  1144. X                       MapStem,
  1145. X                       tm->tm_year + 1900,
  1146. X                       tm->tm_mday,
  1147. X                       appResources.smon[tm->tm_mon],
  1148. X                       tm->tm_year + 1900);
  1149. X        } else {
  1150. X            (void) sprintf(buf, "%s/xc%d%s%d",
  1151. X                       MapStem,
  1152. X                        tm->tm_mday,
  1153. X                       appResources.smon[tm->tm_mon],
  1154. X                       tm->tm_year + 1900);
  1155. X        }
  1156. X        if (LocalMapStem)
  1157. X            XtFree(LocalMapStem);
  1158. X        LocalMapStem = XtNewString(buf);
  1159. X        dprintf("Todays Daily Filename = %s\n", LocalMapStem);
  1160. X
  1161. X        if (TodayFile)
  1162. X            XtFree(TodayFile);
  1163. X
  1164. X        TodayFile = XtNewString(MakeWeeklyName(today.wday));
  1165. X
  1166. X        memset(&localstat, '\0', sizeof (struct stat));
  1167. X        memset(&todaystat, '\0', sizeof (struct stat));
  1168. X    }
  1169. X    files = 0;
  1170. X    changed = 0;
  1171. X    /*
  1172. X     * check for file existence
  1173. X     */
  1174. X    if (access(LocalMapStem, F_OK) == 0) {
  1175. X        files = 1;
  1176. X        oldstat = localstat;
  1177. X        (void) stat(LocalMapStem, &localstat);
  1178. X        if (oldstat.st_mtime != localstat.st_mtime ||
  1179. X            oldstat.st_ctime != localstat.st_ctime)
  1180. X            changed = 1;
  1181. X    }
  1182. X    if (access(TodayFile, F_OK) == 0) {
  1183. X        files |= 2;
  1184. X        oldstat = todaystat;
  1185. X        (void) stat(TodayFile, &todaystat);
  1186. X        if (oldstat.st_mtime != todaystat.st_mtime ||
  1187. X            oldstat.st_ctime != todaystat.st_ctime)
  1188. X            changed |= 2;
  1189. X    }
  1190. X
  1191. X    old = NULL;
  1192. X    if (changed) {
  1193. X        old = head.next;
  1194. X        head.next = NULL;
  1195. X    }
  1196. X    if (files) {
  1197. X        if (changed) {
  1198. X            mnow = MINUTES(tm->tm_hour, tm->tm_min);
  1199. X            if (files & 1)
  1200. X                AlarmScan(LocalMapStem, tm, mnow);
  1201. X            if (files & 2)
  1202. X                AlarmScan(TodayFile, tm, mnow);
  1203. X            /* check on any extant alarm */
  1204. X            if (ReloadAlarms(old, mnow))
  1205. X                AlarmsOff();
  1206. X            if (appResources.interval_id == 0 && head.next)
  1207. X                setCall();
  1208. X        }
  1209. X    } else
  1210. X        dprintf("No files to scan\n");
  1211. X
  1212. X    if (old)
  1213. X        FreeAlarmList(old);
  1214. X
  1215. X    UpdateMemo();
  1216. X}
  1217. X
  1218. Xstatic int
  1219. XReloadAlarms(old, mnow)
  1220. X    Alarm           *old;
  1221. X    int        mnow;
  1222. X{
  1223. X    Alarm           *prev;
  1224. X
  1225. X    dprintf("Checking old alarm details\n");
  1226. X    if (head.next == NULL) {
  1227. X        if (old) {
  1228. X            dprintf("No new alarms, stop old running\n");
  1229. X            return 1;
  1230. X        }
  1231. X    }
  1232. X    else if (head.next->alarm_mm <= mnow && 
  1233. X             (old == NULL ||
  1234. X           old->alarm_mm > head.next->alarm_mm)) {
  1235. X        /* 
  1236. X         * this looks different but let's be careful
  1237. X         * if the entries on the new list are earlier
  1238. X         * than those on the old - then we have
  1239. X         * serviced those requests and we need to
  1240. X         * ensure that we don't fire them again
  1241. X         */
  1242. X        while (head.next && head.next->alarm_mm <= mnow &&
  1243. X               (old == NULL ||
  1244. X                old->alarm_mm > head.next->alarm_mm)) {
  1245. X            dprintf("Discard alarm\n");
  1246. X            XtFree(head.next->alarm);
  1247. X            XtFree(head.next->what);
  1248. X            prev = head.next;
  1249. X            head.next = prev->next;
  1250. X            XtFree((char *)prev);
  1251. X        }
  1252. X        return (ReloadAlarms(old, mnow));
  1253. X    }
  1254. X    else if (old && old->alarm_mm != head.next->alarm_mm) {
  1255. X        dprintf("First new alarm differs from old, stop old alarm\n");
  1256. X        dprintf("Old: %d %s %s\n", old->alarm_mm, old->alarm, old->what);
  1257. X        dprintf("New: %d %s %s\n", head.next->alarm_mm, head.next->alarm, head.next->what);
  1258. X        return 1;
  1259. X    }
  1260. X    return 0;
  1261. X}
  1262. X
  1263. Xstatic void
  1264. XAlarmScan(file, tm, mnow)
  1265. X    String          file;
  1266. X    struct tm      *tm;
  1267. X    int             mnow;
  1268. X{
  1269. X    FILE           *fp;
  1270. X    char            hrstr[16];
  1271. X    char            remline[256];
  1272. X    char           *rem;
  1273. X    int             hr, mn;
  1274. X    Boolean         isAction;
  1275. X
  1276. X
  1277. X    dprintf("Scanning data file %s\n", file);
  1278. X
  1279. X    if ((fp = fopen(file, "r")) == NULL) {
  1280. X        fprintf(stderr, "Unexpected failure to open: %s\n", file);
  1281. X        exit(1);
  1282. X    }
  1283. X    while (readDataLine(fp, &hr, &mn, hrstr, remline)) {
  1284. X        /* see if we have an action string to do */
  1285. X        isAction = False;
  1286. X        rem = remline;
  1287. X        if (*rem == '!' || strncmp(remline, "%cron", 5) == 0) {
  1288. X            if (appResources.execalarms == False)
  1289. X                continue;
  1290. X            isAction = True;
  1291. X            if (*rem == '!')
  1292. X                rem++;
  1293. X            else    rem += 5;
  1294. X            while (isspace(*rem))
  1295. X                rem++;
  1296. X            if (*rem == '\0')
  1297. X                continue;
  1298. X        }
  1299. X        AddAlarm(mnow, isAction, hr, mn, hrstr, rem);
  1300. X    }
  1301. X    (void) fclose(fp);
  1302. X}
  1303. X
  1304. X/*
  1305. X * The idea here is to generate a sorted event list - one element for each
  1306. X * event. We will discard anything that has already happened
  1307. X */
  1308. Xstatic void
  1309. XAddAlarm(mnow, exec, hr, mn, hrstr, rem)
  1310. X    int             mnow;
  1311. X    Boolean         exec;
  1312. X    int             hr;
  1313. X    int             mn;
  1314. X    char           *hrstr;
  1315. X    char           *rem;
  1316. X{
  1317. X
  1318. X    Alarm          *al, *prev, *new;
  1319. X    char           *XtMalloc();
  1320. X    int             al_hr, al_mn, mm;
  1321. X    int             loop;
  1322. X    int             zero = 0;
  1323. X    int            *p;
  1324. X
  1325. X    if (exec || countDownCt == 0) {
  1326. X        loop = 1;
  1327. X        p = &zero;
  1328. X    } else {
  1329. X        loop = countDownCt;
  1330. X        p = countDown;
  1331. X    }
  1332. X
  1333. X    for (; loop--; p++) {
  1334. X        al_hr = hr;
  1335. X        al_mn = mn;
  1336. X        if (*p) {
  1337. X            al_mn -= *p;
  1338. X            if (al_mn < 0) {
  1339. X                al_mn += 60;
  1340. X                al_hr--;
  1341. X                if (al_hr < 0)
  1342. X                    continue;
  1343. X            }
  1344. X        }
  1345. X        if ((mm = MINUTES(al_hr, al_mn)) < mnow)
  1346. X            continue;
  1347. X
  1348. X        new = (Alarm *) XtMalloc(sizeof(Alarm));
  1349. X        new->alarm = XtNewString(hrstr);
  1350. X        new->what = XtNewString(rem);
  1351. X        new->alarm_mm = mm;
  1352. X        new->alarm_state = *p;
  1353. X        new->isAction = exec;
  1354. X        new->next = NULL;
  1355. X
  1356. X        /* now insert into correct place in List */
  1357. X        if (head.next == NULL) {
  1358. X            head.next = new;
  1359. X            dprintf("%s - %s; alarm at %02d:%02d\n",
  1360. X                hrstr, rem, al_hr, al_mn);
  1361. X        } else {
  1362. X            for (prev = &head, al = head.next; al; prev = al, al = prev->next)
  1363. X                if (mm < al->alarm_mm)
  1364. X                    break;
  1365. X            prev->next = new;
  1366. X            new->next = al;
  1367. X            dprintf("%s - %s; alarm at %02d:%02d\n",
  1368. X                hrstr, rem, al_hr, al_mn);
  1369. X        }
  1370. X    }
  1371. X}
  1372. X
  1373. X/*
  1374. X * read a line looking for a time spec and some data
  1375. X * return 1 if found
  1376. X * return 0 at end
  1377. X * Time spec is: hhmm hmm
  1378. X * hh:mm hh.mm
  1379. X * h:mm h.mm
  1380. X * all above may be optionally followed by:
  1381. X * A a AM am Am aM P p PM pm Pm pM
  1382. X * the string is terminated by a space or a tab
  1383. X */
  1384. Xstatic int
  1385. XreadDataLine(fin, hrp, minp, timestr, remline)
  1386. X    FILE           *fin;
  1387. X    int            *hrp;
  1388. X    int            *minp;
  1389. X    char           *timestr;
  1390. X    char           *remline;
  1391. X{
  1392. X    register enum readState {
  1393. X        Ignore, Hr1, Hr2, HrSep,
  1394. X        Mn1, Mn2, AmPm, LoseM,
  1395. X        LookSp, LoseSp, Store, AllDone
  1396. X    }               state;
  1397. X    register int    c = 0;
  1398. X    int             hr = 0, mn = 0;
  1399. X    char           *destp;
  1400. X    Boolean        foundampm = False;
  1401. X
  1402. X    if (feof(fin))
  1403. X        return 0;
  1404. X
  1405. X    state = Hr1;
  1406. X
  1407. X    while (state != AllDone) {
  1408. X        if ((c = getc(fin)) == EOF) {
  1409. X            if (state == Store)
  1410. X                break;
  1411. X            return 0;
  1412. X        }
  1413. X        switch (state) {
  1414. X        case Ignore:
  1415. X            if (c == '\n')
  1416. X                state = Hr1;
  1417. X            continue;
  1418. X        case Hr1:
  1419. X            destp = timestr;
  1420. X            if (isdigit(c)) {
  1421. X                hr = c - '0';
  1422. X                mn = 0;
  1423. X                destp = timestr;
  1424. X                *destp = '\0';
  1425. X                state = Hr2;
  1426. X                break;
  1427. X            }
  1428. X            state = (c == '\n' ? Hr1 : Ignore);
  1429. X            continue;
  1430. X        case Hr2:
  1431. X            if (isdigit(c)) {
  1432. X                hr = hr * 10 + c - '0';
  1433. X                state = HrSep;
  1434. X                break;
  1435. X            }
  1436. X            /* Falls through to .. */
  1437. X        case HrSep:
  1438. X            if (c == ':' || c == '.') {
  1439. X                state = Mn1;
  1440. X                break;
  1441. X            }
  1442. X            /* Falls through to .. */
  1443. X        case Mn1:
  1444. X            if (isdigit(c)) {
  1445. X                mn = c - '0';
  1446. X                state = Mn2;
  1447. X                break;
  1448. X            }
  1449. X            /* Falls through to .. */
  1450. X        case Mn2:
  1451. X            if (isdigit(c)) {
  1452. X                mn = mn * 10 + c - '0';
  1453. X                state = AmPm;
  1454. X                break;
  1455. X            } else if (state == Mn2) {
  1456. X                state = (c == '\n' ? Hr1 : Ignore);
  1457. X                continue;
  1458. X            }
  1459. X            /* Falls through to .. */
  1460. X        case AmPm:
  1461. X            if (c == 'a' || c == 'A') {
  1462. X                if (hr == 12)
  1463. X                    hr = 0;
  1464. X                foundampm = True;
  1465. X                state = LoseM;
  1466. X                break;
  1467. X            } else if (c == 'p' || c == 'P') {
  1468. X                if (hr < 12)
  1469. X                    hr += 12;
  1470. X                foundampm = True;
  1471. X                state = LoseM;
  1472. X                break;
  1473. X            }
  1474. X            /* Falls through to .. */
  1475. X        case LoseM:
  1476. X            if (c == 'M' || c == 'm') {
  1477. X                state = LookSp;
  1478. X                break;
  1479. X            }
  1480. X            /* Falls through to .. */
  1481. X        case LookSp:
  1482. X            if (c == ' ' || c == '\t') {
  1483. X                state = LoseSp;
  1484. X                if (hr >= 24 || mn >= 60)
  1485. X                    state = Ignore;
  1486. X                destp = remline;
  1487. X                *destp = '\0';
  1488. X                continue;
  1489. X            } else {
  1490. X                state = (c == '\n' ? Hr1 : Ignore);
  1491. X                continue;
  1492. X            }
  1493. X            break;
  1494. X        case LoseSp:
  1495. X            if (c == ' ' || c == '\t')
  1496. X                continue;
  1497. X            state = Store;
  1498. X            /* Falls through to .. */
  1499. X        case Store:
  1500. X            if (c == '\n') {
  1501. X                state = AllDone;
  1502. X                continue;
  1503. X            }
  1504. X            break;
  1505. X        }
  1506. X        *destp++ = c;
  1507. X        *destp = '\0';
  1508. X    }
  1509. X    /*
  1510. X     * idea from Marc Pawliger
  1511. X     * if you don't give an am or pm, then hours from 0 to minAlarmWarp
  1512. X     * is treated as a pm time
  1513. X     */
  1514. X    if (appResources.alarmWarp == True &&
  1515. X        hr <= appResources.minAlarmWarp &&
  1516. X        appResources.minAlarmWarp < 12 &&
  1517. X        foundampm == False)
  1518. X        hr += 12;
  1519. X    *hrp = hr;
  1520. X    *minp = mn;
  1521. X    return 1;
  1522. X}
  1523. X
  1524. X/*
  1525. X * set up the timeout for the next event
  1526. X */
  1527. Xstatic void
  1528. XsetCall()
  1529. X{
  1530. X    time_t          ti;
  1531. X    long        mnow;
  1532. X    struct tm      *tm;
  1533. X    Alarm          *sc;
  1534. X    int             togo;
  1535. X
  1536. X    ti = time(0);
  1537. X    tm = localtime(&ti);
  1538. X    mnow = MINUTES(tm->tm_hour, tm->tm_min);
  1539. X
  1540. X    for (sc = head.next; sc; sc = sc->next) {
  1541. X        togo = sc->alarm_mm - mnow;
  1542. X        if (togo == 0)
  1543. X        {    AlarmEvent(1, 0);    /* don't miss any current alarms */
  1544. X            sc = &head;
  1545. X            continue;
  1546. X        }
  1547. X        if (togo < 0)
  1548. X            continue;
  1549. X        appResources.interval_id = XtAppAddTimeOut(appContext, 
  1550. X              togo * 60 * 1000 - tm->tm_sec * 1000,
  1551. X              (XtTimerCallbackProc) AlarmEvent, (caddr_t) NULL);
  1552. X        dprintf("Alarm in %d mins (less %d secs)\n", togo, tm->tm_sec);
  1553. X        break;
  1554. X    }
  1555. X}
  1556. X
  1557. X
  1558. Xstatic void
  1559. XAlarmEvent(client_data, id)
  1560. X    caddr_t         client_data;
  1561. X    XtIntervalId   *id;
  1562. X{
  1563. X    int             tnow;
  1564. X    long            ti;
  1565. X    struct tm      *tm;
  1566. X    Alarm          *al, *action, *actionend;
  1567. X    String        cmd;
  1568. X
  1569. X    appResources.interval_id = 0;
  1570. X
  1571. X    ti = time(0);
  1572. X    tm = localtime(&ti);
  1573. X    tnow = MINUTES(tm->tm_hour, tm->tm_min);
  1574. X
  1575. X    dprintf("Alarm %d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
  1576. X
  1577. X    /*
  1578. X     * Look for alarms that have fired and remove them
  1579. X     * from the list
  1580. X     */
  1581. X    actionend = NULL;
  1582. X    for (al = head.next; al; al = al->next) {
  1583. X        if (al->alarm_mm <= tnow)
  1584. X            actionend = al;
  1585. X        else break;
  1586. X    }
  1587. X    if (actionend) {
  1588. X        al = head.next;
  1589. X        head.next = actionend->next;
  1590. X        actionend->next = NULL;    
  1591. X        /*
  1592. X         * now process the list
  1593. X         */
  1594. X        while (al) {
  1595. X            if (tnow == al->alarm_mm) {
  1596. X
  1597. X                if (appResources.cmd != NULL) {
  1598. X                    cmd = CreateCommand(appResources.cmd, al->what);
  1599. X                    system(cmd);
  1600. X                    XtFree(cmd);
  1601. X                }
  1602. X                if (al->isAction == False) {
  1603. X                    DisplayAlarmWindow(al->alarm_state, al->alarm, al->what);
  1604. X                    beep();    /* notify the user */
  1605. X                } else {
  1606. X                    cmd = CreateCommand(al->what, NULL);
  1607. X                    system(cmd);
  1608. X                    XtFree(cmd);
  1609. X                }
  1610. X            }
  1611. X            actionend = al->next;
  1612. X            XtFree(al->alarm);
  1613. X            XtFree(al->what);
  1614. X            XtFree((char *) al);
  1615. X            al = actionend;
  1616. X        }
  1617. X    }
  1618. X    if (client_data == NULL)
  1619. X        setCall();
  1620. X}
  1621. X
  1622. Xstatic String
  1623. XCreateCommand(cmd, arg)
  1624. X    String    cmd;
  1625. X    String    arg;
  1626. X{
  1627. X    String    buf;
  1628. X    char    *s, *d;
  1629. X    char    *fmt;
  1630. X    int    cmdlen;
  1631. X    int    arglen;
  1632. X    
  1633. X    cmdlen = strlen(cmd);
  1634. X    arglen = arg ? strlen(arg) : 0;
  1635. X
  1636. X    buf = XtMalloc(cmdlen + arglen + 200);
  1637. X    if (arglen == 0)
  1638. X        fmt = "%s&";
  1639. X    else    fmt = "%s '";
  1640. X    (void) sprintf(buf, fmt, cmd);
  1641. X    /*
  1642. X     * copy the arguments worrying about any embedded quote
  1643. X     */
  1644. X#define    QUOTE    '\''
  1645. X#define BACKSLASH '\\'
  1646. X    if (arglen) {
  1647. X        d = buf + strlen(buf);
  1648. X        for(s = arg; *s; s++) {
  1649. X            if (*s == QUOTE) {
  1650. X                *d++ = QUOTE;
  1651. X                *d++ = BACKSLASH;
  1652. X                *d++ = QUOTE;
  1653. X            }
  1654. X            *d++ = *s;
  1655. X        }
  1656. X        *d++ = QUOTE;
  1657. X        *d++ = '&';
  1658. X        *d++ = '\0';
  1659. X    }
  1660. X    return buf;
  1661. X}
  1662. X
  1663. Xstatic void
  1664. Xbeep()
  1665. X{
  1666. X    register Display *dpy = XtDisplay(toplevel);
  1667. X    int             i;
  1668. X
  1669. X    for (i = 0; i < appResources.nbeeps; i++) {
  1670. X        XBell(dpy, appResources.volume);
  1671. X        sleep(1);
  1672. X    }
  1673. X}
  1674. X
  1675. Xstatic void
  1676. XFreeAlarmList(al)
  1677. X    register Alarm *al;
  1678. X{
  1679. X    register Alarm *nx;
  1680. X
  1681. X    for (; al; al = nx) {
  1682. X        nx = al->next;
  1683. X        XtFree(al->alarm);
  1684. X        XtFree(al->what);
  1685. X        XtFree((char *) al);
  1686. X    }
  1687. X}
  1688. X
  1689. Xstatic void
  1690. XAlarmsOff()
  1691. X{
  1692. X    if (appResources.interval_id) {
  1693. X        XtRemoveTimeOut(appResources.interval_id);
  1694. X        appResources.interval_id = 0;
  1695. X    }
  1696. X}
  1697. X    
  1698. Xtypedef struct {
  1699. X    Widget          sa_top;
  1700. X    XtIntervalId    sa_id;
  1701. X} AlarmStatus;
  1702. X
  1703. Xstatic void
  1704. XDisplayAlarmWindow(tleft, str1, str2)
  1705. X    int             tleft;
  1706. X    String          str1, str2;
  1707. X{
  1708. X    Widget          shell, form, title, aq, ah;
  1709. X    Arg             args[10];
  1710. X    Cardinal        nargs;
  1711. X    char           *fmt;
  1712. X    char            buf[255];
  1713. X    AlarmStatus    *als;
  1714. X
  1715. X    /*
  1716. X     * making the top level shell the override widget class causes it to
  1717. X     * popup without window manager interaction or window manager
  1718. X     * handles.  this also means that it pops on the foreground of an
  1719. X     * xlocked terminal and is not resizable by the window manager.  If
  1720. X     * any one finds that to be desirable behavior, then change the
  1721. X     * transient class below to override.
  1722. X     * 
  1723. X     * For now transient class is much better behaved
  1724. X     */
  1725. X    nargs = 0;
  1726. X    argLD(XtNallowShellResize, True);
  1727. X    argLD(XtNinput, True);
  1728. X    argLD(XtNsaveUnder, TRUE);
  1729. X    shell = XtCreatePopupShell("alarm", transientShellWidgetClass,
  1730. X                   toplevel, args, nargs);
  1731. X
  1732. X    form = XtCreateManagedWidget("alarmPanel", panedWidgetClass,
  1733. X                     shell, NULL, 0);
  1734. X    /*
  1735. X     * create alarm status save area
  1736. X     */
  1737. X    als = (AlarmStatus *) XtMalloc(sizeof(AlarmStatus));
  1738. X
  1739. X    als->sa_top = shell;
  1740. X    als->sa_id = (XtIntervalId) NULL;
  1741. X    if (appResources.autoquit) {
  1742. X        als->sa_id = XtAppAddTimeOut(appContext,
  1743. X                            appResources.autoquit * 1000,
  1744. X                         AutoDestroy, (caddr_t) als);
  1745. X    }
  1746. X    nargs = 0;
  1747. X    argLD(XtNshowGrip, False);
  1748. X    argLD(XtNdefaultDistance, 2);
  1749. X    title = XtCreateManagedWidget("alarmForm", formWidgetClass,
  1750. X                      form, args, nargs);
  1751. X    /*
  1752. X     * Exit button Take "Quit" from resources
  1753. X     */
  1754. X    callbacks[0].callback = DestroyAlarm;
  1755. X    callbacks[0].closure = (caddr_t) als;
  1756. X    nargs = 0;
  1757. X    argLD(XtNcallback, callbacks);
  1758. X    argLD(XtNfromHoriz, NULL);
  1759. X    argLD(XtNleft, XtChainLeft);
  1760. X    argLD(XtNright, XtChainLeft);
  1761. X    aq = XtCreateManagedWidget("alarmQuit", commandWidgetClass,
  1762. X                   title, args, nargs);
  1763. X
  1764. X    /*
  1765. X     * Hold button Take "Hold" from resources
  1766. X     */
  1767. X    callbacks[0].callback = HoldAlarm;
  1768. X    callbacks[0].closure = (caddr_t) als;
  1769. X    nargs = 0;
  1770. X    argLD(XtNcallback, callbacks);
  1771. X    argLD(XtNfromHoriz, aq);
  1772. X    if (!appResources.autoquit) {
  1773. X        argLD(XtNsensitive, False);
  1774. X    }
  1775. X    argLD(XtNleft, XtChainLeft);
  1776. X    argLD(XtNright, XtChainLeft);
  1777. X    ah = XtCreateManagedWidget("alarmHold", commandWidgetClass,
  1778. X                   title, args, nargs);
  1779. X
  1780. X    if (tleft == 0)
  1781. X        fmt = appResources.alarmnow;
  1782. X    else
  1783. X        fmt = appResources.alarmleft;
  1784. X
  1785. X    if (fmt && *fmt) {
  1786. X        nargs = 0;
  1787. X        argLD(XtNfromHoriz, ah);
  1788. X        argLD(XtNleft, XtChainLeft);
  1789. X        argLD(XtNright, XtChainLeft);
  1790. X        argLD(XtNborderWidth, 0);
  1791. X        argLD(XtNfromVert, NULL);
  1792. X        argLD(XtNvertDistance, 3);
  1793. X        (void) sprintf(buf, fmt, tleft);
  1794. X        argLD(XtNlabel, buf);
  1795. X        (void) XtCreateManagedWidget("alarmTitle", labelWidgetClass, title, args, nargs);
  1796. X    }
  1797. X    /*
  1798. X     * Now the text which is the remainder of the panel
  1799. X     */
  1800. X    (void) sprintf(buf, "%s\n%s\n", str1, str2);
  1801. X    nargs = 0;
  1802. X    argLD(XtNshowGrip, False);
  1803. X    argLD(XtNstring, buf);
  1804. X    argLD(XtNdisplayCaret, False);
  1805. X    (void) XtCreateManagedWidget("alarmText", asciiTextWidgetClass,
  1806. X                     form, args, nargs);
  1807. X
  1808. X    XtPopup(shell, XtGrabNone);
  1809. X}
  1810. X
  1811. X/* ARGSUSED */
  1812. Xstatic void
  1813. XDestroyAlarm(w, als, call_data)
  1814. X    Widget          w;
  1815. X    AlarmStatus    *als;
  1816. X    caddr_t         call_data;
  1817. X{
  1818. X    if (als->sa_id)
  1819. X        XtRemoveTimeOut(als->sa_id);
  1820. X    AutoDestroy(als, NULL);
  1821. X}
  1822. X
  1823. X/* ARGSUSED */
  1824. Xstatic void
  1825. XHoldAlarm(w, als, call_data)
  1826. X    Widget          w;
  1827. X    AlarmStatus    *als;
  1828. X    caddr_t         call_data;
  1829. X{
  1830. X    if (als->sa_id)
  1831. X        XtRemoveTimeOut(als->sa_id);
  1832. X    XtSetSensitive(w, FALSE);
  1833. X}
  1834. X
  1835. X/* ARGSUSED */
  1836. Xstatic void
  1837. XAutoDestroy(als, id)
  1838. X    AlarmStatus    *als;
  1839. X    XtIntervalId   *id;
  1840. X{
  1841. X
  1842. X    XtDestroyWidget(als->sa_top);
  1843. X    XtFree((char *) als);
  1844. X}
  1845. END_OF_FILE
  1846. if test 19473 -ne `wc -c <'xcal_alarm.c'`; then
  1847.     echo shar: \"'xcal_alarm.c'\" unpacked with wrong size!
  1848. fi
  1849. # end of 'xcal_alarm.c'
  1850. fi
  1851. echo shar: End of archive 7 \(of 8\).
  1852. cp /dev/null ark7isdone
  1853. MISSING=""
  1854. for I in 1 2 3 4 5 6 7 8 ; do
  1855.     if test ! -f ark${I}isdone ; then
  1856.     MISSING="${MISSING} ${I}"
  1857.     fi
  1858. done
  1859. if test "${MISSING}" = "" ; then
  1860.     echo You have unpacked all 8 archives.
  1861.     rm -f ark[1-9]isdone
  1862. else
  1863.     echo You still need to unpack the following archives:
  1864.     echo "        " ${MISSING}
  1865. fi
  1866. ##  End of shell archive.
  1867. exit 0
  1868.  
  1869. exit 0 # Just in case...
  1870. -- 
  1871.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1872. \X/  Amiga: The only way to fly!  |    sources-x@sterling.com
  1873.        "It's intuitively obvious to the most casual observer..."
  1874.  GCS d++(--) -p+ c++ !l u++ e+ m+(-) s++/++ n h--- f+ g+++ w+ t++ r+ y+
  1875.