home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Header: printer.c,v 1.1 91/03/27 16:46:20 billr Exp $
- */
- /*
- * printer.c
- *
- * calentool - a year/month/week/day-at-a-glance calendar for Sun workstations.
- *
- * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller@sun.com>
- *
- * Original source Copyright (C) 1987, Sun Microsystems, Inc.
- * All Rights Reserved
- * Permission is hereby granted to use and modify this program in source
- * or binary form as long as it is not sold for profit and this copyright
- * notice remains intact.
- *
- *
- * Changes/additions by: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
- *
- * Changes and additions Copyright (C) 1988, 1989, 1991 Tektronix, Inc.
- * All Rights Reserved
- * Permission is hereby granted to use and modify the modifications in source
- * or binary form as long as they are not sold for profit and this copyright
- * notice remains intact.
- * Modified parse_date to allow +nnn and -nnn syntax for dates relative to the
- * current date. Peter Marshall <peter.marshall@uwo.ca>. 1989-09-19.
- */
- /********************************************
- * *
- * Printing routines. *
- * *
- ********************************************/
-
- #include "ct.h"
- #include <stdio.h>
- #include <suntool/sunview.h>
- #include <suntool/canvas.h>
- #include <sys/time.h>
-
- extern struct tm current, today;
- extern int n_slots;
- extern struct dayslot *slots;
- extern char apts_pathname[];
- extern int nr_weekdays, n_tslots;
- extern char *mailto;
- extern int findex;
- extern struct appt_entry future[];
- extern char printer[];
- extern Canvas canvas;
- extern Pixwin *main_pixwin;
- extern int mainsw_state;
- extern Pixfont *font, *sfont;
- extern int monday_first, hour24, day_first;
- extern int print_to_file;
- extern int print_dev, week_ofs;
- extern char *daynames[], *monthnames[];
- extern char clockstr[], strbuf[];
-
- char rasfile[] = "/usr/tmp/calentool.ras";
- char psfile[] = "/usr/tmp/calentool.ps";
-
-
- /*
- * convert appt entry to ASCII string for display with date, time and msg
- */
- char *
- format_appt(appt)
- struct appt_entry *appt;
- {
- int e_hour, e_minutes, duration;
- struct tm Save;
-
- if (appt->arrows > 0) {
- duration = appt->arrows + 1;
- e_hour = appt->hour + duration/2;
- e_minutes = appt->minute + ((duration%2) * 30);
- } else {
- e_hour = appt->hour;
- e_minutes = appt->minute + 30;
- }
- if (e_minutes == 60) {
- e_minutes = 0;
- ++e_hour;
- }
- /* get day of week */
- Save = current;
- current.tm_year = appt->year;
- current.tm_mon = appt->month;
- current.tm_mday = appt->day;
- fix_current_day();
-
- if (appt->flags & A_NOTE) {
- /* note */
- if (appt->flags & ALL_YEARS)
- if (day_first)
- sprintf(strbuf,"%3.3s %2d/%02d -- %s",
- daynames[current.tm_wday], appt->day,
- appt->month+1, appt->str);
- else
- sprintf(strbuf,"%3.3s %2d/%02d -- %s",
- daynames[current.tm_wday], appt->month+1,
- appt->day, appt->str);
- else if (appt->year > 99)
- if (day_first)
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %s",
- daynames[current.tm_wday], appt->day,
- appt->month+1, appt->year-100, appt->str);
- else
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %s",
- daynames[current.tm_wday], appt->month+1,
- appt->day, appt->year-100, appt->str);
- else
- if (day_first)
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %s",
- daynames[current.tm_wday], appt->day,
- appt->month+1, appt->year, appt->str);
- else
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %s",
- daynames[current.tm_wday], appt->month+1,
- appt->day, appt->year, appt->str);
- } else {
- /* standard appointment */
- if (hour24)
- if (day_first)
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %2d:%02d to %2d:%02d %s",
- daynames[current.tm_wday], appt->day,
- appt->month+1, appt->year, appt->hour, appt->minute,
- e_hour, e_minutes, appt->str);
- else
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %2d:%02d to %2d:%02d %s",
- daynames[current.tm_wday], appt->month+1,
- appt->day, appt->year, appt->hour, appt->minute,
- e_hour, e_minutes, appt->str);
- else
- if (day_first)
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %2d:%02d%s to %2d:%02d%s %s",
- daynames[current.tm_wday], appt->day,
- appt->month+1, appt->year, (appt->hour < 13 ? appt->hour : appt->hour-12), appt->minute,
- (appt->hour < 12 ? "am" : "pm"),
- (e_hour < 13 ? e_hour : e_hour-12), e_minutes,
- (e_hour < 12 ? "am" : "pm"),
- appt->str);
- else
- sprintf(strbuf,"%3.3s %2d/%02d/%02d -- %2d:%02d%s to %2d:%02d%s %s",
- daynames[current.tm_wday], appt->month+1,
- appt->day, appt->year, (appt->hour < 13 ? appt->hour : appt->hour-12), appt->minute,
- (appt->hour < 12 ? "am" : "pm"),
- (e_hour < 13 ? e_hour : e_hour-12), e_minutes,
- (e_hour < 12 ? "am" : "pm"),
- appt->str);
- }
- current = Save;
- return(strbuf);
- }
-
- /*
- * convert appt entry to ASCII string for display with time and msg
- * if <esc_parens> is true then put '\' in front of parens (for Ps)
- */
- char *
- format_appt_nd(appt, esc_parens)
- struct appt_entry *appt;
- int esc_parens;
- {
- int e_hour, e_minutes, duration;
- char *p, *q;
- struct tm Save;
-
- if (appt->arrows > 0) {
- duration = appt->arrows + 1;
- e_hour = appt->hour + duration/2;
- e_minutes = appt->minute + ((duration%2) * 30);
- } else {
- e_hour = appt->hour;
- e_minutes = appt->minute + 30;
- }
- if (e_minutes == 60) {
- e_minutes = 0;
- ++e_hour;
- }
-
- strbuf[0] = '\0';
- if (!(appt->flags & A_NOTE)) {
- /* standard appointment */
- if (hour24)
- sprintf(strbuf,"%2d:%02d to %2d:%02d ",
- appt->hour, appt->minute, e_hour, e_minutes);
- else
- sprintf(strbuf,"%2d:%02d%s to %2d:%02d%s ",
- (appt->hour < 13 ? appt->hour : appt->hour-12), appt->minute,
- (appt->hour < 12 ? "am" : "pm"),
- (e_hour < 13 ? e_hour : e_hour-12), e_minutes,
- (e_hour < 12 ? "am" : "pm"));
- }
- p = appt->str;
- q = strbuf + strlen(strbuf);
- while (*p) {
- if (esc_parens)
- switch (*p) {
- /* ignore these */
- case '\b':
- case '\f':
- case '\n':
- case '\r':
- case '\t':
- break;
- /* escape these for PostScript */
- case '\\':
- case '(':
- case ')':
- *q++ = '\\';
- break;
- }
- *q++ = *p++;
- }
- *q = '\0';
-
- return(strbuf);
- }
-
- /*
- * Print today's appointments to stdout or mail (useful if we only have an ASCII
- * terminal connected to our Sun). Invoked by the "-p", "-P", "-m" or
- * "-M" options. The -T option is used to select print device
- * (PostScript or ASCII).
- * Month information is only printed as PostScript output.
- */
- print_apts(which, dest)
- int which, dest;
- {
- int i, gd_rtn, target;
- FILE *output, *pfp, *popen();
- char cmd[80], *name, *cuserid(), *mail_subj();
- struct tm Save;
-
- fix_current_day();
- gd_rtn = get_day_appts();
- if (which == PRI_DAY && !gd_rtn)
- return; /* nothing to show */
- if (which == PRI_DAY_XNOTES && gd_rtn == SOME_MKNOTES)
- /* all we have is marked notes */
- return; /* nothing to show */
- if (dest == DST_MAIL) {
- if (mailto != NULL) {
- name = mailto;
- } else if ((name = cuserid(NULL)) == NULL) {
- err_rpt("nobody to mail to", FATAL);
- }
- sprintf(cmd, "%s -s \"Appointments for %s\" %s", MAILPROG, mail_subj(), name);
- if ((output = popen(cmd, "w")) == NULL)
- err_rpt("Couldn't pipe to 'mail'", FATAL);
- } else {
- output = stdout;
- }
-
- if (which == PRI_DAY || which == PRI_DAY_XNOTES) {
- if (print_dev == PR_POSTSCRIPT)
- #ifdef RASTER_ONLY
- fprintf(output, "PostScript output option not compiled in\n");
- #else
- print_psday(output, (which == PRI_DAY_XNOTES ? TRUE : FALSE));
- #endif
- else
- print_one_day(which, output, gd_rtn);
- } else if (which == PRI_WEEK || which == PRI_WEEK_XNOTES) {
- Save = current;
- if (!week_ofs) {
- /* start printing on first dow */
- if (nr_weekdays == 7 && !monday_first)
- target = SUN;
- else
- target = MON;
- if (current.tm_wday >= target)
- while (current.tm_wday-- > target)
- current.tm_mday--;
- else
- /* looking at Sun */
- current.tm_mday++;
- fix_current_day();
- }
- if (print_dev == PR_POSTSCRIPT)
- #ifdef RASTER_ONLY
- fprintf(output, "PostScript output option not compiled in\n");
- #else
- print_psweek(output, (which == PRI_WEEK_XNOTES ? TRUE : FALSE));
- #endif
- else
- for (i=0;i<nr_weekdays;i++) {
- gd_rtn = get_day_appts();
- if ((gd_rtn && which == PRI_WEEK) ||
- (gd_rtn & ~SOME_MKNOTES && which == PRI_WEEK_XNOTES))
- print_one_day(which, output, gd_rtn);
- current.tm_mday++;
- fix_current_day();
- }
- current = Save;
- } else if (which == PRI_MONTH || which == PRI_MONTH_XNOTES) {
- if (print_dev == PR_POSTSCRIPT)
- #ifdef RASTER_ONLY
- fprintf(output, "PostScript output option not compiled in\n");
- #else
- print_psmonth(output, (which == PRI_MONTH_XNOTES ? TRUE : FALSE));
- #endif
- else
- fprintf(output, "\nNo ASCII month printout is available\n");
- }
- fflush(output);
- if (dest == DST_MAIL)
- pclose(output);
- }
-
- print_one_day(which, output, gdrtn)
- int which;
- FILE *output;
- int gdrtn;
- {
- int i;
- struct appt_entry tmp_apt, *aptr;
- char *format_appt();
-
- if (day_first)
- fprintf(output,"\n\t*** Appointments for %s %d %s %d ***\n\n",
- daynames[current.tm_wday], current.tm_mday,
- monthnames[current.tm_mon], current.tm_year+1900);
- else
- fprintf(output,"\n\t*** Appointments for %s %s %d, %d ***\n\n",
- daynames[current.tm_wday], monthnames[current.tm_mon],
- current.tm_mday, current.tm_year+1900);
-
- for (i=0; i<n_slots; i++) {
- if (i == n_tslots)
- /* start of notes section */
- if ((gdrtn & SOME_NOTES) ||
- (!(which & PRI_XNOTES) && (gdrtn & SOME_MKNOTES)))
- fprintf(output,"\n\t\t ===== Notes =====\n");
- if (slots[i].first != NULL && slots[i].active > 0) {
- /* at least one appt here */
- aptr = slots[i].first;
- do {
- if ((which & PRI_XNOTES) && ((aptr->flags & MARKED_NOTE) == MARKED_NOTE))
- continue;
- if (chk_deleted(&slots[i], aptr))
- continue;
- tmp_apt = *aptr;
- tmp_apt.year = current.tm_year;
- tmp_apt.month = current.tm_mon;
- tmp_apt.day = current.tm_mday;
- fprintf(output, "%s\n", format_appt(&tmp_apt));
- } while ((aptr = aptr->next) != NULL);
- }
- }
- if (findex) {
- /* print out future appointments */
- fprintf(output, "\n\t\t===== Future Reminders =====\n");
- for (i=0; i<findex; i++)
- fprintf(output, "%s\n", format_appt(&future[i]));
- }
- fprintf(output,"\n------------------------------------------------------------------\n");
- }
-
- /*
- * mail_subj() - make subject line for appointment mail. Use "today"
- * or "tomorrow" if appropriate, otherwise use the actual date.
- */
- char *
- mail_subj()
- {
- struct tm Save;
-
- if (!ymd_compare(current, today))
- sprintf(strbuf, "today");
- else {
- Save = current;
- current.tm_mday--;
- fix_current_day();
- if (!ymd_compare(current, today))
- sprintf(strbuf, "tomorrow");
- else if (day_first)
- sprintf(strbuf, "%s %d %s %d.",
- daynames[current.tm_wday], current.tm_mday,
- monthnames[current.tm_mon], current.tm_year+1900);
- else
- sprintf(strbuf, "%s %s %d, %d",
- daynames[current.tm_wday], monthnames[current.tm_mon],
- current.tm_mday, current.tm_year+1900);
- current = Save;
- }
- return (strbuf);
- }
-
- #ifndef NO_PRINTER
- /*
- * Print to Postscript compatable printer. If we are displaying
- * the year page, then create a raster file of the canvas and
- * feed it to a raster->ps filter (sun2ps). If on any other page,
- * then print a pretty PostScript calendar with appts written in
- * (as best can be).
- */
- print_calendar(file_type)
- int file_type;
- {
- char prntcmd[64];
- FILE *fp, *pfp;
- struct tm Save;
- int target;
-
- lock_cursors();
- working(TRUE);
- #ifndef RASTER_ONLY
- if (file_type == PR_POSTSCRIPT) {
- if ((pfp = fopen(psfile, "w")) == NULL) {
- err_rpt("can't open tmp ps file", NON_FATAL);
- return;
- }
- switch (mainsw_state) {
- case DISPLAYING_DAY:
- print_psday(pfp, FALSE);
- break;
- case DISPLAYING_WEEK:
- /* start printing on first dow */
- Save = current;
- if (nr_weekdays == 7 && !monday_first)
- target = SUN;
- else
- target = MON;
- if (current.tm_wday >= target)
- while (current.tm_wday-- > target)
- current.tm_mday--;
- else
- /* looking at Sun */
- current.tm_mday++;
- fix_current_day();
- print_psweek(pfp, FALSE);
- current = Save;
- break;
- case DISPLAYING_MONTH:
- print_psmonth(pfp, TRUE);
- break;
- case DISPLAYING_YEAR:
- if (dorasfile()) {
- fp = fopen(rasfile, "r");
- /* ras2ps closes the files that
- * we opened here.
- */
- ras2ps(fp, pfp);
- }
- break;
- }
- fclose(pfp);
- if (!print_to_file) {
- sprintf(prntcmd, "%s %s", printer, psfile);
- system(prntcmd);
- unlink(psfile);
- }
- } else {
- #else
- {
- #endif /* RASTER_ONLY */
- if (dorasfile() && !print_to_file) {
- sprintf(prntcmd, "%s -v %s", printer, rasfile);
- system(prntcmd);
- unlink(rasfile);
- }
- }
- working(FALSE);
- unlock_cursors();
- }
-
- /*
- * convert screen display to sun raster format
- */
- dorasfile()
- {
- Pixrect *save_pr;
- int type = RT_STANDARD;
- int copy_flag = TRUE;
- Rect *rect;
- struct pr_prpos where;
- char buf[128], *cuserid();
- FILE *fp;
-
- sprintf(buf, "Appointments file \"%s\" printed for %s on %s",
- apts_pathname, cuserid(NULL), clockstr);
-
- if ((fp = fopen(rasfile, "w")) != NULL) {
- rect = (Rect *) window_get(canvas, WIN_RECT);
- save_pr = mem_create(rect->r_width, rect->r_height+3*sfont->pf_defaultsize.y, 1);
- pr_rop(save_pr,0,0,rect->r_width-3,rect->r_height,PIX_SRC,main_pixwin->pw_prretained,0,0);
- where.pr = save_pr;
- where.pos.x = 6 * font->pf_defaultsize.x;
- where.pos.y = rect->r_height + 2*sfont->pf_defaultsize.y;
- pf_text(where, PIX_SRC, sfont, buf);
- pr_dump(save_pr, fp, NULL, type, copy_flag);
- fclose(fp);
- pr_destroy(save_pr);
- return (1);
- } else {
- err_rpt("can't open tmp raster file", NON_FATAL);
- return (0);
- }
- }
- #endif /* NO_PRINTER */
-