2015-06-14 22:04:34 +00:00
|
|
|
/*
|
|
|
|
*
|
2015-06-14 22:04:56 +00:00
|
|
|
* wmSun (C) 1999 Mike Henderson (mghenderson@lanl.gov)
|
2015-06-14 22:04:43 +00:00
|
|
|
*
|
2015-06-14 22:04:34 +00:00
|
|
|
* - Shows Sun Rise/Set Times....
|
2015-06-14 22:04:43 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
2015-06-14 22:04:34 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program (see the file COPYING); if not, write to the
|
2015-06-14 22:04:43 +00:00
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
2015-06-14 22:04:34 +00:00
|
|
|
* Boston, MA 02111-1307, USA
|
|
|
|
*
|
|
|
|
* Things TODO:
|
2015-06-14 22:04:43 +00:00
|
|
|
* - clean up code!
|
2015-06-14 22:04:34 +00:00
|
|
|
* - support for 8-bit displays.
|
|
|
|
* - more detailed documentation.
|
|
|
|
* - eclipses?
|
|
|
|
* - add buttons to play will date and lat lon...
|
|
|
|
* Could be something like this;
|
|
|
|
* First click brings up buttons to change date.
|
|
|
|
* Second click brings up buttons to change lat/lon.
|
2015-06-14 22:04:43 +00:00
|
|
|
* Third goes back to display
|
2015-06-14 22:04:34 +00:00
|
|
|
* Set time delay to go back to display if user doesnt do it...
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
/*
|
|
|
|
* Includes
|
2015-06-14 22:04:34 +00:00
|
|
|
*/
|
2015-06-14 22:04:48 +00:00
|
|
|
#define _POSIX_C_SOURCE 1
|
2015-06-14 22:04:55 +00:00
|
|
|
#include <X11/X.h> /* for ButtonPress, ButtonRelease, etc */
|
|
|
|
#include <X11/Xlib.h> /* for XEvent, ConnectionNumber, etc */
|
|
|
|
#include <math.h> /* for cos, sin */
|
|
|
|
#include <stdio.h> /* for printf, NULL */
|
|
|
|
#include <stdlib.h> /* for atof, atoi, exit */
|
|
|
|
#include <string.h> /* for strcmp */
|
|
|
|
#include <sys/select.h> /* for select, FD_SET, FD_ZERO, etc */
|
|
|
|
#include <sys/time.h> /* for timeval */
|
|
|
|
#include <time.h> /* for tm, gmtime_r, localtime_r, etc */
|
|
|
|
#include "wmSun_mask.xbm" /* for wmSun_mask_bits, etc */
|
|
|
|
#include "wmSun_master.xpm" /* for wmSun_master */
|
2015-08-15 22:22:59 +00:00
|
|
|
#include <libdockapp/wmgeneral.h> /* for copyXPMArea, display, etc */
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
/*
|
|
|
|
* Delay between refreshes (in microseconds)
|
2015-06-14 22:04:34 +00:00
|
|
|
*/
|
2015-06-14 22:04:52 +00:00
|
|
|
#define DELAY 1000000L
|
2015-08-25 02:17:24 +00:00
|
|
|
#define WMSUN_VERSION "1.05"
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
#define DegPerRad 57.29577951308232087680
|
|
|
|
#define RadPerDeg 0.01745329251994329576
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ParseCMDLine(int argc, char *argv[]);
|
|
|
|
void pressEvent(XButtonEvent *xev);
|
2015-06-14 22:04:40 +00:00
|
|
|
void SunRise(int year, int month, int day, double LocalHour, double *UTRise,
|
2015-06-14 22:04:38 +00:00
|
|
|
double *UTSet);
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
int ToggleWindow = 0;
|
|
|
|
int nMAX = 1;
|
2015-06-14 22:04:43 +00:00
|
|
|
int Flag = 1;
|
2015-06-14 22:04:34 +00:00
|
|
|
int UseUserTimeDiff = 0;
|
|
|
|
int UseUserDate = 0;
|
|
|
|
long UserDate;
|
|
|
|
double Glat, Glon, SinGlat, CosGlat, TimeZone, UserTimeDiff;
|
2015-06-14 22:04:47 +00:00
|
|
|
int TwelveHour = 0;
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
int xDigit[11] = {8, 18, 27, 37, 46, 55, 64, 74, 83, 92, 102};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
/*
|
|
|
|
* main
|
2015-06-14 22:04:34 +00:00
|
|
|
*/
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct tm *GMTTime, *LocalTime;
|
|
|
|
XEvent event;
|
2015-06-14 22:04:39 +00:00
|
|
|
int n;
|
2015-06-14 22:04:53 +00:00
|
|
|
int Year, Month;
|
|
|
|
int DayOfMonth;
|
2015-06-14 22:04:34 +00:00
|
|
|
long CurrentLocalTime, CurrentGMTTime, date;
|
2015-06-14 22:04:39 +00:00
|
|
|
double UT, val, LTRise, LTSet, LocalHour, hour24();
|
|
|
|
int H, M;
|
2015-06-14 22:04:52 +00:00
|
|
|
struct timeval timeout;
|
|
|
|
fd_set xfdset;
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
|
2015-06-14 22:04:34 +00:00
|
|
|
/*
|
|
|
|
* Parse any command line arguments.
|
|
|
|
*/
|
|
|
|
Glat = Glon = 0.0;
|
|
|
|
ParseCMDLine(argc, argv);
|
|
|
|
Glat *= RadPerDeg; SinGlat = sin( Glat ); CosGlat = cos( Glat );
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
|
|
|
|
|
2015-06-14 22:04:42 +00:00
|
|
|
openXwindow(argc, argv, wmSun_master, (char *)wmSun_mask_bits, wmSun_mask_width, wmSun_mask_height);
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
|
2015-06-14 22:04:34 +00:00
|
|
|
/*
|
|
|
|
* Loop until we die
|
|
|
|
*/
|
|
|
|
n = 32000;
|
|
|
|
while(1) {
|
|
|
|
|
|
|
|
|
|
|
|
if (Flag) {
|
|
|
|
n = 32000;
|
|
|
|
Flag = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The Moon Ephemeris calculations are somewhat costly (the Moon is one of the most
|
|
|
|
* difficult objects to compute position for). So only process every nMAXth cycle of this
|
|
|
|
* loop. We run outer loop it faster to catch expose events, button presses, etc...
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
if (n>nMAX){
|
2015-06-14 22:04:48 +00:00
|
|
|
struct tm result;
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
n = 0;
|
2015-06-14 22:04:53 +00:00
|
|
|
nMAX = 60;
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
2015-06-14 22:04:48 +00:00
|
|
|
CurrentGMTTime = time(CurrentTime);
|
|
|
|
GMTTime = gmtime_r(&CurrentGMTTime, &result);
|
2015-06-14 22:04:34 +00:00
|
|
|
DayOfMonth = GMTTime->tm_mday;
|
|
|
|
|
|
|
|
UT = GMTTime->tm_hour + GMTTime->tm_min/60.0 + GMTTime->tm_sec/3600.0;
|
|
|
|
Year = GMTTime->tm_year+1900;
|
|
|
|
Month = GMTTime->tm_mon+1;
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:48 +00:00
|
|
|
CurrentLocalTime = CurrentGMTTime;
|
|
|
|
LocalTime = localtime_r(&CurrentLocalTime, &result);
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
Flag = 0;
|
|
|
|
|
|
|
|
if (UseUserDate){
|
|
|
|
date = UserDate;
|
|
|
|
Year = date/10000;
|
|
|
|
date -= Year*10000;
|
|
|
|
Month = date/100;
|
|
|
|
date -= Month*100;
|
|
|
|
DayOfMonth = date;
|
|
|
|
date = UserDate;
|
|
|
|
} else {
|
|
|
|
date = Year*10000 + Month*100 + DayOfMonth;
|
|
|
|
}
|
|
|
|
LocalHour = LocalTime->tm_hour + LocalTime->tm_min/60.0 + LocalTime->tm_sec/3600.0;
|
|
|
|
TimeZone = (UseUserTimeDiff) ? UserTimeDiff : UT - LocalHour;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clear Plotting area
|
|
|
|
*/
|
|
|
|
copyXPMArea(65, 5, 54, 54, 5, 5);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute Sun Rise/Set Times in Local Time
|
|
|
|
*/
|
|
|
|
SunRise(Year, Month, DayOfMonth, LocalHour, <Rise, <Set);
|
|
|
|
|
|
|
|
if (LTRise > 0.0){
|
|
|
|
val = LTRise;
|
|
|
|
H = (int)val; val = (val-H)*60.0;
|
2015-06-14 22:04:47 +00:00
|
|
|
if (TwelveHour) {
|
|
|
|
H = H % 12;
|
|
|
|
if (H == 0)
|
|
|
|
H = 12;
|
|
|
|
}
|
2015-06-14 22:04:34 +00:00
|
|
|
M = (int)val;
|
|
|
|
copyXPMArea(xDigit[H/10], 73, 7, 9, 17, 13);
|
|
|
|
copyXPMArea(xDigit[H%10], 73, 7, 9, 17+7, 13);
|
|
|
|
copyXPMArea(xDigit[10], 75, 3, 6, 17+15, 15);
|
|
|
|
copyXPMArea(xDigit[M/10], 73, 7, 9, 17+19, 13);
|
|
|
|
copyXPMArea(xDigit[M%10], 73, 7, 9, 17+26, 13);
|
|
|
|
} else {
|
|
|
|
copyXPMArea(10, 84, 28, 7, 19, 15);
|
|
|
|
}
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
|
2015-06-14 22:04:34 +00:00
|
|
|
if (LTSet > 0.0){
|
|
|
|
val = LTSet;
|
|
|
|
H = (int)val; val = (val-H)*60.0;
|
2015-06-14 22:04:47 +00:00
|
|
|
if (TwelveHour) {
|
|
|
|
H = H % 12;
|
|
|
|
if (H == 0)
|
|
|
|
H = 12;
|
|
|
|
}
|
2015-06-14 22:04:34 +00:00
|
|
|
M = (int)val;
|
|
|
|
copyXPMArea(xDigit[H/10], 73, 7, 9, 17, 40);
|
|
|
|
copyXPMArea(xDigit[H%10], 73, 7, 9, 17+7, 40);
|
|
|
|
copyXPMArea(xDigit[10], 75, 3, 6, 17+15, 42);
|
|
|
|
copyXPMArea(xDigit[M/10], 73, 7, 9, 17+19, 40);
|
|
|
|
copyXPMArea(xDigit[M%10], 73, 7, 9, 17+26, 40);
|
|
|
|
} else {
|
|
|
|
copyXPMArea(10, 84, 28, 7, 19, 40);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/*
|
2015-06-14 22:04:43 +00:00
|
|
|
* Update the counter.
|
2015-06-14 22:04:34 +00:00
|
|
|
*/
|
|
|
|
++n;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:52 +00:00
|
|
|
/*
|
|
|
|
* Add X display to file descriptor set for polling.
|
|
|
|
*/
|
|
|
|
FD_ZERO(&xfdset);
|
|
|
|
FD_SET(ConnectionNumber(display), &xfdset);
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
/*
|
2015-06-14 22:04:34 +00:00
|
|
|
* Process any pending X events.
|
|
|
|
*/
|
|
|
|
while(XPending(display)){
|
|
|
|
XNextEvent(display, &event);
|
|
|
|
switch(event.type){
|
|
|
|
case Expose:
|
|
|
|
RedrawWindow();
|
|
|
|
break;
|
|
|
|
case ButtonPress:
|
|
|
|
pressEvent(&event.xbutton);
|
|
|
|
break;
|
|
|
|
case ButtonRelease:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Redraw and wait for next update
|
2015-06-14 22:04:34 +00:00
|
|
|
*/
|
|
|
|
RedrawWindow();
|
2015-06-14 22:04:52 +00:00
|
|
|
timeout.tv_sec = DELAY / 1000000L;
|
|
|
|
timeout.tv_usec = DELAY % 1000000L;
|
|
|
|
select(ConnectionNumber(display) + 1, &xfdset, NULL, NULL, &timeout);
|
2015-06-14 22:04:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-14 22:04:43 +00:00
|
|
|
/*
|
|
|
|
* ParseCMDLine()
|
2015-06-14 22:04:34 +00:00
|
|
|
*/
|
|
|
|
void ParseCMDLine(int argc, char *argv[]) {
|
|
|
|
|
|
|
|
int i;
|
2015-06-14 22:04:43 +00:00
|
|
|
|
2015-06-14 22:04:34 +00:00
|
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
|
|
|
|
if (!strcmp(argv[i], "-display")){
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
2015-06-14 22:04:44 +00:00
|
|
|
} else if (!strcmp(argv[i], "-geometry")){
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
2015-06-14 22:04:34 +00:00
|
|
|
} else if (!strcmp(argv[i], "-lat")){
|
|
|
|
|
|
|
|
Glat = atof(argv[++i]);
|
|
|
|
|
|
|
|
} else if (!strcmp(argv[i], "-lon")){
|
|
|
|
|
|
|
|
Glon = atof(argv[++i]);
|
|
|
|
|
|
|
|
} else if (!strcmp(argv[i], "-td")){
|
|
|
|
|
|
|
|
UseUserTimeDiff = 1;
|
|
|
|
UserTimeDiff = atof(argv[++i]);
|
|
|
|
|
|
|
|
} else if (!strcmp(argv[i], "-date")){
|
|
|
|
|
|
|
|
UseUserDate = 1;
|
|
|
|
UserDate = atoi(argv[++i]);
|
|
|
|
|
2015-06-14 22:04:47 +00:00
|
|
|
} else if (!strcmp(argv[i], "-12")){
|
|
|
|
|
|
|
|
TwelveHour = 1;
|
|
|
|
|
2015-06-14 22:04:34 +00:00
|
|
|
} else {
|
|
|
|
printf("\nwmSun version: %s\n", WMSUN_VERSION);
|
2015-06-14 22:04:49 +00:00
|
|
|
printf("\nusage: wmsun [-display <Display>] [-lat <Latitude>] [-lon <Longitude>] [-h]\n\n");
|
2015-06-14 22:04:34 +00:00
|
|
|
printf("\t-display <Display>\tUse alternate X display.\n");
|
2015-06-14 22:04:44 +00:00
|
|
|
printf("\t-geometry <Geometry>\tSet window geometry.\n");
|
2015-06-14 22:04:34 +00:00
|
|
|
printf("\t-lat <Latitude>\t\tObservers Latitude. Positive to the west.\n");
|
|
|
|
printf("\t-lon <Longitude>\tObservers Longitude.\n");
|
2015-06-14 22:04:44 +00:00
|
|
|
printf("\t-td <Delta Time>\tUser defined difference between UT an LT (hrs).\n");
|
2015-06-14 22:04:47 +00:00
|
|
|
printf("\t-12\t\t\tUse 12-hour clock.\n");
|
2015-06-14 22:04:34 +00:00
|
|
|
printf("\t-h\t\t\tDisplay help screen.\n\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This routine handles button presses. Clicking in the window
|
|
|
|
* toggles the display.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void pressEvent(XButtonEvent *xev){
|
|
|
|
|
2015-06-14 22:04:41 +00:00
|
|
|
(void) xev;
|
2015-06-14 22:04:34 +00:00
|
|
|
++ToggleWindow;
|
|
|
|
if (ToggleWindow > 4) ToggleWindow = 0;
|
|
|
|
Flag = 1;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|