home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2304 / main.c
Encoding:
C/C++ Source or Header  |  1990-12-28  |  53.1 KB  |  1,989 lines

  1. /*
  2.  * Author: Jason Baietto, jason@ssd.csd.harris.com
  3.  * xdiary Copyright 1990 Harris Corporation
  4.  *
  5.  * Permission to use, copy, modify, and distribute, this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of the copyright holder be used in
  10.  * advertising or publicity pertaining to distribution of the software with
  11.  * specific, written prior permission, and that no fee is charged for further
  12.  * distribution of this software, or any modifications thereof.  The copyright
  13.  * holder makes no representations about the suitability of this software for
  14.  * any purpose.  It is provided "as is" without express or implied warranty.
  15.  *
  16.  * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND IN NO
  18.  * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ITS USE,
  20.  * LOSS OF DATA, PROFITS, QPA OR GPA, WHETHER IN AN ACTION OF CONTRACT,
  21.  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
  22.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23.  */
  24.  
  25. /*
  26.    xdiary -- An X application which displays a calendar in one of two formats
  27.              and/or an interactive daily dairy.
  28.  
  29.    Author: Jason Baietto (jason@ssd.csd.harris.com)
  30.    Date:   October 10, 1990
  31. */
  32.  
  33. /*==========================================================================*/
  34. /*                              Header Files:                               */
  35. /*==========================================================================*/
  36. #include <stdio.h>
  37. #include <ctype.h>
  38. #include <pwd.h>
  39. #include <X11/Xos.h>
  40. #include <X11/Intrinsic.h>
  41. #include <X11/StringDefs.h>
  42. #include <X11/Shell.h>
  43. #include <X11/Xaw/Command.h>
  44. #include <X11/Xaw/Form.h>
  45. #include <X11/Xaw/Paned.h>
  46. #include <X11/Xaw/Box.h>
  47. #include <X11/Xaw/Dialog.h>
  48. #include <X11/Xaw/MenuButton.h>
  49. #include <X11/Xaw/SimpleMenu.h>
  50. #include <X11/Xaw/SmeBSB.h>
  51. #include <X11/Xaw/SmeLine.h>
  52. #include <X11/Xaw/AsciiText.h>
  53. #include "Calendar.h"
  54. #include "main.h"
  55. #include "diary.h"
  56. #include "template.h"
  57. #include "cal.icon"
  58. #include "diary.icon"
  59. #include "arrow_r.xbm"
  60. #include "arrow_l.xbm"
  61. #include "resource.h"
  62. #include "common.h"
  63. #include "patchlevel.h"
  64.  
  65.  
  66. /*==========================================================================*/
  67. /*                            Forward References:                           */
  68. /*==========================================================================*/
  69. void quit();
  70. void day_inc();
  71. void day_dec();
  72. void month_inc();
  73. void month_dec();
  74. void year_inc();
  75. void year_dec();
  76. void entry_inc();
  77. void entry_dec();
  78. void warp_to_dialog();
  79. void warp_to_start();
  80. void dialog_done();
  81. void flip_calendar();
  82. void set_the_date();
  83. void init_bitmaps();
  84. void init_dialog();
  85. void init_button_box();
  86. void init_menu();
  87. void init_single_calendar();
  88. void init_full_calendar();
  89. void process_options();
  90. Widget make_inc_dec_button();
  91. void change_to_full();
  92. void change_to_single();
  93. void initialize_diary_widgets();
  94. void toggle_diary();
  95. void save_diary_callback();
  96. void calendar_callback();
  97. void show_new_diary_entry();
  98. void save_old_diary_entry();
  99. char * get_default_diary_file_name();
  100. char * get_default_template_file_name();
  101. void flash();
  102. void flash_back();
  103. void show_pretty_date();
  104. void sensitize();
  105. void set_initial_time_interval();
  106.  
  107.  
  108. /*==========================================================================*/
  109. /*                                 Globals:                                 */
  110. /*==========================================================================*/
  111. Widget top_level_widget;
  112. Widget single_popup_shell_widget;
  113. Widget full_popup_shell_widget;
  114. Widget button_box_widget;
  115. Widget option_button_widget;
  116. Widget single_form_widget;
  117. Widget single_calendar_widget;
  118. Widget full_form_widget;
  119. Widget full_calendar_widgets[12];
  120. Widget dialog_popup_shell_widget;
  121. Widget dialog_widget;
  122. Widget text_widget;
  123. Widget menu_popup_shell_widget;
  124. Widget menu_today_widget;
  125. Widget menu_warp_widget;
  126. Widget menu_diary_widget;
  127. Widget menu_full_widget;
  128. Widget menu_single_widget;
  129. Widget menu_save_widget;
  130. Widget menu_quit_widget;
  131. Widget diary_popup_shell_widget;
  132. Widget diary_top_paned_widget;
  133. Widget diary_label_widget;
  134. Widget diary_form_widget;
  135. Widget diary_text_widget;
  136. Widget diary_text_source_widget;
  137.  
  138. XtActionsRec xdiary_actions[] = {
  139.    { "dialog_done",     dialog_done },
  140. };
  141.  
  142. char text_translation_table[] = "#override\n\
  143.    <Key>Return:   dialog_done()";
  144.  
  145. XtTranslations text_translations;
  146.  
  147. Date current_date;
  148.  
  149. XrmOptionDescRec command_line_table[] = 
  150. {
  151.    { "-iconic",          "*iconic",             XrmoptionNoArg, "True" },
  152.    { "-linewidth",       "*Calendar*lineWidth", XrmoptionSepArg, NULL  },
  153.    { "-fullgeometry",    "*full.geometry",      XrmoptionSepArg, NULL  },
  154.    { "-singlegeometry",  "*single.geometry",    XrmoptionSepArg, NULL  },
  155.    { "-diarygeometry",   "*diary.geometry",     XrmoptionSepArg, NULL  },
  156.    { "-digitfont",       "*single*digitFont",   XrmoptionSepArg, NULL  },
  157.    { "-weekdayfont",     "*single*weekdayFont", XrmoptionSepArg, NULL  },
  158.    { "-titlefont",       "*single*titleFont",   XrmoptionSepArg, NULL  },
  159.    { "-digitgravity",    "*digitGravity",       XrmoptionSepArg, NULL  },
  160.    { "-startingweekday", "*startingWeekday",    XrmoptionSepArg, NULL  },
  161.    { "-language",        "*language",           XrmoptionSepArg, NULL  },
  162.    { "-diaryfile",       "*diaryFile",          XrmoptionSepArg, NULL  },
  163.    { "-templatefile",    "*templateFile",       XrmoptionSepArg, NULL  },
  164.    { "-nocalendar",      "*noCalendar",         XrmoptionNoArg, "True" },
  165.    { "-nodiary",         "*noDiary",            XrmoptionNoArg, "True" },
  166.    { "-long",            "*long",               XrmoptionNoArg, "True" },
  167.    { "-abbrev",          "*abbrev",             XrmoptionSepArg, NULL  },
  168.    { "-fullyear",        "*fullYear",           XrmoptionNoArg, "True" },
  169.    { "-singlemonth",     "*singleMonth",        XrmoptionNoArg, "True" }
  170.    
  171. };
  172.  
  173. app_data_type application_data;
  174.  
  175. char help[] = "\n\
  176. Usage: xdiary [-linewidth <pixels>]\n\
  177.               [-fullgeometry <geometry>]\n\
  178.               [-singlegeometry <geometry>]\n\
  179.               [-diarygeometry <geometry>]\n\
  180.               [-digitfont <font_name>]\n\
  181.               [-weekdayfont <font_name>]\n\
  182.               [-titlefont <font_name>]\n\
  183.               [-digitgravity <gravity>]\n\
  184.               [-startingweekday <day_name>]\n\
  185.               [-language <lang_name>]\n\
  186.               [-diaryfile <diary_filename>]\n\
  187.               [-templatefile <template_filename>]\n\
  188.               [-nocalendar]\n\
  189.               [-nodiary]\n\
  190.               [-long]\n\
  191.               [-abbrev <letter_count>]\n\
  192.               [-fullyear]\n\
  193.               [-singlemonth]\n\
  194.               [<date_string>]\n\n";
  195.  
  196.  
  197. /* True after initialized. */
  198. int full_initialized = FALSE;
  199. int single_initialized = FALSE;
  200. int diary_initialized = FALSE;
  201.  
  202. /* True if any changes were made. */
  203. int diary_changed = FALSE;
  204.  
  205. /* True after flash, until flash_back */
  206. int currently_flashing;
  207.  
  208.  
  209. /*==========================================================================*/
  210. /*                            Argument Processing:                          */
  211. /*==========================================================================*/
  212. typedef enum { none, single, full } mode;
  213. mode display_mode = single;
  214. int diary_showing = FALSE;
  215. int lang_opt = ENGLISH;
  216. int lang_specified = FALSE;
  217. int date_opt = FALSE;
  218. int long_opt = FALSE;
  219. int abbrev_opt = 3;
  220. int diary_opt = TRUE;
  221. int fly_opt = FALSE;
  222. int arg_error = FALSE;
  223. int forward = TRUE;
  224. int interval = 0;
  225. int using_template = FALSE;
  226. XtIntervalId timeout_id;
  227. char * date_string = NULL;
  228. char * diary_file_name = NULL;
  229. char * template_file_name = NULL;
  230.  
  231. /* Ignores case.  Allows partial abbreviations or garbage at end. */
  232. int check_option(string_ptr, option_ptr)
  233. char * string_ptr;
  234. char * option_ptr;
  235. {
  236.    while (*string_ptr && *option_ptr) {
  237.       if (DOWNCASE(*string_ptr) == *option_ptr) {
  238.          /* Letters match */
  239.          string_ptr++;
  240.          option_ptr++;
  241.       } else {
  242.          /* Doesn't match. */
  243.          return FALSE;
  244.       }
  245.    }
  246.    return TRUE;
  247. }
  248.  
  249.  
  250.  
  251. #define OPTION(opt) (check_option(argv[count],(opt)))
  252. #define ARG  (argv[count])
  253. #define NEXT \
  254.    if (++count == argc) { \
  255.       fprintf(stderr, "xdiary: \"%s\" requires argument\n", argv[count-1]); \
  256.       return FALSE; \
  257.    }
  258.  
  259.  
  260.  
  261. int parse_args(argc, argv)
  262. int argc;
  263. char *argv[];
  264. {
  265.    int count;
  266.    for (count=1; count < argc; count++) {
  267.  
  268.       /* Undocumented, used for testing. */
  269.       if (OPTION("-flies")) { 
  270.          fly_opt = TRUE;
  271.          NEXT;
  272.          interval = atoi(ARG);
  273.          if (interval < 0) {
  274.             interval = abs(interval);
  275.             forward  = FALSE;
  276.          }
  277.          continue; 
  278.       }
  279.  
  280.       if (OPTION("-")) {
  281.          fprintf(stderr, "xdiary: unknown option \"%s\"\n", ARG);
  282.          arg_error = TRUE;
  283.          continue;
  284.       }
  285.  
  286.       if (!date_opt++) {
  287.          date_string = ARG;
  288.          continue;
  289.       }
  290.  
  291.       /* No valid options match. */
  292.       return FALSE;
  293.    }
  294.  
  295.    /* All options present and accounted for. */
  296.    return TRUE;
  297. }
  298.  
  299.  
  300.  
  301.  
  302.  
  303. #define RESOURCE(field) (application_data.field)
  304. #define EQUAL(res, str) (check_option((res),(str)))
  305.  
  306. void process_resources()
  307. {
  308.    if (RESOURCE(language)) {
  309.       lang_specified = TRUE;
  310.       if (EQUAL(RESOURCE(language), "english")) lang_opt = ENGLISH; else
  311.       if (EQUAL(RESOURCE(language), "spanish")) lang_opt = SPANISH; else
  312.       if (EQUAL(RESOURCE(language), "french"))  lang_opt = FRENCH;  else
  313.       if (EQUAL(RESOURCE(language), "german"))  lang_opt = GERMAN;  else {
  314.          lang_specified = FALSE;
  315.          fprintf(
  316.             stderr,
  317.             "xdiary: unknown language \"%s\"\n",
  318.             RESOURCE(language)
  319.          );
  320.       }
  321.    }
  322.  
  323.    if (RESOURCE(diaryfile)) {
  324.       diary_file_name = RESOURCE(diaryfile);
  325.    }
  326.  
  327.    if (RESOURCE(templatefile)) {
  328.       template_file_name = RESOURCE(templatefile);
  329.    }
  330.  
  331.    if (RESOURCE(nocalendar)) {
  332.       display_mode = none;
  333.    }
  334.  
  335.    if (RESOURCE(nodiary)) {
  336.       if (display_mode == none) {
  337.          fprintf(
  338.             stderr, 
  339.             "xdiary: nocalendar and nodiary can't both be specified.\n"
  340.          );
  341.       } else {
  342.          diary_opt = FALSE;
  343.       }
  344.    }
  345.  
  346.    if (RESOURCE(long_opt)) {
  347.       long_opt = TRUE;
  348.       lang_specified = TRUE;
  349.    }
  350.  
  351.    if (RESOURCE(abbrev)) {
  352.       abbrev_opt = RESOURCE(abbrev);
  353.       if (abbrev_opt < 0) {
  354.          abbrev_opt = 0;
  355.       }
  356.       lang_specified = TRUE;
  357.    }
  358.  
  359.    if (RESOURCE(fullyear)) {
  360.       display_mode = full;
  361.    }
  362.  
  363.    if (RESOURCE(singlemonth)) {
  364.       display_mode = single;
  365.    }
  366.  
  367. }
  368.  
  369.  
  370.  
  371.  
  372. void process_options()
  373. {
  374.    int month;
  375.    int weekday;
  376.  
  377.    /* Abbreviate the weekday names as specified. */
  378.    if (lang_specified && !long_opt) {
  379.       for (weekday=0; weekday < 7; weekday++) {
  380.          if (strlen(weekday_names[lang_opt][weekday]) > abbrev_opt) {
  381.             weekday_names[lang_opt][weekday][abbrev_opt] = NULL;
  382.          }
  383.       }
  384.    }
  385.  
  386.    if (display_mode == full) {
  387.       init_full_calendar();
  388.    } else {
  389.       init_single_calendar();
  390.    }
  391.  
  392.    /* Realize a calendar. */
  393.    if (display_mode == single) {
  394.       XtPopup(single_popup_shell_widget, XtGrabNone);
  395.       if (!diary_showing) {
  396.          sensitize(menu_single_widget, False);
  397.       }
  398.    } else if (display_mode == full) {
  399.       XtPopup(full_popup_shell_widget, XtGrabNone);
  400.       if (!diary_showing) {
  401.          sensitize(menu_full_widget, False);
  402.       }
  403.    } else {
  404.       /* Realize it, but don't pop it up. */
  405.       XtRealizeWidget(single_popup_shell_widget);
  406.       sensitize(menu_diary_widget, False);
  407.    }
  408.  
  409.    if (date_opt) {
  410.       /* A date string was specified. */
  411.       if (display_mode == full) {
  412.          current_date = DateConverter(full_calendar_widgets[0], date_string);
  413.        } else {
  414.          current_date = DateConverter(single_calendar_widget, date_string);
  415.       }
  416.    }
  417.  
  418.    if (!date_opt || current_date.year == 0) {
  419.       /* No date was specified or the specified date was bogus, */
  420.       /* so calendar widget chose its own date.  Get that date. */
  421.       if (display_mode == full) {
  422.          CalendarGetDate(full_calendar_widgets[0], ¤t_date);
  423.       } else {
  424.          CalendarGetDate(single_calendar_widget, ¤t_date);
  425.       }
  426.    }
  427.  
  428.    set_the_date(current_date);
  429.  
  430.    /* The undocumentd fly option -- used for testing. */
  431.    if (fly_opt) {
  432.       timeout_id = XtAddTimeOut(interval, flip_calendar, NULL);
  433.    } else {
  434.       /* Make calendar flip with the date. */
  435.       set_initial_time_interval();
  436.       timeout_id = XtAddTimeOut(interval, flip_calendar, NULL);
  437.       interval = TWENTY_FOUR_HOURS;
  438.    }
  439.  
  440.    if (!diary_file_name) {
  441.       diary_file_name = get_default_diary_file_name();
  442.    }
  443.  
  444.    if (template_file_name) {
  445.       using_template = init_template(template_file_name);
  446.       if (!using_template) {
  447.          fprintf(stderr, "xdiary: unable to open template file\n");
  448.       }
  449.    } else {
  450.       /* No template was specified. */
  451.       template_file_name = get_default_template_file_name();
  452.       using_template = init_template(template_file_name);
  453.    }
  454.  
  455.    if (diary_opt) {
  456.       toggle_diary();
  457.    }
  458.  
  459. }
  460.  
  461.  
  462.  
  463.  
  464.  
  465. /*==========================================================================*/
  466. /*                                  Main:                                   */
  467. /*==========================================================================*/
  468. main(argc, argv)
  469. int argc;
  470. char *argv[];
  471. {
  472.    /* Never Realized */
  473.    top_level_widget = XtInitialize(
  474.       argv[0],                       /* application name */
  475.       "Xdiary",                      /* application class */
  476.       command_line_table,            /* resource manager options */
  477.       XtNumber(command_line_table),  /* number of resource manager options */
  478.       &argc,                         /* number of command line args */
  479.       argv                           /* array of command line args */
  480.    );
  481.  
  482.    XtGetApplicationResources(
  483.       top_level_widget,
  484.       &application_data,
  485.       application_resources,
  486.       XtNumber(application_resources),
  487.       NULL,
  488.       0
  489.    );
  490.  
  491.    XtAddActions(xdiary_actions, XtNumber(xdiary_actions));
  492.  
  493.    process_resources();
  494.  
  495.    if (!parse_args(argc, argv) || arg_error) {
  496.       fprintf(stderr, help);
  497.       XtDestroyWidget(top_level_widget);
  498.       exit(0);
  499.    }
  500.    
  501.    init_bitmaps();
  502.  
  503.    init_dialog();
  504.  
  505.    init_menu();
  506.  
  507.    process_options();
  508.  
  509.    XtMainLoop();
  510.    
  511.    return(1);
  512. }
  513.  
  514.  
  515.  
  516.  
  517. /*==========================================================================*/
  518. /*                                 Bitmaps:                                 */
  519. /*==========================================================================*/
  520. Pixmap calendar_icon;
  521. Pixmap diary_icon;
  522. Pixmap right_arrow;
  523. Pixmap left_arrow;
  524. void init_bitmaps()
  525. {
  526.    calendar_icon = XCreateBitmapFromData(
  527.       XtDisplay(top_level_widget),
  528.       RootWindowOfScreen(XtScreen(top_level_widget)),
  529.       calendar_bits,
  530.       calendar_width,
  531.       calendar_height
  532.    );
  533.  
  534.    diary_icon = XCreateBitmapFromData(
  535.       XtDisplay(top_level_widget),
  536.       RootWindowOfScreen(XtScreen(top_level_widget)),
  537.       diary_bits,
  538.       diary_width,
  539.       diary_height
  540.    );
  541.  
  542.    left_arrow = XCreateBitmapFromData(
  543.       XtDisplay(top_level_widget),
  544.       RootWindowOfScreen(XtScreen(top_level_widget)),
  545.       left_arrow_bits,
  546.       left_arrow_width,
  547.       left_arrow_height
  548.    );
  549.  
  550.    right_arrow = XCreateBitmapFromData(
  551.       XtDisplay(top_level_widget),
  552.       RootWindowOfScreen(XtScreen(top_level_widget)),
  553.       right_arrow_bits,
  554.       right_arrow_width,
  555.       right_arrow_height
  556.    );
  557. }
  558.  
  559.  
  560.  
  561. /*==========================================================================*/
  562. /*                               Buttonbox:                                 */
  563. /*==========================================================================*/
  564. void init_button_box(parent_widget, mask)
  565. Widget parent_widget;
  566. int mask;
  567. {
  568.    Widget widget_list[MAX_WIDGETS];
  569.    int num_to_manage = 0;
  570.  
  571.    /*VARARGS0*/
  572.    button_box_widget = XtVaCreateManagedWidget (
  573.       "buttons",           /* widget name */
  574.       boxWidgetClass,      /* widget class */
  575.       parent_widget,       /* parent widget */
  576.       XtNorientation,      XtEhorizontal,
  577.       XtNborderWidth,      0,
  578.       XtNshowGrip,         False,
  579.       XtNskipAdjust,       True,
  580.       NULL                 /* end args */
  581.    );
  582.  
  583.    /*VARARGS0*/
  584.    widget_list[num_to_manage++] = option_button_widget = XtVaCreateWidget (
  585.       "option",               /* widget name */
  586.       menuButtonWidgetClass,  /* widget class */
  587.       button_box_widget,      /* parent widget */
  588.       XtNlabel,               option_label[lang_opt],
  589.       XtNmenuName,            "menu",
  590.       NULL                    /* end args */
  591.    );
  592.  
  593.    if (mask & DAY) {
  594.       widget_list[num_to_manage++] = make_inc_dec_button (
  595.          "day",                  /* widget name */
  596.          button_box_widget,      /* parent widget */
  597.          day_label[lang_opt],    /* label */
  598.          day_dec,                /* dec callback */
  599.          day_inc                 /* inc callback */
  600.       );
  601.    }
  602.     
  603.    if (mask & MONTH) {
  604.       widget_list[num_to_manage++] = make_inc_dec_button (
  605.          "month",                /* widget name */
  606.          button_box_widget,      /* parent widget */
  607.          month_label[lang_opt],  /* label */
  608.          month_dec,              /* dec callback */
  609.          month_inc               /* inc callback */
  610.       );
  611.    }
  612.    
  613.    if (mask & YEAR) {
  614.       widget_list[num_to_manage++] = make_inc_dec_button (
  615.          "year",                 /* widget name */
  616.          button_box_widget,      /* parent widget */
  617.          year_label[lang_opt],   /* label */
  618.          year_dec,               /* dec callback */
  619.          year_inc                /* inc callback */
  620.       );
  621.    }
  622.    
  623.    if (mask & ENTRY) {
  624.       widget_list[num_to_manage++] = make_inc_dec_button (
  625.          "entry",                 /* widget name */
  626.          button_box_widget,       /* parent widget */
  627.          entry_label[lang_opt],   /* label */
  628.          entry_dec,               /* dec callback */
  629.          entry_inc                /* inc callback */
  630.       );
  631.    }
  632.  
  633.    /* Manage the children of the top form widget defined above. */
  634.    XtManageChildren(widget_list, num_to_manage);
  635. }
  636.  
  637.  
  638.  
  639.  
  640. /*==========================================================================*/
  641. /*                                 Dialog:                                  */
  642. /*==========================================================================*/
  643. void init_dialog()
  644. {
  645.    /*VARARGS0*/
  646.    dialog_popup_shell_widget = XtVaCreatePopupShell(
  647.       "dialog",
  648.       transientShellWidgetClass,
  649.       top_level_widget,
  650.       NULL
  651.    );
  652.  
  653.    /*VARARGS0*/
  654.    dialog_widget = XtVaCreateManagedWidget (
  655.       "dialog",                  /* widget name */
  656.       dialogWidgetClass,         /* widget class */
  657.       dialog_popup_shell_widget, /* parent widget */
  658.       XtNlabel,                  dialog_label[lang_opt],
  659.       XtNvalue,                  "",
  660.       NULL                       /* end args */
  661.    );
  662.    text_widget = XtNameToWidget(dialog_widget, "value");
  663.    text_translations  = XtParseTranslationTable(text_translation_table);
  664.    XtOverrideTranslations(text_widget, text_translations);
  665. }
  666.  
  667.  
  668.  
  669.  
  670.  
  671. /*==========================================================================*/
  672. /*                                  Menu:                                   */
  673. /*==========================================================================*/
  674. void init_menu()
  675. {
  676.    Widget widget_list[MAX_WIDGETS];
  677.    int num_to_manage = 0;
  678.  
  679.    /*VARARGS0*/
  680.    menu_popup_shell_widget = XtVaCreatePopupShell(
  681.       "menu",
  682.       simpleMenuWidgetClass,
  683.       top_level_widget,
  684.       NULL
  685.    );
  686.  
  687.    /* TODAY */
  688.    /*VARARGS0*/
  689.    widget_list[num_to_manage++] = menu_today_widget = XtVaCreateWidget (
  690.       "menu_today",              /* widget name */
  691.       smeBSBObjectClass,         /* widget class */
  692.       menu_popup_shell_widget,   /* parent widget */
  693.       XtNlabel,                  today_label[lang_opt],
  694.       NULL                       /* end args */
  695.    );
  696.    XtAddCallback(menu_today_widget, XtNcallback, warp_to_start, 0);
  697.  
  698.    /* LINE */
  699.    /*VARARGS0*/
  700.    widget_list[num_to_manage++] = XtVaCreateWidget (
  701.       "line",                    /* widget name */
  702.       smeLineObjectClass,        /* widget class */
  703.       menu_popup_shell_widget,   /* parent widget */
  704.       NULL                       /* end args */
  705.    );
  706.  
  707.    /* WARP */
  708.    /*VARARGS0*/
  709.    widget_list[num_to_manage++] = menu_warp_widget = XtVaCreateWidget (
  710.       "menu_warp",               /* widget name */
  711.       smeBSBObjectClass,         /* widget class */
  712.       menu_popup_shell_widget,   /* parent widget */
  713.       XtNlabel,                  warp_label[lang_opt],
  714.       NULL                       /* end args */
  715.    );
  716.    XtAddCallback(menu_warp_widget, XtNcallback, warp_to_dialog, 0);
  717.  
  718.    /* LINE */
  719.    /*VARARGS0*/
  720.    widget_list[num_to_manage++] = XtVaCreateWidget (
  721.       "line",                    /* widget name */
  722.       smeLineObjectClass,        /* widget class */
  723.       menu_popup_shell_widget,   /* parent widget */
  724.       NULL                       /* end args */
  725.    );
  726.  
  727.    /* DIARY */
  728.    /*VARARGS0*/
  729.    widget_list[num_to_manage++] = menu_diary_widget = XtVaCreateWidget (
  730.       "menu_diary",              /* widget name */
  731.       smeBSBObjectClass,         /* widget class */
  732.       menu_popup_shell_widget,   /* parent widget */
  733.       XtNlabel,                  diary_label[lang_opt],
  734.       NULL                       /* end args */
  735.    );
  736.    XtAddCallback(menu_diary_widget, XtNcallback, toggle_diary, 0);
  737.  
  738.    /* LINE */
  739.    /*VARARGS0*/
  740.    widget_list[num_to_manage++] = XtVaCreateWidget (
  741.       "line",                    /* widget name */
  742.       smeLineObjectClass,        /* widget class */
  743.       menu_popup_shell_widget,   /* parent widget */
  744.       NULL                       /* end args */
  745.    );
  746.  
  747.    /* FULL */
  748.    /*VARARGS0*/
  749.    widget_list[num_to_manage++] = menu_full_widget = XtVaCreateWidget (
  750.       "menu_full",               /* widget name */
  751.       smeBSBObjectClass,         /* widget class */
  752.       menu_popup_shell_widget,   /* parent widget */
  753.       XtNlabel,                  full_label[lang_opt],
  754.       NULL                       /* end args */
  755.    );
  756.    XtAddCallback(menu_full_widget, XtNcallback, change_to_full, 0);
  757.  
  758.    /* LINE */
  759.    /*VARARGS0*/
  760.    widget_list[num_to_manage++] = XtVaCreateWidget (
  761.       "line",                    /* widget name */
  762.       smeLineObjectClass,        /* widget class */
  763.       menu_popup_shell_widget,   /* parent widget */
  764.       NULL                       /* end args */
  765.    );
  766.  
  767.    /* SINGLE */
  768.    /*VARARGS0*/
  769.    widget_list[num_to_manage++] = menu_single_widget = XtVaCreateWidget (
  770.       "menu_single",             /* widget name */
  771.       smeBSBObjectClass,         /* widget class */
  772.       menu_popup_shell_widget,   /* parent widget */
  773.       XtNlabel,                  single_label[lang_opt],
  774.       NULL                       /* end args */
  775.    );
  776.    XtAddCallback(menu_single_widget, XtNcallback, change_to_single, 0);
  777.  
  778.    /* LINE */
  779.    /*VARARGS0*/
  780.    widget_list[num_to_manage++] = XtVaCreateWidget (
  781.       "line",                    /* widget name */
  782.       smeLineObjectClass,        /* widget class */
  783.       menu_popup_shell_widget,   /* parent widget */
  784.       NULL                       /* end args */
  785.    );
  786.  
  787.    /* SAVE */
  788.    /*VARARGS0*/
  789.    widget_list[num_to_manage++] = menu_save_widget = XtVaCreateWidget (
  790.       "menu_save",               /* widget name */
  791.       smeBSBObjectClass,         /* widget class */
  792.       menu_popup_shell_widget,   /* parent widget */
  793.       XtNlabel,                  save_label[lang_opt],
  794.       NULL                       /* end args */
  795.    );
  796.    XtAddCallback(menu_save_widget, XtNcallback, save_diary_callback, 0);
  797.  
  798.    /* LINE */
  799.    /*VARARGS0*/
  800.    widget_list[num_to_manage++] = XtVaCreateWidget (
  801.       "line",                    /* widget name */
  802.       smeLineObjectClass,        /* widget class */
  803.       menu_popup_shell_widget,   /* parent widget */
  804.       NULL                       /* end args */
  805.    );
  806.  
  807.    /* QUIT */
  808.    /*VARARGS0*/
  809.    widget_list[num_to_manage++] = menu_quit_widget = XtVaCreateWidget (
  810.       "menu_quit",               /* widget name */
  811.       smeBSBObjectClass,         /* widget class */
  812.       menu_popup_shell_widget,   /* parent widget */
  813.       XtNlabel,                  quit_label[lang_opt],
  814.       NULL                       /* end args */
  815.    );
  816.    XtAddCallback(menu_quit_widget, XtNcallback, quit, 0);
  817.    
  818.    /* Manage the children of the top form widget defined above. */
  819.    XtManageChildren(widget_list, num_to_manage);
  820. }
  821.  
  822.  
  823.  
  824.  
  825. /*==========================================================================*/
  826. /*                             Single Calendar:                             */
  827. /*==========================================================================*/
  828. void init_single_calendar() 
  829. {
  830.    Widget single_paned_widget;
  831.    int linewidth;
  832.  
  833.    if (single_initialized) return;
  834.    single_initialized = TRUE;
  835.  
  836.    /*VARARGS0*/
  837.    single_popup_shell_widget = XtVaCreatePopupShell(
  838.       "single",
  839.       topLevelShellWidgetClass,
  840.       top_level_widget,
  841.       XtNiconPixmap,    calendar_icon,
  842.       XtNiconName,      "calendar",
  843.       NULL
  844.    );
  845.  
  846.    /*VARARGS0*/
  847.    single_paned_widget = XtVaCreateManagedWidget (
  848.       "paned",                   /* widget name */
  849.       panedWidgetClass,          /* widget class */
  850.       single_popup_shell_widget, /* parent widget */
  851.       NULL                       /* end args */
  852.    );
  853.  
  854.    init_button_box(single_paned_widget, MONTH | YEAR);
  855.  
  856.    /*VARARGS0*/
  857.    single_form_widget = XtVaCreateManagedWidget (
  858.       "form",               /* widget name */
  859.       formWidgetClass,      /* widget class */
  860.       single_paned_widget,  /* parent widget */
  861.       XtNshowGrip,          False,
  862.       XtNborderWidth,       0,
  863.       NULL                  /* end args */
  864.    );
  865.  
  866.    /*VARARGS0*/
  867.    single_calendar_widget = XtVaCreateManagedWidget (
  868.       "calendar",          /* widget name */
  869.       calendarWidgetClass, /* widget class */
  870.       single_form_widget,  /* parent widget */
  871.       XtNtop,              XtChainTop,
  872.       XtNbottom,           XtChainBottom,
  873.       XtNright,            XtChainRight,
  874.       XtNleft,             XtChainLeft,
  875.       XtNborderWidth,      0,
  876.       NULL                 /* end args */
  877.    );
  878.    XtAddCallback(single_calendar_widget, XtNcallback, calendar_callback, 0);
  879.  
  880.    /* Get the border and the grid to be the same thickness */
  881.    /*VARARGS0*/
  882.    XtVaGetValues(
  883.       single_calendar_widget,
  884.       XtNlineWidth, &linewidth,
  885.       NULL
  886.    );
  887.  
  888.    /*VARARGS0*/
  889.    XtVaSetValues(
  890.       single_calendar_widget,
  891.       XtNborderWidth,  linewidth/2,
  892.       NULL
  893.    );
  894.  
  895.    if (lang_specified) {
  896.       /*VARARGS0*/
  897.       XtVaSetValues(
  898.          single_calendar_widget,
  899.          XtNmonthNames,   (XtPointer) month_names[lang_opt],
  900.          XtNweekdayNames, (XtPointer) weekday_names[lang_opt],
  901.          NULL
  902.       );
  903.    }
  904. }
  905.  
  906.  
  907.  
  908. /*==========================================================================*/
  909. /*                              Full Calendar:                              */
  910. /*==========================================================================*/
  911. void init_full_calendar() 
  912. {
  913.    Widget full_paned_widget;
  914.    Widget widget_list[MAX_WIDGETS];
  915.    int num_to_manage = 0;
  916.    int month;
  917.    int linewidth;
  918.  
  919.    if (full_initialized) return;
  920.    full_initialized = TRUE;
  921.  
  922.    /*VARARGS0*/
  923.    full_popup_shell_widget = XtVaCreatePopupShell (
  924.       "full",
  925.       topLevelShellWidgetClass,
  926.       top_level_widget,
  927.       XtNiconPixmap,    calendar_icon,
  928.       XtNiconName,      "calendar",
  929.       NULL
  930.    );
  931.  
  932.    /*VARARGS0*/
  933.    full_paned_widget = XtVaCreateManagedWidget (
  934.       "paned",                 /* widget name */
  935.       panedWidgetClass,        /* widget class */
  936.       full_popup_shell_widget, /* parent widget */
  937.       NULL                     /* end args */
  938.    );
  939.  
  940.    init_button_box(full_paned_widget, YEAR);
  941.  
  942.    /*VARARGS0*/
  943.    full_form_widget = XtVaCreateManagedWidget (
  944.       "form",                  /* widget name */
  945.       formWidgetClass,         /* widget class */
  946.       full_paned_widget,       /* parent widget */
  947.       XtNshowGrip,             False,
  948.       XtNborderWidth,          1,
  949.       NULL                     /* end args */
  950.    );
  951.  
  952.    /*VARARGS0*/
  953.    widget_list[num_to_manage++] = full_calendar_widgets[0] = XtVaCreateWidget (
  954.       "january",           /* widget name */
  955.       calendarWidgetClass, /* widget class */
  956.       full_form_widget,    /* parent widget */
  957.       XtNtop,              XtChainTop,
  958.       XtNleft,             XtChainLeft,
  959.       XtNborderWidth,      0,
  960.       NULL                 /* end args */
  961.    );
  962.  
  963.    /*VARARGS0*/
  964.    widget_list[num_to_manage++] = full_calendar_widgets[1] = XtVaCreateWidget (
  965.       "february",          /* widget name */
  966.       calendarWidgetClass, /* widget class */
  967.       full_form_widget,    /* parent widget */
  968.       XtNfromHoriz,        full_calendar_widgets[0],
  969.       XtNtop,              XtChainTop,
  970.       XtNborderWidth,      0,
  971.       NULL                 /* end args */
  972.    );
  973.  
  974.    /*VARARGS0*/
  975.    widget_list[num_to_manage++] = full_calendar_widgets[2] = XtVaCreateWidget (
  976.       "march",             /* widget name */
  977.       calendarWidgetClass, /* widget class */
  978.       full_form_widget,    /* parent widget */
  979.       XtNfromHoriz,        full_calendar_widgets[1],
  980.       XtNtop,              XtChainTop,
  981.       XtNright,            XtChainRight,
  982.       XtNborderWidth,      0,
  983.       NULL                 /* end args */
  984.    );
  985.  
  986.    /*VARARGS0*/
  987.    widget_list[num_to_manage++] = full_calendar_widgets[3] = XtVaCreateWidget (
  988.       "april",             /* widget name */
  989.       calendarWidgetClass, /* widget class */
  990.       full_form_widget,    /* parent widget */
  991.       XtNfromVert,         full_calendar_widgets[0],
  992.       XtNleft,             XtChainLeft,
  993.       XtNborderWidth,      0,
  994.       NULL                 /* end args */
  995.    );
  996.  
  997.    /*VARARGS0*/
  998.    widget_list[num_to_manage++] = full_calendar_widgets[4] = XtVaCreateWidget (
  999.       "may",               /* widget name */
  1000.       calendarWidgetClass, /* widget class */
  1001.       full_form_widget,    /* parent widget */
  1002.       XtNfromVert,         full_calendar_widgets[0],
  1003.       XtNfromHoriz,        full_calendar_widgets[3],
  1004.       XtNborderWidth,      0,
  1005.       NULL                 /* end args */
  1006.    );
  1007.  
  1008.    /*VARARGS0*/
  1009.    widget_list[num_to_manage++] = full_calendar_widgets[5] = XtVaCreateWidget (
  1010.       "june",          /* widget name */
  1011.       calendarWidgetClass, /* widget class */
  1012.       full_form_widget,    /* parent widget */
  1013.       XtNfromVert,         full_calendar_widgets[0],
  1014.       XtNfromHoriz,        full_calendar_widgets[4],
  1015.       XtNright,            XtChainRight,
  1016.       XtNborderWidth,      0,
  1017.       NULL                 /* end args */
  1018.    );
  1019.  
  1020.    /*VARARGS0*/
  1021.    widget_list[num_to_manage++] = full_calendar_widgets[6] = XtVaCreateWidget (
  1022.       "july",          /* widget name */
  1023.       calendarWidgetClass, /* widget class */
  1024.       full_form_widget,    /* parent widget */
  1025.       XtNfromVert,         full_calendar_widgets[3],
  1026.       XtNleft,             XtChainLeft,
  1027.       XtNborderWidth,      0,
  1028.       NULL                 /* end args */
  1029.    );
  1030.  
  1031.    /*VARARGS0*/
  1032.    widget_list[num_to_manage++] = full_calendar_widgets[7] = XtVaCreateWidget (
  1033.       "august",          /* widget name */
  1034.       calendarWidgetClass, /* widget class */
  1035.       full_form_widget,    /* parent widget */
  1036.       XtNfromVert,         full_calendar_widgets[3],
  1037.       XtNfromHoriz,        full_calendar_widgets[6],
  1038.       XtNborderWidth,      0,
  1039.       NULL                 /* end args */
  1040.    );
  1041.  
  1042.    /*VARARGS0*/
  1043.    widget_list[num_to_manage++] = full_calendar_widgets[8] = XtVaCreateWidget (
  1044.       "september",          /* widget name */
  1045.       calendarWidgetClass, /* widget class */
  1046.       full_form_widget,    /* parent widget */
  1047.       XtNfromVert,         full_calendar_widgets[3],
  1048.       XtNfromHoriz,        full_calendar_widgets[7],
  1049.       XtNright,            XtChainRight,
  1050.       XtNborderWidth,      0,
  1051.       NULL                 /* end args */
  1052.    );
  1053.  
  1054.    /*VARARGS0*/
  1055.    widget_list[num_to_manage++] = full_calendar_widgets[9] = XtVaCreateWidget (
  1056.       "october",          /* widget name */
  1057.       calendarWidgetClass, /* widget class */
  1058.       full_form_widget,    /* parent widget */
  1059.       XtNfromVert,         full_calendar_widgets[6],
  1060.       XtNbottom,           XtChainBottom,
  1061.       XtNleft,             XtChainLeft,
  1062.       XtNborderWidth,      0,
  1063.       NULL                 /* end args */
  1064.    );
  1065.  
  1066.    /*VARARGS0*/
  1067.    widget_list[num_to_manage++] = full_calendar_widgets[10] = XtVaCreateWidget (
  1068.       "november",          /* widget name */
  1069.       calendarWidgetClass, /* widget class */
  1070.       full_form_widget,    /* parent widget */
  1071.       XtNfromVert,         full_calendar_widgets[6],
  1072.       XtNfromHoriz,        full_calendar_widgets[9],
  1073.       XtNbottom,           XtChainBottom,
  1074.       XtNborderWidth,      0,
  1075.       NULL                 /* end args */
  1076.    );
  1077.  
  1078.    /*VARARGS0*/
  1079.    widget_list[num_to_manage++] = full_calendar_widgets[11] = XtVaCreateWidget (
  1080.       "december",          /* widget name */
  1081.       calendarWidgetClass, /* widget class */
  1082.       full_form_widget,    /* parent widget */
  1083.       XtNfromVert,         full_calendar_widgets[6],
  1084.       XtNfromHoriz,        full_calendar_widgets[10],
  1085.       XtNbottom,           XtChainBottom,
  1086.       XtNright,            XtChainRight,
  1087.       XtNborderWidth,      0,
  1088.       NULL                 /* end args */
  1089.    );
  1090.  
  1091.    /* Get the border and the grid to be the same thickness */
  1092.    /*VARARGS0*/
  1093.    XtVaGetValues(
  1094.       full_calendar_widgets[0],
  1095.       XtNlineWidth, &linewidth,
  1096.       NULL
  1097.    );
  1098.  
  1099.    for (month=0; month < 12; month++) {
  1100.       XtAddCallback(
  1101.          full_calendar_widgets[month],
  1102.          XtNcallback,
  1103.          calendar_callback,
  1104.          0
  1105.       );
  1106.  
  1107.       /*VARARGS0*/
  1108.       XtVaSetValues(
  1109.          full_calendar_widgets[month],
  1110.          XtNborderWidth,  linewidth/2,
  1111.          NULL
  1112.       );
  1113.  
  1114.       if (lang_specified) {
  1115.          /*VARARGS0*/
  1116.          XtVaSetValues(
  1117.             full_calendar_widgets[month],
  1118.             XtNmonthNames,   (XtPointer) month_names[lang_opt],
  1119.             XtNweekdayNames, (XtPointer) weekday_names[lang_opt],
  1120.             NULL
  1121.          );
  1122.       }
  1123.    }
  1124.  
  1125.    /* Manage all the children of the form widget */
  1126.    XtManageChildren(widget_list, num_to_manage);
  1127. }
  1128.  
  1129.  
  1130.  
  1131. /*==========================================================================*/
  1132. /*                            Make Inc/Dec Button:                          */
  1133. /*==========================================================================*/
  1134. Widget make_inc_dec_button(name, parent_widget, label, callback1, callback2)
  1135. char * name;
  1136. Widget parent_widget;
  1137. char * label;
  1138. void (*callback1)();
  1139. void (*callback2)();
  1140. {
  1141.    Widget form_widget;
  1142.    Widget button1;
  1143.    Widget button2;
  1144.    Widget label_widget;
  1145.    Widget widget_list[MAX_WIDGETS];
  1146.    int num_to_manage = 0;
  1147.  
  1148.    /*VARARGS0*/
  1149.    form_widget = XtVaCreateManagedWidget (
  1150.       "form",              /* widget name */
  1151.       formWidgetClass,     /* widget class */
  1152.       parent_widget,       /* parent widget */
  1153.       XtNtop,               XtChainTop,
  1154.       XtNbottom,            XtChainBottom,
  1155.       XtNleft,              XtChainLeft,
  1156.       XtNright,             XtChainRight,
  1157.       XtNdefaultDistance,   0,
  1158.       XtNborderWidth,       0,
  1159.       NULL                 /* end args */
  1160.    );
  1161.  
  1162.    /*VARARGS0*/
  1163.    widget_list[num_to_manage++] = label_widget = XtVaCreateWidget (
  1164.       name,                /* widget name */
  1165.       labelWidgetClass,    /* widget class */
  1166.       form_widget,         /* parent widget */
  1167.       XtNlabel,            label,
  1168.       XtNtop,              XtChainTop,
  1169.       XtNbottom,           XtChainTop,
  1170.       XtNleft,             XtChainLeft,
  1171.       XtNright,            XtChainLeft,
  1172.       XtNborderWidth,      0,
  1173.       NULL                 /* end args */
  1174.    );
  1175.    
  1176.    /*VARARGS0*/
  1177.    widget_list[num_to_manage++] = button1 = XtVaCreateWidget (
  1178.       "dec",               /* widget name */
  1179.       commandWidgetClass,  /* widget class */
  1180.       form_widget,         /* parent widget */
  1181.       XtNfromHoriz,        label_widget,
  1182.       XtNtop,              XtChainTop,
  1183.       XtNbottom,           XtChainTop,
  1184.       XtNleft,             XtChainLeft,
  1185.       XtNright,            XtChainLeft,
  1186.       XtNbitmap,           left_arrow,
  1187.       XtNborderWidth,      1,
  1188.       NULL                 /* end args */
  1189.    );
  1190.    XtAddCallback(button1, XtNcallback, callback1, NULL);
  1191.  
  1192.    /*VARARGS0*/
  1193.    widget_list[num_to_manage++] = button2 = XtVaCreateWidget (
  1194.       "inc",               /* widget name */
  1195.       commandWidgetClass,  /* widget class */
  1196.       form_widget,         /* parent widget */
  1197.       XtNfromHoriz,        button1,
  1198.       XtNtop,              XtChainTop,
  1199.       XtNbottom,           XtChainTop,
  1200.       XtNleft,             XtChainLeft,
  1201.       XtNright,            XtChainLeft,
  1202.       XtNbitmap,           right_arrow,
  1203.       XtNborderWidth,      1,
  1204.       NULL                 /* end args */
  1205.    );
  1206.    XtAddCallback(button2, XtNcallback, callback2, NULL);
  1207.  
  1208.    /* Manage all the children of the form widget */
  1209.    XtManageChildren(widget_list, num_to_manage);
  1210.  
  1211.    return (form_widget);
  1212. }
  1213.  
  1214.  
  1215.  
  1216. /*==========================================================================*/
  1217. /*                          Miscellaneous Functions:                        */
  1218. /*==========================================================================*/
  1219. void set_the_date(new_date)
  1220. Date new_date;
  1221. {
  1222.    int month;
  1223.    Date temp_date;
  1224.  
  1225.    if (display_mode == full) {
  1226.  
  1227.       temp_date.year = new_date.year;
  1228.  
  1229.       /* Only change the calendar date if a day was specified. */
  1230.       if (new_date.day) {
  1231.          for (month=0; month < 12; month ++) {
  1232.             /* Set date to highlight for each calendar. */
  1233.             CalendarSetDate(full_calendar_widgets[month], new_date);
  1234.             current_date = new_date;
  1235.          }
  1236.       }
  1237.  
  1238.       for (month=0; month < 12; month ++) {
  1239.          /* Set month to show for each calendar. */
  1240.          temp_date.month = month+1;
  1241.          CalendarShowMonth(full_calendar_widgets[month], temp_date);
  1242.       }
  1243.  
  1244.    } else if (display_mode == single) {
  1245.  
  1246.       /* Only change the calendar date if a day was specified. */
  1247.       if (new_date.day) {
  1248.          CalendarSetDate(single_calendar_widget, new_date);
  1249.          current_date = new_date;
  1250.       }
  1251.       CalendarShowMonth(single_calendar_widget, new_date);
  1252.  
  1253.    } else {
  1254.  
  1255.       /* No calendar is displayed. */
  1256.       if (new_date.day) {
  1257.          CalendarSetDate(single_calendar_widget, new_date);
  1258.          current_date = new_date;
  1259.       }
  1260.    }
  1261.  
  1262. }
  1263.  
  1264.  
  1265.  
  1266.  
  1267. void flip_calendar()
  1268. {
  1269.    if (fly_opt) {
  1270.       if (forward) {
  1271.          day_inc();
  1272.       } else {
  1273.          day_dec();
  1274.       }
  1275.    } else {
  1276.       warp_to_start(NULL, NULL, NULL);
  1277.    }
  1278.    timeout_id = XtAddTimeOut(interval, flip_calendar, NULL);
  1279. }
  1280.  
  1281.  
  1282.  
  1283.  
  1284. char * get_default_diary_file_name()
  1285. {
  1286.    static char file_name[MAXPATHLEN];
  1287.    uid_t uid = getuid();
  1288.    struct passwd * pwent = getpwuid(uid);
  1289.    strcpy(file_name, pwent->pw_dir);
  1290.    strcat(file_name, DIARY_FILE);
  1291.    return(file_name);
  1292. }
  1293.  
  1294.  
  1295.  
  1296.  
  1297. char * get_default_template_file_name()
  1298. {
  1299.    static char file_name[MAXPATHLEN];
  1300.    uid_t uid = getuid();
  1301.    struct passwd * pwent = getpwuid(uid);
  1302.    strcpy(file_name, pwent->pw_dir);
  1303.    strcat(file_name, TEMPLATE_FILE);
  1304.    return(file_name);
  1305. }
  1306.  
  1307.  
  1308.  
  1309.  
  1310. /* Determine micro seconds til midnight. */
  1311. void set_initial_time_interval()
  1312. {
  1313.    time_t seconds = time(NULL);
  1314.    struct tm * tm_ptr = localtime(&seconds);
  1315.    int minutes = tm_ptr->tm_hour * 60 + tm_ptr->tm_min;
  1316.  
  1317.    /* Wait until 5 minutes after midnight and then flip */
  1318.    interval = TWENTY_FOUR_HOURS + FIVE_MINUTES - (1000 * 60 * minutes);
  1319. }
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325. /*==========================================================================*/
  1326. /*                               Callbacks:                                 */
  1327. /*==========================================================================*/
  1328. /*ARGSUSED*/
  1329. void quit(widget, client_data, call_data)
  1330. Widget widget;
  1331. XtPointer client_data;
  1332. XtPointer call_data;
  1333. {
  1334.    save_old_diary_entry();
  1335.    XtDestroyWidget(top_level_widget);
  1336.    if (diary_changed) {
  1337.       save_diary(diary_file_name);
  1338.       diary_changed = FALSE;
  1339.    }
  1340.    XtRemoveTimeOut(timeout_id);
  1341.    exit(0);
  1342. }
  1343.  
  1344.  
  1345.  
  1346. /*ARGSUSED*/
  1347. void month_inc(widget, client_data, call_data)
  1348. Widget widget;
  1349. XtPointer client_data;
  1350. XtPointer call_data;
  1351. {
  1352.    /* Only called from single calendar mode. */
  1353.    CalendarIncMonth(single_calendar_widget);
  1354. }
  1355.  
  1356.  
  1357.  
  1358.  
  1359. /*ARGSUSED*/
  1360. void month_dec(widget, client_data, call_data)
  1361. Widget widget;
  1362. XtPointer client_data;
  1363. XtPointer call_data;
  1364. {
  1365.    /* Only called from single calendar mode. */
  1366.    CalendarDecMonth(single_calendar_widget);
  1367. }
  1368.  
  1369.  
  1370.  
  1371.  
  1372. /*ARGSUSED*/
  1373. void year_inc(widget, client_data, call_data)
  1374. Widget widget;
  1375. XtPointer client_data;
  1376. XtPointer call_data;
  1377. {
  1378.    int month;
  1379.    if (display_mode == full) {
  1380.       for (month=0; month < 12; month++) {
  1381.          CalendarIncYear(full_calendar_widgets[month]);
  1382.       }
  1383.    } else {
  1384.       CalendarIncYear(single_calendar_widget);
  1385.    }
  1386. }
  1387.  
  1388.  
  1389.  
  1390. /*ARGSUSED*/
  1391. void year_dec(widget, client_data, call_data)
  1392. Widget widget;
  1393. XtPointer client_data;
  1394. XtPointer call_data;
  1395. {
  1396.    int month;
  1397.    if (display_mode == full) {
  1398.       for (month=0; month < 12; month++) {
  1399.          CalendarDecYear(full_calendar_widgets[month]);
  1400.       }
  1401.    } else {
  1402.       CalendarDecYear(single_calendar_widget);
  1403.    }
  1404. }
  1405.  
  1406.  
  1407.  
  1408.  
  1409. /*ARGSUSED*/
  1410. void warp_to_dialog(widget, client_data, call_data)
  1411. Widget widget;
  1412. XtPointer client_data;
  1413. XtPointer call_data;
  1414. {
  1415.    Position x, y;
  1416.  
  1417.    XtTranslateCoords(
  1418.       widget,
  1419.       0, 0,
  1420.       &x, &y
  1421.    );
  1422.  
  1423.    /*VARARGS0*/
  1424.    XtVaSetValues(
  1425.       dialog_popup_shell_widget,
  1426.       XtNx, x+6,
  1427.       XtNy, y-6,
  1428.       NULL
  1429.    );
  1430.  
  1431.    /*VARARGS0*/
  1432.    XtVaSetValues(
  1433.       dialog_widget,
  1434.       XtNvalue, "",
  1435.       NULL
  1436.    );
  1437.    XtPopup(dialog_popup_shell_widget, XtGrabExclusive);
  1438. }
  1439.  
  1440.  
  1441.  
  1442.  
  1443. /*ARGSUSED*/
  1444. void warp_to_start(widget, client_data, call_data)
  1445. Widget widget;
  1446. XtPointer client_data;
  1447. XtPointer call_data;
  1448. {
  1449.    Date todays_date;
  1450.    todays_date = GetTodaysDate();
  1451.    save_old_diary_entry();
  1452.    set_the_date(todays_date);
  1453.    show_new_diary_entry();
  1454. }
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460. /*ARGSUSED*/
  1461. void day_inc(widget, client_data, call_data)
  1462. Widget widget;
  1463. XtPointer client_data;
  1464. XtPointer call_data;
  1465. {
  1466.    int month;
  1467.    Date temp_date;
  1468.  
  1469.    save_old_diary_entry();
  1470.  
  1471.    if (display_mode == full) {
  1472.       
  1473.       for (month=0; month < 12; month++) {
  1474.          CalendarIncDay(full_calendar_widgets[month], False);
  1475.       }
  1476.  
  1477.       CalendarGetDate(full_calendar_widgets[0], ¤t_date);
  1478.  
  1479.       temp_date.year = current_date.year;
  1480.       for (month=0; month < 12; month++) {
  1481.          temp_date.month = month+1;
  1482.          CalendarShowMonth(full_calendar_widgets[month], temp_date);
  1483.       }
  1484.  
  1485.    } else if (display_mode == single) {
  1486.  
  1487.       CalendarIncDay(single_calendar_widget, True);
  1488.       CalendarGetDate(single_calendar_widget, ¤t_date);
  1489.       CalendarShowMonth(single_calendar_widget, current_date);
  1490.    
  1491.    } else {
  1492.  
  1493.       /* No calendar is displayed. */
  1494.       CalendarIncDay(single_calendar_widget, True);
  1495.       CalendarGetDate(single_calendar_widget, ¤t_date);
  1496.    }
  1497.  
  1498.    show_new_diary_entry();
  1499. }
  1500.  
  1501.  
  1502.  
  1503.  
  1504. /*ARGSUSED*/
  1505. void day_dec(widget, client_data, call_data)
  1506. Widget widget;
  1507. XtPointer client_data;
  1508. XtPointer call_data;
  1509. {
  1510.    int month;
  1511.    Date temp_date;
  1512.  
  1513.    save_old_diary_entry();
  1514.  
  1515.    if (display_mode == full) {
  1516.       
  1517.       for (month=0; month < 12; month++) {
  1518.          CalendarDecDay(full_calendar_widgets[month], False);
  1519.       }
  1520.  
  1521.       CalendarGetDate(full_calendar_widgets[0], ¤t_date);
  1522.  
  1523.       temp_date.year = current_date.year;
  1524.       for (month=0; month < 12; month++) {
  1525.          temp_date.month = month+1;
  1526.          CalendarShowMonth(full_calendar_widgets[month], temp_date);
  1527.       }
  1528.  
  1529.    } else if (display_mode == single) {
  1530.  
  1531.       CalendarDecDay(single_calendar_widget, True);
  1532.       CalendarGetDate(single_calendar_widget, ¤t_date);
  1533.       CalendarShowMonth(single_calendar_widget, current_date);
  1534.  
  1535.    } else {
  1536.  
  1537.       /* No calendar is displayed. */
  1538.       CalendarDecDay(single_calendar_widget, True);
  1539.       CalendarGetDate(single_calendar_widget, ¤t_date);
  1540.    }
  1541.  
  1542.    show_new_diary_entry();
  1543. }
  1544.  
  1545.  
  1546.  
  1547.  
  1548. /*ARGSUSED*/
  1549. void change_to_full(widget, client_data, call_data)
  1550. Widget widget;
  1551. XtPointer client_data;
  1552. XtPointer call_data;
  1553. {
  1554.    if (display_mode == full) {
  1555.       if (diary_showing) {
  1556.          XtPopdown(full_popup_shell_widget);
  1557.          sensitize(menu_diary_widget, False);
  1558.          sensitize(menu_full_widget, True);
  1559.          sensitize(menu_single_widget, True);
  1560.          display_mode = none;
  1561.       } else {
  1562.          /* Can't hide full if no diary is showing. */
  1563.       }
  1564.       return;
  1565.    }
  1566.  
  1567.    if (display_mode == single) {
  1568.       XtPopdown(single_popup_shell_widget);
  1569.    }
  1570.  
  1571.    if (!full_initialized) {
  1572.       init_full_calendar();
  1573.    }
  1574.  
  1575.    if (!diary_showing) {
  1576.       sensitize(menu_full_widget, False);
  1577.       sensitize(menu_single_widget, True);
  1578.    } else {
  1579.       sensitize(menu_diary_widget, True);
  1580.    }
  1581.  
  1582.    XtPopup(full_popup_shell_widget, XtGrabNone);
  1583.    display_mode = full;
  1584.    set_the_date(current_date);
  1585. }
  1586.  
  1587.  
  1588.  
  1589.  
  1590. /*ARGSUSED*/
  1591. void change_to_single(widget, client_data, call_data)
  1592. Widget widget;
  1593. XtPointer client_data;
  1594. XtPointer call_data;
  1595. {
  1596.    if (display_mode == single) {
  1597.       if (diary_showing) {
  1598.          XtPopdown(single_popup_shell_widget);
  1599.          sensitize(menu_diary_widget, False);
  1600.          sensitize(menu_full_widget, True);
  1601.          sensitize(menu_single_widget, True);
  1602.          display_mode = none;
  1603.       } else {
  1604.          /* Can't hide single if no diary is showing. */
  1605.       }
  1606.       return;
  1607.    } 
  1608.  
  1609.    if (display_mode == full) {
  1610.       XtPopdown(full_popup_shell_widget);
  1611.    }
  1612.  
  1613.    if (!single_initialized) {
  1614.       init_single_calendar();
  1615.    }
  1616.  
  1617.    if (!diary_showing) {
  1618.       sensitize(menu_single_widget, False);
  1619.       sensitize(menu_full_widget, True);
  1620.    } else {
  1621.       sensitize(menu_diary_widget, True);
  1622.    }
  1623.  
  1624.    XtPopup(single_popup_shell_widget, XtGrabNone);
  1625.    display_mode = single;
  1626.    set_the_date(current_date);
  1627. }
  1628.  
  1629.  
  1630.  
  1631.  
  1632. /*==========================================================================*/
  1633. /*                                Actions:                                  */
  1634. /*==========================================================================*/
  1635. /*ARGSUSED*/
  1636. void dialog_done(w, event, params, num_params)
  1637. Widget w;
  1638. XButtonEvent *event;
  1639. String *params;
  1640. Cardinal *num_params;
  1641. {
  1642.    char * string;
  1643.    Date new_date;
  1644.  
  1645.    XtPopdown(dialog_popup_shell_widget);
  1646.    string = XawDialogGetValueString(dialog_widget);
  1647.    if (!strcmp(string, "")) {
  1648.       return;
  1649.    }
  1650.  
  1651.    if (display_mode == full) {
  1652.       new_date = DateConverter(full_calendar_widgets[0], string);
  1653.    } else {
  1654.       new_date = DateConverter(single_calendar_widget, string);
  1655.    }
  1656.  
  1657.    if (new_date.year) {
  1658.       /* The date was valid. */
  1659.       if (diary_showing) {
  1660.          save_old_diary_entry();
  1661.          set_the_date(new_date);
  1662.          show_new_diary_entry();
  1663.       } else {
  1664.          set_the_date(new_date);
  1665.       }
  1666.    }
  1667. }
  1668.  
  1669.  
  1670.  
  1671.  
  1672. /*==========================================================================*/
  1673. /*                                  Diary:                                  */
  1674. /*==========================================================================*/
  1675. void initialize_diary_widgets()
  1676. {
  1677.    diary_initialized = TRUE;
  1678.  
  1679.    init_diary(diary_file_name);
  1680.  
  1681.    /*VARARGS0*/
  1682.    diary_popup_shell_widget = XtVaCreatePopupShell(
  1683.       "diary",
  1684.       topLevelShellWidgetClass,
  1685.       top_level_widget,
  1686.       XtNiconPixmap,    diary_icon,
  1687.       XtNiconName,      "diary",
  1688.       XtNwaitForWm,     False,
  1689.       NULL
  1690.    );
  1691.  
  1692.    /*VARARGS0*/
  1693.    diary_top_paned_widget = XtVaCreateManagedWidget (
  1694.       "paned",                   /* widget name */
  1695.       panedWidgetClass,          /* widget class */
  1696.       diary_popup_shell_widget,  /* parent widget */
  1697.       NULL                       /* end args */
  1698.    );
  1699.  
  1700.    init_button_box(diary_top_paned_widget, DAY | ENTRY);
  1701.  
  1702.    /*VARARGS0*/
  1703.    diary_label_widget = XtVaCreateManagedWidget (
  1704.      "label",                   /* widget name */
  1705.       labelWidgetClass,         /* widget class */
  1706.       diary_top_paned_widget,   /* parent widget */
  1707.       XtNlabel,                 "",
  1708.       XtNshowGrip,              False,
  1709.       XtNskipAdjust,            True,
  1710.       NULL                      /* end args */
  1711.    );
  1712.  
  1713.    /*VARARGS0*/
  1714.    diary_form_widget = XtVaCreateManagedWidget (
  1715.       "form",                  /* widget name */
  1716.       formWidgetClass,         /* widget class */
  1717.       diary_top_paned_widget,  /* parent widget */
  1718.       XtNshowGrip,             False,
  1719.       NULL                     /* end args */
  1720.    );
  1721.  
  1722.    /*VARARGS0*/
  1723.    diary_text_widget = XtVaCreateManagedWidget(
  1724.       "text",                  /* widget name */
  1725.       asciiTextWidgetClass,    /* widget class */
  1726.       diary_form_widget,       /* parent widget */
  1727.       XtNeditType,             XtEtextEdit,
  1728.       XtNtop,                  XtChainTop,
  1729.       XtNbottom,               XtChainBottom,
  1730.       XtNright,                XtChainRight,
  1731.       XtNleft,                 XtChainLeft,
  1732.       NULL                     /* end args */
  1733.    );
  1734.  
  1735.    /*VARARGS0*/
  1736.    XtVaGetValues(
  1737.       diary_text_widget,
  1738.       XtNtextSource, &diary_text_source_widget,
  1739.       NULL
  1740.    );
  1741. }
  1742.  
  1743.  
  1744.  
  1745.  
  1746. void toggle_diary()
  1747. {
  1748.    if (!diary_initialized) {
  1749.       initialize_diary_widgets();
  1750.    }
  1751.  
  1752.    if (!diary_showing) {
  1753.       /* Display the diary. */
  1754.       XtPopup(diary_popup_shell_widget, XtGrabNone);
  1755.       diary_showing = TRUE;
  1756.       sensitize(menu_diary_widget, True);
  1757.       if (display_mode != none) {
  1758.          sensitize(menu_full_widget, True);
  1759.          sensitize(menu_single_widget, True);
  1760.       } else {
  1761.          sensitize(menu_diary_widget, False);
  1762.       }
  1763.       show_new_diary_entry();
  1764.    } else if (display_mode != none) {
  1765.       /* Hide the diary. */
  1766.       XtPopdown(diary_popup_shell_widget);
  1767.       diary_showing = FALSE;
  1768.       if (display_mode == single) {
  1769.           sensitize(menu_single_widget, False);
  1770.       } else {
  1771.          sensitize(menu_full_widget, False);
  1772.       }
  1773.       save_old_diary_entry();
  1774.    } 
  1775. }
  1776.  
  1777.  
  1778.  
  1779. void show_new_diary_entry()
  1780. {
  1781.    char * pretty_string;
  1782.    char * entry_text;
  1783.  
  1784.    if (!diary_showing) {
  1785.       return;
  1786.    }
  1787.  
  1788.    entry_text = retrieve(current_date);
  1789.  
  1790.    if (using_template && !entry_text[0]) {
  1791.       /* Initialize the entry to the template. */
  1792.       entry_text = template;
  1793.    }
  1794.  
  1795.    /*VARARGS0*/ 
  1796.    XtVaSetValues(
  1797.       diary_text_widget,
  1798.       XtNstring, entry_text,
  1799.       NULL
  1800.    );
  1801.  
  1802.    if (display_mode == full) {
  1803.       pretty_string = CalendarPrettyDate(full_calendar_widgets[0]);
  1804.    } else {
  1805.       pretty_string = CalendarPrettyDate(single_calendar_widget);
  1806.    }
  1807.  
  1808.    /*VARARGS0*/ 
  1809.    XtVaSetValues(
  1810.       diary_label_widget,
  1811.       XtNlabel,             pretty_string,
  1812.       NULL                  /* end args */
  1813.    );
  1814. }
  1815.  
  1816.  
  1817.  
  1818. void save_old_diary_entry()
  1819. {
  1820.    char * old_text;
  1821.    char * copy;
  1822.  
  1823.    if (!diary_initialized) {
  1824.       return;
  1825.    }
  1826.  
  1827.    if (XawAsciiSourceChanged(diary_text_source_widget)) {
  1828.  
  1829.       diary_changed = TRUE;
  1830.  
  1831.       /*VARARGS0*/ 
  1832.       XtVaGetValues(
  1833.          diary_text_widget,
  1834.          XtNstring, &old_text,
  1835.          NULL
  1836.       );
  1837.  
  1838.       if (using_template) {
  1839.          if (entry_modified(old_text)) {
  1840.             copy = XtNewString(old_text);
  1841.             install(current_date, copy, TRUE);
  1842.          } else {
  1843.             /* Only whitespace changes were made to the template */
  1844.             install(current_date, "", FALSE);
  1845.          }
  1846.       } else {
  1847.          copy = XtNewString(old_text);
  1848.          install(current_date, copy, TRUE);
  1849.       }
  1850.    }
  1851. }
  1852.  
  1853.  
  1854.  
  1855.  
  1856. void sensitize(widget, flag)
  1857. Widget widget;
  1858. Boolean flag;
  1859. {
  1860.    /*VARARGS0*/
  1861.    XtVaSetValues(
  1862.       widget,
  1863.       XtNsensitive, flag,
  1864.       NULL
  1865.    );
  1866. }
  1867.  
  1868.  
  1869.  
  1870.  
  1871. /*==========================================================================*/
  1872. /*                             Diary Callbacks:                             */
  1873. /*==========================================================================*/
  1874. /*ARGSUSED*/
  1875. void entry_inc(widget, client_data, call_data)
  1876. Widget widget;
  1877. XtPointer client_data;
  1878. XtPointer call_data;
  1879. {
  1880.    Date next_date;
  1881.    if (currently_flashing) {
  1882.       return;
  1883.    }
  1884.    next_date = next_entry(current_date);
  1885.    if (next_date.year) {
  1886.       save_old_diary_entry();
  1887.       set_the_date(next_date);
  1888.       show_new_diary_entry();
  1889.    } else {
  1890.       flash("No following diary entry exists");
  1891.    }
  1892. }
  1893.  
  1894.  
  1895.  
  1896.  
  1897. /*ARGSUSED*/
  1898. void entry_dec(widget, client_data, call_data)
  1899. Widget widget;
  1900. XtPointer client_data;
  1901. XtPointer call_data;
  1902. {
  1903.    Date prev_date;
  1904.    if (currently_flashing) {
  1905.       return;
  1906.    }
  1907.    prev_date = prev_entry(current_date);
  1908.    if (prev_date.year) {
  1909.       save_old_diary_entry();
  1910.       set_the_date(prev_date);
  1911.       show_new_diary_entry();
  1912.    } else {
  1913.       flash("No previous diary entry exists");
  1914.    }
  1915. }
  1916.  
  1917.  
  1918.  
  1919.  
  1920. /*ARGSUSED*/
  1921. void save_diary_callback(widget, client_data, call_data)
  1922. Widget widget;
  1923. XtPointer client_data;
  1924. XtPointer call_data;
  1925. {
  1926.    save_old_diary_entry();
  1927.    if (diary_changed) {
  1928.       save_diary(diary_file_name);
  1929.       diary_changed = FALSE;
  1930.    }
  1931. }
  1932.  
  1933.  
  1934.  
  1935. /*ARGSUSED*/
  1936. void calendar_callback(widget, client_data, call_data)
  1937. Widget widget;
  1938. XtPointer client_data;
  1939. XtPointer call_data;
  1940. {
  1941.    Date * date_ptr = (Date *) call_data;
  1942.  
  1943.    if (diary_showing) {
  1944.       save_old_diary_entry();
  1945.       set_the_date(*date_ptr);
  1946.       show_new_diary_entry();
  1947.    } else {
  1948.       set_the_date(*date_ptr);
  1949.    }
  1950. }
  1951.  
  1952.  
  1953.  
  1954.  
  1955. void flash(string)
  1956. char * string;
  1957. {
  1958.    currently_flashing = TRUE;
  1959.    /*VARARGS0*/
  1960.    XtVaSetValues(
  1961.       diary_label_widget,
  1962.       XtNlabel,             string,
  1963.       NULL                  /* end args */
  1964.    );
  1965.    XtAddTimeOut(ONE_SECOND, flash_back, NULL);
  1966. }
  1967.  
  1968.  
  1969.  
  1970.  
  1971. void flash_back()
  1972. {
  1973.    char * pretty_string;
  1974.  
  1975.    if (display_mode == full) {
  1976.       pretty_string = CalendarPrettyDate(full_calendar_widgets[0]);
  1977.    } else {
  1978.       pretty_string = CalendarPrettyDate(single_calendar_widget);
  1979.    }
  1980.  
  1981.    /*VARARGS0*/
  1982.    XtVaSetValues(
  1983.       diary_label_widget,
  1984.       XtNlabel,             pretty_string,
  1985.       NULL                  /* end args */
  1986.    );
  1987.    currently_flashing = FALSE;
  1988. }
  1989.