v01i013: Calendar/planning tool: Part 04/09
Charles Mcgrew
mcgrew at dartagnan.rutgers.edu
Sun May 28 07:09:57 AEST 1989
Submitted-by: Bill Randle <billr at saab.cna.tek.com>
Posting-number: Volume 1, Issue 13
Archive-name: calentool/part04
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# devent.c
# dpaint.c
# holidays.c
# This archive created: Sat May 27 13:12:02 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'devent.c'" '(27402 characters)'
if test -f 'devent.c'
then
echo shar: will not over-write existing file "'devent.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'devent.c'
X/*
X * $Header: devent.c,v 2.1 89/05/09 14:18:59 billr Exp $
X */
X/*
X * devent.c
X *
X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller at sun.com>
X *
X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
X * All Rights Reserved
X * Permission is hereby granted to use and modify this program in source
X * or binary form as long as it is not sold for profit and this copyright
X * notice remains intact.
X *
X *
X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr at saab.CNA.TEK.COM>
X *
X * Changes and additions Copyright (C) 1988, 1989 Tektronix, Inc.
X * All Rights Reserved
X * Permission is hereby granted to use and modify the modifications in source
X * or binary form as long as they are not sold for profit and this copyright
X * notice remains intact.
X */
X/********************************************************
X * *
X * Day event routines for main subwindow. *
X * *
X ********************************************************/
X
X
X#include <stdio.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <suntool/panel.h>
X#include <suntool/menu.h>
X#include <sys/time.h>
X#include <fcntl.h>
X#include "ct.h"
X#include "event.h"
X
Xextern Menu day_sel_menu;
Xextern Frame attr_frame;
Xextern Panel_item everyx_pi, repeat_pi, remind_pi;
Xextern Panel_item whichwk_pi, marked_pi;
Xextern Panel_item del_choice_pi;
Xextern Frame del_frame;
Xextern Panel del_panel;
Xextern Pixrect tri_right_pr, tri_up_pr;
Xextern Pixrect *leftarrow, *rightarrow, *morebutton;
Xextern int n_tslots;
Xint attr_bi;
Xstruct appt_entry shelf_appt = {0};
Xint old_slot = -1; /* for text cursor location */
X
Xday_inputevent(canvas, event)
XCanvas canvas;
XEvent *event;
X{
X Menu_item an_item;
X int box_index, x, y, found_flag;
X int i, j, active_above, strl;
X struct appt_entry *aptr;
X static int start_arrow_box = -1, prev_box = 0;
X static int expecting = 0;
X
X found_flag = 0; /* See if cursor is in a box. */
X /* translate coordinates back to pixwin space */
X event = canvas_window_event(canvas, event);
X x = event_x(event);
X y = event_y(event);
X /*fix_event(canvas, event); /* check for LOC_RGNENTER */
X if (event_id(event) == LOC_RGNEXIT && old_slot >= 0) {
X /* erase text cursor */
X text_cursor(old_slot);
X old_slot = -1;
X }
X
X for (box_index=0; box_index<N_SLOTS; box_index++) {
X /* is cursor inside a slot ? */
X if (x>=slots[box_index].slot_pos.left && x<=slots[box_index].slot_pos.right &&
X y>=slots[box_index].slot_pos.top && y<=slots[box_index].slot_pos.bottom) {
X found_flag = FOUND_SLOT;
X break;
X }
X /* is cursor inside a "more" button ? */
X if (x>=slots[box_index].moreb_pos.left && x<=slots[box_index].moreb_pos.right &&
X y>=slots[box_index].moreb_pos.top && y<=slots[box_index].moreb_pos.bottom) {
X if (slots[box_index].count > 1) {
X /* "more" button is active */
X found_flag = FOUND_MORE;
X break;
X }
X }
X /* is cursor inside a "leftarrow" button ? */
X if (x>=slots[box_index].larrow_pos.left && x<=slots[box_index].larrow_pos.right &&
X y>=slots[box_index].larrow_pos.top && y<=slots[box_index].larrow_pos.bottom) {
X found_flag = FOUND_LARROW;
X break;
X }
X /* is cursor inside a "rightarrow" button ? */
X if (x>=slots[box_index].rarrow_pos.left && x<=slots[box_index].rarrow_pos.right &&
X y>=slots[box_index].rarrow_pos.top && y<=slots[box_index].rarrow_pos.bottom) {
X found_flag = FOUND_RARROW;
X break;
X }
X }
X if (old_slot >= 0) {
X /* erase text cursor at old location */
X text_cursor(old_slot);
X old_slot = -1;
X }
X
X if (!found_flag && !expecting)
X return(0); /* Not in a box => ignore. */
X
X if (event_id(event) == LOC_STILL || (event_is_button(event) && event_is_up(event))) {
X if (found_flag == FOUND_SLOT && box_index != old_slot)
X /* in a different slot than we were before */
X if (slots[box_index].active == ACTIVE)
X /* display cursor at new location */
X text_cursor(box_index);
X }
X if (found_flag == FOUND_SLOT && event_id(event) <= ASCII_LAST) {
X /* Process a kbd event. */
X if (slots[box_index].active != ACTIVE)
X return(0);
X if (event_id(event) == CTRL_R) {
X rewrite_string(box_index, JUSTIFY_LEFT);
X return(0);
X }
X new_entry = 1; /* flag for file updating */
X strl = strlen(slots[box_index].cur_appt->str);
X if (event_id(event) == CTRL_U) {
X slots[box_index].cur_appt->str[0] = '\0';
X rewrite_string(box_index, JUSTIFY_LEFT);
X } else if (event_id(event) == CTRL_W) {
X while (strl > 0 && slots[box_index].cur_appt->str[strl-1] != ' ') {
X slots[box_index].cur_appt->str[strl-1] = '\0';
X strl--;
X }
X rewrite_string(box_index, JUSTIFY_RIGHT);
X } else if (event_id(event) == DEL || event_id(event) == BACKSPACE) {
X if (strl > 0) {
X slots[box_index].cur_appt->str[strl-1] = '\0';
X rewrite_string(box_index, JUSTIFY_RIGHT);
X }
X } else if (event_id(event) >= (int)' ' && strl < MAX_STRLEN-2) {
X slots[box_index].cur_appt->str[strl] = (char)event_id(event);
X slots[box_index].cur_appt->str[strl+1] = '\0';
X rewrite_string(box_index, JUSTIFY_RIGHT);
X }
X /* display cursor at new location */
X text_cursor(box_index);
X } else if (event_id(event) == MS_LEFT && event_is_down(event)) {
X /* LB down event */
X switch (found_flag) {
X case FOUND_SLOT:
X break;
X case FOUND_MORE:
X /* reverse video "more" button */
X pw_rop(main_pixwin, slots[box_index].moreb_pos.left, slots[box_index].moreb_pos.top,
X morebutton->pr_width, morebutton->pr_height, PIX_NOT(PIX_DST),
X morebutton, 0, 0);
X expecting = box_index + (FOUND_MORE<<8);
X break;
X case FOUND_LARROW:
X do_left_arrow(canvas, box_index);
X break;
X case FOUND_RARROW:
X do_right_arrow(canvas, box_index);
X break;
X }
X } else if (event_id(event) == MS_LEFT && event_is_up(event)) {
X /* Process an LB up click. */
X i = expecting>>8;
X if (expecting && found_flag != i) {
X /* return button to normal video */
X if (i == FOUND_MORE) {
X /* "more" button */
X i = expecting & 0xff;
X pw_rop(main_pixwin, slots[i].moreb_pos.left, slots[i].moreb_pos.top,
X morebutton->pr_width, morebutton->pr_height, PIX_SRC,
X morebutton, 0, 0);
X }
X } else {
X switch (found_flag) {
X case FOUND_SLOT:
X make_box_active(box_index);
X new_entry = 1;
X break;
X case FOUND_MORE:
X next_appt(box_index, TRUE);
X /* normal video "more" button */
X pw_rop(main_pixwin, slots[box_index].moreb_pos.left, slots[box_index].moreb_pos.top,
X morebutton->pr_width, morebutton->pr_height, PIX_SRC,
X morebutton, 0, 0);
X break;
X case FOUND_LARROW:
X break;
X case FOUND_RARROW:
X break;
X }
X }
X expecting = 0;
X } else if (found_flag == FOUND_SLOT && event_id(event) == MS_MIDDLE) {
X /* Process a MB click. */
X if (box_index >= n_tslots)
X /* don't flow into notes section */
X box_index = n_tslots - 1;
X if (event_is_down(event)) {
X /* try to start dragging from here */
X if (slots[box_index].active != ACTIVE) {
X start_arrow_box = -1;
X return(0);
X }
X if (slots[box_index].cur_appt->arrows > 0) {
X /* remove old arrows and adjust counts */
X (void)deactivate_lower_arrows(box_index);
X j = slots[box_index].cur_appt->arrows;
X while (j > 0)
X slots[box_index+(j--)].count--;
X slots[box_index].cur_appt->arrows = 0;
X }
X prev_box = start_arrow_box = box_index;
X } else {
X /* end of dragging => end of arrow */
X if (box_index < start_arrow_box || start_arrow_box == -1) {
X start_arrow_box = -1;
X return(0);
X }
X if (box_index > start_arrow_box) {
X i = start_arrow_box;
X slots[i].cur_appt->arrows = box_index - start_arrow_box;
X while (++i < box_index) {
X slots[i].count++;
X if (slots[i].active == INACTIVE)
X slots[i].active = ARROW_SHAFT;
X /*
X * erase arrow shaft on boxes - it will be
X * replaced by a real arrowshaft during redraw
X */
X pw_rop(main_pixwin, slots[i].slot_pos.left+1,
X slots[i].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2,
X PIX_SRC^PIX_DST, arrowshaft_pr,
X 0, 0);
X }
X slots[i].count++;
X if (slots[i].active == INACTIVE)
X slots[i].active = ARROW_HEAD;
X /*
X * erase arrow shaft on last box - it will be
X * replaced by an arrowhead during redraw
X */
X pw_rop(main_pixwin, slots[i].slot_pos.left+1,
X slots[i].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2,
X PIX_SRC^PIX_DST, arrowshaft_pr,
X 0, 0);
X }
X start_arrow_box = -1;
X new_entry = 1;
X draw_day_appts();
X }
X } else if (found_flag == FOUND_SLOT && event_id(event) == LOC_DRAG) {
X /* mouse dragging - is it the middle button ? */
X if ((int)window_get(canvas, WIN_EVENT_STATE, MS_MIDDLE) && start_arrow_box >= 0) {
X if (box_index >= n_tslots)
X /* don't flow into notes section */
X box_index = n_tslots - 1;
X /*
X * xor arrow shaft thru current slot so
X * we can see where we're dragging
X */
X if (box_index > prev_box) {
X while (++prev_box <= box_index) {
X pw_rop(main_pixwin, slots[prev_box].slot_pos.left+1,
X slots[prev_box].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2,
X PIX_SRC^PIX_DST, arrowshaft_pr,
X 0, 0);
X }
X prev_box = box_index;
X } else if (box_index < prev_box && box_index >= start_arrow_box) {
X /* going backwards - cleanup as we go */
X while (prev_box > box_index) {
X pw_rop(main_pixwin, slots[prev_box].slot_pos.left+1,
X slots[prev_box].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2,
X PIX_SRC^PIX_DST, arrowshaft_pr,
X 0, 0);
X --prev_box;
X }
X }
X }
X } else if (found_flag == FOUND_SLOT && event_id(event) == MS_RIGHT && event_is_down(event)) {
X /* Process a RB click. */
X /*
X * display popup menu of choices, but first disable
X * certain entries if this is a readonly appointment
X * or an empty slot.
X */
X /* undelete - almost always inactive */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MUNDELETE);
X menu_set(an_item, MENU_INACTIVE, TRUE, 0);
X if (!slots[box_index].first) {
X /* empty slot. only paste active */
X paste_only();
X } else if (slots[box_index].cur_appt->flags & READONLY) {
X /* readonly => paste and copy only */
X paste_only();
X /* copy */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCOPY);
X menu_set(an_item, MENU_INACTIVE, FALSE, 0);
X } else {
X /* delete */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MDELETE);
X menu_set(an_item, MENU_INACTIVE, FALSE, 0);
X /* cut */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCUT);
X menu_set(an_item, MENU_INACTIVE, FALSE, 0);
X /* copy */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCOPY);
X menu_set(an_item, MENU_INACTIVE, FALSE, 0);
X /* modify */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MMODIFY);
X menu_set(an_item, MENU_INACTIVE, FALSE, 0);
X for (aptr=slots[box_index].first; aptr; aptr=aptr->next)
X if (aptr->flags & DELETED) {
X if (slots[box_index].active != ACTIVE)
X /* only paste and undelete */
X paste_only();
X /* undelete */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MUNDELETE);
X menu_set(an_item, MENU_INACTIVE, FALSE, 0);
X break;
X }
X }
X i = (int) menu_show(day_sel_menu, canvas, event, 0);
X if (i > 0)
X switch (i) {
X case MDELETE:
X delete_appt(box_index, canvas);
X break;
X case MCUT:
X cut_appt(box_index, canvas);
X break;
X case MCOPY:
X copy_appt(box_index);
X break;
X case MPASTE:
X paste_appt(box_index);
X break;
X case MMODIFY:
X modify_appt(box_index, canvas);
X break;
X case MUNDELETE:
X undelete_appt(box_index);
X break;
X }
X if (new_entry) {
X close_day();
X draw_day(); /* redraw display */
X }
X } else
X window_default_event_proc(canvas, event, 0);
X
X}
X
X/* make "paste" the only active menu entry */
Xpaste_only()
X{
X Menu_item an_item;
X
X /* delete */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MDELETE);
X menu_set(an_item, MENU_INACTIVE, TRUE, 0);
X /* cut */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCUT);
X menu_set(an_item, MENU_INACTIVE, TRUE, 0);
X /* copy */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MCOPY);
X menu_set(an_item, MENU_INACTIVE, TRUE, 0);
X /* modify */
X an_item = menu_get(day_sel_menu, MENU_NTH_ITEM, MMODIFY);
X menu_set(an_item, MENU_INACTIVE, TRUE, 0);
X}
X
X/* draw (or erase) text cursor in a day slot */
Xtext_cursor(slotno)
Xint slotno;
X{
X int strl, x;
X
X strl = strlen(&slots[slotno].cur_appt->str[slots[slotno].cur_appt->sindex]);
X if (strl > (day_message_size-1)) {
X pw_write(main_pixwin, slots[slotno].slot_pos.right, slots[slotno].slot_pos.bottom-4,
X 8, 8, PIX_SRC^PIX_DST, &tri_right_pr, 0, 0);
X } else {
X x = slots[slotno].slot_pos.left + strl * font->pf_defaultsize.x;
X pw_write(main_pixwin, x, slots[slotno].slot_pos.bottom-4,
X 16, 16, PIX_SRC^PIX_DST, &tri_up_pr, 0, 0);
X }
X old_slot = slotno;
X}
X
X/* make slot active */
Xmake_box_active(bi)
Xint bi;
X{
X add_to_slot(bi, NULL, TRUE);
X fill_appt(bi);
X rewrite_string(bi, JUSTIFY_LEFT);
X text_cursor(bi);
X}
X
X/* activate a hidden appt and make it visible */
Xint
Xactivate_slot(bi, dpyflag)
Xint bi;
Xint dpyflag;
X{
X int n, e_slot;
X
X if (slots[bi].count <= 0)
X /* nothing to activate */
X return(0);
X if (slots[bi].cur_appt == NULL) {
X /* may be hidden arrows */
X /* find appt that they came from so we can see if
X * it should be arrow shaft or arrow head
X */
X n = bi;
X while (--n >= 0 && slots[n].active != ACTIVE)
X ;
X if (n >= 0) {
X e_slot = n + slots[n].cur_appt->arrows;
X if (e_slot < bi)
X /* no arrows here to show */
X return(0);
X while (++n < e_slot && slots[n].active != ACTIVE)
X slots[n].active = ARROW_SHAFT;
X if (slots[n].active != ACTIVE)
X slots[n].active = ARROW_HEAD;
X } else
X /* no active appt above */
X return(0);
X } else {
X /* there's a real appt hidden */
X slots[bi].active = ACTIVE;
X if (slots[bi].cur_appt->arrows > 0) {
X e_slot = bi + slots[bi].cur_appt->arrows;
X while (++bi < e_slot && slots[bi].active != ACTIVE)
X slots[bi].active = ARROW_SHAFT;
X if (slots[bi].active != ACTIVE)
X slots[bi].active = ARROW_HEAD;
X }
X }
X if (dpyflag)
X draw_day_appts(); /* redraw display */
X return(1);
X}
X
X/* clears a day slot */
Xdeactivate_slot(bi, dpyflag)
Xint bi;
X{
X slots[bi].active = INACTIVE;
X if (!dpyflag)
X return;
X /* erase text cursor at old location */
X if (old_slot >= 0) {
X text_cursor(old_slot);
X old_slot = -1;
X }
X /* erase displayed slot */
X if (!ymd_compare(current, today))
X pw_write(main_pixwin, slots[bi].slot_pos.left, slots[bi].slot_pos.top,
X dayslot_width, dayslot_height, PIX_SRC, timeslot_td_pr, 0, 0);
X else
X pw_write(main_pixwin, slots[bi].slot_pos.left+1, slots[bi].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2, PIX_CLR, NULL, 0, 0);
X}
X
X/* returns pointer to slot containing arrow head */
Xint
Xdeactivate_lower_arrows(bi, dpyflag)
Xint bi;
X{
X while (bi < N_SLOTS-1) {
X bi++;
X if (slots[bi].active != ARROW_SHAFT &&
X slots[bi].active != ARROW_HEAD)
X return(bi-1);
X slots[bi].active = INACTIVE;
X if (!dpyflag)
X continue;
X /* erase displayed slot */
X if (!ymd_compare(current, today))
X pw_write(main_pixwin, slots[bi].slot_pos.left, slots[bi].slot_pos.top,
X dayslot_width, dayslot_height, PIX_SRC, timeslot_td_pr, 0, 0);
X else
X pw_write(main_pixwin, slots[bi].slot_pos.left+1, slots[bi].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2, PIX_CLR, NULL, 0, 0);
X }
X}
X
X/* fill in appt struct with current info */
Xfill_appt(bi)
Xint bi;
X{
X int s_hour, s_minute, n_arrows;
X
X slots[bi].cur_appt->year = current.tm_year;
X slots[bi].cur_appt->month = current.tm_mon;
X slots[bi].cur_appt->day = current.tm_mday;
X slots[bi].cur_appt->arrows = 0;
X slots[bi].cur_appt->flags = slots[bi].cur_appt->repeat = 0;
X slots[bi].cur_appt->lookahead = slots[bi].cur_appt->sindex = 0;
X if (bi >= n_tslots) {
X /* notes section */
X slots[bi].cur_appt->hour = 99;
X slots[bi].cur_appt->minute = 0;
X slots[bi].cur_appt->flags = A_NOTE;
X } else {
X /* regular appt */
X slots[bi].cur_appt->hour = bi/2 + START_HOUR;
X slots[bi].cur_appt->minute = (bi % 2) * 30;
X }
X slots[bi].cur_appt->str[0] = '\0';
X}
X
X/*
X * Display delete popup window to let user choose delete mode for
X * recurring appts (delete this one only or delete all), otherwise,
X * just wipe it out with no options.
X */
Xdelete_appt(bi, canvas)
Xint bi;
XCanvas canvas;
X{
X Rect *canvas_r;
X int top, left, width, height;
X
X if (slots[bi].cur_appt->flags & READONLY) {
X err_rpt("Can't delete a read-only appt", NON_FATAL);
X return;
X }
X if (slots[bi].cur_appt->flags & (REPEAT|ALL_YEARS|ALL_MONTHS|ALL_DAYS)) {
X attr_bi = bi; /* set global index for notify func */
X
X /* get x,y position of canvas window on the screen so we
X * can center popup window in it.
X */
X canvas_r = (Rect *) window_get(canvas, WIN_RECT);
X panel_set(del_choice_pi, PANEL_CHOICE_STRINGS,
X "Delete this occurrance only",
X "Delete all occurrances", 0,
X PANEL_CLIENT_DATA, 0,
X 0);
X window_fit(del_panel);
X window_fit(del_frame);
X width = (int) window_get(del_frame, WIN_WIDTH);
X height = (int) window_get(del_frame, WIN_HEIGHT);
X left = canvas_r->r_left + (canvas_r->r_width - width) / 2;
X top = canvas_r->r_top + (canvas_r->r_height - height) / 2;
X window_set(del_frame, WIN_X, left, WIN_Y, top, 0);
X panel_set_value(del_choice_pi, 0);
X
X window_loop(del_frame); /* let user select things */
X } else {
X cut_delete(bi);
X new_entry = 1;
X }
X}
X
Xcut_appt(bi, canvas)
Xint bi;
XCanvas canvas;
X{
X Rect *canvas_r;
X int top, left, width, height;
X int i;
X
X /* cut (delete) current entry, saving the info on the "shelf" */
X if (slots[bi].cur_appt->flags & READONLY) {
X err_rpt("Can't cut a read-only appt", NON_FATAL);
X return;
X }
X shelf_appt = *slots[bi].cur_appt;
X if (slots[bi].cur_appt->flags & (REPEAT|ALL_YEARS|ALL_MONTHS|ALL_DAYS)) {
X attr_bi = bi; /* set global index for notify func */
X
X /* get x,y position of canvas window on the screen so we
X * can center popup window in it.
X */
X canvas_r = (Rect *) window_get(canvas, WIN_RECT);
X panel_set(del_choice_pi, PANEL_CHOICE_STRINGS,
X "Move this occurrance only",
X "Move all occurrances", 0,
X PANEL_CLIENT_DATA, 1,
X 0);
X window_fit(del_panel);
X window_fit(del_frame);
X width = (int) window_get(del_frame, WIN_WIDTH);
X height = (int) window_get(del_frame, WIN_HEIGHT);
X left = canvas_r->r_left + (canvas_r->r_width - width) / 2;
X top = canvas_r->r_top + (canvas_r->r_height - height) / 2;
X window_set(del_frame, WIN_X, left, WIN_Y, top, 0);
X panel_set_value(del_choice_pi, 0);
X
X window_loop(del_frame); /* let user select things */
X } else {
X cut_delete(bi);
X new_entry = 1;
X }
X}
X
Xcut_delete(bi)
Xint bi;
X{
X int j;
X struct appt_entry *aptr, *cptr, *optr;
X
X cptr = slots[bi].cur_appt;
X slots[bi].count--;
X deactivate_slot(bi, TRUE);
X if ( (j = cptr->arrows) > 0) {
X /* remove old arrows and adjust counts */
X (void) deactivate_lower_arrows(bi, TRUE);
X while (j > 0)
X slots[bi+(j--)].count--;
X }
X if (slots[bi].cur_appt == slots[bi].first) {
X /* displaying first entry in list */
X /* see if there's any more */
X if (slots[bi].first->next)
X slots[bi].first = slots[bi].first->next;
X else {
X /* last one */
X slots[bi].first = NULL;
X slots[bi].active = INACTIVE;
X }
X slots[bi].cur_appt = slots[bi].first;
X } else {
X /* not first, so find previous one to this */
X for (aptr=slots[bi].first; slots[bi].cur_appt!=aptr; optr=aptr,aptr=aptr->next)
X ;
X slots[bi].cur_appt = optr->next = aptr->next;
X if (!optr->next)
X slots[bi].cur_appt = slots[bi].first;
X }
X free(cptr);
X (void)activate_slot(bi, TRUE); /* show any hidden appts */
X}
X
Xcopy_appt(bi)
Xint bi;
X{
X /* copy current entry, saving the info on the "shelf" */
X shelf_appt = *slots[bi].cur_appt;
X}
X
Xpaste_appt(bi)
Xint bi;
X{
X int j;
X
X /* insert the saved entry (if any) */
X if (shelf_appt.str[0] == '\0') {
X err_rpt("nothing to paste", NON_FATAL);
X return;
X }
X shelf_appt.year = current.tm_year;
X shelf_appt.month = current.tm_mon;
X shelf_appt.day = current.tm_mday;
X if (bi >= N_TSLOTS) {
X /* notes section */
X shelf_appt.hour = 99;
X shelf_appt.minute = 0;
X /* just in case converting from time to note */
X shelf_appt.flags |= A_NOTE;
X } else {
X /* regular appt */
X shelf_appt.hour = bi/2 + START_HOUR;
X shelf_appt.minute = (bi % 2) * 30;
X /* just in case converting from note to time */
X shelf_appt.flags &= ~MARKED_NOTE;
X }
X add_to_slot(bi, &shelf_appt, TRUE);
X new_entry = 1;
X}
X
X/*
X * Display attributes popup window to let user modify
X * various appointment options (such as repeat interval,
X * etc.)
X */
Xmodify_appt(bi, canvas)
Xint bi;
XCanvas canvas;
X{
X Rect *canvas_r;
X int top, left, width, height;
X
X if (slots[bi].cur_appt->flags & READONLY) {
X err_rpt("Can't modify a read-only appt", NON_FATAL);
X return;
X }
X attr_bi = bi; /* set global index for notify func */
X set_attr(); /* set panel item current values */
X
X /* get x,y position of canvas window on the screen so we
X * can center this one in it.
X */
X canvas_r = (Rect *) window_get(canvas, WIN_RECT);
X width = (int) window_get(attr_frame, WIN_WIDTH);
X height = (int) window_get(attr_frame, WIN_HEIGHT);
X left = canvas_r->r_left + (canvas_r->r_width - width) / 2;
X top = canvas_r->r_top + (canvas_r->r_height - height) / 2;
X window_set(attr_frame, WIN_X, left, WIN_Y, top, 0);
X
X window_loop(attr_frame); /* let user select things */
X window_set(attr_frame, WIN_SHOW, FALSE, 0);
X}
X
X/* undelete a recurring appointment for this day */
X/* we only get here if a deleted appt exits */
Xundelete_appt(bi)
Xint bi;
X{
X struct appt_entry *aptr, *optr;
X
X /* search list to find deleted entry */
X for (optr=aptr=slots[bi].first; aptr; optr=aptr,aptr=aptr->next)
X if (aptr->flags & DELETED)
X break;
X if (aptr == slots[bi].first)
X slots[bi].first = aptr->next;
X else
X optr->next = aptr->next;
X slots[bi].count++;
X if (slots[bi].active == INACTIVE) {
X slots[bi].cur_appt = slots[bi].first;
X (void)activate_slot(bi, TRUE);
X }
X free(aptr);
X new_entry = 1;
X}
X
Xset_attr()
X{
X int everyx_val = 0, whichwk_val = 0;
X char str[5];
X struct appt_entry *apt = slots[attr_bi].cur_appt;
X
X panel_set_value(repeat_pi, ""); /* set default */
X panel_set_value(remind_pi, ""); /* set default */
X if (apt->flags & ALL_DAYS)
X everyx_val |= 0x1;
X if (apt->flags & ALL_MONTHS)
X everyx_val |= 0x4;
X if (apt->flags & ALL_YEARS)
X everyx_val |= 0x8;
X if (apt->flags & EVERY_SOMEDAY) {
X everyx_val |= 0x2;
X whichwk_val = apt->repeat;
X panel_set(repeat_pi, PANEL_SHOW_ITEM, FALSE, 0);
X panel_set(whichwk_pi, PANEL_SHOW_ITEM, TRUE, 0);
X } else {
X if (apt->repeat) {
X sprintf(str, "%d", apt->repeat);
X panel_set_value(repeat_pi, str);
X }
X panel_set(whichwk_pi, PANEL_SHOW_ITEM, FALSE, 0);
X panel_set(repeat_pi, PANEL_SHOW_ITEM, TRUE, 0);
X }
X panel_set_value(everyx_pi, everyx_val);
X panel_set_value(whichwk_pi, whichwk_val);
X if (apt->flags & LOOKAHEAD) {
X sprintf(str, "%d", apt->lookahead);
X panel_set_value(remind_pi, str);
X }
X panel_set_value(marked_pi, (apt->flags & MARKED ? 1 : 0));
X if (apt->flags & A_NOTE)
X panel_set(marked_pi, PANEL_SHOW_ITEM, TRUE, 0);
X else
X panel_set(marked_pi, PANEL_SHOW_ITEM, FALSE, 0);
X}
X
X/* "more" button selected. Display next appt in rotation. */
Xnext_appt(bi, dpyflag)
Xint bi;
Xint dpyflag;
X{
X if (slots[bi].active == ACTIVE) {
X deactivate_slot(bi, dpyflag);
X if (slots[bi].cur_appt->arrows > 0)
X (void)deactivate_lower_arrows(bi, dpyflag);
X } else
X /* must have arrows displayed */
X (void)deactivate_lower_arrows(bi, dpyflag);
X
X if (slots[bi].cur_appt == NULL)
X /* end of the chain */
X slots[bi].cur_appt = slots[bi].first;
X else
X /* activate next in chain */
X slots[bi].cur_appt = slots[bi].cur_appt->next;
X /* make sure it is not a deleted one */
X if (chk_deleted(bi))
X next_appt(bi, dpyflag); /* try next in chain */
X else if (!activate_slot(bi, dpyflag))
X next_appt(bi, dpyflag); /* try next in chain */
X}
X
X/* check to see if current is deleted */
Xint
Xchk_deleted(bi)
Xint bi;
X{
X int found = 0;
X struct appt_entry *aptr;
X
X if (slots[bi].cur_appt == NULL)
X return(0);
X if (slots[bi].cur_appt->flags & DELETED)
X return(1);
X /* run through the list to see if there are any deleted */
X for (aptr=slots[bi].first; aptr; aptr=aptr->next)
X if (aptr->flags & DELETED) {
X found = 1;
X break;
X }
X /* now see if the current one matches */
X if (found && !strcmp(aptr->str, slots[bi].cur_appt->str))
X return(1);
X
X return(0);
X}
X
X/* left scroll arrow selected */
Xdo_left_arrow(canvas, bi)
XCanvas canvas;
Xint bi;
X{
X struct timeval timeout;
X Event event;
X int fd, ertn, flags;
X
X if (slots[bi].active != ACTIVE || strlen(slots[bi].cur_appt->str) < day_message_size)
X return;
X timeout.tv_sec = 0L;
X timeout.tv_usec = 100000L; /* 1/10 sec */
X fd = (int)window_get(canvas, WIN_FD);
X flags = fcntl(fd, F_GETFL, 0);
X (void)fcntl(fd, F_SETFL, flags|FNDELAY);
X /* reverse video the arrow */
X pw_rop(main_pixwin, slots[bi].larrow_pos.left, slots[bi].larrow_pos.top,
X 19, 14, PIX_NOT(PIX_DST), leftarrow, 0, 0);
X while (TRUE) {
X if (slots[bi].cur_appt->sindex < strlen(slots[bi].cur_appt->str)) {
X ++slots[bi].cur_appt->sindex;
X rewrite_string(bi, JUSTIFY_INDEX);
X /* reverse video the arrow (rewrite changed it) */
X pw_rop(main_pixwin, slots[bi].larrow_pos.left, slots[bi].larrow_pos.top,
X 19, 14, PIX_NOT(PIX_DST), leftarrow, 0, 0);
X }
X /* do this garbage to handle a repeat function */
X (void)select(0, NULL, NULL, NULL, &timeout);
X ertn = window_read_event(canvas, &event);
X if (ertn != -1 && event_is_up(&event))
X break;
X }
X /* put arrow back to normal */
X pw_rop(main_pixwin, slots[bi].larrow_pos.left, slots[bi].larrow_pos.top,
X 19, 14, PIX_SRC, leftarrow, 0, 0);
X (void)fcntl(fd, F_SETFL, flags & ~FNDELAY);
X}
X
X/* right scroll arrow selected */
Xdo_right_arrow(canvas, bi)
XCanvas canvas;
Xint bi;
X{
X struct timeval timeout;
X Event event;
X int fd, ertn, flags;
X
X if (slots[bi].active != ACTIVE || strlen(slots[bi].cur_appt->str) < day_message_size)
X return;
X timeout.tv_sec = 0L;
X timeout.tv_usec = 100000L; /* 1/10 sec */
X fd = (int)window_get(canvas, WIN_FD);
X flags = fcntl(fd, F_GETFL, 0);
X (void)fcntl(fd, F_SETFL, flags|FNDELAY);
X /* reverse video the arrow */
X pw_rop(main_pixwin, slots[bi].rarrow_pos.left, slots[bi].rarrow_pos.top,
X 19, 14, PIX_NOT(PIX_DST), rightarrow, 0, 0);
X while (TRUE) {
X if (slots[bi].cur_appt->sindex > 0) {
X --slots[bi].cur_appt->sindex;
X rewrite_string(bi, JUSTIFY_INDEX);
X /* reverse video the arrow (rewrite changed it) */
X pw_rop(main_pixwin, slots[bi].rarrow_pos.left, slots[bi].rarrow_pos.top,
X 19, 14, PIX_NOT(PIX_DST), rightarrow, 0, 0);
X }
X /* do this garbage to handle a repeat function */
X (void)select(0, NULL, NULL, NULL, &timeout);
X ertn = window_read_event(canvas, &event);
X if (ertn != -1 && event_is_up(&event))
X break;
X }
X pw_rop(main_pixwin, slots[bi].rarrow_pos.left, slots[bi].rarrow_pos.top,
X 19, 14, PIX_SRC, rightarrow, 0, 0);
X (void)fcntl(fd, F_SETFL, flags & ~FNDELAY);
X}
SHAR_EOF
if test 27402 -ne "`wc -c < 'devent.c'`"
then
echo shar: error transmitting "'devent.c'" '(should have been 27402 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'dpaint.c'" '(24098 characters)'
if test -f 'dpaint.c'
then
echo shar: will not over-write existing file "'dpaint.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'dpaint.c'
X/*
X * $Header: dpaint.c,v 2.2 89/05/10 10:06:20 billr Exp $
X */
X/*
X * dpaint.c
X *
X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller at sun.com>
X *
X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
X * All Rights Reserved
X * Permission is hereby granted to use and modify this program in source
X * or binary form as long as it is not sold for profit and this copyright
X * notice remains intact.
X *
X *
X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr at saab.CNA.TEK.COM>
X *
X * Changes and additions Copyright (C) 1988, 1989 Tektronix, Inc.
X * All Rights Reserved
X * Permission is hereby granted to use and modify the modifications in source
X * or binary form as long as they are not sold for profit and this copyright
X * notice remains intact.
X */
X/***************************************************
X * *
X * Artistic routines that draw in the main *
X * subwindow for the day display. *
X * *
X ***************************************************/
X
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <ctype.h>
X#include <sys/time.h>
X#include <stdio.h>
X#include "ct.h"
X#include "paint.h"
X#include "riseset.h"
X#define J1970 2440587.5 /* VAX clock Epoch 1970 Jan 1 (0h UT) */
X
X#ifndef NO_SUN_MOON
Xextern Frame mframe, sframe;
Xextern Canvas mcanvas, scanvas;
Xextern Panel_item mdate_pi, sdate_pi;
X#endif
Xextern Pixrect *leftarrow, *rightarrow;
Xextern Pixrect *arrowshaft_pr, *arrowhead_pr;
Xextern int day_message_size;
Xextern char riseset_buf[][64];
Xextern int old_slot;
Xextern int show_future;
Xextern char *index();
X
Xstruct tm save_day;
Xstruct appt_entry future[MAX_FUTURE_ENTRIES];
Xint findex = 0; /* index into struct future array */
X
X/*
X * This one draws the current selected day in the
X * main subwindow.
X */
X
Xdraw_day()
X{
X draw_day1();
X draw_future_appts();
X#ifndef NO_SUN_MOON
X if (sframe)
X write_sun_data();
X if (mframe)
X write_moon_data();
X#endif
X}
X
X/*
X * Draw main day page without future appts or Sun/Moon data
X */
Xdraw_day1()
X{
X lock_cursors();
X fix_current_day();
X working(TRUE);
X pw_batch_on(main_pixwin);
X draw_day_outline();
X pw_batch_off(main_pixwin);
X get_day_appts();
X working(FALSE);
X pw_batch_on(main_pixwin);
X draw_day_appts();
X pw_batch_off(main_pixwin);
X day_is_open = TRUE;
X unlock_cursors();
X}
X
X/*
X * Utility for draw_day ... draws the outline of a day.
X */
Xdraw_day_outline()
X{
X char timestring[6], daystring[31], buf[64], *src;
X int x, y, starty, i, d;
X Rect *rect;
X
X /* First erase the window. */
X rect = (Rect *) window_get(canvas, WIN_RECT);
X pw_writebackground(main_pixwin, 0, 0,
X rect->r_width, rect->r_height, PIX_CLR);
X old_slot = -1; /* text cursor no longer displayed */
X
X /* Calculate coords of top-left corner of big box. */
X x = (rect->r_width - dayslot_width) / 2;
X starty = y = (rect->r_height - (N_SLOTS * dayslot_height)) / 2;
X
X /* Format daystring to say, for example, */
X /* Tuesday, March 12, 1985 */
X sprintf(daystring, "%s %s %d, %d",
X daynames[current.tm_wday], monthnames[current.tm_mon],
X current.tm_mday, 1900 + current.tm_year);
X pw_text(main_pixwin, (rect->r_width - bigfont->pf_defaultsize.x*strlen(daystring))/2, starty/2 + 7,
X PIX_SRC, bigfont, daystring);
X
X for (i=0; i<N_SLOTS; i++) { /* Init and draw each 30 minute slot. */
X slots[i].slot_pos.top = y;
X slots[i].slot_pos.left = x;
X slots[i].slot_pos.bottom = y + dayslot_height + 1;
X slots[i].slot_pos.right = x + dayslot_width + 1;
X slots[i].moreb_pos.top = y;
X slots[i].moreb_pos.left = rect->r_width - 8 - morebutton->pr_size.x;
X slots[i].moreb_pos.bottom = y + morebutton->pr_size.y;
X slots[i].moreb_pos.right = rect->r_width - 8;
X slots[i].larrow_pos.top = slots[i].slot_pos.top+(dayslot_height-leftarrow->pr_size.y)/2;
X slots[i].larrow_pos.left = slots[i].slot_pos.right + 8;
X slots[i].larrow_pos.bottom = slots[i].larrow_pos.top + leftarrow->pr_size.y;
X slots[i].larrow_pos.right = slots[i].larrow_pos.left + leftarrow->pr_size.x;
X slots[i].rarrow_pos.top = slots[i].larrow_pos.top;
X slots[i].rarrow_pos.left = slots[i].larrow_pos.right + 8;
X slots[i].rarrow_pos.bottom = slots[i].larrow_pos.bottom;
X slots[i].rarrow_pos.right = slots[i].rarrow_pos.left + rightarrow->pr_size.x;
X if (!ymd_compare(current, today))
X pw_write(main_pixwin,x,y,dayslot_width,dayslot_height,PIX_SRC,timeslot_td_pr,0,0);
X else
X pw_write(main_pixwin,x,y,dayslot_width,dayslot_height,PIX_SRC,timeslot_pr,0,0);
X if (i < n_tslots) {
X /* display time */
X sprintf(timestring, "%2d:%s",
X (START_HOUR+(i/2))%12 == 0 ? 12 : (START_HOUR+(i/2))%12,
X i%2 == 0 ? "00" : "30");
X } else if (i == n_tslots) {
X sprintf(timestring, "Notes");
X } else {
X sprintf(timestring, " ");
X }
X pw_text(main_pixwin,x-8*font->pf_defaultsize.x,y+font->pf_defaultsize.y,PIX_SRC,font,timestring);
X y += dayslot_height - 1;
X }
X
X pw_vector(main_pixwin,x,starty,x+dayslot_width-1,starty,PIX_SET,1);
X pw_vector(main_pixwin,x,y,x+dayslot_width-1,y,PIX_SET,1);
X y += (dayslot_height - 1) * 2;
X sprintf(buf, "Day of year: %d -- %d days remaining",
X day_of_year((double)current.tm_mday, current.tm_mon+1, current.tm_year),
X days_remaining_in_year((double)current.tm_mday, current.tm_mon+1, current.tm_year));
X pw_text(main_pixwin, x, y, PIX_SRC, font, buf);
X sun_moon_buttons(TRUE);
X print_button(TRUE);
X}
X
X
X/*
X * Fills in appointments for the day.
X * The ".tmp.aptsXXXXX" file is filled out
X * with all the lines from the ".appointments" file
X * which do not pertain to the current day.
X */
Xget_day_appts()
X{
X FILE *apts, *temp_apts;
X int slotno, n_arrows, i;
X int read_stat;
X struct appt_entry appt;
X struct appt_entry *nappt, *aptr;
X char buf[MAX_STRLEN], *sptr;
X
X if ((apts = fopen(apts_pathname, "r")) == NULL)
X err_rpt("can't open appointments file", FATAL);
X
X if (!read_only)
X if ((temp_apts = fopen(tmpapts_pathname, "w")) == NULL)
X err_rpt("can't open temp file for writing", FATAL);
X
X for (i=0; i<N_SLOTS; i++) { /* init each slot */
X slots[i].active = INACTIVE;
X slots[i].count = 0;
X slots[i].cur_appt = NULL;
X slots[i].first = NULL;
X }
X First = current;
X findex = 0;
X
X#ifndef NO_HOLIDAYS
X /*
X * First check to see if the user has selected any holiday
X * options and add them in.
X */
X if (a_dates(&appt, holiday_a))
X add_note(&appt);
X if (c_dates(&appt, holiday_c))
X add_note(&appt);
X working(FALSE);
X if (i = i_dates(&appt, holiday_i))
X if (i == 2) {
X /* two notes in one */
X strcpy(buf, appt.str);
X /* look for \n */
X sptr = index(appt.str, '\n');
X *sptr = '\0';
X add_note(&appt);
X /* now second half of string in the next note */
X strcpy(appt.str, &buf[(int)(sptr-appt.str)+1]);
X add_note(&appt);
X } else
X add_note(&appt);
X working(TRUE);
X if (j_dates(&appt, holiday_j))
X add_note(&appt);
X if (s_dates(&appt, holiday_s))
X add_note(&appt);
X#endif
X
X /*
X * now go thru the appointments file
X */
X while ((read_stat=get_aentry(apts, &appt)) != EOF) {
X if (read_stat)
X continue; /* read error (ignore) */
X if (appt.flags & A_COMMENT) {
X if (put_aentry(temp_apts, &appt)) {
X /* write error */
X break;
X }
X continue;
X }
X current.tm_year = appt.year;
X current.tm_mon = appt.month;
X current.tm_mday = appt.day;
X if (appt.flags & ALL_YEARS)
X current.tm_year = First.tm_year;
X if (appt.flags & ALL_MONTHS)
X current.tm_mon = First.tm_mon;
X if (appt.flags & ALL_DAYS)
X current.tm_mday = First.tm_mday;
X else if (appt.flags & EVERY_SOMEDAY) {
X if (Pickday(appt.flags) == First.tm_wday) {
X if (chk_week(appt.repeat, First.tm_mday))
X current.tm_mday = First.tm_mday;
X }
X } else if (appt.flags & REPEAT) {
X while (ymd_compare(current, First) < 0) {
X current.tm_mday += appt.repeat;
X fix_current_day();
X }
X }
X if (ymd_compare(current, First) == 0) {
X /* if it's for this day, fill in slot info */
X if (appt.flags & A_NOTE)
X /* notes section */
X add_note(&appt);
X else {
X /* regular appointment */
X slotno = (appt.hour-START_HOUR) * 2 + appt.minute / 30;
X if (slotno < 0)
X slotno = 0;
X if (slotno >= n_tslots)
X slotno = n_tslots - 1;
X /* add this appt to the list of appts for the slot */
X /* and update all the reference counts */
X add_to_slot(slotno, &appt, FALSE);
X }
X } else if (appt.flags & LOOKAHEAD) {
X /* This lookahead appt was not for today, so
X * put it in the temp file.
X */
X if (put_aentry(temp_apts, &appt)) {
X /* write error */
X break;
X }
X if (appt.flags & EVERY_SOMEDAY) {
X /* find next occurance of this appt */
X /* starting from the current day */
X current.tm_mday = First.tm_mday;
X fix_current_day();
X find_date(&appt); /* may modify current */
X }
X if (ymd_compare(current, First) > 0) {
X /* this appt is happening in
X * the future, so remind us of it if
X * it is within the lookahead window.
X */
X save_day = current;
X current.tm_mday -= appt.lookahead;
X fix_current_day();
X if (ymd_compare(current, First) <=0) {
X /* save this one for the future popup window */
X if (findex > MAX_FUTURE_ENTRIES-1) {
X err_rpt("Too many future reminders", NON_FATAL);
X continue;
X }
X future[findex] = appt;
X /* fix up ymd */
X future[findex].year = save_day.tm_year;
X future[findex].month = save_day.tm_mon;
X future[findex].day = save_day.tm_mday;
X ++findex;
X }
X }
X } else { /* line is not for today */
X /* copy it to temp file */
X if (put_aentry(temp_apts, &appt)) {
X /* write error */
X break;
X }
X }
X }
X if (!read_only) {
X if (ferror(temp_apts))
X err_rpt("write on temp file failed", FATAL);
X fclose(temp_apts);
X }
X fclose(apts);
X current = First;
X fix_current_day();
X}
X
X
X/* check for match on weekly re-ocurring appts */
Xchk_week(repeat, curday)
Xint repeat, curday;
X{
X int weeknr = 0;
X
X if ((repeat & ALL_WEEKS) == ALL_WEEKS)
X return(1); /* every week */
X if ((repeat & LAST_WEEK) && ((curday+7) > monthlength(current.tm_mon)))
X return(1); /* last week in month */
X
X while (curday > 7) {
X /* find which week this day is in */
X curday -= 7;
X weeknr++;
X }
X if (repeat & (0x1<<weeknr))
X return(1);
X
X return(0); /* no match */
X}
X
X
X/*
X * get date of next occurrance of a weekly repeated appt
X * (it may bridge into next week, month or year)
X */
Xfind_date(appt)
Xstruct appt_entry *appt;
X{
X struct tm save;
X
X save = current;
X /* set current to match dow of repeated appt */
X current.tm_mday += Pickday(appt->flags) - current.tm_wday;
X fix_current_day();
X if (ymd_compare(current, save) < 0) {
X /* already happened, so start looking next week */
X current.tm_mday += 7;
X fix_current_day();
X }
X /* search for first matching week */
X while (!chk_week(appt->repeat, current.tm_mday)) {
X current.tm_mday += 7;
X fix_current_day();
X }
X /* now check to make sure this is legal, i.e. there
X * were no month or year restrictions
X */
X if ((!(appt->flags & ALL_YEARS) && current.tm_year != save.tm_year)
X || (!(appt->flags & ALL_MONTHS) && current.tm_mon != save.tm_mon))
X /* invalid date, due to month or year wrap */
X current = save;
X}
X
X
X/* add a note to the current day */
Xadd_note(appt)
Xstruct appt_entry *appt;
X{
X int slotno;
X
X /* auto-hunt for free note slot */
X for (slotno=n_tslots; slotno<N_SLOTS; slotno++)
X if (slots[slotno].active == INACTIVE)
X break;
X if (slotno == N_SLOTS) {
X /* overflow of notes field, so
X * add to last note field list
X */
X slotno = N_SLOTS - 1;
X }
X add_to_slot(slotno, appt, FALSE);
X}
X
X/* draw in todays appointments */
Xdraw_day_appts()
X{
X int slotno = 0;
X
X while (slotno < N_SLOTS) {
X if (slots[slotno].count > 0) {
X switch (slots[slotno].active) {
X case ACTIVE:
X rewrite_string(slotno, JUSTIFY_LEFT);
X break;
X case ARROW_SHAFT:
X draw_arrowshaft(slotno);
X break;
X case ARROW_HEAD:
X draw_arrowhead(slotno);
X break;
X case INACTIVE:
X break;
X }
X more_check(slotno);
X }
X ++slotno;
X }
X}
X
X/* Blacks out day-slot and then re-writes string. */
Xrewrite_string(bi, justify)
Xint bi, justify;
X{
X char slot_str[MAX_STRLEN];
X char *ptr;
X int strl, *iptr;
X
X strl = strlen(slots[bi].cur_appt->str);
X iptr = &slots[bi].cur_appt->sindex;
X if (strl < day_message_size) {
X *iptr = 0; /* just in case */
X strcpy(slot_str, slots[bi].cur_appt->str);
X /* erase any previously existing scroll arrows */
X pw_writebackground(main_pixwin, slots[bi].larrow_pos.left,
X slots[bi].larrow_pos.top, slots[bi].rarrow_pos.right-slots[bi].larrow_pos.left,
X slots[bi].larrow_pos.bottom-slots[bi].larrow_pos.top,
X PIX_CLR);
X } else {
X if (justify == JUSTIFY_RIGHT) {
X /* show trailing part */
X ptr = &slots[bi].cur_appt->str[strl - day_message_size + 1];
X *iptr = strl - day_message_size + 1;
X strcpy(slot_str, ptr);
X } else {
X /* show leading or indexed part */
X if (justify == JUSTIFY_LEFT)
X *iptr = 0;
X if (*iptr > (strl - day_message_size + 1))
X *iptr = strl - day_message_size + 1;
X if (strlen(&slots[bi].cur_appt->str[*iptr]) >= day_message_size-1) {
X strncpy(slot_str, &slots[bi].cur_appt->str[*iptr], day_message_size-1);
X slot_str[day_message_size-1] = '\0';
X } else
X strcpy(slot_str, &slots[bi].cur_appt->str[*iptr]);
X }
X /* display scroll arrows */
X pw_write(main_pixwin, slots[bi].larrow_pos.left,
X slots[bi].larrow_pos.top, leftarrow->pr_size.x,
X leftarrow->pr_size.y, PIX_SRC, leftarrow, 0, 0);
X pw_write(main_pixwin, slots[bi].rarrow_pos.left,
X slots[bi].rarrow_pos.top, rightarrow->pr_size.x,
X rightarrow->pr_size.y, PIX_SRC, rightarrow, 0, 0);
X }
X pw_write(main_pixwin, slots[bi].slot_pos.left+1, slots[bi].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2, PIX_SET, NULL, 0, 0);
X pw_text(main_pixwin, slots[bi].slot_pos.left+5, slots[bi].slot_pos.top+font->pf_defaultsize.y,
X PIX_NOT(PIX_SRC), font, slot_str);
X}
X
X/* display "more" button if necessary */
Xmore_check(slotno)
Xint slotno;
X{
X int x, y, w;
X
X x = morebutton->pr_size.x;
X y = morebutton->pr_size.y;
X
X /* clear any previous button that may be there */
X pw_write(main_pixwin, slots[slotno].moreb_pos.left, slots[slotno].moreb_pos.top,
X x, y, PIX_CLR, NULL, 0, 0);
X /* button displayed when more than 1 reference
X * and at least one real appt for this slot.
X */
X if (slots[slotno].count > 1 && slots[slotno].first)
X /* display more button to right of slot */
X pw_write(main_pixwin, slots[slotno].moreb_pos.left, slots[slotno].moreb_pos.top,
X x, y, PIX_SRC, morebutton, 0, 0);
X}
X
Xdraw_arrowshaft(i)
Xint i;
X{
X pw_rop(main_pixwin, slots[i].slot_pos.left+1, slots[i].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2, PIX_SRC|PIX_DST, arrowshaft_pr, 0, 0);
X slots[i].active = ARROW_SHAFT;
X}
X
X
X
Xdraw_arrowhead(i)
Xint i;
X{
X pw_rop(main_pixwin, slots[i].slot_pos.left+1, slots[i].slot_pos.top+1,
X dayslot_width-2, dayslot_height-2, PIX_SRC|PIX_DST, arrowhead_pr, 0, 0);
X slots[i].active = ARROW_HEAD;
X}
X
X/*
X * Routine to create popup window with future appts shown in it
X */
Xdraw_future_appts()
X{
X if (show_future && findex && (ymd_compare(current, today) == 0)) {
X create_future_popup();
X } else {
X /* nothing to show */
X /* destroy future appts popup, if it exists */
X if (fframe) {
X window_destroy(fframe);
X fframe = 0;
X }
X }
X}
X
X/*
X * Add an appointment entry pointed to by aptr to the day slot
X * specified by slotno. This routine is also used by paste()
X * when copying an entry off the save shelf. If dpyflag is true,
X * then any deactivated slots are cleared on the display (used by
X * paste). Also used to add a deleted entry for a specific day.
X */
Xadd_to_slot(slotno, aptr, dpyflag)
Xint slotno;
Xstruct appt_entry *aptr;
Xint dpyflag;
X{
X struct appt_entry *nappt, *optr;
X int n_arrows, n, nbi, found = 0, i;
X int deactivate_lower_arrows();
X
X if ((nappt = (struct appt_entry *)malloc(sizeof(struct appt_entry))) == NULL)
X err_rpt("out of memory", FATAL);
X if (aptr == NULL) {
X /* fill in some needed fields */
X nappt->arrows = nappt->flags = 0;
X nappt->sindex = 0;
X nappt->str[0] = '\0';
X } else
X *nappt = *aptr;
X nappt->next = NULL;
X /* add appt to list of appts for this slot */
X if (slots[slotno].first == NULL) {
X slots[slotno].first = nappt;
X slots[slotno].cur_appt = nappt;
X } else {
X /* search for end of list */
X for (optr=slots[slotno].first;optr->next;optr=optr->next)
X ;
X optr->next = nappt;
X }
X /* make sure it doesn't extend too far and truncate if neccessary */
X if (slotno >= n_tslots)
X nappt->arrows = 0; /* force notes to have no arrows */
X else if ((slotno + nappt->arrows) >= n_tslots)
X nappt->arrows = n_tslots - slotno - 1; /* truncate */
X n_arrows = nappt->arrows;
X if (nappt->flags & DELETED) {
X /* look for matching non-deleted appt in list */
X for (optr=slots[slotno].first;optr;optr=optr->next)
X if (!strcmp(nappt->str, optr->str) && !(optr->flags & DELETED)) {
X found = 1;
X break;
X }
X if (found && slots[slotno].cur_appt == optr) {
X /* the deleted appt is the current one */
X /* if it's active, undisplay it and display
X * next one in list (if any)
X */
X if (slots[slotno].active == ACTIVE) {
X if (slots[slotno].count > 1)
X /* there's another one here */
X next_appt(slotno, dpyflag);
X else {
X deactivate_slot(slotno, dpyflag);
X if (slots[slotno].cur_appt->arrows > 0)
X (void)deactivate_lower_arrows(slotno, dpyflag);
X }
X /* adjust reference counts */
X slots[slotno].count--;
X i = 1;
X while (i <= n_arrows) {
X if (--(slots[slotno+i].count) > 0)
X /* try to activate any hidden ones */
X (void)activate_slot(slotno+i, dpyflag);
X ++i;
X }
X } else {
X /* currently inactive */
X /* set current to next one in the list */
X if (optr->next)
X slots[slotno].cur_appt = optr->next;
X else
X slots[slotno].cur_appt = slots[slotno].first;
X while (n_arrows >= 0)
X slots[slotno+(n_arrows--)].count--;
X }
X } else {
X /* just adjust the counts */
X while (n_arrows >= 0)
X slots[slotno+(n_arrows--)].count--;
X }
X } else {
X /* look for matching deleted appt in list */
X for (optr=slots[slotno].first;optr;optr=optr->next)
X if (!strcmp(nappt->str, optr->str) && optr->flags & DELETED) {
X found = 1;
X break;
X }
X if (found) {
X /* just adjust reference counts and return */
X while (n_arrows >= 0)
X slots[slotno+(n_arrows--)].count++;
X return;
X }
X /*
X * Make sure there are no overlaps with the appt we
X * are adding. If there are, hide the overlapping appt.
X */
X nbi = slotno;
X do {
X if (slots[nbi].active == ACTIVE) {
X deactivate_slot(nbi, dpyflag);
X if (slots[nbi].cur_appt->arrows > 0)
X nbi = deactivate_lower_arrows(nbi, dpyflag);
X } else if (slots[nbi].active != INACTIVE)
X nbi = deactivate_lower_arrows(nbi, dpyflag);
X while (++nbi <= slotno+n_arrows)
X if (slots[nbi].active == ACTIVE)
X break;
X } while (nbi <= slotno + n_arrows);
X /* set current one to the new one */
X slots[slotno].cur_appt = nappt;
X /* now go back and put in the info for the appt we're inserting */
X slots[slotno].active = ACTIVE;
X slots[slotno].count++;
X if (n_arrows > 0) {
X slots[slotno+n_arrows].count++;
X slots[slotno+n_arrows].active = ARROW_HEAD;
X while (--n_arrows > 0) {
X slots[slotno+n_arrows].count++;
X slots[slotno+n_arrows].active = ARROW_SHAFT;
X }
X }
X }
X if (dpyflag)
X draw_day_appts(); /* redraw display */
X}
X
X
X#ifndef NO_SUN_MOON
X/*
X * write sun data to the popup canvas
X */
Xwrite_sun_data()
X{
X int x, y, height;
X char buf[64];
X Pixwin *spixwin;
X Rect *rect;
X struct timeval tp;
X double jdays, secs, offset;
X double julian_day();
X
X /* first erase the window. */
X spixwin = (Pixwin *)canvas_pixwin(scanvas);
X rect = (Rect *) window_get(scanvas, WIN_RECT);
X pw_writebackground(spixwin, 0, 0,
X rect->r_width, rect->r_height, PIX_CLR);
X
X x = font->pf_defaultsize.x;
X height = y = font->pf_defaultsize.y;
X
X gettimeofday(&tp, 0);
X if (ymd_compare(current, today) == 0) {
X /* use current time */
X write_times();
X panel_set(sdate_pi, PANEL_LABEL_STRING, riseset_buf[B_DMY], 0);
X y += 11 * height;
X } else {
X /* convert today's date to approx. seconds from 1-1-1970 */
X jdays = julian_day((double)today.tm_mday, today.tm_mon+1, today.tm_year+1900) - J1970;
X /* seconds from 00:00 GMT to now */
X offset = tp.tv_sec - (jdays * 24. * 3600.);
X /* convert this date to approx. seconds from 1-1-1970 */
X jdays = julian_day((double)current.tm_mday, current.tm_mon+1, current.tm_year+1900) - J1970;
X /* seconds to the same time on selected day */
X secs = (jdays * 24.0 * 3600.) + offset;
X riseset((long)secs);
X panel_set(sdate_pi, PANEL_LABEL_STRING, riseset_buf[B_DMY], 0);
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_JLD]);
X y += height;
X }
X sprintf(buf, "Sun Rise (today): %s", riseset_buf[B_SRD]);
X pw_text(spixwin, x, y, PIX_SRC, font, buf);
X y += height;
X sprintf(buf, "Sun Set (today): %s", riseset_buf[B_SSD]);
X pw_text(spixwin, x, y, PIX_SRC, font, buf);
X y += height;
X sprintf(buf, "Sun Rise (tomorrow): %s", riseset_buf[B_SRT]);
X pw_text(spixwin, x, y, PIX_SRC, font, buf);
X y += height;
X sprintf(buf, "Sun Set (tomorrow): %s", riseset_buf[B_SST]);
X pw_text(spixwin, x, y, PIX_SRC, font, buf);
X}
X
X/*
X * write sun time data to the popup canvas
X */
Xwrite_times()
X{
X int x, y, height;
X Pixwin *spixwin;
X struct timeval tp;
X
X /* only update these if displaying today's page */
X if (ymd_compare(current, today) != 0)
X return;
X
X spixwin = (Pixwin *)canvas_pixwin(scanvas);
X
X x = font->pf_defaultsize.x;
X y = height = font->pf_defaultsize.y;
X
X gettimeofday(&tp, 0);
X riseset(tp.tv_sec);
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_GMT]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_TDT]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_LCT]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_LMT]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_GST]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_LST]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_JLD]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_LHA]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_SDE]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_SAZ]);
X y += height;
X pw_text(spixwin, x, y, PIX_SRC, font, riseset_buf[B_SEL]);
X}
X
X/*
X * write moon data to the popup canvas
X */
Xwrite_moon_data()
X{
X int x, y, height;
X char buf[64];
X Pixwin *mpixwin;
X Rect *rect;
X struct timeval tp;
X double jdays, secs, offset;
X double julian_day();
X
X /* first erase the window. */
X mpixwin = (Pixwin *)canvas_pixwin(mcanvas);
X rect = (Rect *) window_get(mcanvas, WIN_RECT);
X pw_writebackground(mpixwin, 0, 0,
X rect->r_width, rect->r_height, PIX_CLR);
X
X x = font->pf_defaultsize.x;
X y = height = font->pf_defaultsize.y;
X
X gettimeofday(&tp, 0);
X if (ymd_compare(current, today) == 0) {
X /* use current time */
X riseset(tp.tv_sec);
X moon_data(tp.tv_sec);
X } else {
X /* convert today's date to approx. seconds from 1-1-1970 */
X jdays = julian_day((double)today.tm_mday, today.tm_mon+1, today.tm_year+1900) - J1970;
X /* seconds from 00:00 GMT to now */
X offset = tp.tv_sec - (jdays * 24. * 3600.);
X /* convert this date to seconds from 1-1-1970 */
X jdays = julian_day((double)current.tm_mday, current.tm_mon+1, current.tm_year+1900) - J1970;
X /* seconds to the same time on selected day */
X secs = (jdays * 24.0 * 3600.) + offset;
X riseset((long)secs);
X moon_data((long)secs);
X }
X panel_set(mdate_pi, PANEL_LABEL_STRING, riseset_buf[B_DMY], 0);
X y = 6 * height;
X sprintf(buf, "Moon Rise (today): %s", riseset_buf[B_MRD]);
X pw_text(mpixwin, x, y, PIX_SRC, font, buf);
X y += height;
X sprintf(buf, "Moon Set (today): %s", riseset_buf[B_MSD]);
X pw_text(mpixwin, x, y, PIX_SRC, font, buf);
X y += height;
X sprintf(buf, "Moon Rise (tomorrow): %s", riseset_buf[B_MRT]);
X pw_text(mpixwin, x, y, PIX_SRC, font, buf);
X y += height;
X sprintf(buf, "Moon Set (tomorrow): %s", riseset_buf[B_MST]);
X pw_text(mpixwin, x, y, PIX_SRC, font, buf);
X}
X#endif /* NO_SUN_MOON */
SHAR_EOF
if test 24098 -ne "`wc -c < 'dpaint.c'`"
then
echo shar: error transmitting "'dpaint.c'" '(should have been 24098 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'holidays.c'" '(9579 characters)'
if test -f 'holidays.c'
then
echo shar: will not over-write existing file "'holidays.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'holidays.c'
X/*
X * $Header: holidays.c,v 2.1 89/05/09 14:19:10 billr Exp $
X */
X/*
X * holidays.c
X *
X * Author: Bill Randle, Tektronix, Inc. <billr at saab.CNA.TEK.COM>
X * (based on a test driver by R.P.C. Rodgers)
X *
X * Copyright (C) 1989, Tektronix, Inc. All Rights Reserved
X *
X * Permission is hereby granted to use and modify this code in source
X * or binary form as long as it is not sold for profit and this copyright
X * notice remains intact.
X */
X/*
X * functions from datelib (by R.P.C. Rodgers)
X */
X#include "ct.h" /* for the NO_HOLIDAYS #define */
X#ifndef NO_HOLIDAYS
X
X#include <sys/time.h>
X
Xdouble election_day(); /* Secular US holidays */
X
Xdouble autumn_equinox(), /* Astronomical events */
X summer_solstice(),
X vernal_equinox(),
X winter_solstice();
X
Xdouble ascension_day(), /* Christian holidays */
X ash_wednesday(),
X corpus_christi(),
X easter(),
X easter_monday(),
X easter_offset(),
X first_sunday_advent(),
X first_sunday_lent(),
X fourth_sunday_lent(),
X good_friday(),
X maundy_thursday(),
X palm_sunday(),
X passion_sunday(),
X rogation_sunday(),
X septuagesima(),
X sexagesima(),
X quinquagesima(),
X second_sunday_lent(),
X shrove_monday(),
X shrove_tuesday(),
X third_sunday_lent(),
X trinity_sunday(),
X whitsunday();
X
Xdouble islamic_new_year(), /* Islamic holidays */
X muharram_9(),
X muharram_10(),
X muharram_16(),
X eid_i_milad_un_nabi(),
X jumada_al_akhir_23(),
X shab_e_miraj(),
X shab_e_barat(),
X shab_e_qadr(),
X ramadan(),
X eid_al_fitr(),
X dhul_hijja_9(),
X eid_al_adha(),
X ghadir();
X
Xdouble chanukah(), /* Jewish holidays */
X passover(),
X passover_offset(),
X purim(),
X rosh_hashanah(),
X shavuot(),
X simchat_torah(),
X sukkot(),
X yom_kippur();
X
Xint check_date();
X
Xextern struct tm current; /* current day displayed from calentool */
Xint marked_note;
X
Xint
Xa_dates(appt, flag)
Xstruct appt_entry *appt;
Xint flag;
X{
X /*
X * Astromonical Events
X */
X if (!flag)
X return(0);
X marked_note = flag - 1;
X if (check_date(appt, "Vernal Equinox", vernal_equinox, TRUE))
X return(1);
X if (check_date(appt, "Summer Solstice", summer_solstice, TRUE))
X return(1);
X if (check_date(appt, "Autumn Equinox", autumn_equinox, TRUE))
X return(1);
X if (check_date(appt, "Winter Solstice", winter_solstice, TRUE))
X return(1);
X return(0);
X}
X
Xint
Xc_dates(appt, flag)
Xstruct appt_entry *appt;
Xint flag;
X{
X /*
X * Christian holidays
X */
X if (!flag)
X return(0);
X marked_note = flag - 1;
X if (check_date(appt, "Septuagesima Sunday", septuagesima, FALSE))
X return(1);
X if (check_date(appt, "Sexagesima Sunday", sexagesima, FALSE))
X return(1);
X if (check_date(appt, "Quinquagesima Sunday", quinquagesima, FALSE))
X return(1);
X if (check_date(appt, "Shrove Monday", shrove_monday, FALSE))
X return(1);
X if (check_date(appt, "Shrove Tuesday (Mardi Gras)", shrove_tuesday, FALSE))
X return(1);
X if (check_date(appt, "Ash Wednesday", ash_wednesday, FALSE))
X return(1);
X if (check_date(appt, "First Sunday in Lent", first_sunday_lent, FALSE))
X return(1);
X if (check_date(appt, "Second Sunday in Lent", second_sunday_lent, FALSE))
X return(1);
X if (check_date(appt, "Third Sunday in Lent", third_sunday_lent, FALSE))
X return(1);
X if (check_date(appt, "Fourth Sunday in Lent", fourth_sunday_lent, FALSE))
X return(1);
X if (check_date(appt, "Passion Sunday", passion_sunday, FALSE))
X return(1);
X if (check_date(appt, "Palm Sunday", palm_sunday, FALSE))
X return(1);
X if (check_date(appt, "Maundy Thursday", maundy_thursday, FALSE))
X return(1);
X if (check_date(appt, "Good Friday", good_friday, FALSE))
X return(1);
X if (check_date(appt, "Easter", easter, FALSE))
X return(1);
X if (check_date(appt, "Easter Monday (Canada)", easter_monday, FALSE))
X return(1);
X if (check_date(appt, "Rogation Sunday", rogation_sunday, FALSE))
X return(1);
X if (check_date(appt, "Ascension Day", ascension_day, FALSE))
X return(1);
X if (check_date(appt, "Whitsunday", whitsunday, FALSE))
X return(1);
X if (check_date(appt, "Trinity Sunday", trinity_sunday, FALSE))
X return(1);
X if (check_date(appt, "Corpus Christi", corpus_christi, FALSE))
X return(1);
X if (check_date(appt, "First Sunday in Advent", first_sunday_advent, FALSE))
X return(1);
X return(0);
X}
X
Xint
Xi_dates(appt, flag)
Xstruct appt_entry *appt;
Xint flag;
X{
X double day, date1, date2;
X int ndates, myear1, myear2=0;
X int month, year;
X char buf[16];
X
X /*
X * Islamic holidays
X */
X if (!flag)
X return(0);
X marked_note = flag - 1;
X if (check_idate(appt, "Muharram 1, %d A.H.: Islamic New Year", islamic_new_year))
X return(1);
X if (check_idate(appt, "Muharram 9, %d A.H.: Day of fasting", muharram_9))
X return(1);
X if (check_idate(appt,
X "Muharram 10, %d A.H.: Deliverance of Moses from the Pharoah (for Shia Islam, martyrdom of Husain)", muharram_10))
X return(1);
X if (check_idate(appt, "Muharram 16, %d A.H. (Imamat Day; Ismaili Khoja)", muharram_16))
X return(1);
X if (check_idate(appt, "Rabi I 12, %d A.H. (Eid-i-Milad-un-Nabi: The Prophet's Birthday)", eid_i_milad_un_nabi))
X return(1);
X if (check_idate(appt, "Jumada al-Akhir 23, %d A.H. (Birth of Agha Khan IV, Ismaili)", jumada_al_akhir_23))
X return(1);
X if (check_idate(appt, "Rajab 27, %d A.H. (Shab-e-Mi'raj: The Prophet's Ascension)", shab_e_miraj))
X return(1);
X if (check_idate(appt, "Shaban 15, %d A.H. (Shab-e-Bara't: Night, followed by day of fasting)", shab_e_barat))
X return(1);
X if (check_idate(appt, "Ramadan 1, %d A.H. (Fasting month begins)", ramadan))
X return(1);
X if (check_idate(appt, "Ramadan 27, %d A.H. (Shab-e-Qadr: Night vigil))", shab_e_qadr))
X return(1);
X if (check_idate(appt, "Shawwal 1, %d A.H. (Eid-al-Fitr: Day of Feast)", eid_al_fitr))
X return(1);
X if (check_idate(appt, "Dhul-Hijj 9, %d A.H. (Day of Pilgrimage at Arafat, Mecca)", dhul_hijja_9))
X return(1);
X if (check_idate(appt, "Dhul-Hijj 10, %d A.H. (Eid-al-Azha: Day of Abraham's Sacrifice)", eid_al_adha))
X return(1);
X if (check_idate(appt, "Dhul-Hijj 18, %d A.H. (Ghadir: Ali's Nomination)", ghadir))
X return(1);
X return(0);
X}
X
Xint
Xj_dates(appt, flag)
Xstruct appt_entry *appt;
Xint flag;
X{
X char buf[24];
X int jyear;
X
X /*
X * Jewish holidays
X */
X if (!flag)
X return(0);
X marked_note = flag - 1;
X if (check_jdate(appt, "Purim", purim))
X return(1);
X if (check_jdate(appt, "First day of Passover", passover))
X return(1);
X if (check_jdate(appt, "Shavuot", shavuot))
X return(1);
X if (check_jdate(appt, "Rosh Hashanah (Jewish New Year)", rosh_hashanah))
X return(1);
X if (check_jdate(appt, "Yom Kippur", yom_kippur))
X return(1);
X if (check_jdate(appt, "First day of Sukkot (9 days)", sukkot))
X return(1);
X if (check_jdate(appt, "Simchat Torah", simchat_torah))
X return(1);
X if (check_jdate(appt, "First day of Chanukah (8 days)", chanukah))
X return(1);
X return(0);
X}
X
Xint
Xs_dates(appt, flag)
Xstruct appt_entry *appt;
Xint flag;
X{
X /*
X * SECULAR US HOLIDAYS
X * [Holidays specified as a given date (e.g. July 4) or as
X * a known nth mday of a month (e.g. 2nd Monday) are not
X * calculated here. They are available from one of the
X * auxillary date files.]
X */
X if (!flag)
X return(0);
X marked_note = flag - 1;
X if (check_date(appt, "Election Day", election_day, FALSE))
X return(1);
X return(0);
X}
X
X/*
X * check for gregorian (i.e. US secular & Christian) holidays
X */
Xint
Xcheck_date(aptr, str, func, timeflag)
Xstruct appt_entry *aptr;
Xchar *str;
Xdouble (*func)();
Xint timeflag;
X{
X int month, year;
X double day, hday;
X char *julian_time();
X
X hday = (*func)(current.tm_year+1900);
X gregorian_date(&day, &month, &year, hday);
X if (current.tm_mon == --month && current.tm_mday == (int)day) {
X aptr->year = current.tm_year;
X aptr->month = current.tm_mon;
X aptr->day = current.tm_mday;
X aptr->arrows = aptr->repeat = aptr->lookahead = 0;
X aptr->flags = (A_NOTE | READONLY);
X if (marked_note)
X aptr->flags |= MARKED;
X strcpy(aptr->str, str);
X if (timeflag) {
X strcat(aptr->str, julian_time(hday));
X strcat(aptr->str, " GMT");
X }
X return(1);
X }
X return(0);
X}
X
X/*
X * check for Islamic holidays
X */
Xint
Xcheck_idate(aptr, str, func)
Xstruct appt_entry *aptr;
Xchar *str;
Xint (*func)();
X{
X double day, date1, date2;
X int nr_dates, year1, year2;
X int month, year;
X int match = 0;
X
X (void)(*func)(current.tm_year+1900, &nr_dates, &date1, &date2, &year1, &year2);
X gregorian_date(&day, &month, &year, date1);
X if (current.tm_mon == --month && current.tm_mday == (int)day)
X match = 1;
X else if (nr_dates == 2) {
X gregorian_date(&day, &month, &year, date2);
X if (current.tm_mon == --month && current.tm_mday == (int)day)
X match = 2;
X }
X if (match) {
X aptr->year = current.tm_year;
X aptr->month = current.tm_mon;
X aptr->day = current.tm_mday;
X aptr->arrows = aptr->repeat = aptr->lookahead = 0;
X aptr->flags = (A_NOTE | READONLY);
X if (marked_note)
X aptr->flags |= MARKED;
X if (match == 1)
X /* match was on first year */
X sprintf(aptr->str, str, year1);
X else
X /* must have been second year */
X sprintf(aptr->str, str, year2);
X return(1);
X }
X return(0);
X}
X
X/*
X * check for Jewish holidays
X */
Xint
Xcheck_jdate(aptr, str, func)
Xstruct appt_entry *aptr;
Xchar *str;
Xdouble (*func)();
X{
X int month, year, jyear;
X double hday, day;
X char buf[32];
X
X hday = (*func)(current.tm_year+1900, &jyear);
X gregorian_date(&day, &month, &year, hday);
X if (current.tm_mon == --month && current.tm_mday == (int)day) {
X
X aptr->year = current.tm_year;
X aptr->month = current.tm_mon;
X aptr->day = current.tm_mday;
X aptr->arrows = aptr->repeat = aptr->lookahead = 0;
X aptr->flags = (A_NOTE | READONLY);
X if (marked_note)
X aptr->flags |= MARKED;
X strcpy(aptr->str, str);
X sprintf(buf, " [Jewish year %d]", jyear);
X strcat(aptr->str, buf);
X return(1);
X }
X return(0);
X}
X#endif /* NO_HOLIDAYS */
SHAR_EOF
if test 9579 -ne "`wc -c < 'holidays.c'`"
then
echo shar: error transmitting "'holidays.c'" '(should have been 9579 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Comp.sources.sun
mailing list