commit 45dc8902a92e5b47cb3420f3e00a4bac31d03ac1
parent 135dcf099a6ff35bce21a62ed2b792085aab36ae
Author: mcizek <cizek.michal@gmail.com>
Date: Sat, 28 Oct 2023 16:55:36 -0400
[slock][patch][showtime] add patch
This patch displays the current date and time. It uses Cairo to render the text.
Diffstat:
2 files changed, 202 insertions(+), 0 deletions(-)
diff --git a/tools.suckless.org/slock/patches/showtime/index.md b/tools.suckless.org/slock/patches/showtime/index.md
@@ -0,0 +1,14 @@
+Show time
+=======
+
+Description
+-----------
+This patch simply displays the current date and time while the screen is locked. It requires the Cairo graphics library to render the text.
+
+Download
+--------
+* [slock-showtime-1.5.diff](slock-showtime-1.5.diff)
+
+Authors
+-------
+* Michal Cizek - <cizek.michal@gmail.com>
diff --git a/tools.suckless.org/slock/patches/showtime/slock-showtime-1.5.diff b/tools.suckless.org/slock/patches/showtime/slock-showtime-1.5.diff
@@ -0,0 +1,188 @@
+From: Michal Cizek <cizek.michal@gmail.com>
+Date: Sat, 28 Oct 2023 16:46:42 -0400
+Subject: [PATCH] Patch that displays current date and time on the locked
+ screen.
+
+---
+ config.mk | 2 +-
+ slock.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 86 insertions(+), 5 deletions(-)
+
+diff --git a/config.mk b/config.mk
+index 514c236..c42e301 100644
+--- a/config.mk
++++ b/config.mk
+@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib
+
+ # includes and libs
+ INCS = -I. -I/usr/include -I${X11INC}
+-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lcairo
+
+ # flags
+ CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
+diff --git a/slock.c b/slock.c
+index b2f14e3..03839bc 100644
+--- a/slock.c
++++ b/slock.c
+@@ -5,6 +5,7 @@
+ #endif
+
+ #include <ctype.h>
++#include <cairo/cairo-xlib.h>
+ #include <errno.h>
+ #include <grp.h>
+ #include <pwd.h>
+@@ -18,7 +19,8 @@
+ #include <X11/keysym.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+-
++#include <pthread.h>
++#include <time.h>
+ #include "arg.h"
+ #include "util.h"
+
+@@ -44,6 +46,14 @@ struct xrandr {
+ int errbase;
+ };
+
++struct displayData{
++ struct lock **locks;
++ Display* dpy;
++ int nscreens;
++ cairo_t **crs;
++ cairo_surface_t **surfaces;
++};
++static pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER;
+ #include "config.h"
+
+ static void
+@@ -123,10 +133,46 @@ gethash(void)
+
+ return hash;
+ }
++static void
++refresh(Display *dpy, Window win , int screen, struct tm time, cairo_t* cr, cairo_surface_t* sfc)
++{/*Function that displays given time on the given screen*/
++ static char tm[24]="";
++ int xpos,ypos;
++ xpos=DisplayWidth(dpy, screen)/4;
++ ypos=DisplayHeight(dpy, screen)/2;
++ sprintf(tm,"%02d/%02d/%d %02d:%02d",time.tm_mday,time.tm_mon,time.tm_year+1900,time.tm_hour,time.tm_min);
++ XClearWindow(dpy, win);
++ cairo_set_source_rgb(cr, 256, 256, 256);
++ cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
++ cairo_set_font_size(cr, 64.0);
++ cairo_move_to(cr, xpos, ypos);
++ cairo_show_text(cr, tm);
++ cairo_surface_flush(sfc);
++ XFlush(dpy);
++}
++static void*
++displayTime(void* input)
++{ /*Thread that keeps track of time and refreshes it every 5 seconds */
++ struct displayData* displayData=(struct displayData*)input;
++ while (1){
++ pthread_mutex_lock(&mutex); /*Mutex to prevent interference with refreshing screen while typing password*/
++ time_t rawtime;
++ time(&rawtime);
++ struct tm tm = *localtime(&rawtime);
++ for (int k=0;k<displayData->nscreens;k++){
++ refresh(displayData->dpy, displayData->locks[k]->win, displayData->locks[k]->screen, tm,displayData->crs[k],displayData->surfaces[k]);
++ }
++ pthread_mutex_unlock(&mutex);
++ sleep(5);
++ }
++ return NULL;
++}
++
++
+
+ static void
+ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+- const char *hash)
++ const char *hash,cairo_t **crs,cairo_surface_t **surfaces)
+ {
+ XRRScreenChangeNotifyEvent *rre;
+ char buf[32], passwd[256], *inputhash;
+@@ -189,16 +235,23 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ }
+ color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
+ if (running && oldc != color) {
++ pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering*/
+ for (screen = 0; screen < nscreens; screen++) {
+ XSetWindowBackground(dpy,
+ locks[screen]->win,
+ locks[screen]->colors[color]);
+ XClearWindow(dpy, locks[screen]->win);
++ time_t rawtime;
++ time(&rawtime);
++ refresh(dpy, locks[screen]->win,locks[screen]->screen, *localtime(&rawtime),crs[screen],surfaces[screen]);
++ /*Redraw the time after screen cleared*/
+ }
++ pthread_mutex_unlock(&mutex);
+ oldc = color;
+ }
+ } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
+ rre = (XRRScreenChangeNotifyEvent*)&ev;
++ pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering.*/
+ for (screen = 0; screen < nscreens; screen++) {
+ if (locks[screen]->win == rre->window) {
+ if (rre->rotation == RR_Rotate_90 ||
+@@ -212,6 +265,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ break;
+ }
+ }
++
++ pthread_mutex_unlock(&mutex);
+ } else {
+ for (screen = 0; screen < nscreens; screen++)
+ XRaiseWindow(dpy, locks[screen]->win);
+@@ -343,7 +398,7 @@ main(int argc, char **argv) {
+ errno = 0;
+ if (!crypt("", hash))
+ die("slock: crypt: %s\n", strerror(errno));
+-
++ XInitThreads();
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("slock: cannot open display\n");
+
+@@ -389,7 +444,33 @@ main(int argc, char **argv) {
+ }
+
+ /* everything is now blank. Wait for the correct password */
+- readpw(dpy, &rr, locks, nscreens, hash);
++ pthread_t thredid;
++ /* Create Cairo drawables upon which the time will be shown. */
++ struct displayData displayData;
++ cairo_surface_t **surfaces;
++ cairo_t **crs;
++ if (!(surfaces=calloc(nscreens, sizeof(cairo_surface_t*)))){
++ die("Out of memory");
++ }
++ if (!(crs=calloc(nscreens, sizeof(cairo_t*)))){
++ die("Out of memory");
++ }
++ for (int k=0;k<nscreens;k++){
++ Drawable win=locks[k]->win;
++ int screen=locks[k]->screen;
++ XMapWindow(dpy, win);
++ surfaces[k]=cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, screen),DisplayWidth(dpy, screen) , DisplayHeight(dpy, screen));
++ crs[k]=cairo_create(surfaces[k]);
++ }
++ displayData.dpy=dpy;
++ displayData.locks=locks;
++ displayData.nscreens=nscreens;
++ displayData.crs=crs;
++ displayData.surfaces=surfaces;
++ /*Start the thread that redraws time every 5 seconds*/
++ pthread_create(&thredid, NULL, displayTime, &displayData);
++ /*Wait for the password*/
++ readpw(dpy, &rr, locks, nscreens, hash,crs,surfaces);
+
+ return 0;
+ }
+--
+2.34.1
+