/* * Mlclock is "Macintsh like clock" . * Written by Hideki Kimata. * Send Email to hideki@hry.info.gifu-u.ac.jp. * Access to http://www.hry.info.gifu-u.ac.jp/~hideki/index.html */ #include #include #include #include #include #include #include #include #include #define VERSION "1.1" #define TRUE 1 #define FALSE 0 #define NONE -1 #define MAX_FORM 1000 #ifndef RCFILE #define RCFILE ".mlclockrc" #endif #define FOCUS 0 #define CLICK 1 #define DEFAULTFONT "-*-*-medium-r-normal--14-*" #define NEAR 10 #define FORM1 "(%a)%p%l:%M:%S" #define FORM2 "(%a)%Y.%b.%d" #define DEFAULTLANG "C" int Mode; /* timing of change form */ int Near; /* the distance of activity */ int Head; /* space of window head */ char *Form1; /* display form of main */ char *Form2; /* display form of second */ char *LocaleName; /* locale name */ char *FSName; /* font set name */ char *RCFile; /* path of config file */ int Color[2][3]; /* the color for font and background */ int Bold = False; /* software bold font */ void SetFont(char *localename, Display *dpy, char *fsname); void readrc(); void getRGB(char *color, int *store); void usage(char *name); Display *dpy; Window win; XEvent eve; XRectangle ink, logical; GC gc; XFontSet fs; Colormap cmap; struct timeval wait; int main(int argc, char **argv) { char str[MAX_FORM], str2[MAX_FORM], *form = NULL; int screen, sw = False, lsec = 0, uhead, width, height, i; struct tm *tmm; time_t tmt; Window root, child; int rootx, rooty, wx, wy; unsigned int key; XColor xcol; XSizeHints hint; int iro[2]; wait.tv_usec = 200000; wait.tv_sec = 0; str[0] = '\0'; i = 1; while ( i < argc ) { if ( !strcmp("-display", argv[i]) ) { i++; if ( argc >= argc ) usage(argv[0]); strcpy(str, argv[i]); break; } usage(argv[0]); } dpy = XOpenDisplay(NULL); if ( dpy == NULL ) { fprintf(stderr, "Can't open display.\n"); exit(0); } screen = DefaultScreen(dpy); gc = DefaultGC(dpy, screen); cmap = DefaultColormap(dpy, screen); readrc(); if ( XSupportsLocale() == False ) fprintf(stderr,"X does not support the locale\n"); SetFont(LocaleName, dpy, FSName); XSetForeground(dpy, gc, BlackPixel(dpy, screen)); setlocale(LC_TIME, LocaleName); time(&tmt); tmm = localtime(&tmt); tmm->tm_sec = 59; tmm->tm_min = 59; tmm->tm_hour = 23; tmm->tm_mday = 30; tmm->tm_yday = 365; strftime(str, MAX_FORM, Form1, tmm); XmbTextExtents(fs, str, strlen(str), &ink, &logical); width=logical.width; uhead = logical.y; height = logical.height; strftime(str, MAX_FORM, Form2, tmm); XmbTextExtents(fs, str, strlen(str), &ink, &logical); if ( width < logical.width ) width = logical.width; if ( uhead < logical.y ) uhead = logical.y; if ( height < logical.height ) height = logical.height; xcol.flags = DoRed|DoGreen|DoBlue; for ( i = 0; i < 2; i++ ) { xcol.red = Color[i][0]; xcol.green = Color[i][1]; xcol.blue = Color[i][2]; if ( XAllocColor(dpy, cmap, &xcol) ) iro[i] = xcol.pixel; else fprintf(stderr,"Can't allocate Color \n"); } win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, width + 3, height + Head + 2, 0, iro[0], iro[1]); hint.max_width = hint.min_width = width + 3; hint.max_height = hint.min_height = height + Head + 2; hint.flags = PMinSize | PMaxSize; XSetNormalHints(dpy, win, &hint); XSelectInput(dpy, win, ButtonReleaseMask); XStoreName(dpy, win, "mlclock"); XSetForeground(dpy, gc, iro[0]); XSync(dpy, 0); XMapWindow(dpy, win); XSync(dpy, 0); str2[0] = '\0'; form = Form1; while (1) { select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &wait); time(&tmt); tmm = localtime(&tmt); if ( Mode == FOCUS ) { XQueryPointer(dpy, win, &root, &child, &rootx, &rooty, &wx, &wy, &key); if ( (-Near < wx) && (wx < width + Near) && (-Near < wy) && (wy < height + Near + Head) ) form = Form2; else form = Form1; } else if ( Mode == CLICK ) { if ( XEventsQueued(dpy, QueuedAfterFlush) ) { XNextEvent(dpy, &eve); if ( eve.type == ButtonRelease ) { if ( !sw ) { sw = True; lsec = tmm->tm_sec; form = Form2; } else { sw = False; form = Form1; } } } if ( sw ) { if ( tmm->tm_sec < lsec ) tmm->tm_sec += 60; if ( tmm->tm_sec > lsec + 2 ) { sw = False; form = Form1; } } } strftime(str, sizeof(str), form, tmm); if ( strcmp(str, str2) ) { XClearWindow(dpy, win); XmbDrawString(dpy, win, fs, gc, 1, - uhead + Head + 1, str, strlen(str)); if ( Bold ) XmbDrawString(dpy, win, fs, gc, 2, - uhead + Head + 1, str, strlen(str)); XSync(dpy, 0); strcpy(str2, str); } } return 0; } void SetFont(char *localename, Display *dpy, char *fsname) { char **miss, *def; int nMiss; if ( setlocale(LC_ALL, localename) == NULL ) fprintf(stderr,"Can't set the locale\n"); fs = XCreateFontSet(dpy, fsname, &miss, &nMiss, &def); if ( fs == NULL ) fprintf(stderr,"Can't get fontset.\n"); } void readrc() { int i, end, len, sw1, cn = 0; char string[501], work[201], code[100], data[100], *ptr; char *fore, *back; struct _name { char name[10]; int sw; }; FILE *file; struct _name N[] ={ { "FORM1", 1 }, { "FORM2", 2 }, { "NEAR", 3 }, { "EVENT", 4 }, { "LOCALE", 5 }, { "FONTSET", 6 }, { "HEAD", 7 }, { "FONTCOLOR", 8 }, { "BACKCOLOR", 9 }, { "BOLD", 10 }, { "", 0 }}; Mode = Near = Head = NONE; Form1 = Form2 = LocaleName = FSName = NULL; for ( i = 0; i < 3; i++ ) { Color[0][i] = 0; Color[1][i] = 0xffff; } RCFile = malloc(sizeof(RCFILE) + strlen(getenv("HOME")) + 3); sprintf(RCFile, "%s/%s", getenv("HOME"), RCFILE); if ( (file = fopen(RCFile, "r")) == NULL ) { fprintf(stderr, "Can't open \"%s\" file.\n", RCFile); fprintf(stderr, "Now making rc file.\n", RCFile); if ( (file = fopen(RCFile, "a")) == NULL ) fprintf(stderr, "You can't make rc file in your own dirctory.\n"); else{ fprintf(file, "FORM1 = \"(%%a)%%l:%%M:%%S%%p\"\n"); fprintf(file, "FORM2 = \"(%%a)%%b-%%d\"\n"); fprintf(file, "EVENT = FOCUS ; FOCUS or CLICK\n"); fprintf(file, "NEAR = 10\n"); fprintf(file, "LOCALE = \"C\"\n"); fprintf(file, "FONTSET = \"-*-*-medium-r-normal--12-*\"\n"); fprintf(file, "HEAD = 5\n"); fprintf(file, "FONTCOLOR = \"blue\"\n"); fprintf(file, "BACKCOLOR = \"white\"\n"); fprintf(file, "BOLD = FALSE ; TRUE or FALSE\n"); fclose(file); fprintf(stderr, "Created %s file.\n", RCFile); } } else while ( fgets(string, 500, file) ) { end = FALSE; i = 0; sw1 = False; while ( string[i] != ';' && string[i] != '\0' && string[i] != '\n' ) { if ( string[i] == '=' && sw1 == False ) { string[i] = ' '; sw1 = True; } work[i] = string[i]; i++; } work[i] = '\0'; if ( sw1 == False ) continue; code[0] = '\0'; data[0] = '\0'; sscanf(work, "%s %s", code, data); if ( code[0] == '\0' ) continue; i = 0; while ( True ) { if ( N[i].name[0] == '\0' ) { cn = 0; break; } if ( !strcmp(N[i].name, code) ) { cn = N[i].sw; break; } i++; } switch ( cn ) { case 1: len = strlen(data); Form1 = malloc(len); strcpy(Form1, &data[1]); Form1[len-2] = '\0'; break; case 2: len = strlen(data); Form2 = malloc(len); strcpy(Form2, &data[1]); Form2[len-2] = '\0'; break; case 3: Near = atoi(data); break; case 4: if ( !strcmp(data, "FOCUS") ) { Mode = FOCUS; break; } if ( !strcmp(data, "CLICK") ) { Mode = CLICK; break; } break; case 5: len = strlen(data); LocaleName = malloc(len); strcpy(LocaleName, &data[1]); LocaleName[len-2] = '\0'; break; case 6: len = strlen(data); FSName = malloc(len); strcpy(FSName, &data[1]); FSName[len-2] = '\0'; break; case 7: Head = atoi(data); break; case 8: len = strlen(data); fore = malloc(len); strcpy(fore, &data[1]); fore[len-2] = '\0'; getRGB(fore, Color[0]); break; case 9: len = strlen(data); back = malloc(len); strcpy(back, &data[1]); back[len-2] = '\0'; getRGB(back, Color[1]); break; case 10: if ( !strcmp(data, "TRUE") ) { Bold = True; break; } if ( !strcmp(data, "FALSE") ) { Bold = False; break; } break; default: break; } } if ( Mode == NONE ) Mode = FOCUS; if ( Near == NONE ) Near = NEAR; if ( Head == NONE ) Head = 0; if ( Form1 == NULL ) { Form1 = malloc(strlen(FORM1) + 1); strcpy(Form1, FORM1); } if ( Form2 == NULL ) { Form2 = malloc(strlen(FORM2) + 1); strcpy(Form2, FORM2); } if ( FSName == NULL ) { FSName = malloc(strlen(DEFAULTFONT) + 1); strcpy(FSName, DEFAULTFONT); } if ( LocaleName == NULL ) { ptr = getenv("LANG"); if ( ptr == NULL ) ptr = DEFAULTLANG; LocaleName = malloc(strlen(ptr) + 1); strcpy(LocaleName, ptr); } } void getRGB(char *color, int *store) { int i; char tmpcolor[3]; XColor rgb, hard; if ( color[0] == '#' ) { color++; for ( i = 0; i < 3; i++ ) { strncpy(tmpcolor, color, 2); sscanf(tmpcolor, "%x", store); (*store) *= 256; color += 2; } } else { XLookupColor(dpy, cmap, color, &rgb, &hard); store[0] = hard.red; store[1] = hard.green; store[2] = hard.blue; } } void usage(char *name) { printf("%s: usage\n", name); printf(" -display display name\n\n"); printf(" Version %s\n", VERSION); printf(" Written by Hideki Kimata\n"); printf(" EMail hideki@hry.info.gifu-u.ac.jp\n"); printf(" Access to http://www.hry.info.gifu-u.ac.jp/~hideki/index.html\n"); exit(0); }