2a83b07b5f584d32ce71417b3fee1b3a6f333e73
[dockapps.git] / wmsun / wmsun.c
blob2a83b07b5f584d32ce71417b3fee1b3a6f333e73
1 /*
3 * wmSun (C) 1999 Mike Henderson (mghenderson@lanl.gov)
5 * - Shows Sun Rise/Set Times....
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA
26 * Things TODO:
27 * - clean up code!
28 * - support for 8-bit displays.
29 * - more detailed documentation.
30 * - eclipses?
31 * - add buttons to play will date and lat lon...
32 * Could be something like this;
33 * First click brings up buttons to change date.
34 * Second click brings up buttons to change lat/lon.
35 * Third goes back to display
36 * Set time delay to go back to display if user doesnt do it...
44 * Includes
46 #define _POSIX_C_SOURCE 1
47 #include <X11/X.h> /* for ButtonPress, ButtonRelease, etc */
48 #include <X11/Xlib.h> /* for XEvent, ConnectionNumber, etc */
49 #include <math.h> /* for cos, sin */
50 #include <stdio.h> /* for printf, NULL */
51 #include <stdlib.h> /* for atof, atoi, exit */
52 #include <string.h> /* for strcmp */
53 #include <sys/select.h> /* for select, FD_SET, FD_ZERO, etc */
54 #include <sys/time.h> /* for timeval */
55 #include <time.h> /* for tm, gmtime_r, localtime_r, etc */
56 #include "wmSun_mask.xbm" /* for wmSun_mask_bits, etc */
57 #include "wmSun_master.xpm" /* for wmSun_master */
58 #include <libdockapp/wmgeneral.h> /* for copyXPMArea, display, etc */
63 * Delay between refreshes (in microseconds)
65 #define DELAY 1000000L
66 #define WMSUN_VERSION "1.04"
68 #define DegPerRad 57.29577951308232087680
69 #define RadPerDeg 0.01745329251994329576
75 void ParseCMDLine(int argc, char *argv[]);
76 void pressEvent(XButtonEvent *xev);
77 void SunRise(int year, int month, int day, double LocalHour, double *UTRise,
78 double *UTSet);
80 int ToggleWindow = 0;
81 int nMAX = 1;
82 int Flag = 1;
83 int UseUserTimeDiff = 0;
84 int UseUserDate = 0;
85 long UserDate;
86 double Glat, Glon, SinGlat, CosGlat, TimeZone, UserTimeDiff;
87 int TwelveHour = 0;
90 int xDigit[11] = {8, 18, 27, 37, 46, 55, 64, 74, 83, 92, 102};
96 * main
98 int main(int argc, char *argv[]) {
104 struct tm *GMTTime, *LocalTime;
105 XEvent event;
106 int n;
107 int Year, Month;
108 int DayOfMonth;
109 long CurrentLocalTime, CurrentGMTTime, date;
110 double UT, val, LTRise, LTSet, LocalHour, hour24();
111 int H, M;
112 struct timeval timeout;
113 fd_set xfdset;
121 * Parse any command line arguments.
123 Glat = Glon = 0.0;
124 ParseCMDLine(argc, argv);
125 Glat *= RadPerDeg; SinGlat = sin( Glat ); CosGlat = cos( Glat );
129 openXwindow(argc, argv, wmSun_master, (char *)wmSun_mask_bits, wmSun_mask_width, wmSun_mask_height);
136 * Loop until we die
138 n = 32000;
139 while(1) {
142 if (Flag) {
143 n = 32000;
144 Flag = 0;
151 * The Moon Ephemeris calculations are somewhat costly (the Moon is one of the most
152 * difficult objects to compute position for). So only process every nMAXth cycle of this
153 * loop. We run outer loop it faster to catch expose events, button presses, etc...
156 if (n>nMAX){
157 struct tm result;
159 n = 0;
160 nMAX = 60;
163 CurrentGMTTime = time(CurrentTime);
164 GMTTime = gmtime_r(&CurrentGMTTime, &result);
165 DayOfMonth = GMTTime->tm_mday;
167 UT = GMTTime->tm_hour + GMTTime->tm_min/60.0 + GMTTime->tm_sec/3600.0;
168 Year = GMTTime->tm_year+1900;
169 Month = GMTTime->tm_mon+1;
172 CurrentLocalTime = CurrentGMTTime;
173 LocalTime = localtime_r(&CurrentLocalTime, &result);
176 Flag = 0;
178 if (UseUserDate){
179 date = UserDate;
180 Year = date/10000;
181 date -= Year*10000;
182 Month = date/100;
183 date -= Month*100;
184 DayOfMonth = date;
185 date = UserDate;
186 } else {
187 date = Year*10000 + Month*100 + DayOfMonth;
189 LocalHour = LocalTime->tm_hour + LocalTime->tm_min/60.0 + LocalTime->tm_sec/3600.0;
190 TimeZone = (UseUserTimeDiff) ? UserTimeDiff : UT - LocalHour;
193 * Clear Plotting area
195 copyXPMArea(65, 5, 54, 54, 5, 5);
200 * Compute Sun Rise/Set Times in Local Time
202 SunRise(Year, Month, DayOfMonth, LocalHour, &LTRise, &LTSet);
204 if (LTRise > 0.0){
205 val = LTRise;
206 H = (int)val; val = (val-H)*60.0;
207 if (TwelveHour) {
208 H = H % 12;
209 if (H == 0)
210 H = 12;
212 M = (int)val;
213 copyXPMArea(xDigit[H/10], 73, 7, 9, 17, 13);
214 copyXPMArea(xDigit[H%10], 73, 7, 9, 17+7, 13);
215 copyXPMArea(xDigit[10], 75, 3, 6, 17+15, 15);
216 copyXPMArea(xDigit[M/10], 73, 7, 9, 17+19, 13);
217 copyXPMArea(xDigit[M%10], 73, 7, 9, 17+26, 13);
218 } else {
219 copyXPMArea(10, 84, 28, 7, 19, 15);
223 if (LTSet > 0.0){
224 val = LTSet;
225 H = (int)val; val = (val-H)*60.0;
226 if (TwelveHour) {
227 H = H % 12;
228 if (H == 0)
229 H = 12;
231 M = (int)val;
232 copyXPMArea(xDigit[H/10], 73, 7, 9, 17, 40);
233 copyXPMArea(xDigit[H%10], 73, 7, 9, 17+7, 40);
234 copyXPMArea(xDigit[10], 75, 3, 6, 17+15, 42);
235 copyXPMArea(xDigit[M/10], 73, 7, 9, 17+19, 40);
236 copyXPMArea(xDigit[M%10], 73, 7, 9, 17+26, 40);
237 } else {
238 copyXPMArea(10, 84, 28, 7, 19, 40);
241 } else {
244 * Update the counter.
246 ++n;
253 * Add X display to file descriptor set for polling.
255 FD_ZERO(&xfdset);
256 FD_SET(ConnectionNumber(display), &xfdset);
263 * Process any pending X events.
265 while(XPending(display)){
266 XNextEvent(display, &event);
267 switch(event.type){
268 case Expose:
269 RedrawWindow();
270 break;
271 case ButtonPress:
272 pressEvent(&event.xbutton);
273 break;
274 case ButtonRelease:
275 break;
285 * Redraw and wait for next update
287 RedrawWindow();
288 timeout.tv_sec = DELAY / 1000000L;
289 timeout.tv_usec = DELAY % 1000000L;
290 select(ConnectionNumber(display) + 1, &xfdset, NULL, NULL, &timeout);
307 * ParseCMDLine()
309 void ParseCMDLine(int argc, char *argv[]) {
311 int i;
313 for (i = 1; i < argc; i++) {
315 if (!strcmp(argv[i], "-display")){
317 ++i;
319 } else if (!strcmp(argv[i], "-geometry")){
321 ++i;
323 } else if (!strcmp(argv[i], "-lat")){
325 Glat = atof(argv[++i]);
327 } else if (!strcmp(argv[i], "-lon")){
329 Glon = atof(argv[++i]);
331 } else if (!strcmp(argv[i], "-td")){
333 UseUserTimeDiff = 1;
334 UserTimeDiff = atof(argv[++i]);
336 } else if (!strcmp(argv[i], "-date")){
338 UseUserDate = 1;
339 UserDate = atoi(argv[++i]);
341 } else if (!strcmp(argv[i], "-12")){
343 TwelveHour = 1;
345 } else {
346 printf("\nwmSun version: %s\n", WMSUN_VERSION);
347 printf("\nusage: wmsun [-display <Display>] [-lat <Latitude>] [-lon <Longitude>] [-h]\n\n");
348 printf("\t-display <Display>\tUse alternate X display.\n");
349 printf("\t-geometry <Geometry>\tSet window geometry.\n");
350 printf("\t-lat <Latitude>\t\tObservers Latitude. Positive to the west.\n");
351 printf("\t-lon <Longitude>\tObservers Longitude.\n");
352 printf("\t-td <Delta Time>\tUser defined difference between UT an LT (hrs).\n");
353 printf("\t-12\t\t\tUse 12-hour clock.\n");
354 printf("\t-h\t\t\tDisplay help screen.\n\n");
355 exit(1);
363 * This routine handles button presses. Clicking in the window
364 * toggles the display.
367 void pressEvent(XButtonEvent *xev){
369 (void) xev;
370 ++ToggleWindow;
371 if (ToggleWindow > 4) ToggleWindow = 0;
372 Flag = 1;
374 return;