wmpager: use select(2) instead of usleep(3), increase sleep time to 0.5 sec
[dockapps.git] / wmitime / wmitime / wmitime.c
blobc280547ce6955a0020f45fee83073cc95e49a831
1 /*
3 wmitime.c -- internet time clock
5 by Dave Clark (clarkd@skynet.ca) (http://www.neotokyo.org/illusion)
7 This software is licensed through the GNU General Public Lisence.
9 */
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <time.h>
14 #include <string.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 #include <ctype.h>
18 #include <math.h>
20 #include <sys/wait.h>
21 #include <sys/stat.h>
22 #include <sys/param.h>
23 #include <sys/types.h>
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
27 #include <X11/Xlib.h>
28 #include <X11/xpm.h>
29 #include <X11/extensions/shape.h>
31 #include "../wmgeneral/wmgeneral.h"
32 #include "../wmgeneral/misc.h"
34 #ifdef fr_FR
35 #define fr
36 #endif
38 #ifdef fr
39 #include "french.h"
40 #else
41 #include "language.h"
42 #endif
44 #include "wmitime-master.xpm"
45 char wmitime_mask_bits[64*64];
46 int wmitime_mask_width = 64;
47 int wmitime_mask_height = 64;
49 #define WMITIME_VERSION "0.1"
51 #define CHAR_WIDTH 5
52 #define CHAR_HEIGHT 7
54 #define BCHAR_WIDTH 6
55 #define BCHAR_HEIGHT 9
57 #define MY_PI (3.14159)
59 extern char **environ;
61 char *ProgName;
63 char uconfig_file[256];
65 time_t curtime;
66 time_t prevtime;
68 int prevhourx=19;
69 int prevhoury=33;
70 int prevminx=19;
71 int prevminy=33;
73 static struct tm *clk;
75 int TwelveHour=0;
77 void usage(void);
78 void printversion(void);
79 void BlitString(char *name, int x, int y);
80 void BlitNum(int num, int x, int y);
81 void wmitime_routine(int, char **);
82 int PortWatch( short port );
83 int ReadConfigInt(FILE *fp, char *setting, int *value);
84 int ReadConfigString(FILE *fp, char *setting, char *value);
85 int Read_Config_File( char *filename );
86 void DrawInetTime(void);
87 void DrawStdTime(void);
88 void DrawDate(void);
89 void DrawInetWheel(void);
90 void DrawStdWheel(void);
91 void DrawLine(int x1, int y1, int x2, int y2, int sourcex, int sourcey);
93 int main(int argc, char *argv[]) {
95 int i;
97 uconfig_file[0] = 0;
99 /* Parse Command Line */
101 ProgName = argv[0];
102 if (strlen(ProgName) >= 5)
103 ProgName += (strlen(ProgName) - 5);
105 for (i=1; i<argc; i++) {
106 char *arg = argv[i];
108 if (*arg=='-') {
109 switch (arg[1]) {
110 case 'd' :
111 if (strcmp(arg+1, "display")) {
112 usage();
113 exit(1);
115 break;
116 case 'g' :
117 if (strcmp(arg+1, "geometry")) {
118 usage();
119 exit(1);
121 break;
122 case 'v' :
123 printversion();
124 exit(0);
125 break;
126 case 'c' :
127 if (argc > (i+1))
129 strcpy(uconfig_file, argv[i+1]);
130 i++;
132 break;
133 case '1' :
134 if (arg[2] == '2')
136 // Twelve-hour mode
137 TwelveHour = 1;
139 break;
140 default:
141 usage();
142 exit(0);
143 break;
148 wmitime_routine(argc, argv);
150 return 0;
153 /*******************************************************************************\
154 |* wmitime_routine *|
155 \*******************************************************************************/
157 void wmitime_routine(int argc, char **argv)
159 int i;
160 XEvent Event;
161 int but_stat = -1;
164 // char config_file[512];
166 createXBMfromXPM(wmitime_mask_bits, wmitime_master_xpm, wmitime_mask_width, wmitime_mask_height);
168 openXwindow(argc, argv, wmitime_master_xpm, wmitime_mask_bits, wmitime_mask_width, wmitime_mask_height);
170 AddMouseRegion(0, 5, 6, 58, 16);
172 // We don't need a config file (yet)...
174 #if 0
175 // Read config file
177 if (uconfig_file[0] != 0)
179 // user-specified config file
180 fprintf(stderr, "Using user-specified config file '%s'.\n", uconfig_file);
181 Read_Config_File(uconfig_file);
183 else
185 sprintf(config_file, "%s/.wmitimerc", getenv("HOME"));
187 if (!Read_Config_File(config_file))
189 // Fall back to /etc/wminetrc
190 sprintf(config_file, "/etc/wmitimerc");
192 Read_Config_File(config_file);
195 #endif
197 RedrawWindow();
199 prevtime = time(0) - 1;
201 while (1)
203 curtime = time(0);
205 if ( curtime > prevtime)
207 prevtime = curtime;
209 clk = localtime(&curtime);
211 // Update display
213 DrawInetTime();
215 DrawStdTime();
217 DrawInetWheel();
219 DrawDate();
221 DrawStdWheel();
223 RedrawWindow();
227 // X Events
228 while (XPending(display))
230 XNextEvent(display, &Event);
231 switch (Event.type)
233 case Expose:
234 RedrawWindow();
235 break;
236 case DestroyNotify:
237 XCloseDisplay(display);
238 exit(0);
239 break;
240 case ButtonPress:
241 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
243 but_stat = i;
244 break;
245 case ButtonRelease:
246 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
248 if (but_stat == i && but_stat >= 0)
250 switch (but_stat)
252 case 0 :
253 TwelveHour = (!TwelveHour);
254 prevtime--;
255 break;
256 case 1 :
257 break;
258 case 2:
259 break;
260 case 3:
261 break;
262 case 4:
263 break;
267 but_stat = -1;
268 // RedrawWindow();
269 break;
273 usleep(100000);
278 void DrawInetTime(void)
280 int iTime;
282 // Compute Inet Time
283 iTime=(clk->tm_hour*3600+clk->tm_min*60+clk->tm_sec);
284 iTime=iTime+((timezone-1)+3600);
285 if (clk->tm_isdst)
286 iTime-=3600;
287 iTime=(iTime*1000)/86400;
289 if (iTime >= 1000)
290 iTime-=1000;
291 else
292 if (iTime < 0)
293 iTime+=1000;
295 // Blit it
297 BlitNum(iTime, 38, 18);
301 void DrawStdTime(void)
303 int xoff=0, yoff=0;
304 int srcx=0, srcy=0;
305 int i,j;
306 char blitstr[32];
307 int len;
309 i = clk->tm_hour;
311 if (TwelveHour)
313 if (i > 12)
314 i-=12;
316 if (i==0)
317 i=12;
319 sprintf(blitstr, "%2i:%02i:%02i", i, clk->tm_min, clk->tm_sec);
321 else
323 sprintf(blitstr, "%02i:%02i:%02i", i, clk->tm_min, clk->tm_sec);
328 len = strlen(blitstr);
330 // Set starting co-ordinates...
331 xoff = 6;
332 yoff = 6;
334 // Blit it.
335 for( i=0; i<len; i++)
337 if (blitstr[i] == ':')
339 copyXPMArea(138, 23, 4, BCHAR_HEIGHT, xoff, yoff);
340 xoff+=4;
342 else if (isdigit(blitstr[i]))
344 j = blitstr[i] - '0';
345 srcx = 68;
346 srcy = 23;
348 while (j)
350 j--;
351 srcx += (BCHAR_WIDTH + 1);
354 copyXPMArea(srcx, srcy, BCHAR_WIDTH+1, BCHAR_HEIGHT, xoff, yoff);
355 xoff+=(BCHAR_WIDTH + 1);
357 else
359 copyXPMArea(66, 10, BCHAR_WIDTH+1, BCHAR_HEIGHT, xoff, yoff);
360 xoff+=(BCHAR_WIDTH + 1);
366 void DrawDate(void)
368 char BlitStr[20];
370 sprintf(BlitStr, "%s", daynames[clk->tm_wday]);
371 BlitString( BlitStr, 6, 50);
373 #ifdef fr
375 // French date model
376 sprintf(BlitStr, "%s", monthnames[clk->tm_mon]);
377 BlitString( BlitStr, 40, 50);
379 sprintf(BlitStr, "%02i", clk->tm_mday);
380 BlitString( BlitStr, 25, 50);
381 #else
383 sprintf(BlitStr, "%s", monthnames[clk->tm_mon]);
384 BlitString( BlitStr, 25, 50);
386 sprintf(BlitStr, "%02i", clk->tm_mday);
387 BlitString( BlitStr, 45, 50);
389 #endif
392 void DrawInetWheel(void)
394 int WheelPos=0;
395 int i;
396 int xoff=0, yoff=0;
397 int iTime;
399 // Calculate Wheel Position...
400 iTime=(clk->tm_hour*3600+clk->tm_min*60+clk->tm_sec);
401 iTime=iTime+((timezone-1)+3600);
402 if (clk->tm_isdst)
403 iTime-=3600;
404 iTime=(iTime*1000)/8640;
406 if (iTime >= 10000)
407 iTime-=10000;
408 else
409 if (iTime < 0)
410 iTime+=10000;
412 iTime %= 10;
414 WheelPos = floor( (iTime *8) / 10);
416 // Draw the Wheel...
417 i=WheelPos;
418 yoff=35;
419 xoff=67;
421 xoff+=19;
423 while(i)
425 xoff +=19;
426 i--;
429 copyXPMArea(xoff, yoff, 19, 19, 39, 29);
434 void DrawStdWheel(void)
436 //19x33 = center
437 //radius of 14
439 int sx, sy;
440 int cx, cy;
441 int dx, dy;
442 int hr;
443 double psi;
445 cx=19;
446 cy=33;
448 sx = 2;
449 sy = 97;
451 // Hour Hand...
453 DrawLine(cx, cy, prevhourx, prevhoury, 66, 9); // erase old line
455 hr = (clk->tm_hour % 12);
457 psi = hr * (M_PI / 6.0);
458 psi += clk->tm_min * (M_PI / 360);
460 dx = floor(sin(psi) * 22 * 0.5 + 0.5);
461 dy = floor(-cos(psi) * 16 * 0.5 + 0.5);
463 dx += cx;
464 dy += cy;
466 prevhourx=dx;
467 prevhoury=dy;
469 DrawLine(cx, cy, dx, dy, sx, sy);
471 // Minute Hand...
473 DrawLine(cx, cy, prevminx, prevminy, 66, 9); // erase old line
475 cx=19;
476 cy=33;
477 sx = 2;
478 sy = 96;
480 psi = clk->tm_min * (M_PI / 30.0);
481 psi += clk->tm_sec * (M_PI / 1800);
483 dx = floor(sin(psi) * 22 * 0.7 + 0.5);
484 dy = floor(-cos(psi) * 16 * 0.7 + 0.5);
486 dx += cx;
487 dy += cy;
489 prevminx = dx;
490 prevminy = dy;
493 DrawLine(cx, cy, dx, dy, sx, sy);
496 void DrawLine(int x1, int y1, int x2, int y2, int sourcex, int sourcey)
498 int x, y;
499 int deltax, deltay;
500 int xs, ys;
502 float xd=0, yd=0;
503 float xi, yi;
505 x = x1;
506 y = y1;
509 if ( (x2-x1) < 0)
510 xs = -1;
511 else
512 xs = 1;
514 if ( (y2-y1) < 0)
515 ys = -1;
516 else
517 ys = 1;
519 deltax = abs( x2 - x1 );
520 deltay = abs( y2 - y1 );
522 if (deltay !=0)
523 xi = (float) ((float)deltax / (float) deltay);
524 else
525 xi=0;
527 if (deltax !=0)
528 yi = (float) ((float)deltay / (float) deltax);
529 else
530 yi=0;
532 if ( deltax > deltay )
534 for (x=x1; x!= x2; x+= xs)
536 yd += yi;
537 y += (int) (yd * ys);
539 copyXPMArea(sourcex, sourcey, 1, 1, x, y);
541 yd -= (int) yd;
544 else
546 for (y=y1; y!= y2; y+= ys)
548 xd += xi;
549 x += (int) (xd * xs);
551 copyXPMArea(sourcex, sourcey, 1, 1, x, y);
553 xd -= (int) xd;
560 // Blits a string at given co-ordinates
561 void BlitString(char *name, int x, int y)
563 int i;
564 int c;
565 int k;
567 k = x;
568 for (i=0; name[i]; i++)
571 c = toupper(name[i]);
572 if (c >= 'A' && c <= 'Z')
573 { // its a letter
574 c -= 'A';
575 copyXPMArea(c * 6, 74, 6, 8, k, y);
576 k += 6;
578 else
579 { // its a number or symbol
580 c -= '0';
581 copyXPMArea(c * 6, 64, 6, 8, k, y);
582 k += 6;
588 void BlitNum(int num, int x, int y)
590 char buf[1024];
591 int newx=x;
593 sprintf(buf, "%03i", num);
595 BlitString(buf, newx, y);
599 // ReadConfigSetting
600 int ReadConfigString(FILE *fp, char *setting, char *value)
602 char str[1024];
603 char buf[1024];
604 int i;
605 int len;
606 int slen;
607 char *p=NULL;
610 if (!fp)
612 return 0;
615 sprintf(str, "%s=", setting);
616 slen = strlen(str);
618 fseek(fp, 0, SEEK_SET);
620 while ( !feof(fp) )
623 if (!fgets(buf, 512, fp))
624 break;
626 len = strlen(buf);
628 // strip linefeed
629 for (i=0; i!=len; i++)
631 if (buf[i] == '\n')
633 buf[i] = 0;
637 //printf("Scanning '%s'...\n", buf);
638 if ( strncmp(buf, str, strlen(str)) == 0)
640 // found our setting
642 for(i=0; i!=slen; i++)
644 if ( buf[i] == '=' )
646 p=buf+i+1;
647 strcpy(value, p);
648 return 1;
655 return 0;
658 int ReadConfigInt(FILE *fp, char *setting, int *value)
660 char buf[1024];
662 if (ReadConfigString(fp, setting, (char *) &buf))
664 *value = atoi(buf);
665 return 1;
668 return 0;
671 int Read_Config_File( char *filename )
673 FILE *fp;
675 fp = fopen(filename, "r");
676 if (fp)
679 fclose(fp);
680 return 1;
682 else
684 perror("Read_Config_File");
685 fprintf(stderr, "Unable to open %s, no settings read.\n", filename);
686 return 0;
697 /*******************************************************************************\
698 |* usage *|
699 \*******************************************************************************/
701 void usage(void)
703 fprintf(stderr, "\nWMiTIME - illusion <clarkd@skynet.ca> http://www.neotokyo.org/illusion\n\n");
704 fprintf(stderr, "usage:\n");
705 fprintf(stderr, " -12 12-hour mode\n");
706 fprintf(stderr, " -display <display name>\n");
707 fprintf(stderr, " -geometry +XPOS+YPOS initial window position\n");
708 // fprintf(stderr, " -c <filename> use specified config file\n");
709 fprintf(stderr, " -h this help screen\n");
710 fprintf(stderr, " -v print the version number\n");
711 fprintf(stderr, "\n");
714 /*******************************************************************************\
715 |* printversion *|
716 \*******************************************************************************/
718 void printversion(void)
720 fprintf(stderr, "wmitime v%s\n", WMITIME_VERSION);