mlclock/mlclock.c

453 lines
10 KiB
C
Raw Normal View History

2020-03-03 23:49:26 +00:00
/*
* 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 <X11/Xlib.h>
#include <X11/Xlocale.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#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 */
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
void SetFont( char *localename, Display *dpy, char *fsname );
void readrc();
2020-03-07 16:01:56 +00:00
void getRGB( char *color, int *store );
void usage( char *name );
2020-03-03 23:49:26 +00:00
Display *dpy;
Window win;
XEvent eve;
2020-03-04 00:04:10 +00:00
XRectangle ink, logical;
GC gc;
XFontSet fs;
Colormap cmap;
2020-03-03 23:49:26 +00:00
struct timeval wait;
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
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;
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
Window root, child;
int rootx, rooty, wx, wy;
unsigned int key;
XColor xcol;
XSizeHints hint;
int iro[2];
2020-03-03 23:49:26 +00:00
wait.tv_usec = 200000;
wait.tv_sec = 0;
2020-03-06 16:01:08 +00:00
str[0] = '\0';
i = 1;
2020-03-03 23:49:26 +00:00
while( i < argc ){
2020-03-07 16:01:56 +00:00
if ( !strcmp( "-display", argv[i] )){
i++;
2020-03-03 23:49:26 +00:00
if ( argc >= argc )
usage( argv[0]);
2020-03-07 16:01:56 +00:00
strcpy( str, argv[i] );
break;
2020-03-03 23:49:26 +00:00
}
usage(argv[0]);
2020-03-03 23:49:26 +00:00
}
dpy = XOpenDisplay(NULL);
if ( dpy == NULL ){
2020-03-07 16:01:56 +00:00
fprintf( stderr, "Can't open display.\n" );
exit(0);
2020-03-03 23:49:26 +00:00
}
screen = DefaultScreen( dpy );
2020-03-07 16:01:56 +00:00
gc = DefaultGC( dpy, screen );
cmap = DefaultColormap( dpy, screen );
2020-03-03 23:49:26 +00:00
readrc();
2020-03-03 23:49:26 +00:00
if (XSupportsLocale() == False)
fprintf(stderr,"X does not support the locale\n");
2020-03-07 16:01:56 +00:00
SetFont( LocaleName, dpy, FSName );
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
XSetForeground( dpy, gc, BlackPixel( dpy, screen ));
2020-03-03 23:49:26 +00:00
setlocale(LC_TIME, LocaleName );
time( &tmt );
tmm = localtime( &tmt );
2020-03-03 23:49:26 +00:00
tmm->tm_sec = 59;
tmm->tm_min = 59;
tmm->tm_hour = 23;
tmm->tm_mday = 30;
tmm->tm_yday = 365;
2020-03-07 16:01:56 +00:00
strftime(str, MAX_FORM, Form1, tmm);
XmbTextExtents( fs, str, strlen(str), &ink, &logical);
width=logical.width;
uhead = logical.y;
height = logical.height;
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
strftime(str, MAX_FORM, Form2, tmm);
XmbTextExtents( fs, str, strlen(str), &ink, &logical);
2020-03-04 00:04:10 +00:00
if ( width < logical.width )
width = logical.width;
2020-03-04 00:04:10 +00:00
if ( uhead < logical.y )
uhead = logical.y;
2020-03-04 00:04:10 +00:00
if ( height < logical.height )
height = logical.height;
2020-03-03 23:49:26 +00:00
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];
2020-03-07 16:01:56 +00:00
if ( XAllocColor( dpy, cmap, &xcol ))
iro[i] = xcol.pixel;
else fprintf(stderr,"Can't allocate Color \n" );
2020-03-03 23:49:26 +00:00
}
2020-03-07 16:01:56 +00:00
win = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ),
0, 0, width + 3, height + Head + 2, 0,
iro[0], iro[1] );
2020-03-03 23:49:26 +00:00
hint.max_width = hint.min_width = width + 3;
hint.max_height = hint.min_height = height + Head + 2;
2020-03-03 23:49:26 +00:00
hint.flags = PMinSize | PMaxSize;
2020-03-07 16:01:56 +00:00
XSetNormalHints(dpy, win, &hint);
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
XSelectInput( dpy, win, ButtonReleaseMask );
XStoreName( dpy, win, "mlclock" );
XSetForeground( dpy, gc, iro[0] );
XSync( dpy, 0 );
XMapWindow( dpy, win );
XSync( dpy, 0 );
2020-03-03 23:49:26 +00:00
str2[0] = '\0';
form = Form1;
2020-03-03 23:49:26 +00:00
while(1){
2020-03-07 16:01:56 +00:00
select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &wait);
2020-03-03 23:49:26 +00:00
time( &tmt );
tmm = localtime( &tmt );
2020-03-03 23:49:26 +00:00
if ( Mode == FOCUS ){
2020-03-07 16:01:56 +00:00
XQueryPointer( dpy, win, &root, &child, &rootx, &rooty, &wx, &wy, &key);
2020-03-03 23:49:26 +00:00
if (( -Near < wx ) && ( wx < width + Near ) &&
( -Near < wy ) && ( wy < height + Near + Head ))
form = Form2;
2020-03-03 23:49:26 +00:00
else
form = Form1; }
2020-03-03 23:49:26 +00:00
else
if ( Mode == CLICK ){
if( XEventsQueued( dpy, QueuedAfterFlush ) ){
2020-03-07 16:01:56 +00:00
XNextEvent( dpy, &eve );
2020-03-03 23:49:26 +00:00
if ( eve.type == ButtonRelease ){
if ( !sw ){
sw = True;
lsec = tmm->tm_sec;
form = Form2;
2020-03-03 23:49:26 +00:00
}
else {
sw = False;
form = Form1;
2020-03-03 23:49:26 +00:00
}
}
}
if ( sw ){
if ( tmm->tm_sec < lsec )
tmm->tm_sec += 60;
2020-03-03 23:49:26 +00:00
if ( tmm->tm_sec > lsec + 2 ){
sw = False;
form = Form1;
2020-03-03 23:49:26 +00:00
}
}
}
2020-03-07 16:01:56 +00:00
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));
2020-03-03 23:49:26 +00:00
if ( Bold )
2020-03-07 16:01:56 +00:00
XmbDrawString( dpy, win, fs, gc, 2, - uhead + Head + 1, str, strlen(str));
XSync( dpy, 0 );
strcpy( str2, str );
2020-03-03 23:49:26 +00:00
}
}
2020-03-04 00:04:10 +00:00
return 0;
2020-03-03 23:49:26 +00:00
}
2020-03-07 16:01:56 +00:00
void SetFont( char *localename, Display *dpy, char *fsname )
2020-03-03 23:49:26 +00:00
{
char **miss, *def;
int nMiss;
if (setlocale(LC_ALL, localename) == NULL)
fprintf(stderr,"Can't set the locale\n");
2020-03-07 16:01:56 +00:00
fs = XCreateFontSet( dpy, fsname, &miss, &nMiss, &def);
2020-03-03 23:49:26 +00:00
if (fs == NULL)
fprintf(stderr,"Can't get fontset.\n" );
2020-03-03 23:49:26 +00:00
}
void readrc(){
2020-03-07 16:01:56 +00:00
int i, end, len, sw1, cn = 0;
char string[501], work[201], code[100], data[100], *ptr;
char *fore, *back;
2020-03-03 23:49:26 +00:00
struct _name {
char name[10];
int sw;
};
2020-03-03 23:49:26 +00:00
FILE *file;
2020-03-03 23:49:26 +00:00
struct _name N[] ={
2020-03-07 16:01:56 +00:00
{ "FORM1", 1 },
{ "FORM2", 2 },
{ "NEAR", 3 },
{ "EVENT", 4 },
{ "LOCALE", 5 },
{ "FONTSET", 6 },
{ "HEAD", 7 },
{ "FONTCOLOR", 8 },
{ "BACKCOLOR", 9 },
{ "BOLD", 10 },
{ "", 0 }};
2020-03-03 23:49:26 +00:00
Mode = Near = Head = NONE;
Form1 = Form2 = LocaleName = FSName = NULL;
2020-03-06 16:01:08 +00:00
for ( i = 0; i < 3; i ++ ){
Color[0][i] = 0;
Color[1][i] = 0xffff;
2020-03-03 23:49:26 +00:00
}
RCFile = malloc ( sizeof( RCFILE ) + strlen( getenv("HOME")) + 3 );
2020-03-07 16:01:56 +00:00
sprintf( RCFile, "%s/%s",getenv("HOME"),RCFILE );
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
if ( ( file = fopen( RCFile, "r" )) == NULL ){
fprintf( stderr, "Can't open \"%s\" file.\n", RCFile );
fprintf( stderr, "Now making rc file.\n", RCFile );
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
if ((file = fopen( RCFile, "a" )) == NULL )
fprintf( stderr, "You can't make rc file in your own dirctory.\n" );
2020-03-03 23:49:26 +00:00
else{
2020-03-07 16:01:56 +00:00
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 );
2020-03-07 16:01:56 +00:00
fprintf( stderr, "Created %s file.\n", RCFile );
2020-03-03 23:49:26 +00:00
}
}
else
2020-03-07 16:01:56 +00:00
while( fgets( string, 500, file )){
end = FALSE;
i = 0;
sw1 = False;
2020-03-03 23:49:26 +00:00
while( string[i] != ';' && string[i] != '\0' && string[i] != '\n' ){
if ( string[i] == '=' && sw1 == False ){
string[i] = ' ';
sw1 = True;
2020-03-03 23:49:26 +00:00
}
work[i] = string[i];
2020-03-06 16:01:08 +00:00
i++;
2020-03-03 23:49:26 +00:00
}
work[i] = '\0';
2020-03-03 23:49:26 +00:00
if ( sw1 == False )
continue;
2020-03-03 23:49:26 +00:00
code[0] = '\0';
data[0] = '\0';
2020-03-03 23:49:26 +00:00
2020-03-07 16:01:56 +00:00
sscanf( work, "%s %s", code, data);
2020-03-03 23:49:26 +00:00
if ( code[0] == '\0' )
continue;
2020-03-03 23:49:26 +00:00
i = 0;
2020-03-03 23:49:26 +00:00
while( True ){
if ( N[i].name[0] == '\0' ){
cn = 0;
break;
2020-03-03 23:49:26 +00:00
}
2020-03-07 16:01:56 +00:00
if ( !strcmp( N[i].name, code )){
cn = N[i].sw;
break;
2020-03-03 23:49:26 +00:00
}
i ++;
2020-03-03 23:49:26 +00:00
}
switch( cn ){
case 1:
len = strlen( data );
Form1 = malloc( len );
2020-03-07 16:01:56 +00:00
strcpy( Form1, &data[1] );
Form1[len-2] = '\0';
break;
2020-03-03 23:49:26 +00:00
case 2:
len = strlen( data );
Form2 = malloc( len );
2020-03-07 16:01:56 +00:00
strcpy( Form2, &data[1] );
Form2[len-2] = '\0';
break;
2020-03-03 23:49:26 +00:00
case 3:
Near = atoi( data );
2020-03-03 23:49:26 +00:00
break;
case 4:
2020-03-07 16:01:56 +00:00
if ( !strcmp( data, "FOCUS" )){
Mode = FOCUS;
break;
2020-03-03 23:49:26 +00:00
}
2020-03-07 16:01:56 +00:00
if ( !strcmp( data, "CLICK" )){
Mode = CLICK;
break;
2020-03-03 23:49:26 +00:00
}
break;
2020-03-03 23:49:26 +00:00
case 5:
len = strlen( data );
LocaleName = malloc( len );
2020-03-07 16:01:56 +00:00
strcpy( LocaleName, &data[1] );
LocaleName[len-2] = '\0';
break;
2020-03-03 23:49:26 +00:00
case 6:
len = strlen( data );
FSName = malloc( len );
2020-03-07 16:01:56 +00:00
strcpy( FSName, &data[1] );
FSName[len-2] = '\0';
break;
2020-03-03 23:49:26 +00:00
case 7:
Head = atoi( data );
2020-03-03 23:49:26 +00:00
break;
case 8:
len = strlen( data );
fore = malloc( len );
2020-03-07 16:01:56 +00:00
strcpy( fore, &data[1] );
fore[len-2] = '\0';
2020-03-07 16:01:56 +00:00
getRGB( fore, Color[0] );
break;
2020-03-03 23:49:26 +00:00
case 9:
len = strlen( data );
back = malloc( len );
2020-03-07 16:01:56 +00:00
strcpy( back, &data[1] );
back[len-2] = '\0';
2020-03-07 16:01:56 +00:00
getRGB( back, Color[1] );
break;
2020-03-03 23:49:26 +00:00
case 10:
2020-03-07 16:01:56 +00:00
if ( !strcmp( data, "TRUE" )){
Bold = True;
break;
2020-03-03 23:49:26 +00:00
}
2020-03-07 16:01:56 +00:00
if ( !strcmp( data, "FALSE" )){
Bold = False;
break;
2020-03-03 23:49:26 +00:00
}
break;
2020-03-03 23:49:26 +00:00
default:
break;
2020-03-03 23:49:26 +00:00
}
}
if ( Mode == NONE )
Mode = FOCUS;
2020-03-03 23:49:26 +00:00
if ( Near == NONE )
Near = NEAR;
2020-03-03 23:49:26 +00:00
if ( Head == NONE )
Head = 0;
2020-03-03 23:49:26 +00:00
if ( Form1 == NULL ){
Form1 = malloc( strlen( FORM1 ) + 1);
2020-03-07 16:01:56 +00:00
strcpy( Form1, FORM1 );
2020-03-03 23:49:26 +00:00
}
if ( Form2 == NULL ){
Form2 = malloc( strlen( FORM2 ) + 1);
2020-03-07 16:01:56 +00:00
strcpy( Form2, FORM2 );
2020-03-03 23:49:26 +00:00
}
if ( FSName == NULL ){
FSName = malloc( strlen( DEFAULTFONT ) + 1);
2020-03-07 16:01:56 +00:00
strcpy( FSName, DEFAULTFONT );
2020-03-03 23:49:26 +00:00
}
if ( LocaleName == NULL ){
ptr = getenv( "LANG" );
2020-03-03 23:49:26 +00:00
if ( ptr == NULL )
ptr = DEFAULTLANG;
LocaleName = malloc( strlen( ptr ) + 1);
2020-03-07 16:01:56 +00:00
strcpy( LocaleName, ptr );
2020-03-03 23:49:26 +00:00
}
}
2020-03-07 16:01:56 +00:00
void getRGB( char *color, int *store ){
int i;
char tmpcolor[3];
2020-03-07 16:01:56 +00:00
XColor rgb, hard;
2020-03-03 23:49:26 +00:00
if ( color[0] == '#' ){
color ++;
for ( i = 0; i < 3; i ++ ){
2020-03-07 16:01:56 +00:00
strncpy( tmpcolor, color, 2 );
sscanf( tmpcolor, "%x", store );
(*store) *= 256;
color += 2;
2020-03-03 23:49:26 +00:00
}
}
else {
2020-03-07 16:01:56 +00:00
XLookupColor( dpy, cmap, color, &rgb, &hard );
store[0] = hard.red;
store[1] = hard.green;
store[2] = hard.blue;
2020-03-03 23:49:26 +00:00
}
}
void usage( char *name ){
2020-03-07 16:01:56 +00:00
printf("%s: usage\n", name );
printf(" -display display name\n\n" );
2020-03-07 16:01:56 +00:00
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);
2020-03-03 23:49:26 +00:00
}