/* 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 uconfig_file[256]; 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 ); int ReadConfigInt(FILE *fp, char *setting, int *value); int ReadConfigString(FILE *fp, char *setting, char *value); int Read_Config_File( char *filename ); 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; uconfig_file[0] = 0; locale[0] = 0; /* Parse Command Line */ ProgName = argv[0]; if (strlen(ProgName) >= 5) ProgName += (strlen(ProgName) - 5); for (i=1; i (i+1)) { strcpy(uconfig_file, argv[i+1]); i++; } break; case '1' : if (arg[2] == '2') { // Twelve-hour mode TwelveHour = 1; } break; case 'l' : if (argc > (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; // char config_file[512]; 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); // We don't need a config file (yet)... #if 0 // Read config file if (uconfig_file[0] != 0) { // user-specified config file fprintf(stderr, "Using user-specified config file '%s'.\n", uconfig_file); Read_Config_File(uconfig_file); } else { sprintf(config_file, "%s/.wmitimerc", getenv("HOME")); if (!Read_Config_File(config_file)) { // Fall back to /etc/wminetrc sprintf(config_file, "/etc/wmitimerc"); Read_Config_File(config_file); } } #endif 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); } // ReadConfigSetting int ReadConfigString(FILE *fp, char *setting, char *value) { char str[1024]; char buf[1024]; int i; int len; int slen; char *p=NULL; if (!fp) { return 0; } sprintf(str, "%s=", setting); slen = strlen(str); fseek(fp, 0, SEEK_SET); while ( !feof(fp) ) { if (!fgets(buf, 512, fp)) break; len = strlen(buf); // strip linefeed for (i=0; i!=len; i++) { if (buf[i] == '\n') { buf[i] = 0; } } //printf("Scanning '%s'...\n", buf); if ( strncmp(buf, str, strlen(str)) == 0) { // found our setting for(i=0; i!=slen; i++) { if ( buf[i] == '=' ) { p=buf+i+1; strcpy(value, p); return 1; } } } } return 0; } int ReadConfigInt(FILE *fp, char *setting, int *value) { char buf[1024]; if (ReadConfigString(fp, setting, (char *) &buf)) { *value = atoi(buf); return 1; } return 0; } int Read_Config_File( char *filename ) { FILE *fp; fp = fopen(filename, "r"); if (fp) { fclose(fp); return 1; } else { perror("Read_Config_File"); fprintf(stderr, "Unable to open %s, no settings read.\n", filename); return 0; } } /*******************************************************************************\ |* 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, " -c use specified config file\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); }