/* Analogue Clock Local Time X11 Desktop Application in C++ RJM Programming September, 2019 Thanks to ttps://www.linuxjournal.com/article/4879 */ #include /* puts, printf */ #include /* puts, printf */ #include /* time_t, struct tm, time, localtime */ #include #include #include #include #include #include #include #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 origx=50; int origy=50; time_t gtime_ptr; tm* gtm_local; int kk=1; bool doesFileExist(const std::string& name) { // thanks to https://stackoverflow.com/questions/46292764/check-for-file-existence-in-c-without-creating-file if (FILE *file = fopen(name.c_str(), "r")) { fclose(file); return true; } else { return false; } } 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), origx, origy, // origin 200, 200, // size 0, white, // border black ); // backgd } else { win = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), origx, origy, // 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 (kk > 1) { memcpy((buff + strlen(buff)), (-3 + strstr(ctime(&time_ptr), ":")), 21); //, (1 + strlen(suffix))); } else 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, 220 + (i % 11), 220 + (i % 11)); } while( evt.type != ButtonRelease && seconds < 1.0 ); //ButtonRelease ); //usleep(1000); XDestroyWindow( dsp, win ); XCloseDisplay( dsp ); dsp = NULL; } catch (int ez) { if (1 == 2) { printf("%i\n", ez); } } return 0; } int main(int argc, char* argv[]) { int status=0; int ostatus=256; int jj=0; char datehuh[80]="TZ= date\0"; char gbuff[81]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; kk=argc; gtime_ptr = time(NULL); gtm_local = localtime(>ime_ptr); strftime(gbuff,80,"%Z",gtm_local); std::string suff (" ... Click to refresh as required\0"); //suff.assign((std::string)" ... Click to refresh as required"); if (kk <= 1) { if (doesFileExist("get_tz.php")) { status=std::system("php -f get_tz.php"); ostatus=status; } } else { if (strstr(argv[1], "/")) { usleep(1100); if (doesFileExist("stop_x1.x1")) { remove("stop_x1.x1"); } usleep(1100); memcpy((datehuh + 3), argv[1], strlen(argv[1])); } else { kk=1; } } while (!doesFileExist("stop_x1.x1")) { if (dsp) { XDestroyWindow( dsp, win ); XCloseDisplay( dsp ); } redraw(suff.substr (jj), jj); jj = ((jj + 1) % suff.length()); if (kk <= 1) { std::system("date"); } else { gtime_ptr = time(NULL); printf("%s%s\n", ctime(>ime_ptr), gbuff); } //usleep(200); } if (doesFileExist("stop_x1.x1")) { remove("stop_x1.x1"); exit(EXIT_FAILURE); } return 0; }