/* wmitime.c -- internet time clock by Dave Clark (clarkd@skynet.ca) (http://www.neotokyo.org/illusion) This software is licensed through the GNU General Public Lisence. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "wmgeneral/wmgeneral.h" #include "wmgeneral/misc.h" #include "wmitime-master.xpm" char wmitime_mask_bits[64*64]; int wmitime_mask_width = 64; int wmitime_mask_height = 64; #define WMITIME_VERSION "0.1" #define CHAR_WIDTH 5 #define CHAR_HEIGHT 7 #define BCHAR_WIDTH 6 #define BCHAR_HEIGHT 9 #define MY_PI (3.14159) extern char **environ; char *ProgName; char locale[256]; time_t curtime; time_t prevtime; int prevhourx=19; int prevhoury=33; int prevminx=19; int prevminy=33; static struct tm *clk; int TwelveHour=0; void usage(void); void printversion(void); void BlitString(char *name, int x, int y); void BlitNum(int num, int x, int y); void wmitime_routine(int, char **); int PortWatch( short port ); void DrawInetTime(void); void DrawStdTime(void); void DrawDate(void); void DrawInetWheel(void); void DrawStdWheel(void); void DrawLine(int x1, int y1, int x2, int y2, int sourcex, int sourcey); int main(int argc, char *argv[]) { int i; locale[0] = 0; /* Parse Command Line */ ProgName = argv[0]; if (strlen(ProgName) >= 5) ProgName += (strlen(ProgName) - 5); for (i=1; i (i+1)) { strcpy(locale, argv[i+1]); i++; } break; default: usage(); exit(0); break; } } } if (setlocale(LC_ALL, locale) == NULL) fprintf(stderr, "warning: locale '%s' not recognized; defaulting to '%s'.", locale, setlocale(LC_ALL, NULL)); wmitime_routine(argc, argv); return 0; } /*******************************************************************************\ |* wmitime_routine *| \*******************************************************************************/ void wmitime_routine(int argc, char **argv) { int i; XEvent Event; int but_stat = -1; createXBMfromXPM(wmitime_mask_bits, wmitime_master_xpm, wmitime_mask_width, wmitime_mask_height); openXwindow(argc, argv, wmitime_master_xpm, wmitime_mask_bits, wmitime_mask_width, wmitime_mask_height); AddMouseRegion(0, 5, 6, 58, 16); RedrawWindow(); prevtime = time(0) - 1; while (1) { curtime = time(0); if ( curtime > prevtime) { prevtime = curtime; clk = localtime(&curtime); /* Update display */ DrawInetTime(); DrawStdTime(); DrawInetWheel(); DrawDate(); DrawStdWheel(); 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) { switch (but_stat) { case 0 : TwelveHour = (!TwelveHour); prevtime--; break; case 1 : break; case 2: break; case 3: break; case 4: break; } } but_stat = -1; /* RedrawWindow(); */ break; } } usleep(100000); } } void DrawInetTime(void) { int iTime; /* Compute Inet Time */ iTime=(clk->tm_hour*3600+clk->tm_min*60+clk->tm_sec); iTime=iTime+((timezone-1)+3600); if (clk->tm_isdst) iTime-=3600; iTime=(iTime*1000)/86400; if (iTime >= 1000) iTime-=1000; else if (iTime < 0) iTime+=1000; /* Blit it */ BlitNum(iTime, 38, 18); } void DrawStdTime(void) { int xoff=0, yoff=0; int srcx=0, srcy=0; int i,j; char blitstr[32]; int len; i = clk->tm_hour; if (TwelveHour) { if (i > 12) i-=12; if (i==0) i=12; sprintf(blitstr, "%2i:%02i:%02i", i, clk->tm_min, clk->tm_sec); } else { sprintf(blitstr, "%02i:%02i:%02i", i, clk->tm_min, clk->tm_sec); } len = strlen(blitstr); /* Set starting co-ordinates... */ xoff = 6; yoff = 6; /* Blit it. */ for( i=0; itm_wday)); iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); BlitStr[2] = 0; BlitString( BlitStr, 6, 50); inbuf = OrigBlitStr; outbuf = BlitStr; inbytesleft = sizeof OrigBlitStr; outbytesleft = sizeof BlitStr; sprintf(OrigBlitStr, "%s", nl_langinfo(ABMON_1 + clk->tm_mon)); iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); BlitStr[3] = 0; BlitString( BlitStr, 40, 50); iconv_close(cd); sprintf(BlitStr, "%02i", clk->tm_mday); BlitString( BlitStr, 25, 50); } void DrawInetWheel(void) { int WheelPos=0; int i; int xoff=0, yoff=0; int iTime; /* Calculate Wheel Position... */ iTime=(clk->tm_hour*3600+clk->tm_min*60+clk->tm_sec); iTime=iTime+((timezone-1)+3600); if (clk->tm_isdst) iTime-=3600; iTime=(iTime*1000)/8640; if (iTime >= 10000) iTime-=10000; else if (iTime < 0) iTime+=10000; iTime %= 10; WheelPos = floor( (iTime *8) / 10); /* Draw the Wheel... */ i=WheelPos; yoff=35; xoff=67; xoff+=19; while(i) { xoff +=19; i--; } copyXPMArea(xoff, yoff, 19, 19, 39, 29); } void DrawStdWheel(void) { /* 19x33 = center * radius of 14 */ int sx, sy; int cx, cy; int dx, dy; int hr; double psi; cx=19; cy=33; sx = 2; sy = 97; /* Hour Hand... */ DrawLine(cx, cy, prevhourx, prevhoury, 66, 9); /* erase old line */ hr = (clk->tm_hour % 12); psi = hr * (M_PI / 6.0); psi += clk->tm_min * (M_PI / 360); dx = floor(sin(psi) * 22 * 0.5 + 0.5); dy = floor(-cos(psi) * 16 * 0.5 + 0.5); dx += cx; dy += cy; prevhourx=dx; prevhoury=dy; DrawLine(cx, cy, dx, dy, sx, sy); /* Minute Hand... */ DrawLine(cx, cy, prevminx, prevminy, 66, 9); /* erase old line */ cx=19; cy=33; sx = 2; sy = 96; psi = clk->tm_min * (M_PI / 30.0); psi += clk->tm_sec * (M_PI / 1800); dx = floor(sin(psi) * 22 * 0.7 + 0.5); dy = floor(-cos(psi) * 16 * 0.7 + 0.5); dx += cx; dy += cy; prevminx = dx; prevminy = dy; DrawLine(cx, cy, dx, dy, sx, sy); } void DrawLine(int x1, int y1, int x2, int y2, int sourcex, int sourcey) { int x, y; int deltax, deltay; int xs, ys; float xd=0, yd=0; float xi, yi; x = x1; y = y1; if ( (x2-x1) < 0) xs = -1; else xs = 1; if ( (y2-y1) < 0) ys = -1; else ys = 1; deltax = abs( x2 - x1 ); deltay = abs( y2 - y1 ); if (deltay !=0) xi = (float) ((float)deltax / (float) deltay); else xi=0; if (deltax !=0) yi = (float) ((float)deltay / (float) deltax); else yi=0; if ( deltax > deltay ) { for (x=x1; x!= x2; x+= xs) { yd += yi; y += (int) (yd * ys); copyXPMArea(sourcex, sourcey, 1, 1, x, y); yd -= (int) yd; } } else { for (y=y1; y!= y2; y+= ys) { xd += xi; x += (int) (xd * xs); copyXPMArea(sourcex, sourcey, 1, 1, x, y); xd -= (int) xd; } } } /* Blits a string at given co-ordinates */ 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 * 6, 74, 6, 8, k, y); k += 6; } else { /* its a number or symbol */ c -= '0'; copyXPMArea(c * 6, 64, 6, 8, k, y); k += 6; } } } void BlitNum(int num, int x, int y) { char buf[1024]; int newx=x; sprintf(buf, "%03i", num); BlitString(buf, newx, y); } /*******************************************************************************\ |* usage *| \*******************************************************************************/ void usage(void) { fprintf(stderr, "\nWMiTIME - illusion http://www.neotokyo.org/illusion\n\n"); fprintf(stderr, "usage:\n"); fprintf(stderr, " -12 12-hour mode\n"); fprintf(stderr, " -display \n"); fprintf(stderr, " -geometry +XPOS+YPOS initial window position\n"); fprintf(stderr, " -l specify locale\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, "wmitime v%s\n", WMITIME_VERSION); }