Make AddMouseRegion's index unsigned
[dockapps.git] / wmitime / wmitime.c
blob3f68669334a66d977194476304d863850b10ab3e
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>
19 #include <locale.h>
20 #include <langinfo.h>
21 #include <iconv.h>
23 #include <sys/wait.h>
24 #include <sys/stat.h>
25 #include <sys/param.h>
26 #include <sys/types.h>
27 #include <sys/ioctl.h>
28 #include <sys/socket.h>
30 #include <X11/Xlib.h>
31 #include <X11/xpm.h>
32 #include <X11/extensions/shape.h>
34 #include <libdockapp/wmgeneral.h>
36 #include "wmitime-master.xpm"
37 char wmitime_mask_bits[64*64];
38 int wmitime_mask_width = 64;
39 int wmitime_mask_height = 64;
41 #define WMITIME_VERSION "0.5"
43 #define CHAR_WIDTH 5
44 #define CHAR_HEIGHT 7
46 #define BCHAR_WIDTH 6
47 #define BCHAR_HEIGHT 9
49 #define MY_PI (3.14159)
51 extern char **environ;
53 char *ProgName;
55 char locale[256];
57 time_t curtime;
58 time_t prevtime;
60 int prevhourx=19;
61 int prevhoury=33;
62 int prevminx=19;
63 int prevminy=33;
65 static struct tm *clk;
67 int TwelveHour=0;
69 void usage(void);
70 void printversion(void);
71 void BlitString(char *name, int x, int y);
72 void BlitNum(int num, int x, int y);
73 void wmitime_routine(int, char **);
74 int PortWatch( short port );
75 void DrawInetTime(void);
76 void DrawStdTime(void);
77 void DrawDate(void);
78 void DrawInetWheel(void);
79 void DrawStdWheel(void);
80 void DrawLine(int x1, int y1, int x2, int y2, int sourcex, int sourcey);
82 int main(int argc, char *argv[]) {
84 int i;
86 locale[0] = 0;
88 /* Parse Command Line */
90 ProgName = argv[0];
91 if (strlen(ProgName) >= 5)
92 ProgName += (strlen(ProgName) - 5);
94 for (i=1; i<argc; i++) {
95 char *arg = argv[i];
97 if (*arg=='-') {
98 switch (arg[1]) {
99 case 'd' :
100 if (strcmp(arg+1, "display")) {
101 usage();
102 exit(1);
104 break;
105 case 'g' :
106 if (strcmp(arg+1, "geometry")) {
107 usage();
108 exit(1);
110 break;
111 case 'v' :
112 printversion();
113 exit(0);
114 break;
115 case '1' :
116 if (arg[2] == '2')
118 /* Twelve-hour mode */
119 TwelveHour = 1;
121 break;
122 case 'l' :
123 if (argc > (i+1))
125 strcpy(locale, argv[i+1]);
126 i++;
128 break;
129 default:
130 usage();
131 exit(0);
132 break;
137 if (setlocale(LC_ALL, locale) == NULL)
138 fprintf(stderr,
139 "warning: locale '%s' not recognized; defaulting to '%s'.",
140 locale, setlocale(LC_ALL, NULL));
142 wmitime_routine(argc, argv);
144 return 0;
147 /*******************************************************************************\
148 |* wmitime_routine *|
149 \*******************************************************************************/
151 void wmitime_routine(int argc, char **argv)
153 int i;
154 XEvent Event;
155 int but_stat = -1;
158 createXBMfromXPM(wmitime_mask_bits, wmitime_master_xpm, wmitime_mask_width, wmitime_mask_height);
160 openXwindow(argc, argv, wmitime_master_xpm, wmitime_mask_bits, wmitime_mask_width, wmitime_mask_height);
162 AddMouseRegion(0, 5, 6, 58, 16);
164 RedrawWindow();
166 prevtime = time(0) - 1;
168 while (1)
170 curtime = time(0);
172 if ( curtime > prevtime)
174 prevtime = curtime;
176 clk = localtime(&curtime);
178 /* Update display */
180 DrawInetTime();
182 DrawStdTime();
184 DrawInetWheel();
186 DrawDate();
188 DrawStdWheel();
190 RedrawWindow();
194 /* X Events */
195 while (XPending(display))
197 XNextEvent(display, &Event);
198 switch (Event.type)
200 case Expose:
201 RedrawWindow();
202 break;
203 case DestroyNotify:
204 XCloseDisplay(display);
205 exit(0);
206 break;
207 case ButtonPress:
208 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
210 but_stat = i;
211 break;
212 case ButtonRelease:
213 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
215 if (but_stat == i && but_stat >= 0)
217 switch (but_stat)
219 case 0 :
220 TwelveHour = (!TwelveHour);
221 prevtime--;
222 break;
223 case 1 :
224 break;
225 case 2:
226 break;
227 case 3:
228 break;
229 case 4:
230 break;
234 but_stat = -1;
235 /* RedrawWindow(); */
236 break;
240 usleep(100000);
245 void DrawInetTime(void)
247 int iTime;
249 /* Compute Inet Time */
250 iTime=(clk->tm_hour*3600+clk->tm_min*60+clk->tm_sec);
251 iTime=iTime+((timezone-1)+3600);
252 if (clk->tm_isdst)
253 iTime-=3600;
254 iTime=(iTime*1000)/86400;
256 if (iTime >= 1000)
257 iTime-=1000;
258 else
259 if (iTime < 0)
260 iTime+=1000;
262 /* Blit it */
264 BlitNum(iTime, 38, 18);
268 void DrawStdTime(void)
270 int xoff=0, yoff=0;
271 int srcx=0, srcy=0;
272 int i,j;
273 char blitstr[32];
274 int len;
276 i = clk->tm_hour;
278 if (TwelveHour)
280 if (i > 12)
281 i-=12;
283 if (i==0)
284 i=12;
286 sprintf(blitstr, "%2i:%02i:%02i", i, clk->tm_min, clk->tm_sec);
288 else
290 sprintf(blitstr, "%02i:%02i:%02i", i, clk->tm_min, clk->tm_sec);
295 len = strlen(blitstr);
297 /* Set starting co-ordinates... */
298 xoff = 6;
299 yoff = 6;
301 /* Blit it. */
302 for( i=0; i<len; i++)
304 if (blitstr[i] == ':')
306 copyXPMArea(138, 23, 4, BCHAR_HEIGHT, xoff, yoff);
307 xoff+=4;
309 else if (isdigit(blitstr[i]))
311 j = blitstr[i] - '0';
312 srcx = 68;
313 srcy = 23;
315 while (j)
317 j--;
318 srcx += (BCHAR_WIDTH + 1);
321 copyXPMArea(srcx, srcy, BCHAR_WIDTH+1, BCHAR_HEIGHT, xoff, yoff);
322 xoff+=(BCHAR_WIDTH + 1);
324 else
326 copyXPMArea(66, 10, BCHAR_WIDTH+1, BCHAR_HEIGHT, xoff, yoff);
327 xoff+=(BCHAR_WIDTH + 1);
333 void DrawDate(void)
335 char OrigBlitStr[20], BlitStr[20];
336 char *inbuf, *outbuf;
337 size_t inbytesleft, outbytesleft;
338 iconv_t cd;
340 cd = iconv_open("ASCII//TRANSLIT", nl_langinfo(CODESET));
342 inbuf = OrigBlitStr;
343 outbuf = BlitStr;
344 inbytesleft = sizeof OrigBlitStr;
345 outbytesleft = sizeof BlitStr;
347 sprintf(OrigBlitStr, "%s", nl_langinfo(ABDAY_1 + clk->tm_wday));
348 iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
349 BlitStr[2] = 0;
350 BlitString( BlitStr, 6, 50);
352 inbuf = OrigBlitStr;
353 outbuf = BlitStr;
354 inbytesleft = sizeof OrigBlitStr;
355 outbytesleft = sizeof BlitStr;
357 sprintf(OrigBlitStr, "%s", nl_langinfo(ABMON_1 + clk->tm_mon));
358 iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
359 BlitStr[3] = 0;
360 BlitString( BlitStr, 40, 50);
362 iconv_close(cd);
364 sprintf(BlitStr, "%02i", clk->tm_mday);
365 BlitString( BlitStr, 25, 50);
368 void DrawInetWheel(void)
370 int WheelPos=0;
371 int i;
372 int xoff=0, yoff=0;
373 int iTime;
375 /* Calculate Wheel Position... */
376 iTime=(clk->tm_hour*3600+clk->tm_min*60+clk->tm_sec);
377 iTime=iTime+((timezone-1)+3600);
378 if (clk->tm_isdst)
379 iTime-=3600;
380 iTime=(iTime*1000)/8640;
382 if (iTime >= 10000)
383 iTime-=10000;
384 else
385 if (iTime < 0)
386 iTime+=10000;
388 iTime %= 10;
390 WheelPos = floor( (iTime *8) / 10);
392 /* Draw the Wheel... */
393 i=WheelPos;
394 yoff=35;
395 xoff=67;
397 xoff+=19;
399 while(i)
401 xoff +=19;
402 i--;
405 copyXPMArea(xoff, yoff, 19, 19, 39, 29);
410 void DrawStdWheel(void)
412 /* 19x33 = center
413 * radius of 14 */
415 int sx, sy;
416 int cx, cy;
417 int dx, dy;
418 int hr;
419 double psi;
421 cx=19;
422 cy=33;
424 sx = 2;
425 sy = 97;
427 /* Hour Hand... */
429 DrawLine(cx, cy, prevhourx, prevhoury, 66, 9); /* erase old line */
431 hr = (clk->tm_hour % 12);
433 psi = hr * (M_PI / 6.0);
434 psi += clk->tm_min * (M_PI / 360);
436 dx = floor(sin(psi) * 22 * 0.5 + 0.5);
437 dy = floor(-cos(psi) * 16 * 0.5 + 0.5);
439 dx += cx;
440 dy += cy;
442 prevhourx=dx;
443 prevhoury=dy;
445 DrawLine(cx, cy, dx, dy, sx, sy);
447 /* Minute Hand... */
449 DrawLine(cx, cy, prevminx, prevminy, 66, 9); /* erase old line */
451 cx=19;
452 cy=33;
453 sx = 2;
454 sy = 96;
456 psi = clk->tm_min * (M_PI / 30.0);
457 psi += clk->tm_sec * (M_PI / 1800);
459 dx = floor(sin(psi) * 22 * 0.7 + 0.5);
460 dy = floor(-cos(psi) * 16 * 0.7 + 0.5);
462 dx += cx;
463 dy += cy;
465 prevminx = dx;
466 prevminy = dy;
469 DrawLine(cx, cy, dx, dy, sx, sy);
472 void DrawLine(int x1, int y1, int x2, int y2, int sourcex, int sourcey)
474 int x, y;
475 int deltax, deltay;
476 int xs, ys;
478 float xd=0, yd=0;
479 float xi, yi;
481 x = x1;
482 y = y1;
485 if ( (x2-x1) < 0)
486 xs = -1;
487 else
488 xs = 1;
490 if ( (y2-y1) < 0)
491 ys = -1;
492 else
493 ys = 1;
495 deltax = abs( x2 - x1 );
496 deltay = abs( y2 - y1 );
498 if (deltay !=0)
499 xi = (float) ((float)deltax / (float) deltay);
500 else
501 xi=0;
503 if (deltax !=0)
504 yi = (float) ((float)deltay / (float) deltax);
505 else
506 yi=0;
508 if ( deltax > deltay )
510 for (x=x1; x!= x2; x+= xs)
512 yd += yi;
513 y += (int) (yd * ys);
515 copyXPMArea(sourcex, sourcey, 1, 1, x, y);
517 yd -= (int) yd;
520 else
522 for (y=y1; y!= y2; y+= ys)
524 xd += xi;
525 x += (int) (xd * xs);
527 copyXPMArea(sourcex, sourcey, 1, 1, x, y);
529 xd -= (int) xd;
536 /* Blits a string at given co-ordinates */
537 void BlitString(char *name, int x, int y)
539 int i;
540 int c;
541 int k;
543 k = x;
544 for (i=0; name[i]; i++)
547 c = toupper(name[i]);
548 if (c >= 'A' && c <= 'Z')
549 { /* its a letter */
550 c -= 'A';
551 copyXPMArea(c * 6, 74, 6, 8, k, y);
552 k += 6;
554 else
555 { /* its a number or symbol */
556 c -= '0';
557 copyXPMArea(c * 6, 64, 6, 8, k, y);
558 k += 6;
564 void BlitNum(int num, int x, int y)
566 char buf[1024];
567 int newx=x;
569 sprintf(buf, "%03i", num);
571 BlitString(buf, newx, y);
574 /*******************************************************************************\
575 |* usage *|
576 \*******************************************************************************/
578 void usage(void)
580 fprintf(stderr, "\nWMiTIME - Window Maker Developers Team <wmaker-dev@googlegroups.com>\n");
581 fprintf(stderr, " original author: Dave Clark <clarkd@skynet.ca>\n\n");
582 fprintf(stderr, "usage:\n");
583 fprintf(stderr, " -12 12-hour mode\n");
584 fprintf(stderr, " -display <display name>\n");
585 fprintf(stderr, " -geometry +XPOS+YPOS initial window position\n");
586 fprintf(stderr, " -l <locale> specify locale\n");
587 fprintf(stderr, " -h this help screen\n");
588 fprintf(stderr, " -v print the version number\n");
589 fprintf(stderr, "\n");
592 /*******************************************************************************\
593 |* printversion *|
594 \*******************************************************************************/
596 void printversion(void)
598 fprintf(stderr, "wmitime v%s\n", WMITIME_VERSION);