From 806673dd9b256e879d1483255886a8881d1d8115 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Thu, 14 Feb 2013 10:52:44 +0100 Subject: calendar.c: Rename to "ui-calendar.c" This unit belongs to the presentation layer -- rename the file accordingly. Also, rename calendar_*() to ui_calendar_*(). Signed-off-by: Lukas Fleischer --- src/calendar.c | 915 --------------------------------------------------------- 1 file changed, 915 deletions(-) delete mode 100644 src/calendar.c (limited to 'src/calendar.c') diff --git a/src/calendar.c b/src/calendar.c deleted file mode 100644 index cad9ad9..0000000 --- a/src/calendar.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * Calcurse - text-based organizer - * - * Copyright (c) 2004-2013 calcurse Development Team - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Send your feedback or comments to : misc@calcurse.org - * Calcurse home page : http://calcurse.org - * - */ - -#include -#include -#include -#include -#include -#include - -#include "calcurse.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#define EPOCH 90 -#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */ -#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */ -#define ECCEN 0.016713 /* solar orbit eccentricity */ -#define lzero 318.351648 /* lunar mean long at EPOCH */ -#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */ -#define Nzero 318.510107 /* lunar mean long of node at EPOCH */ - -#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) - -enum pom { - NO_POM, - FIRST_QUARTER, - FULL_MOON, - LAST_QUARTER, - NEW_MOON, - MOON_PHASES -}; - -static struct date today, slctd_day; -static unsigned calendar_view, week_begins_on_monday; -static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_t calendar_t_date; - -static void draw_monthly_view(struct window *, struct date *, unsigned); -static void draw_weekly_view(struct window *, struct date *, unsigned); -static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *, - unsigned) = { -draw_monthly_view, draw_weekly_view}; - -static int monthly_view_cache[MAXDAYSPERMONTH]; -static int monthly_view_cache_valid = 0; -static int monthly_view_cache_month = 0; - -/* Switch between calendar views (monthly view is selected by default). */ -void calendar_view_next(void) -{ - calendar_view++; - if (calendar_view == CAL_VIEWS) - calendar_view = 0; -} - -void calendar_view_prev(void) -{ - if (calendar_view == 0) - calendar_view = CAL_VIEWS; - calendar_view--; -} - -void calendar_set_view(int view) -{ - calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view; -} - -int calendar_get_view(void) -{ - return (int)calendar_view; -} - -/* Thread needed to update current date in calendar. */ -/* ARGSUSED0 */ -static void *calendar_date_thread(void *arg) -{ - time_t actual, tomorrow; - - for (;;) { - tomorrow = (time_t) (get_today() + DAYINSEC); - - while ((actual = time(NULL)) < tomorrow) - sleep(tomorrow - actual); - - calendar_set_current_date(); - calendar_update_panel(&win[CAL]); - } - - return NULL; -} - -/* Launch the calendar date thread. */ -void calendar_start_date_thread(void) -{ - pthread_create(&calendar_t_date, NULL, calendar_date_thread, NULL); -} - -/* Stop the calendar date thread. */ -void calendar_stop_date_thread(void) -{ - if (calendar_t_date) { - pthread_cancel(calendar_t_date); - pthread_join(calendar_t_date, NULL); - } -} - -/* Set static variable today to current date */ -void calendar_set_current_date(void) -{ - time_t timer; - struct tm tm; - - timer = time(NULL); - localtime_r(&timer, &tm); - - pthread_mutex_lock(&date_thread_mutex); - today.dd = tm.tm_mday; - today.mm = tm.tm_mon + 1; - today.yyyy = tm.tm_year + 1900; - pthread_mutex_unlock(&date_thread_mutex); -} - -/* Needed to display sunday or monday as the first day of week in calendar. */ -void calendar_set_first_day_of_week(enum wday first_day) -{ - switch (first_day) { - case SUNDAY: - week_begins_on_monday = 0; - break; - case MONDAY: - week_begins_on_monday = 1; - break; - default: - ERROR_MSG(_("ERROR setting first day of week")); - week_begins_on_monday = 0; - /* NOTREACHED */ - } -} - -/* Swap first day of week in calendar. */ -void calendar_change_first_day_of_week(void) -{ - week_begins_on_monday = !week_begins_on_monday; -} - -/* Return 1 if week begins on monday, 0 otherwise. */ -unsigned calendar_week_begins_on_monday(void) -{ - return week_begins_on_monday; -} - -/* Fill in the given variable with the current date. */ -void calendar_store_current_date(struct date *date) -{ - pthread_mutex_lock(&date_thread_mutex); - *date = today; - pthread_mutex_unlock(&date_thread_mutex); -} - -/* This is to start at the current date in calendar. */ -void calendar_init_slctd_day(void) -{ - calendar_store_current_date(&slctd_day); -} - -/* Return the selected day in calendar */ -struct date *calendar_get_slctd_day(void) -{ - return &slctd_day; -} - -/* Returned value represents the selected day in calendar (in seconds) */ -long calendar_get_slctd_day_sec(void) -{ - return date2sec(slctd_day, 0, 0); -} - -static int calendar_get_wday(struct date *date) -{ - struct tm t; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = date->dd; - t.tm_mon = date->mm - 1; - t.tm_year = date->yyyy - 1900; - - mktime(&t); - - return t.tm_wday; -} - -static unsigned months_to_days(unsigned month) -{ - return (month * 3057 - 3007) / 100; -} - -static long years_to_days(unsigned year) -{ - return year * 365L + year / 4 - year / 100 + year / 400; -} - -static long ymd_to_scalar(unsigned year, unsigned month, unsigned day) -{ - long scalar; - - scalar = day + months_to_days(month); - if (month > 2) - scalar -= ISLEAP(year) ? 1 : 2; - year--; - scalar += years_to_days(year); - - return scalar; -} - -/* - * Used to change date by adding a certain amount of days or weeks. - * Returns 0 on success, 1 otherwise. - */ -static int date_change(struct tm *date, int delta_month, int delta_day) -{ - struct tm t; - - t = *date; - t.tm_mon += delta_month; - t.tm_mday += delta_day; - - if (mktime(&t) == -1) - return 1; - else { - *date = t; - return 0; - } -} - -void calendar_monthly_view_cache_set_invalid(void) -{ - monthly_view_cache_valid = 0; -} - -/* Draw the monthly view inside calendar panel. */ -static void -draw_monthly_view(struct window *cwin, struct date *current_day, - unsigned sunday_first) -{ - const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); - struct date check_day; - int c_day, c_day_1, day_1_sav, numdays, j; - unsigned yr, mo; - int OFFX, SBAR_WIDTH, ofs_x, ofs_y; - int item_this_day = 0; - - mo = slctd_day.mm; - yr = slctd_day.yyyy; - - /* offset for centering calendar in window */ - SBAR_WIDTH = wins_sbar_width(); - OFFX = (SBAR_WIDTH - 27) / 2; - ofs_y = OFFY; - ofs_x = OFFX; - - /* checking the number of days in february */ - numdays = days[mo - 1]; - if (2 == mo && ISLEAP(yr)) - ++numdays; - - /* - * the first calendar day will be monday or sunday, depending on - * 'week_begins_on_monday' value - */ - c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L); - - /* Write the current month and year on top of the calendar */ - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, ofs_y, - (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2, - "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - ++ofs_y; - - /* print the days, with regards to the first day of the week */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - for (j = 0; j < WEEKINDAYS; j++) { - mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first])); - } - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - - day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; - - /* invalidate cache if a new month is selected */ - if (yr * YEARINMONTHS + mo != monthly_view_cache_month) { - monthly_view_cache_month = yr * YEARINMONTHS + mo; - monthly_view_cache_valid = 0; - } - - for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { - check_day.dd = c_day; - check_day.mm = slctd_day.mm; - check_day.yyyy = slctd_day.yyyy; - - /* check if the day contains an event or an appointment */ - if (monthly_view_cache_valid) { - item_this_day = monthly_view_cache[c_day - 1]; - } - else { - item_this_day = monthly_view_cache[c_day - 1] = - day_check_if_item(check_day); - } - - /* Go to next line, the week is over. */ - if (!c_day_1 && 1 != c_day) { - ofs_y++; - ofs_x = OFFX - day_1_sav - 4 * c_day; - } - - WINS_CALENDAR_LOCK; - if (c_day == current_day->dd - && current_day->mm == slctd_day.mm - && current_day->yyyy == slctd_day.yyyy - && current_day->dd != slctd_day.dd) { - /* This is today, so print it in yellow. */ - custom_apply_attr(cwin->p, ATTR_LOWEST); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_LOWEST); - } else if (c_day == slctd_day.dd) { - /* This is the selected day, print it according to user's theme. */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - } else if (item_this_day) { - custom_apply_attr(cwin->p, ATTR_LOW); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_LOW); - } else { - /* otherwise, print normal days in black */ - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - } - WINS_CALENDAR_UNLOCK; - } - - monthly_view_cache_valid = 1; -} - -static int weeknum(const struct tm *t, int firstweekday) -{ - int wday, wnum; - - wday = t->tm_wday; - if (firstweekday == MONDAY) { - if (wday == SUNDAY) - wday = 6; - else - wday--; - } - wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS); - if (wnum < 0) - wnum = 0; - - return wnum; -} - -/* - * Compute the week number according to ISO 8601. - */ -static int ISO8601weeknum(const struct tm *t) -{ - int wnum, jan1day; - - wnum = weeknum(t, MONDAY); - - jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS); - if (jan1day < 0) - jan1day += WEEKINDAYS; - - switch (jan1day) { - case MONDAY: - break; - case TUESDAY: - case WEDNESDAY: - case THURSDAY: - wnum++; - break; - case FRIDAY: - case SATURDAY: - case SUNDAY: - if (wnum == 0) { - /* Get week number of last week of last year. */ - struct tm dec31ly; /* 12/31 last year */ - - dec31ly = *t; - dec31ly.tm_year--; - dec31ly.tm_mon = 11; - dec31ly.tm_mday = 31; - dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1; - dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900); - wnum = ISO8601weeknum(&dec31ly); - } - break; - } - - if (t->tm_mon == 11) { - int wday, mday; - - wday = t->tm_wday; - mday = t->tm_mday; - if ((wday == MONDAY && (mday >= 29 && mday <= 31)) - || (wday == TUESDAY && (mday == 30 || mday == 31)) - || (wday == WEDNESDAY && mday == 31)) - wnum = 1; - } - - return wnum; -} - -/* Draw the weekly view inside calendar panel. */ -static void -draw_weekly_view(struct window *cwin, struct date *current_day, - unsigned sunday_first) -{ -#define DAYSLICESNO 6 - const int WCALWIDTH = 30; - const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); - struct tm t; - int OFFX, j, c_wday, days_to_remove, weeknum; - - OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1; - - /* Fill in a tm structure with the first day of the selected week. */ - c_wday = calendar_get_wday(&slctd_day); - if (sunday_first) - days_to_remove = c_wday; - else - days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = slctd_day.dd; - t.tm_mon = slctd_day.mm - 1; - t.tm_year = slctd_day.yyyy - 1900; - mktime(&t); - date_change(&t, 0, -days_to_remove); - - /* Print the week number. */ - weeknum = ISO8601weeknum(&t); - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, "(# %02d)", - weeknum); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - - /* Now draw calendar view. */ - for (j = 0; j < WEEKINDAYS; j++) { - struct date date; - unsigned attr, item_this_day; - int i, slices[DAYSLICESNO]; - - /* print the day names, with regards to the first day of the week */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, _(daynames[1 + j - sunday_first])); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - - /* Check if the day to be printed has an item or not. */ - date.dd = t.tm_mday; - date.mm = t.tm_mon + 1; - date.yyyy = t.tm_year + 1900; - item_this_day = day_check_if_item(date); - - /* Print the day numbers with appropriate decoration. */ - if (t.tm_mday == current_day->dd - && current_day->mm == slctd_day.mm - && current_day->yyyy == slctd_day.yyyy - && current_day->dd != slctd_day.dd) - attr = ATTR_LOWEST; /* today, but not selected */ - else if (t.tm_mday == slctd_day.dd) - attr = ATTR_HIGHEST; /* selected day */ - else if (item_this_day) - attr = ATTR_LOW; - else - attr = 0; - - WINS_CALENDAR_LOCK; - if (attr) - custom_apply_attr(cwin->p, attr); - mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday); - if (attr) - custom_remove_attr(cwin->p, attr); - WINS_CALENDAR_UNLOCK; - - /* Draw slices indicating appointment times. */ - memset(slices, 0, DAYSLICESNO * sizeof *slices); - if (day_chk_busy_slices(date, DAYSLICESNO, slices)) { - for (i = 0; i < DAYSLICESNO; i++) { - if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) { - WINS_CALENDAR_LOCK; - mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2); - WINS_CALENDAR_UNLOCK; - } - if (slices[i]) { - int highlight; - - highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0; - WINS_CALENDAR_LOCK; - if (highlight) - custom_apply_attr(cwin->p, attr); - wattron(cwin->p, A_REVERSE); - mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " "); - mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " "); - wattroff(cwin->p, A_REVERSE); - if (highlight) - custom_remove_attr(cwin->p, attr); - WINS_CALENDAR_UNLOCK; - } - } - } - - /* get next day */ - date_change(&t, 0, 1); - } - - /* Draw marks to indicate midday on the sides of the calendar. */ - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1); - mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, - OFFX + WCALWIDTH - 3, ACS_S9, 1); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - -#undef DAYSLICESNO -} - -/* Function used to display the calendar panel. */ -void calendar_update_panel(struct window *cwin) -{ - struct date current_day; - unsigned sunday_first; - - calendar_store_current_date(¤t_day); - - WINS_CALENDAR_LOCK; - erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, cwin->w - 2, - cwin->h - 2); - if (!conf.compact_panels) - mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); - WINS_CALENDAR_UNLOCK; - - sunday_first = calendar_week_begins_on_monday()? 0 : 1; - - draw_calendar[calendar_view] (cwin, ¤t_day, sunday_first); - - wnoutrefresh(cwin->p); -} - -/* Set the selected day in calendar to current day. */ -void calendar_goto_today(void) -{ - struct date today; - - calendar_store_current_date(&today); - slctd_day.dd = today.dd; - slctd_day.mm = today.mm; - slctd_day.yyyy = today.yyyy; -} - -/* - * Ask for a date to jump to, then check the correctness of that date - * and jump to it. - * If the entered date is empty, automatically jump to the current date. - * slctd_day is updated with the newly selected date. - */ -void calendar_change_day(int datefmt) -{ -#define LDAY 11 - char selected_day[LDAY] = ""; - char outstr[BUFSIZ]; - int dday, dmonth, dyear; - int wrong_day = 1; - const char *mesg_line1 = - _("The day you entered is not valid " - "(should be between 01/01/1902 and 12/31/2037)"); - const char *mesg_line2 = _("Press [ENTER] to continue"); - const char *request_date = _("Enter the day to go to [ENTER for today] : %s"); - - while (wrong_day) { - snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt)); - status_mesg(outstr, ""); - if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC) - return; - else { - if (strlen(selected_day) == 0) { - wrong_day = 0; - calendar_goto_today(); - } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday, - calendar_get_slctd_day())) { - wrong_day = 0; - /* go to chosen day */ - slctd_day.dd = dday; - slctd_day.mm = dmonth; - slctd_day.yyyy = dyear; - } - if (wrong_day) { - status_mesg(mesg_line1, mesg_line2); - wgetch(win[KEY].p); - } - } - } - - return; -} - -void calendar_move(enum move move, int count) -{ - int ret, days_to_remove, days_to_add; - struct tm t; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = slctd_day.dd; - t.tm_mon = slctd_day.mm - 1; - t.tm_year = slctd_day.yyyy - 1900; - - switch (move) { - case DAY_PREV: - ret = date_change(&t, 0, -count); - break; - case DAY_NEXT: - ret = date_change(&t, 0, count); - break; - case WEEK_PREV: - ret = date_change(&t, 0, -count * WEEKINDAYS); - break; - case WEEK_NEXT: - ret = date_change(&t, 0, count * WEEKINDAYS); - break; - case MONTH_PREV: - ret = date_change(&t, -count, 0); - break; - case MONTH_NEXT: - ret = date_change(&t, count, 0); - break; - case YEAR_PREV: - ret = date_change(&t, -count * YEARINMONTHS, 0); - break; - case YEAR_NEXT: - ret = date_change(&t, count * YEARINMONTHS, 0); - break; - case WEEK_START: - /* Normalize struct tm to get week day number. */ - mktime(&t); - if (calendar_week_begins_on_monday()) - days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1); - else - days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday); - days_to_remove += (count - 1) * WEEKINDAYS; - ret = date_change(&t, 0, -days_to_remove); - break; - case WEEK_END: - mktime(&t); - if (calendar_week_begins_on_monday()) - days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday); - else - days_to_add = ((t.tm_wday == 0) ? - WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday); - days_to_add += (count - 1) * WEEKINDAYS; - ret = date_change(&t, 0, days_to_add); - break; - default: - ret = 1; - /* NOTREACHED */ - } - - if (ret == 0) { - if (t.tm_year < 2) { - t.tm_mday = 1; - t.tm_mon = 0; - t.tm_year = 2; - } else if (t.tm_year > 137) { - t.tm_mday = 31; - t.tm_mon = 11; - t.tm_year = 137; - } - - slctd_day.dd = t.tm_mday; - slctd_day.mm = t.tm_mon + 1; - slctd_day.yyyy = t.tm_year + 1900; - } -} - -/* Returns the beginning of current year as a long. */ -long calendar_start_of_year(void) -{ - time_t timer; - struct tm tm; - - timer = time(NULL); - localtime_r(&timer, &tm); - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - timer = mktime(&tm); - - return (long)timer; -} - -long calendar_end_of_year(void) -{ - time_t timer; - struct tm tm; - - timer = time(NULL); - localtime_r(&timer, &tm); - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_year++; - timer = mktime(&tm); - - return (long)(timer - 1); -} - -/* - * The pom, potm, dotr, adj360 are used to compute the current - * phase of the moon. - * The code is based on the OpenBSD version of pom(6). - * Below is reported the copyright notice. - */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software posted to USENET. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * dtor -- - * convert degrees to radians - */ -static double dtor(double deg) -{ - return deg * M_PI / 180; -} - -/* - * adj360 -- - * adjust value so 0 <= deg <= 360 - */ -static void adj360(double *deg) -{ - for (;;) - if (*deg < 0.0) - *deg += 360.0; - else if (*deg > 360.0) - *deg -= 360.0; - else - break; -} - -/* - * potm -- - * return phase of the moon - */ -static double potm(double days) -{ - double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; - double A4, lprime, V, ldprime, D, Nm; - - N = 360.0 * days / 365.242191; /* sec 46 #3 */ - adj360(&N); - Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ - adj360(&Msol); - Ec = 360 / M_PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */ - LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ - adj360(&LambdaSol); - l = 13.1763966 * days + lzero; /* sec 65 #4 */ - adj360(&l); - Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */ - adj360(&Mm); - Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */ - adj360(&Nm); - Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */ - Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */ - A3 = 0.37 * sin(dtor(Msol)); - Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ - Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */ - A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */ - lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ - V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */ - ldprime = lprime + V; /* sec 65 #14 */ - D = ldprime - LambdaSol; /* sec 67 #2 */ - return 50.0 * (1 - cos(dtor(D))); /* sec 67 #3 */ -} - -/* - * Phase of the Moon. Calculates the current phase of the moon. - * Based on routines from `Practical Astronomy with Your Calculator', - * by Duffett-Smith. Comments give the section from the book that - * particular piece of code was adapted from. - * - * -- Keith E. Brandt VIII 1984 - * - * Updated to the Third Edition of Duffett-Smith's book, IX 1998 - * - */ -static double pom(time_t tmpt) -{ - struct tm *GMT; - double days; - int cnt; - - GMT = gmtime(&tmpt); - days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) + - (GMT->tm_sec / 3600.0)) / 24.0); - for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) - days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; - /* Selected time could be before EPOCH */ - for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt) - days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; - - return potm(days); -} - -/* - * Return a pictogram representing the current phase of the moon. - * Careful: date is the selected day in calendar at 00:00, so it represents - * the phase of the moon for previous day. - */ -const char *calendar_get_pom(time_t date) -{ - const char *pom_pict[MOON_PHASES] = { " ", "|) ", "(|)", "(| ", " | " }; - enum pom phase = NO_POM; - double pom_today, relative_pom, pom_yesterday, pom_tomorrow; - const double half = 50.0; - - pom_yesterday = pom(date); - pom_today = pom(date + DAYINSEC); - relative_pom = abs(pom_today - half); - pom_tomorrow = pom(date + 2 * DAYINSEC); - if (pom_today > pom_yesterday && pom_today > pom_tomorrow) - phase = FULL_MOON; - else if (pom_today < pom_yesterday && pom_today < pom_tomorrow) - phase = NEW_MOON; - else if (relative_pom < abs(pom_yesterday - half) - && relative_pom < abs(pom_tomorrow - half)) - phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER; - - return pom_pict[phase]; -} -- cgit v1.2.3-54-g00ecf