958 lines
26 KiB
C
958 lines
26 KiB
C
/*****************************************************************************/
|
|
/* */
|
|
/* wmtz.c */
|
|
/* Shows local time in different timezones + JD + Sidereal time + */
|
|
/* internet time + local date and time. */
|
|
/* */
|
|
/* Jan Lindblom <99jl@home.se> (http://www.geocities.com/~jl1n/) */
|
|
/* */
|
|
/* wmtz.c was derived from: */
|
|
/* */
|
|
/* wminet.c */
|
|
/* */
|
|
/* Multi-function system monitor */
|
|
/* Dave Clark (clarkd@skynet.ca) (http://www.neotokyo.org/illusion) */
|
|
/* Martijn Pieterse (pieterse@xs4all.nl) (http://windowmaker.mezaway.org) */
|
|
/* and Antoine Nulle (warp@xs4all.nl) (http://windowmaker.mezaway.org) */
|
|
/* */
|
|
/* This software is licensed through the GNU General Public Licence. */
|
|
/* Read the COPYING file for details. */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <stdarg.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/xpm.h>
|
|
#include <X11/extensions/shape.h>
|
|
|
|
#include "../wmgeneral/wmgeneral.h"
|
|
#include "../wmgeneral/misc.h"
|
|
#include "wmtz.xpm"
|
|
#include "wmtz_mono.xpm"
|
|
|
|
|
|
/*
|
|
* Defines
|
|
*/
|
|
#define WMTZ_VERSION "0.7"
|
|
#define CHAR_WIDTH 6
|
|
#define STRSIZE 10
|
|
#define LMST 1
|
|
#define GMST 0
|
|
#define ABOUT "xmessage -center -buttons \"Close\" \"WMTZ - Window Maker Time Zone dockapp v0.7
|
|
http://www.geocities.com/jl1n/wmtz/wmtz.html\""
|
|
|
|
|
|
/*
|
|
* Typedefs
|
|
*/
|
|
typedef struct
|
|
{
|
|
char label[10]; /* Time zone designation */
|
|
int diff; /* Time zone diff. from UT in hours */
|
|
double epoch; /* Epoch (for JD) */
|
|
char tz[256]; /* TZ environment variable string */
|
|
} timezone_t; /* ...numbers of days to subtract from JD */
|
|
|
|
|
|
/*
|
|
* Global variables
|
|
*/
|
|
timezone_t zone[6];
|
|
double longitude = 0.0;
|
|
double latitude = 0.0;
|
|
static struct tm *clk;
|
|
char *pname;
|
|
char *uconfig_file;
|
|
char *config_file;
|
|
char *defedit;
|
|
char *month[12];
|
|
char *week_day[7];
|
|
char wmtz_mask_bits[64*64];
|
|
int wmtz_mask_width = 64;
|
|
int wmtz_mask_height = 64;
|
|
int mono = 0;
|
|
extern char *tzname[2];
|
|
static char originalTZ[64];
|
|
|
|
/*
|
|
* Function declarations
|
|
*/
|
|
void usage(void);
|
|
void printversion(void);
|
|
void BlitString(char *name, int x, int y);
|
|
void wmtz_routine(int, char **);
|
|
int ReadConfigInt(FILE *fp, char *setting, int *value);
|
|
int ReadConfigString(FILE *fp, char *setting, char *value);
|
|
int Read_Config_File(char *filename);
|
|
void range(double *val, double ran);
|
|
void siderealTime(double jde, int *result, int mode);
|
|
double julianDay(int year, int month, double day, double hour,
|
|
double minute, double second, int julian);
|
|
int calendarDate(double jd, int *year, int *month, double *day);
|
|
int handleJD(void);
|
|
void errH(int printErrno, int exitCode, const char *msg, ...);
|
|
void handleTheMenu(int but_stat);
|
|
double jdn(time_t curtime);
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* main *|
|
|
\*****************************************************************************/
|
|
int main(int argc, char *argv[]) {
|
|
|
|
int i;
|
|
char *envbuf;
|
|
|
|
/* Store away the executable name for error messages */
|
|
if ( (pname = strrchr( argv[0], '/' )) == NULL )
|
|
pname = argv[0];
|
|
else
|
|
pname++;
|
|
|
|
/* Store away the TZ environment variable, if set */
|
|
if ( (envbuf = getenv("TZ")) != NULL )
|
|
{
|
|
//Write TZ=envbuf into originalTZ
|
|
(void) sprintf(originalTZ, "TZ=%s", envbuf);
|
|
}
|
|
else
|
|
{
|
|
// Set originalTZ to TZ erase TZ env.
|
|
(void) sprintf(originalTZ, "TZ");
|
|
}
|
|
|
|
/* Parse Command Line */
|
|
for (i=1; i<argc; i++) {
|
|
char *arg = argv[i];
|
|
|
|
if (*arg=='-') {
|
|
switch (arg[1]) {
|
|
case 'd' :
|
|
if (strcmp(arg+1, "display")) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
break;
|
|
case 'g' :
|
|
if (strcmp(arg+1, "geometry")) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
break;
|
|
case 'j' :
|
|
if (strcmp(arg+1, "jd")) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
handleJD();
|
|
exit(0);
|
|
break;
|
|
case 'm' :
|
|
mono = 1;
|
|
break;
|
|
case 'v' :
|
|
printversion();
|
|
exit(0);
|
|
break;
|
|
case 'c' :
|
|
if (argc > (i+1))
|
|
{
|
|
uconfig_file = strdup(argv[i+1]);
|
|
if (uconfig_file == NULL)
|
|
errH(1, 1, "strdup");
|
|
i++;
|
|
}
|
|
break;
|
|
case 'e' :
|
|
if (argc > (i+1))
|
|
{
|
|
defedit = strdup(argv[i+1]);
|
|
if (defedit == NULL)
|
|
errH(1, 1, "strdup");
|
|
i++;
|
|
}
|
|
break;
|
|
default:
|
|
usage();
|
|
exit(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
month[0] = "JAN"; month[1] = "FEB"; month[2] = "MAR";
|
|
month[3] = "APR"; month[4] = "MAY"; month[5] = "JUN";
|
|
month[6] = "JUL"; month[7] = "AUG"; month[8] = "SEP";
|
|
month[9] = "OUT"; month[10] = "NOV"; month[11] = "DEC";
|
|
|
|
week_day[0] = "SUNDAY ";
|
|
week_day[1] = "MONDAY ";
|
|
week_day[2] = "TUESDAY ";
|
|
week_day[3] = "WEDNESDAY";
|
|
week_day[4] = "THURSDAY ";
|
|
week_day[5] = "FRIDAY ";
|
|
week_day[6] = "SATURDAY ";
|
|
|
|
wmtz_routine(argc, argv);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* wmtz_routine - Creates the wmtz window. *|
|
|
\*****************************************************************************/
|
|
void wmtz_routine(int argc, char **argv)
|
|
{
|
|
int j = 0,k = 0, hour = 0, i = 0;
|
|
int sid[2], clicked = 0, but_stat = -1;
|
|
double jd = 0;
|
|
float swatch_beats;
|
|
time_t curtime;
|
|
time_t prevtime;
|
|
char *home;
|
|
char buf[64];
|
|
char blitstr[STRSIZE];
|
|
XEvent Event;
|
|
|
|
if (mono)
|
|
{
|
|
fprintf(stderr, "Starting monochrome version.\n");
|
|
createXBMfromXPM(wmtz_mask_bits, wmtz_mono_xpm,
|
|
wmtz_mask_width, wmtz_mask_height);
|
|
|
|
openXwindow(argc, argv, wmtz_mono_xpm, wmtz_mask_bits,
|
|
wmtz_mask_width, wmtz_mask_height);
|
|
}
|
|
else
|
|
{
|
|
createXBMfromXPM(wmtz_mask_bits, wmtz_master_xpm,
|
|
wmtz_mask_width, wmtz_mask_height);
|
|
|
|
openXwindow(argc, argv, wmtz_master_xpm, wmtz_mask_bits,
|
|
wmtz_mask_width, wmtz_mask_height);
|
|
}
|
|
|
|
memset(&zone, 0, sizeof(zone));
|
|
|
|
AddMouseRegion(0, 5, 6, 58, 16);
|
|
AddMouseRegion(1, 5, 16, 58, 26);
|
|
AddMouseRegion(2, 5, 26, 58, 36);
|
|
AddMouseRegion(3, 5, 36, 58, 46);
|
|
AddMouseRegion(4, 5, 46, 58, 56);
|
|
|
|
/* Read config file */
|
|
if (uconfig_file != NULL)
|
|
{
|
|
/* user-specified config file */
|
|
fprintf(stderr, "Using user-specified config file '%s'.\n",
|
|
uconfig_file);
|
|
config_file = strdup(uconfig_file);
|
|
free(uconfig_file);
|
|
Read_Config_File(config_file);
|
|
}
|
|
else
|
|
{
|
|
home = getenv("HOME");
|
|
config_file = malloc( strlen(home) + 9 );
|
|
if (config_file == NULL)
|
|
errH(1, 1, "malloc");
|
|
|
|
sprintf(config_file, "%s/.wmtzrc", home);
|
|
|
|
if (!Read_Config_File(config_file))
|
|
{
|
|
/* Fall back to /etc/wmtzrc */
|
|
free(config_file);
|
|
config_file = malloc( 12 );
|
|
if (config_file == NULL)
|
|
errH(1, 1, "malloc");
|
|
|
|
sprintf(config_file, "/etc/wmtzrc");
|
|
|
|
fprintf(stderr, "Using /etc/wmtzrc as config file.\n");
|
|
|
|
Read_Config_File(config_file);
|
|
}
|
|
}
|
|
|
|
RedrawWindow();
|
|
prevtime = time(0) - 1;
|
|
|
|
while (1)
|
|
{
|
|
waitpid(0, NULL, WNOHANG);
|
|
|
|
/* If wmtz have been mouse-clicked, show menu */
|
|
if ( clicked )
|
|
{
|
|
BlitString("MENU: ", 5, (11*(0)) + 5);
|
|
BlitString(" WMTZ ", 5, (11*(1)) + 5);
|
|
BlitString(" CONFIG ", 5, (11*(2)) + 5);
|
|
BlitString(" RESTART ", 5, (11*(3)) + 5);
|
|
BlitString(" QUIT ", 5, (11*(4)) + 5);
|
|
}
|
|
else if ( (curtime = time(0)) > prevtime)
|
|
{
|
|
prevtime = curtime;
|
|
|
|
/* Update the display */
|
|
for (j=1; j<6; j++)
|
|
{
|
|
/* Display empty line */
|
|
if (strncmp( zone[j].label, "xxx", 3) == 0 )
|
|
{
|
|
BlitString(" ", 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display local day/mon/year */
|
|
else if (strncmp( zone[j].label, "DATE", 4) == 0 )
|
|
{
|
|
clk = localtime(&curtime);
|
|
while(clk->tm_year>99) clk->tm_year-=100;
|
|
snprintf(blitstr, STRSIZE,"%s %02d.%02d",
|
|
month[clk->tm_mon],clk->tm_mday,clk->tm_year);
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display local weekday */
|
|
else if (strncmp( zone[j].label, "WDAY", 4) == 0 )
|
|
{
|
|
clk = localtime(&curtime);
|
|
snprintf(blitstr, STRSIZE,"%s",week_day[clk->tm_wday]);
|
|
BlitString(blitstr, 4, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display more precise internet time */
|
|
else if (strncmp( zone[j].label,"@", 1) == 0 )
|
|
{
|
|
/* Calculate Internet time */
|
|
swatch_beats = (float)(((curtime+3600)%86400)/86.4);
|
|
snprintf (blitstr, STRSIZE, "@:%7.3f", swatch_beats);
|
|
BlitString (blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display Julian Day Number */
|
|
else if (strncmp( zone[j].label, "JDN", 3) == 0 )
|
|
{
|
|
clk = gmtime(&curtime);
|
|
/* Calculate Julin Day Number */
|
|
jd = jdn(curtime) - zone[j].epoch;
|
|
snprintf(blitstr, STRSIZE, "%10f", jd );
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display Local Mean Sidereal Time */
|
|
else if (strncmp( zone[j].label, "LMST", 3) == 0 )
|
|
{
|
|
clk = gmtime(&curtime);
|
|
jd = jdn(curtime);
|
|
siderealTime( jd, sid, LMST );
|
|
snprintf(blitstr, STRSIZE, "%s%02i.%02i","LST:", sid[0], sid[1]);
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display Greenwich Mean Sidereal Time */
|
|
else if (strncmp( zone[j].label, "GMST", 3) == 0 )
|
|
{
|
|
clk = gmtime(&curtime);
|
|
jd = jdn(curtime);
|
|
siderealTime( jd, sid, GMST );
|
|
snprintf(blitstr, STRSIZE, "%s%02i.%02i","GST:", sid[0], sid[1]);
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display local time */
|
|
else if (strncmp( zone[j].label, "LOCAL", 5) == 0 )
|
|
{
|
|
clk = localtime(&curtime);
|
|
strncpy(buf, tzname[0], 3);
|
|
|
|
for (k=0; k<3; k++)
|
|
if (buf[k] == 0)
|
|
buf[k] = ' ';
|
|
|
|
buf[3] = ':';
|
|
buf[4] = 0;
|
|
hour = clk->tm_hour;
|
|
|
|
/* Print Label */
|
|
snprintf(blitstr, STRSIZE, "%s%02i.%02i",buf,hour,clk->tm_min);
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
|
|
/* Display time in specified time zone */
|
|
else if (strncmp( zone[j].label, "TZONE", 4) == 0 )
|
|
{
|
|
putenv(zone[j].tz);
|
|
tzset();
|
|
clk = localtime(&curtime);
|
|
|
|
strncpy(buf, tzname[0], 3);
|
|
|
|
for (k=0; k<3; k++)
|
|
if (buf[k] == 0)
|
|
buf[k] = ' ';
|
|
|
|
buf[3] = ':';
|
|
buf[4] = 0;
|
|
|
|
snprintf(blitstr, STRSIZE, "%s%02i.%02i", buf,
|
|
clk->tm_hour, clk->tm_min);
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
|
|
/* Reset TZ environment variable to old value */
|
|
putenv(originalTZ);
|
|
}
|
|
|
|
/* Display time in specified time zone without TZ env. var. */
|
|
else
|
|
{
|
|
clk = gmtime(&curtime);
|
|
strncpy(buf, zone[j].label, 3);
|
|
|
|
for (k=0; k<3; k++)
|
|
if (buf[k] == 0)
|
|
buf[k] = ' ';
|
|
|
|
buf[3] = ':';
|
|
buf[4] = 0;
|
|
|
|
hour = clk->tm_hour - zone[j].diff;
|
|
if (hour > 23 )
|
|
hour -= 24;
|
|
else if (hour < 0 )
|
|
hour += 24;
|
|
|
|
/* Print Label */
|
|
snprintf(blitstr, STRSIZE, "%s%02i.%02i",buf,hour,clk->tm_min);
|
|
BlitString(blitstr, 5, (11*(j-1)) + 5);
|
|
}
|
|
}
|
|
}
|
|
RedrawWindow();
|
|
|
|
/* X Events */
|
|
while (XPending(display))
|
|
{
|
|
XNextEvent(display, &Event);
|
|
switch (Event.type)
|
|
{
|
|
case Expose:
|
|
RedrawWindow();
|
|
break;
|
|
case DestroyNotify:
|
|
XCloseDisplay(display);
|
|
exit(0);
|
|
break;
|
|
case ButtonPress:
|
|
i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
|
|
but_stat = i;
|
|
break;
|
|
case ButtonRelease:
|
|
i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
|
|
if (but_stat == i && but_stat >= 0)
|
|
{
|
|
if ( clicked ) /* The menu is up */
|
|
{
|
|
handleTheMenu(but_stat);
|
|
clicked = 0;
|
|
}
|
|
else /* Show the menu instead of time */
|
|
{
|
|
clicked = 1;
|
|
}
|
|
}
|
|
but_stat = -1;
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
|
|
usleep(10000);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* handleTheMenu *|
|
|
\*****************************************************************************/
|
|
void handleTheMenu(int but_stat)
|
|
{
|
|
char *editor;
|
|
char *ed;
|
|
|
|
switch( but_stat )
|
|
{
|
|
case 0:
|
|
execCommand(ABOUT);
|
|
break;
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
/* Figure out what editor to use */
|
|
if ( defedit == NULL )
|
|
{
|
|
ed = getenv("XEDITOR");
|
|
if ( ed == NULL )
|
|
ed = "xedit";
|
|
}
|
|
else
|
|
{
|
|
ed = defedit;
|
|
}
|
|
editor = malloc( strlen(ed)+strlen(config_file)+2 );
|
|
if ( editor == NULL )
|
|
errH(1, 1, "malloc");
|
|
sprintf(editor, "%s %s", ed, config_file);
|
|
waitpid( execCommand(editor), NULL, 0 );
|
|
Read_Config_File(config_file);
|
|
free(editor);
|
|
break;
|
|
case 3:
|
|
Read_Config_File(config_file);
|
|
break;
|
|
case 4:
|
|
exit(0);
|
|
break;
|
|
default:
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* ReadConfigSetting *|
|
|
\*****************************************************************************/
|
|
int ReadConfigString(FILE *fp, char *setting, char *value)
|
|
{
|
|
char str[1024];
|
|
char buf[1024];
|
|
int i;
|
|
int len;
|
|
int slen;
|
|
char *p=NULL;
|
|
|
|
if (!fp)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
snprintf(str,1024, "%s=", setting);
|
|
slen = strlen(str);
|
|
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
while ( !feof(fp) )
|
|
{
|
|
|
|
if (!fgets(buf, 512, fp))
|
|
break;
|
|
|
|
len = strlen(buf);
|
|
|
|
/* strip linefeed */
|
|
for (i=0; i!=len; i++)
|
|
if (buf[i] == '\n')
|
|
buf[i] = 0;
|
|
|
|
/* printf("Scanning '%s'...\n", buf); */
|
|
if ( strncmp(buf, str, strlen(str)) == 0)
|
|
{
|
|
/* found our setting */
|
|
|
|
for(i=0; i!=slen; i++)
|
|
if ( buf[i] == '=' )
|
|
{
|
|
p=buf+i+1;
|
|
strcpy(value, p);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* ReadConfigInt *|
|
|
\*****************************************************************************/
|
|
int ReadConfigInt(FILE *fp, char *setting, int *value)
|
|
{
|
|
char buf[1024];
|
|
|
|
if (ReadConfigString(fp, setting, (char *) &buf))
|
|
{
|
|
*value = atoi(buf);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* ReadConfigDouble *|
|
|
\*****************************************************************************/
|
|
int ReadConfigDouble(FILE *fp, char *setting, double *value)
|
|
{
|
|
char buf[1024];
|
|
|
|
if (ReadConfigString(fp, setting, (char *) &buf))
|
|
{
|
|
*value = atof(buf);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* Read_Config_File *|
|
|
\*****************************************************************************/
|
|
int Read_Config_File( char *filename )
|
|
{
|
|
FILE *fp;
|
|
char temp[253];
|
|
|
|
fp = fopen(filename, "r");
|
|
if (fp)
|
|
{
|
|
ReadConfigString(fp, "time1", zone[1].label);
|
|
ReadConfigString(fp, "time2", zone[2].label);
|
|
ReadConfigString(fp, "time3", zone[3].label);
|
|
ReadConfigString(fp, "time4", zone[4].label);
|
|
ReadConfigString(fp, "time5", zone[5].label);
|
|
ReadConfigInt(fp, "utdiff1", &zone[1].diff);
|
|
ReadConfigInt(fp, "utdiff2", &zone[2].diff);
|
|
ReadConfigInt(fp, "utdiff3", &zone[3].diff);
|
|
ReadConfigInt(fp, "utdiff4", &zone[4].diff);
|
|
ReadConfigInt(fp, "utdiff5", &zone[5].diff);
|
|
ReadConfigDouble(fp, "utdiff1", &zone[1].epoch);
|
|
ReadConfigDouble(fp, "utdiff2", &zone[2].epoch);
|
|
ReadConfigDouble(fp, "utdiff3", &zone[3].epoch);
|
|
ReadConfigDouble(fp, "utdiff4", &zone[4].epoch);
|
|
ReadConfigDouble(fp, "utdiff5", &zone[5].epoch);
|
|
|
|
ReadConfigString(fp, "utdiff1", temp);
|
|
sprintf(zone[1].tz, "TZ=%s", temp);
|
|
ReadConfigString(fp, "utdiff2", temp);
|
|
sprintf(zone[2].tz, "TZ=%s", temp);
|
|
ReadConfigString(fp, "utdiff3", temp);
|
|
sprintf(zone[3].tz, "TZ=%s", temp);
|
|
ReadConfigString(fp, "utdiff4", temp);
|
|
sprintf(zone[4].tz, "TZ=%s", temp);
|
|
ReadConfigString(fp, "utdiff5", temp);
|
|
sprintf(zone[5].tz, "TZ=%s", temp);
|
|
|
|
ReadConfigDouble(fp, "longitude", &longitude);
|
|
/* ReadConfigDouble(fp, "latitude", &latitude); */
|
|
|
|
fclose(fp);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
errH(1, 0, "Unable to open %s", filename);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* BlitString - Blits a string at given coordinates. *|
|
|
\*****************************************************************************/
|
|
void BlitString(char *name, int x, int y)
|
|
{
|
|
int i;
|
|
int c;
|
|
int k;
|
|
|
|
k = x;
|
|
for (i=0; name[i]; i++)
|
|
{
|
|
|
|
c = toupper(name[i]);
|
|
if (c >= 'A' && c <= 'Z')
|
|
{ /* its a letter */
|
|
c -= 'A';
|
|
copyXPMArea(c * CHAR_WIDTH, 74, CHAR_WIDTH, 8, k, y);
|
|
k += CHAR_WIDTH;
|
|
}
|
|
else if ( c >= '0' && c <= ':')
|
|
{
|
|
c -= '0';
|
|
copyXPMArea(c * CHAR_WIDTH, 64, CHAR_WIDTH, 8, k, y);
|
|
k += CHAR_WIDTH;
|
|
}
|
|
else if (c == ';') /* used as a slim ':' */
|
|
{
|
|
copyXPMArea(60, 64, CHAR_WIDTH, 8, k, y);
|
|
k += 4;
|
|
}
|
|
else if (c=='.')
|
|
{
|
|
copyXPMArea(115, 64, 4, 8, k, y);
|
|
k += 4;
|
|
}
|
|
else if (c=='@')
|
|
{
|
|
copyXPMArea(108, 64, CHAR_WIDTH, 8, k, y);
|
|
k += CHAR_WIDTH;
|
|
}
|
|
else /* print a ' ' */
|
|
{
|
|
copyXPMArea(120, 64, CHAR_WIDTH, 8, k, y);
|
|
k += CHAR_WIDTH;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* usage *|
|
|
\*****************************************************************************/
|
|
void usage(void)
|
|
{
|
|
fprintf(stderr, "\nwmtz - shows local time around the world and more.\n");
|
|
fprintf(stderr, "See ~/.wmtzrc or /etc/wmtzrc for configuration.\n\n");
|
|
fprintf(stderr, "Usage:\n");
|
|
fprintf(stderr, " -display <display name>\n");
|
|
fprintf(stderr, " -e <editor> use specified editor\n");
|
|
fprintf(stderr, " -geometry +XPOS+YPOS initial window position\n");
|
|
fprintf(stderr, " -jd Julian<->Date conversion\n");
|
|
fprintf(stderr, " -c <filename> use specified config file\n");
|
|
fprintf(stderr, " -m start monochrome version\n");
|
|
fprintf(stderr, " -h this help screen\n");
|
|
fprintf(stderr, " -v print the version number\n");
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* printversion *|
|
|
\*****************************************************************************/
|
|
void printversion(void)
|
|
{
|
|
fprintf(stderr, "wmtz v%s\n", WMTZ_VERSION);
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* range - Put val in 0<->ran interval. *|
|
|
\*****************************************************************************/
|
|
void range (double *val, double ran)
|
|
{
|
|
*val -= ran*floor(*val/ran);
|
|
|
|
if (*val < 0)
|
|
*val += ran;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* jdn - converts a time_t to Julian Day *|
|
|
\*****************************************************************************/
|
|
double jdn(time_t curtime)
|
|
{
|
|
return (curtime/86400.0 + 2440587.5);
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|* siderealTime - Gives sidereal time from JD. *|
|
|
\*****************************************************************************/
|
|
void siderealTime( double jde, int *result, int mode )
|
|
{
|
|
double t, t2, t3, ts;
|
|
|
|
t = (jde - 2451545.0)/36525.0;
|
|
t2 = t*t;
|
|
t3 = t2*t;
|
|
|
|
/* Expression from "Astronomical Algorithms" by J. Meeus */
|
|
ts = 280.46061837 + 360.98564736629 * ( jde - 2451545.0 )
|
|
+ 0.000387933 * t2 - t3/38710000.0;
|
|
|
|
range( &ts, 360.0 );
|
|
ts /= 15.0;
|
|
|
|
/* If local time add one hour for every 15 degree in longitude */
|
|
if ( mode == LMST )
|
|
{
|
|
ts += longitude/15.0;
|
|
}
|
|
|
|
range( &ts, 24.0 );
|
|
result[0] = (int)ts;
|
|
result[1] = (int)(60 *(ts - result[0]));
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* julianDay - Gives JD from date. *|
|
|
\*****************************************************************************/
|
|
double julianDay( int year, int month, double day, double hour,
|
|
double minute, double second, int julian )
|
|
{
|
|
int a, b, c, d;
|
|
double jd;
|
|
|
|
day = day + hour/24.0 + minute/1440.0 + second/86400.0;
|
|
|
|
if ( month < 3 )
|
|
{
|
|
year -= 1;
|
|
month += 12;
|
|
}
|
|
|
|
/* If the date is a Julian calendar date, set julian to TRUE */
|
|
if ( julian )
|
|
{
|
|
b = 0;
|
|
}
|
|
else /* If Gregorian calendar date, julian should be FALSE */
|
|
{
|
|
a = year/100;
|
|
b = 2 - a + a/4;
|
|
}
|
|
c = 365.25 * (year + 4716);
|
|
d = 30.6001 * (month + 1);
|
|
jd = c + d + day + b - 1524.5;
|
|
|
|
return( jd );
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* calendarDate - Gives date from JD. Only Gregorian calendar dates. *|
|
|
\*****************************************************************************/
|
|
int calendarDate( double jd, int *year, int *month, double *day )
|
|
{
|
|
double a, b, frac, ij, alfa, beta, c, d, e, f;
|
|
|
|
if ( jd < 0 )
|
|
return 0;
|
|
|
|
jd += 0.5;
|
|
ij = floor(jd);
|
|
frac = jd - ij;
|
|
|
|
if ( ij < 2299161 )
|
|
{
|
|
a = ij;
|
|
}
|
|
else
|
|
{
|
|
alfa = floor((ij - 1867216.25)/36524.25);
|
|
beta = floor(alfa/4);
|
|
a = ij + 1 + alfa - beta;
|
|
}
|
|
|
|
b = a + 1524;
|
|
c = floor((b - 122.1)/365.25);
|
|
d = floor(365.25 * c);
|
|
e = floor((b - d)/30.6001);
|
|
f = floor(30.6001 * e);
|
|
|
|
*day = b - d - f + frac;
|
|
|
|
if (e < 14)
|
|
*month = e - 1;
|
|
else if (e == 14 || e == 15)
|
|
*month = e - 13;
|
|
else
|
|
return 0;
|
|
|
|
if (*month > 2)
|
|
*year = c - 4716;
|
|
else if (*month == 1 || *month == 2)
|
|
*year = c - 4715;
|
|
else
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
|* handleJD *|
|
|
\*****************************************************************************/
|
|
int handleJD( void )
|
|
{
|
|
int conv, y, m, d, h, min, sec;
|
|
double day, jd;
|
|
|
|
printf(" 1 : Date to JD.\n 2 : JD to date.\n");
|
|
printf("Choose conversion (1 or 2): ");
|
|
scanf("%d", &conv);
|
|
|
|
if (conv == 1 )
|
|
{
|
|
printf("Enter UT date with time (YYYY,MM,DD,hh:mm:ss): ");
|
|
scanf("%d,%d,%d,%d:%d:%d", &y, &m, &d, &h, &min, &sec);
|
|
printf("\nJulian Day: %f\n", julianDay( y, m, d, h, min, sec, 0 ) );
|
|
}
|
|
else if (conv == 2)
|
|
{
|
|
printf("Enter Julian Day Number: ");
|
|
scanf("%lf", &jd );
|
|
if ( !calendarDate( jd, &y, &m, &day ) )
|
|
{
|
|
printf("Conversion error! Negative JD not allowed.\n");
|
|
return 0;
|
|
}
|
|
|
|
printf("\nGregorian date: %d-%2.2d-%2.4f\n", y, m, day);
|
|
}
|
|
else
|
|
{
|
|
printf("Invalid choice! Try again, please...\n");
|
|
handleJD();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|* errH *|
|
|
\*****************************************************************************/
|
|
void errH(int printErrno, int exitCode, const char *msg, ...)
|
|
{
|
|
int error = errno;
|
|
va_list arg;
|
|
char buf[2048];
|
|
|
|
/* Put the name of the program first */
|
|
buf[0] = 0;
|
|
strcat(buf, pname);
|
|
strcat(buf, ": ");
|
|
|
|
va_start(arg, msg);
|
|
vsprintf(buf+strlen(buf), msg, arg);
|
|
if (printErrno)
|
|
sprintf(buf+strlen(buf), ": %s", strerror(error));
|
|
strcat(buf, "\n");
|
|
fflush(stdout);
|
|
fputs(buf, stderr);
|
|
fflush(NULL);
|
|
va_end(arg);
|
|
|
|
if ( exitCode )
|
|
exit(exitCode);
|
|
|
|
return;
|
|
}
|