static void fill_day(Calendar *c, Week *w, int x, int y, int day, Paint_cache *cache, int a_total, XRectangle *rect) { CSA_return_code stat; Dtcm_appointment *appt; register int lower = (int)lowerbound(day); register int upper = (int)next_ndays(day, 1); register int i, loop, n; register int nlines = 0; XFontSetExtents fontextents; int char_width; int char_height; int maxlines; int maxchars; Tick tick; CalFontExtents(w->small_font, &fontextents); char_width = fontextents.max_logical_extent.width; char_height = fontextents.max_logical_extent.height; maxlines = ((w->day_height - w->label_height) / char_height)- 1; maxchars = (w->day_width / char_width); #if 0 x += char_width; #endif x += 3; y += (w->label_height + char_height); /* * Fill in a day with appointments */ /* loop thru twice, first displaying "no time" appointments, and then the others. */ for (loop = 0; loop < 2; loop++) { for (i = 0; i < a_total; i++) { if ((cache[i].start_time < lower) || (cache[i].start_time >= upper)) continue; if (cache[i].show_time != loop) continue; if (nlines < maxlines) { n = paint_entry(c, x, y, maxchars, &cache[i], rect); y += n * char_height; nlines += n; } } } }
extern void paint_day_header(Calendar *c, Tick date, void *rect) { Props *p = (Props*)c->properties; OrderingType ot = get_int_prop(p, CP_DATEORDERING); int pfy, x; char buf[100]; Boolean inrange = False; Colormap cmap; Pixel foreground_pixel; XFontSetExtents fontextents; struct tm *tm; _Xltimeparams localtime_buf; tm = _XLocaltime(&date, localtime_buf); CalFontExtents(c->fonts->labelfont, &fontextents); pfy = fontextents.max_logical_extent.height; XtVaGetValues(c->canvas, XmNcolormap, &cmap, NULL); XtVaGetValues(c->canvas, XmNforeground, &foreground_pixel, NULL); buf [0] = '\0'; /* NL_COMMENT Attention Translator: This string is used in the calendar day view. In the C locale it has the form: Monday, January 16, 1995 strftime conversion string: "%A, %B %e, %Y" is used. Use the appropriate strftime conversion for your locale. */ strftime(buf, 100, catgets(c->DT_catd, 1, 992, "%A, %B %e, %Y"), tm); inrange = today_inrange(c, date); x = gr_center(c->view->winw-(int)MOBOX_AREA_WIDTH, buf, c->fonts->labelfont) + (int)MOBOX_AREA_WIDTH; if (c->xcontext->screen_depth >= 8 && inrange) gr_text_rgb(c->xcontext, x, c->view->topoffset - (pfy/2), c->fonts->labelfont, buf, foreground_pixel, cmap, rect); else gr_text(c->xcontext, x, c->view->topoffset - (pfy/2), c->fonts->labelfont, buf, rect); }
extern void monthbox_datetoxy(Calendar *c) { char str[5]; int week, x_off, dayw, daym, mo; Day *day_info = (Day *) c->view->day_info; XFontSetExtents fontextents; int pfy; int col_w = day_info->col_w; int row_h = day_info->row_h; struct tm tm; _Xltimeparams localtime_buf; CalFontExtents(c->fonts->labelfont, &fontextents); pfy = fontextents.max_logical_extent.height; tm = *_XLocaltime(&c->view->date, localtime_buf); mo = tm.tm_mon+1; dayw = tm.tm_wday; daym = tm.tm_mday; week = (12+tm.tm_mday-tm.tm_wday)/7; day_info->day_selected_x = c->view->outside_margin + INSIDE_MARGIN + col_w*dayw; if (mo == month(day_info->month1)) day_info->day_selected_y = day_info->month1_y + row_h*week; else if (mo == month(day_info->month2)) day_info->day_selected_y = day_info->month2_y + row_h*week; else if (mo == month(day_info->month3)) day_info->day_selected_y = day_info->month3_y + row_h*week; sprintf(str, "%d", daym); x_off = gr_center(col_w, str, c->fonts->labelfont); day_info->day_selected_x2 = day_info->day_selected_x+x_off; day_info->day_selected_y2 = day_info->day_selected_y + pfy; day_info->day_selected = daym; }
static int paint_entry(Calendar *c, int x, int y, int maxchars, Paint_cache *cache_entry, XRectangle *rect) { XFontSetExtents fontextents; Props *p = (Props*)c->properties; int nlines = 0, dt = get_int_prop(p, CP_DEFAULTDISP); new_XContext *xc = c->xcontext; char buf1[50], buf2[WHAT_LEN+1]; Week *w = (Week *)c->view->week_info; Tick tick; /* * Write an appointment entry into a day */ if (maxchars >= 40) /* maxed out possible=40 */ maxchars = 40; buf1[0] = '\0'; buf2[0] = '\0'; format_entry(cache_entry, buf1, buf2, dt); tick = cache_entry->start_time; if (cache_entry->show_time && !magic_time(tick) && (buf1[0] != '\0')) { maxchars = gr_nchars(w->day_width - 5, buf1,c->fonts->boldfont); buf1[min(cm_strlen(buf1), maxchars)] = '\0'; gr_text(xc, x, y, c->fonts->boldfont, buf1, rect); nlines++; CalFontExtents(c->fonts->boldfont, &fontextents); y += fontextents.max_logical_extent.height;; } if (buf2[0] != '\0') { maxchars = gr_nchars(w->day_width - 5, buf2, c->fonts->viewfont); buf2[min(cm_strlen(buf2), maxchars)] = '\0'; gr_text(xc, x, y, c->fonts->viewfont, buf2, rect); nlines++; } return(nlines); }
extern void monthbox_xytodate(Calendar *c, int x, int y) { char str[5]; Day *day_info = (Day *)c->view->day_info; XFontSetExtents fontextents; int pfy; int col_w = day_info->col_w; int row_h = day_info->row_h; int row, col, x_off; int day_selected, tmpx; CalFontExtents(c->fonts->labelfont, &fontextents); pfy = fontextents.max_ink_extent.height; col = (x-c->view->outside_margin-INSIDE_MARGIN) / col_w; if (col < 0) return; tmpx = c->view->outside_margin + INSIDE_MARGIN + col * col_w; if (y < (day_info->month1_y + day_info->mobox_height1)) { row = (y-day_info->month1_y-row_h) / row_h; day_selected = (7 * (row+1)) - fdom(day_info->month1) - (6 - col); if (day_selected <= 0 || day_selected > monthlength(day_info->month1)) return; day_info->day_selected = day_selected; day_info->day_selected_y = day_info->month1_y + (row+1)*row_h; c->view->olddate = c->view->date; c->view->date = next_ndays(first_dom(day_info->month1), day_info->day_selected); } else if (y < (day_info->month2_y + day_info->mobox_height2)) { row = (y-day_info->month2_y-row_h) / row_h; day_selected = (7 * (row+1)) - fdom(day_info->month2) - (6 - col); if (day_selected <= 0 || day_selected > monthlength(day_info->month2)) return; day_info->day_selected = day_selected; day_info->day_selected_y = day_info->month2_y + (row+1)*row_h; c->view->olddate = c->view->date; c->view->date = next_ndays(first_dom(day_info->month2), day_info->day_selected); } else if (y < (day_info->month3_y + day_info->mobox_height3)) { row = (y-day_info->month3_y-row_h) / row_h; day_selected = (7 * (row+1)) - fdom(day_info->month3) - (6 - col); if (day_selected <= 0 || day_selected > monthlength(day_info->month3)) return; day_info->day_selected = day_selected; day_info->day_selected_y = day_info->month3_y + (row+1)*row_h; c->view->olddate = c->view->date; c->view->date = next_ndays(first_dom(day_info->month3), day_info->day_selected); } day_info->day_selected_x = tmpx; sprintf(str, "%d", day_info->day_selected); x_off = gr_center(col_w, str, c->fonts->labelfont); day_info->day_selected_x2 = day_info->day_selected_x+x_off; day_info->day_selected_y2 = day_info->day_selected_y + pfy; }
static void paint_dayview_appts(Calendar *c, Paint_cache *cache, int a_total, void *rect) { int w = c->view->boxw; int h = c->view->boxh; int begin_time, end_time; int x, x2, y, y2, num_hrs, i, last_hr, hr, x_off; Cal_Font *pf = c->fonts->boldfont; Cal_Font *pf2 = c->fonts->viewfont; XFontSetExtents fontextents; XFontSetExtents fontextents2; Props *p = (Props*)c->properties; Boolean am = True; char buf[5], *appt_str; int pfy, curr_line, maxlines; Lines *lines = NULL, *headlines = NULL; DisplayType disp_t; Colormap cmap; Pixel fg; Tick start_tick, end_tick; int nop, hrbox_margin; CalFontExtents(pf, &fontextents); CalFontExtents(pf2, &fontextents2); XtVaGetValues(c->canvas, XmNcolormap, &cmap, XmNforeground, &fg, NULL); /* draw horizontal lines */ begin_time = get_int_prop(p, CP_DAYBEGIN); end_time = get_int_prop(p, CP_DAYEND); disp_t = get_int_prop(p, CP_DEFAULTDISP); num_hrs = end_time - begin_time + 1; if (disp_t == HOUR12) CalTextExtents(pf, "12pm", 4, &nop, &nop, &hrbox_margin, &nop); else CalTextExtents(pf, "24 ", 3, &nop, &nop, &hrbox_margin, &nop); x = MOBOX_AREA_WIDTH+2; x2 = x + w; y = c->view->topoffset; for (i = 0; i <= num_hrs; i++) { gr_draw_line(c->xcontext, x, y, x2, y, gr_solid, rect); y += h; } /* draw vertical line */ y = c->view->topoffset; y2 = y + num_hrs * h; x += hrbox_margin; gr_draw_line(c->xcontext, x, y, x, y2, gr_solid, rect); x = MOBOX_AREA_WIDTH+3; y += h/2+4; /* draw in hours */ for (i = begin_time - 1; i < end_time; i++) { hr = i; if (i < begin_time) (void) sprintf(buf, ""); else if (disp_t == HOUR12) { am = adjust_hour(&hr); (void) sprintf(buf, "%d%s", hr, am ? "a" : "p"); } else (void) sprintf(buf, "%02d", hr); x_off = gr_center(hrbox_margin, buf, pf); /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb] if (c->xcontext->screen_depth >= 8) gr_text_rgb(c->xcontext, x+x_off, y, pf, buf, fg, cmap, rect); else */ gr_text(c->xcontext, x+x_off, y, pf, buf, rect); y += h; } /* draw in appointments */ x = MOBOX_AREA_WIDTH + hrbox_margin + 6; pfy = fontextents2.max_logical_extent.height; maxlines = (h - 6) / pfy; curr_line = last_hr = 0; /* loop thru, getting out the "no time" appointments */ for (i = 0; i < a_total; i++) { if (i != a_total) last_hr = hr; hr = begin_time; if (cache[i].show_time == 0) { if (last_hr != hr) curr_line = 0; y = c->view->topoffset + 2 + pfy; if (curr_line < maxlines) { y += (curr_line * pfy) + h * (hr - begin_time); headlines = lines = text_to_lines(cache[i].summary, 4); start_tick = cache[i].start_time; end_tick = cache[i].end_time; if (lines != NULL && lines->s != NULL) { appt_str = ckalloc(cm_strlen(lines->s)+18); format_line(start_tick, lines->s, appt_str, end_tick, cache[i].show_time, disp_t); lines = lines->next; } else { appt_str = ckalloc(15); format_line(start_tick, (char*)NULL, appt_str, end_tick, cache[i].show_time, disp_t); } appt_str[cm_strlen(appt_str)]=NULL; /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb] if (c->xcontext->screen_depth >= 8) gr_text_rgb(c->xcontext, x, y, pf2, appt_str, fg, cmap, rect); else */ gr_text(c->xcontext, x, y, pf2, appt_str, rect); free(appt_str); appt_str = NULL; curr_line++; if (curr_line < maxlines && lines != NULL) { appt_str = ckalloc(324); cm_strcpy(appt_str, " "); while (lines != NULL) { if (lines->s != NULL) cm_strcat(appt_str, lines->s); lines = lines->next; if (lines != NULL && lines->s != NULL) cm_strcat(appt_str, " - "); } y += pfy; /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb] if (c->xcontext->screen_depth >= 8) gr_text_rgb(c->xcontext, x, y, pf2, appt_str, fg, cmap, rect); else */ gr_text(c->xcontext, x, y, pf2, appt_str, rect); curr_line++; free(appt_str); appt_str = NULL; } destroy_lines(headlines); lines=NULL; } } } for (i = 0; i < a_total; i++) { if (i != a_total) last_hr = hr; start_tick = cache[i].start_time; end_tick = cache[i].end_time; hr = hour(start_tick); if (hr >= begin_time && hr < end_time && (cache[i].show_time && !magic_time(start_tick))) { if (last_hr != hr) curr_line = 0; y = c->view->topoffset + 2 + pfy; if (curr_line < maxlines) { y += (curr_line * pfy) + h * (hr - begin_time + 1); headlines = lines = text_to_lines(cache[i].summary, 4); if (lines != NULL && lines->s != NULL) { appt_str = ckalloc(cm_strlen(lines->s)+18); format_line(start_tick, lines->s, appt_str, end_tick, cache[i].show_time, disp_t); lines = lines->next; } else { appt_str = ckalloc(15); format_line(start_tick, (char*)NULL, appt_str, end_tick, cache[i].show_time, disp_t); } appt_str[cm_strlen(appt_str)]=NULL; /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb] if (c->xcontext->screen_depth >= 8) gr_text_rgb(c->xcontext, x, y, pf2, appt_str, fg, cmap, rect); else */ gr_text(c->xcontext, x, y, pf2, appt_str, rect); free(appt_str); appt_str = NULL; curr_line++; if (curr_line < maxlines && lines != NULL) { appt_str = ckalloc(324); cm_strcpy(appt_str, " "); while (lines != NULL) { if (lines->s != NULL) cm_strcat(appt_str, lines->s); lines = lines->next; if (lines != NULL && lines->s != NULL) cm_strcat(appt_str, " - "); } y += pfy; /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb] if (c->xcontext->screen_depth >= 8) gr_text_rgb(c->xcontext, x, y, pf2, appt_str, fg, cmap, rect); else */ gr_text(c->xcontext, x, y, pf2, appt_str, rect); curr_line++; free(appt_str); appt_str = NULL; } destroy_lines(headlines); lines=NULL; } } } }
static void draw_week(Calendar *c, XRectangle *rect, Boundary boundary) { Week *w = (Week *)c->view->week_info; register int current_day; register int n; register int x, y; int char_height; int start_date; char **day_names; char label[80]; char buf[MAXNAMELEN]; char *footer_message = NULL; int start_ind, end_ind; int today_dom, day_om; new_XContext *xc; Props *p = (Props*)c->properties; XRectangle chartrect; OrderingType ot = get_int_prop(p, CP_DATEORDERING); Tick start_tick, end_tick; time_t start, stop; CSA_return_code stat; CSA_entry_handle *list; CSA_attribute *range_attrs; CSA_enum *ops; CSA_uint32 a_total; int i, lower_bound = 0, upper_bound = 0; XFontSetExtents regfontextents, boldfontextents; int notused, width1, width2, width3; CalFontExtents(w->font, ®fontextents); char_height = regfontextents.max_logical_extent.height; start_date = w->start_date; xc = c->xcontext; start = (time_t) lowerbound(start_date); stop = (time_t) next_ndays(start, 7) - 1; if (c->paint_cache == NULL) { setup_range(&range_attrs, &ops, &i, start, stop, CSA_TYPE_EVENT, 0, B_FALSE, c->general->version); csa_list_entries(c->cal_handle, i, range_attrs, ops, &a_total, &list, NULL); free_range(&range_attrs, &ops, i); allocate_paint_cache(list, a_total, &c->paint_cache); c->paint_cache_size = a_total; csa_free(list); } gr_clear_box(xc, 0, 0, w->canvas_w, w->canvas_h); CalTextExtents(w->font, days2[3], cm_strlen(days2[3]), ¬used, ¬used, &width1, ¬used); CalTextExtents(w->font, " 00", cm_strlen(" 00"), ¬used, ¬used, &width2, ¬used); CalTextExtents(w->font, "Wed 00", cm_strlen("Wed 00"), ¬used, ¬used, &width3, ¬used); if (width1 + width2 <= w->day_width - 2) day_names = days2; else if (width3 <= w->day_width - 2) day_names = days; else day_names = days3; x = w->x; y = w->y; format_week_header(start_date, ot, label); gr_text(xc, x, y - char_height / 2, w->font, label, rect); /* * Draw bold box around first 5 days */ gr_draw_box(xc, x, y, w->width, w->day_height, rect); gr_draw_box(xc, x - 1, y - 1, w->width + 2, w->day_height + 2, rect); gr_draw_line(xc, x, y + w->label_height, x + w->width, y + w->label_height, gr_solid, rect); /* * Draw bold box around last 2 days */ x += 3 * w->day_width; y += w->day_height; gr_draw_box(xc, x, y, 2 * w->day_width, w->day_height, rect); gr_draw_box(xc, x - 1, y, 2 * w->day_width + 2, w->day_height + 1,rect); gr_draw_line(xc, x, y + w->label_height, x + 2 * w->day_width, y + w->label_height, gr_solid, rect); y = w->y; x = w->x + w->day_width; for (n = 0; n < 4; n++) { if (n < 3) { gr_draw_line(xc, x, y, x, y + w->day_height, gr_solid, rect); } else { gr_draw_line(xc, x, y, x, y + 2 * w->day_height, gr_solid, rect); } x += w->day_width; } /* * Fill in week with appointments */ x = w->x; y = w->y; current_day = start_date; today_dom = dom(time(0)); /* Crock alert!!!! The obscure code below is doing something really nasty. The variable boundary indicates whether the week being displayed falls across a boundary with the beginning or the end of time. In the case of the beginning of time, the code then assumes that the first 2 days in the week need to be unbuttoned, and the rest buttoned and painted. Likewise, with the end of time case, the code assumes the last 3 days of the week need similar treatment. */ for (n = 0; n < 7; n++) { if (n == 5) { y += w->day_height; x = w->x + 3 * w->day_width; } if (boundary == okay) { day_om = dom(current_day); display_hot_btn(c, n, day_om); fill_day(c, w, x, y, current_day, c->paint_cache, c->paint_cache_size, rect); current_day += daysec; if (lower_bound > 0) { sprintf(buf, "%s", catgets(c->DT_catd, 1, 623, "Calendar does not display dates prior to January 1, 1970")); footer_message = buf; } else footer_message = NULL; } else if (boundary == lower) { /* skip days before Jan 1, 1970 */ clear_hot_btn(c, n); if (lower_bound++ == 2) boundary = okay; } else if (boundary == upper) { day_om = dom(current_day); if (++upper_bound <= 4) display_hot_btn(c, n, day_om); fill_day(c, w, x, y, current_day, c->paint_cache, c->paint_cache_size, rect); current_day += daysec; sprintf(buf, "%s", catgets(c->DT_catd, 1, 624, "Calendar does not display dates after December 31, 2037")); footer_message = buf; if (upper_bound > 4) clear_hot_btn(c, n); } x += w->day_width; } if (rect != NULL) { CalFontExtents(w->small_bold_font, &boldfontextents); chartrect.x = w->x; chartrect.y = w->chart_y - w->label_height; chartrect.width = w->chart_width + 3*boldfontextents.max_logical_extent.width; chartrect.height = w->chart_height + 2*w->label_height; } if (rect == NULL || myrect_intersectsrect(rect, &chartrect)) { for (i = 0; i < c->paint_cache_size; i++) { start_tick = (c->paint_cache)[i].start_time; end_tick = (c->paint_cache)[i].end_time; cm_update_segs(w, start_tick, (end_tick ? (end_tick - start_tick) : 0), &start_ind, &end_ind, True); } chart_draw_appts(w, 0, w->segs_in_array); draw_chart(c, w, NULL); } /* do not repaint the footer message in a damage display. For some reason this causes the damage routine to get called again, resulting in a recursive dsaster. */ if (footer_message && !rect) set_message(c->message_text, footer_message); }
/* * Set up data needed to draw this particular week */ static void init_week(Calendar *c, Boundary *boundary) { Week *w = (Week *)c->view->week_info; int char_width, char_height; Props *p; int num_hrs, day_of_week; int empty_space, day_box; int skip_days = 0; XFontSetExtents regfontextents, boldfontextents; *boundary = okay; /* * The week view starts on Monday. Map Sunday to the last day of the * week */ if ((day_of_week = dow(c->view->date)) == 0) day_of_week = 6; else day_of_week--; ((Selection*)w->current_selection)->col = day_of_week; w->start_date = lowerbound(c->view->date - (day_of_week * daysec)); /* make sure date is within bounds */ if (w->start_date == -1) { if (year(c->view->date) == year(get_bot())) { w->start_date = get_bot(); *boundary = lower; } } else if (year(next_ndays(w->start_date, 7)) > year(get_eot())) { *boundary = upper; } /* * Set up a bunch of variables which are needed to draw and fill * the week at a glance screen */ XtVaGetValues(c->canvas, XmNwidth, &w->canvas_w, XmNheight, &w->canvas_h, NULL); w->font = c->fonts->labelfont; w->small_font = c->fonts->viewfont; w->small_bold_font = c->fonts->boldfont; CalFontExtents(w->font, ®fontextents); CalFontExtents(w->small_bold_font, &boldfontextents); w->x = c->view->outside_margin; w->y = 2 * (int) boldfontextents.max_logical_extent.height; char_height = regfontextents.max_logical_extent.height; char_width = regfontextents.max_logical_extent.width; w->label_height = char_height * 2; w->day_width = ((int) (w->canvas_w - 2 * w->x)) / 5; /* height of box with label */ w->day_height = ((int) (w->canvas_h - 2 * w->y)) / 2; /* * We compute week dimensions from day dimensions to remove rounding * errors */ w->width = w->day_width * 5; /* height from top of box to bottom of weekend boxes */ w->height = w->day_height * 2; p = (Props *)c->properties; w->begin_hour = get_int_prop(p, CP_DAYBEGIN); w->end_hour = get_int_prop(p, CP_DAYEND); /* width of a column in chart */ w->chart_day_width = (3 * w->day_width - 3 * char_width) / 7; /* width of chart */ w->chart_width = w->chart_day_width * 7; num_hrs = w->end_hour - w->begin_hour; /* height of box without label */ day_box = w->day_height - w->label_height; /* height of an hour in chart */ w->chart_hour_height = day_box / num_hrs; /* chart_hour_height must be evenly divisble by BOX_SEG */ w->chart_hour_height -= (w->chart_hour_height % BOX_SEG); w->chart_height = w->chart_hour_height * num_hrs; /* x point of upper left corner of chart */ w->chart_x = w->x + 2 * boldfontextents.max_logical_extent.width; /* y point of upper left corner of chart */ w->chart_y = w->y + w->height - w->chart_height; /* left over empty space above chart after round off error */ empty_space = day_box - w->chart_height; /* add pixels to the height of each hour box in chart to fill gap*/ if (w->add_pixels = ((double)empty_space / (double)num_hrs)) { w->chart_y -= w->add_pixels * num_hrs; w->chart_height += w->add_pixels * num_hrs; } w->segs_in_array = BOX_SEG * num_hrs * 7; if (w->time_array != NULL) free(w->time_array); w->time_array = (char*)ckalloc(w->segs_in_array); c->view->outside_margin = w->x; c->view->topoffset = w->y; }
static void draw_chart(Calendar *c, register Week *w, XRectangle *rect) { register int x, y; int n; XFontSetExtents fontextents; int char_height; char label[5]; new_XContext *xc = c->xcontext; Props *p = (Props*)c->properties; DisplayType dt = get_int_prop(p, CP_DEFAULTDISP); CalFontExtents(w->font, &fontextents); char_height = fontextents.max_logical_extent.height; /* * Draw chart. We first draw all the lines, then the labels * so that Xlib can batch the lines into 1 X request */ /* Draw horizontal lines for time */ x = w->chart_x; y = w->chart_y; for (n = w->begin_hour; n <= w->end_hour; n++) { gr_draw_line(xc, x, y, x + w->chart_width, y, gr_solid, rect); y += w->chart_hour_height + w->add_pixels; } /* Draw vertical lines for days */ y = w->chart_y; for (n = 0; n < 7; n++) { gr_draw_line(xc, w->chart_x + (w->chart_day_width * n), y, w->chart_x + (w->chart_day_width * n), y + w->chart_height, gr_solid, rect); } /* * Draw box around the whole thing. */ gr_draw_box(xc, w->chart_x, w->chart_y, w->chart_width, w->chart_height, rect); gr_draw_box(xc, w->chart_x - 1, w->chart_y - 1, w->chart_width + 2, w->chart_height + 2, rect); /* Label horizontal lines with time of day */ x = w->chart_x; y = w->chart_y; for (n = w->begin_hour; n <= w->end_hour; n++) { if (dt == HOUR12) sprintf(label, "%2d", n > 12 ? n - 12 : n); else sprintf(label, "%2d", n); gr_text(xc, w->x - 8, y+3, w->small_bold_font, label, rect); y += w->chart_hour_height + w->add_pixels; } /* Label vertical lines with day labels */ y = w->chart_y; for (n = 0; n < 7; n++) { x = gr_center(w->chart_day_width, days3[n+1], w->font); gr_text(xc, w->chart_x + (w->chart_day_width * n) + x, y - char_height / 2, w->font, days3[n+1], rect); } }