wmaker-eukara/dockapps/wmitime/wmitime.c

600 lines
12 KiB
C

/*
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 <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <locale.h>
#include <langinfo.h>
#include <iconv.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include "wmgeneral/wmgeneral.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.4"
#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<argc; i++) {
char *arg = argv[i];
if (*arg=='-') {
switch (arg[1]) {
case 'd' :
if (strcmp(arg+1, "display")) {
usage();
exit(1);
}
break;
case 'g' :
if (strcmp(arg+1, "geometry")) {
usage();
exit(1);
}
break;
case 'v' :
printversion();
exit(0);
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;
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; i<len; i++)
{
if (blitstr[i] == ':')
{
copyXPMArea(138, 23, 4, BCHAR_HEIGHT, xoff, yoff);
xoff+=4;
}
else if (isdigit(blitstr[i]))
{
j = blitstr[i] - '0';
srcx = 68;
srcy = 23;
while (j)
{
j--;
srcx += (BCHAR_WIDTH + 1);
}
copyXPMArea(srcx, srcy, BCHAR_WIDTH+1, BCHAR_HEIGHT, xoff, yoff);
xoff+=(BCHAR_WIDTH + 1);
}
else
{
copyXPMArea(66, 10, BCHAR_WIDTH+1, BCHAR_HEIGHT, xoff, yoff);
xoff+=(BCHAR_WIDTH + 1);
}
}
}
void DrawDate(void)
{
char OrigBlitStr[20], BlitStr[20];
char *inbuf, *outbuf;
size_t inbytesleft, outbytesleft;
iconv_t cd;
cd = iconv_open("ASCII//TRANSLIT", nl_langinfo(CODESET));
inbuf = OrigBlitStr;
outbuf = BlitStr;
inbytesleft = sizeof OrigBlitStr;
outbytesleft = sizeof BlitStr;
sprintf(OrigBlitStr, "%s", nl_langinfo(ABDAY_1 + clk->tm_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 - Window Maker Developers Team <wmaker-dev@lists.windowmaker.org>\n");
fprintf(stderr, " original author: Dave Clark <clarkd@skynet.ca>\n\n");
fprintf(stderr, "usage:\n");
fprintf(stderr, " -12 12-hour mode\n");
fprintf(stderr, " -display <display name>\n");
fprintf(stderr, " -geometry +XPOS+YPOS initial window position\n");
fprintf(stderr, " -l <locale> 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);
}