/*
Analogue Clock Local Time X11 Desktop Application in C++
RJM Programming
September, 2019
Thanks to ttps://www.linuxjournal.com/article/4879
*/
#include <stdio.h> /* puts, printf */
#include <time.h> /* time_t, struct tm, time, localtime */
#include <string.h>
#include <unistd.h>
#include <cmath>
#include <iostream>
#include <ctime>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#define sinDegrees(x) sin((x) * M_PI / 180.0)
#define cosDegrees(x) cos((x) * M_PI / 180.0)
XGCValues gr_values;
XFontStruct *fontinfo;
GC gr_context;
XColor colour, dummy;
double hhang;
double mhang;
double shang;
//Display *display;
Display *dsp=NULL;
Window win;
int redraw(std::string suffix, int jk) {
try {
dsp = XOpenDisplay( NULL );
if( !dsp ){ return 1; }
fontinfo = XLoadQueryFont(dsp,"6x10");
int screenNumber = DefaultScreen(dsp);
unsigned long white = WhitePixel(dsp,screenNumber);
unsigned long black = BlackPixel(dsp,screenNumber);
double seconds=0.0;
time_t time_ptr;
time_t time_ptr2;
tm* tm_local2;
time_ptr = time(NULL);
// Get the localtime
tm* tm_local = localtime(&time_ptr);
if (tm_local->tm_hour >= 12) {
win = XCreateSimpleWindow(dsp,
DefaultRootWindow(dsp),
50, 50, // origin
200, 200, // size
0, white, // border
black ); // backgd
} else {
win = XCreateSimpleWindow(dsp,
DefaultRootWindow(dsp),
50, 50, // origin
200, 200, // size
0, black, // border
white ); // backgd
}
std::string buffer (80, '\0');
char buff[80];
strftime(buff,80,"%Z",tm_local);
//*(buff + 79)=0;
//puts (buffer);
if (jk < strlen(" ... Click to refresh\0")){
memcpy((buff + strlen(buff)), ((char *)(" ... Click to refresh\0\0\0\0") + jk), (-jk + 2 + strlen(" ... Click to refresh\0"))); //, (1 + strlen(suffix)));
}
//strcat((char *)buffer, " ");
//strcat((char *)buffer, suffix); // " ... Click to refresh");
buffer.append(buff);
//strcat(buff, suffix);
buffer.append(" ");
buffer.append(suffix);
XStoreName( dsp, win, buff );
XSetIconName( dsp, win, buff );
XMapWindow( dsp, win );
long eventMask = StructureNotifyMask;
XSelectInput( dsp, win, eventMask );
XEvent evt;
do {
time_ptr = time(NULL);
// Get the localtime
tm* tm_local = localtime(&time_ptr);
XNextEvent( dsp, &evt ); // calls XFlush
} while( evt.type != MapNotify );
XAllocNamedColor(dsp, DefaultColormap(dsp, screenNumber),"red",
&colour,&dummy);
gr_values.font = fontinfo->fid;
gr_values.foreground = colour.pixel;
GC gc = XCreateGC( dsp, win,
GCFont+GCForeground, // mask of values
&gr_values ); // array of values
if (tm_local->tm_hour >= 12) {
XSetForeground( dsp, gc, white );
hhang=-90.0 + ((tm_local->tm_hour - 12) * 30.0 + tm_local->tm_min * 0.5 + tm_local->tm_sec * 0.00733);
mhang=-90.0 + (tm_local->tm_min * 6.0 + tm_local->tm_sec * 0.1);
shang=-90.0 + (tm_local->tm_sec * 6.0);
XDrawLine(dsp, win, gc, 100, 100,100 + cosDegrees(hhang) * 40,100 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,100 + cosDegrees(mhang) * 80,100 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(hhang) * 40,99.3 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(mhang) * 80,99.3 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(hhang) * 40,100.7 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(mhang) * 80,100.7 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(hhang) * 40,100.7 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(mhang) * 80,99.3 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(hhang) * 40,99.3 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(mhang) * 80,100.7 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,100 + cosDegrees(shang) * 20,100 + sinDegrees(shang) * 20); //from-to
} else {
XSetForeground( dsp, gc, black );
hhang=-90.0 + ((tm_local->tm_hour - 0) * 30.0 + tm_local->tm_min * 0.5 + tm_local->tm_sec * 0.00733);
mhang=-90.0 + (tm_local->tm_min * 6.0 + tm_local->tm_sec * 0.1);
shang=-90.0 + (tm_local->tm_sec * 6.0);
XDrawLine(dsp, win, gc, 100, 100,100 + cosDegrees(hhang) * 40,100 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,100 + cosDegrees(mhang) * 80,100 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(hhang) * 40,99.3 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(mhang) * 80,99.3 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(hhang) * 40,100.7 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(mhang) * 80,100.7 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(hhang) * 40,100.7 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(mhang) * 80,99.3 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,100.7 + cosDegrees(hhang) * 40,99.3 + sinDegrees(hhang) * 40); //from-to
XDrawLine(dsp, win, gc, 100, 100,99.3 + cosDegrees(mhang) * 80,100.7 + sinDegrees(mhang) * 80); //from-to
XDrawLine(dsp, win, gc, 100, 100,100 + cosDegrees(shang) * 20,100 + sinDegrees(shang) * 20); //from-to
}
//XDrawLine(dsp, win, gc, 10, 10,190,190); //from-to
//XDrawLine(dsp, win, gc, 10,190,190, 10); //from-to
XDrawLine(dsp, win, gc, 100, 10,100,190); //from-to
XDrawLine(dsp, win, gc, 10, 100,190,100); //from-to
//XDrawLine(dsp, win, gc, 55, 10,145,190); //from-to
//XDrawLine(dsp, win, gc, 145, 10,55,190); //from-to
//XDrawLine(dsp, win, gc, 10, 55,190,145); //from-to
//XDrawLine(dsp, win, gc, 10, 145,190,55); //from-to
XDrawLine(dsp, win, gc, 42, 10,158,190); //from-to
XDrawLine(dsp, win, gc, 158, 10,42,190); //from-to
XDrawLine(dsp, win, gc, 10, 42,190,158); //from-to
XDrawLine(dsp, win, gc, 10, 158,190,42); //from-to
eventMask = ResizeRedirectMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask;
XSelectInput(dsp,win,eventMask); // override prev
int i=0;
do {
i++;
XNextEvent( dsp, &evt ); // calls XFlush()
usleep(200);
time_ptr2 = time(NULL);
tm_local2 = localtime(&time_ptr2);
seconds = difftime(time(NULL), time_ptr);
XResizeWindow(dsp, win, 200 + (i % 11), 200 + (i % 11));
} while( evt.type != ButtonRelease && seconds < 1.0 ); //ButtonRelease );
//usleep(1000);
XDestroyWindow( dsp, win );
XCloseDisplay( dsp );
dsp = NULL;
}
catch (int ez) { printf("%i\n", ez); }
return 0;
}
int main() {
int jj=0;
std::string suff (" ... Click to refresh as required\0");
//suff.assign((std::string)" ... Click to refresh as required");
while(1) {
if (dsp) {
XDestroyWindow( dsp, win );
XCloseDisplay( dsp );
}
redraw(suff.substr (jj), jj);
jj = ((jj + 1) % suff.length());
//usleep(200);
}
return 0;
}