sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

slock-showtime-1.5.diff (6293B)


      1 diff --git a/config.def.h b/config.def.h
      2 index 9855e21..bc883ad 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -1,6 +1,11 @@
      6 -/* user and group to drop privileges to */
      7 -static const char *user  = "nobody";
      8 +/* user and group to drop privileges to */ static const char *user  = "nobody";
      9  static const char *group = "nogroup";
     10 +/*Font settings for the time text*/
     11 +static const float textsize=64.0;
     12 +static const char* textfamily="serif";
     13 +static const double textcolorred=255;
     14 +static const double textcolorgreen=255;
     15 +static const double textcolorblue=255;
     16  
     17  static const char *colorname[NUMCOLS] = {
     18  	[INIT] =   "black",     /* after initialization */
     19 diff --git a/config.mk b/config.mk
     20 index 514c236..c42e301 100644
     21 --- a/config.mk
     22 +++ b/config.mk
     23 @@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib
     24  
     25  # includes and libs
     26  INCS = -I. -I/usr/include -I${X11INC}
     27 -LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
     28 +LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lcairo
     29  
     30  # flags
     31  CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
     32 diff --git a/slock.c b/slock.c
     33 index b2f14e3..d370a00 100644
     34 --- a/slock.c
     35 +++ b/slock.c
     36 @@ -5,6 +5,7 @@
     37  #endif
     38  
     39  #include <ctype.h>
     40 +#include <cairo/cairo-xlib.h>
     41  #include <errno.h>
     42  #include <grp.h>
     43  #include <pwd.h>
     44 @@ -18,7 +19,8 @@
     45  #include <X11/keysym.h>
     46  #include <X11/Xlib.h>
     47  #include <X11/Xutil.h>
     48 -
     49 +#include <pthread.h>
     50 +#include <time.h>
     51  #include "arg.h"
     52  #include "util.h"
     53  
     54 @@ -44,6 +46,14 @@ struct xrandr {
     55  	int errbase;
     56  };
     57  
     58 +struct displayData{
     59 +	struct lock **locks;
     60 +	Display* dpy;
     61 +	int nscreens;
     62 +	cairo_t **crs;
     63 +	cairo_surface_t **surfaces;
     64 +};
     65 +static pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER;
     66  #include "config.h"
     67  
     68  static void
     69 @@ -123,10 +133,46 @@ gethash(void)
     70  
     71  	return hash;
     72  }
     73 +static void
     74 +refresh(Display *dpy, Window win , int screen, struct tm time, cairo_t* cr, cairo_surface_t* sfc)
     75 +{/*Function that displays given time on the given screen*/
     76 +	static char tm[24]="";
     77 +	int xpos,ypos;
     78 +	xpos=DisplayWidth(dpy, screen)/4;
     79 +	ypos=DisplayHeight(dpy, screen)/2;
     80 +	sprintf(tm,"%02d/%02d/%d %02d:%02d",time.tm_mday,time.tm_mon + 1,time.tm_year+1900,time.tm_hour,time.tm_min);
     81 +	XClearWindow(dpy, win);
     82 +    cairo_set_source_rgb(cr, textcolorred, textcolorgreen, textcolorblue);
     83 +	cairo_select_font_face(cr, textfamily, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
     84 +    cairo_set_font_size(cr, textsize);
     85 +	cairo_move_to(cr, xpos, ypos);
     86 +	cairo_show_text(cr, tm);
     87 +	cairo_surface_flush(sfc);
     88 +	XFlush(dpy);
     89 +}
     90 +static void*
     91 +displayTime(void* input)
     92 +{ /*Thread that keeps track of time and refreshes it every 5 seconds */
     93 + struct displayData* displayData=(struct displayData*)input;
     94 + while (1){
     95 + pthread_mutex_lock(&mutex); /*Mutex to prevent interference with refreshing screen while typing password*/
     96 + time_t rawtime;
     97 + time(&rawtime);
     98 + struct tm tm = *localtime(&rawtime);
     99 + for (int k=0;k<displayData->nscreens;k++){
    100 +	 refresh(displayData->dpy, displayData->locks[k]->win, displayData->locks[k]->screen, tm,displayData->crs[k],displayData->surfaces[k]);
    101 +	 }
    102 + pthread_mutex_unlock(&mutex);
    103 + sleep(5);
    104 + }
    105 + return NULL;
    106 +}
    107 +
    108 +
    109  
    110  static void
    111  readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
    112 -       const char *hash)
    113 +       const char *hash,cairo_t **crs,cairo_surface_t **surfaces)
    114  {
    115  	XRRScreenChangeNotifyEvent *rre;
    116  	char buf[32], passwd[256], *inputhash;
    117 @@ -189,16 +235,23 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
    118  			}
    119  			color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
    120  			if (running && oldc != color) {
    121 +		        pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering*/
    122  				for (screen = 0; screen < nscreens; screen++) {
    123  					XSetWindowBackground(dpy,
    124  					                     locks[screen]->win,
    125  					                     locks[screen]->colors[color]);
    126  					XClearWindow(dpy, locks[screen]->win);
    127 +                    time_t rawtime;
    128 +                    time(&rawtime);
    129 +	                refresh(dpy, locks[screen]->win,locks[screen]->screen, *localtime(&rawtime),crs[screen],surfaces[screen]);
    130 +					/*Redraw the time after screen cleared*/
    131  				}
    132 +				pthread_mutex_unlock(&mutex);
    133  				oldc = color;
    134  			}
    135  		} else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
    136  			rre = (XRRScreenChangeNotifyEvent*)&ev;
    137 +		    pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering.*/
    138  			for (screen = 0; screen < nscreens; screen++) {
    139  				if (locks[screen]->win == rre->window) {
    140  					if (rre->rotation == RR_Rotate_90 ||
    141 @@ -212,6 +265,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
    142  					break;
    143  				}
    144  			}
    145 +
    146 +				pthread_mutex_unlock(&mutex);
    147  		} else {
    148  			for (screen = 0; screen < nscreens; screen++)
    149  				XRaiseWindow(dpy, locks[screen]->win);
    150 @@ -343,7 +398,7 @@ main(int argc, char **argv) {
    151  	errno = 0;
    152  	if (!crypt("", hash))
    153  		die("slock: crypt: %s\n", strerror(errno));
    154 -
    155 +	XInitThreads();
    156  	if (!(dpy = XOpenDisplay(NULL)))
    157  		die("slock: cannot open display\n");
    158  
    159 @@ -389,7 +444,33 @@ main(int argc, char **argv) {
    160  	}
    161  
    162  	/* everything is now blank. Wait for the correct password */
    163 -	readpw(dpy, &rr, locks, nscreens, hash);
    164 +	pthread_t thredid;
    165 +    /* Create Cairo drawables upon which the time will be shown. */
    166 +    struct displayData displayData;
    167 +	cairo_surface_t **surfaces;
    168 +	cairo_t **crs;
    169 +    if (!(surfaces=calloc(nscreens, sizeof(cairo_surface_t*)))){
    170 +		die("Out of memory");
    171 +	}
    172 +	if (!(crs=calloc(nscreens, sizeof(cairo_t*)))){
    173 +		die("Out of memory");
    174 +	}
    175 +	for (int k=0;k<nscreens;k++){
    176 +		Drawable win=locks[k]->win;
    177 +		int screen=locks[k]->screen;
    178 +		XMapWindow(dpy, win);
    179 +		surfaces[k]=cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, screen),DisplayWidth(dpy, screen) , DisplayHeight(dpy, screen));
    180 +		crs[k]=cairo_create(surfaces[k]);
    181 +	}
    182 +	displayData.dpy=dpy;
    183 +	displayData.locks=locks;
    184 +	displayData.nscreens=nscreens;
    185 +	displayData.crs=crs;
    186 +	displayData.surfaces=surfaces;
    187 +    /*Start the thread that redraws time every 5 seconds*/
    188 +	pthread_create(&thredid, NULL, displayTime, &displayData);
    189 +	/*Wait for the password*/
    190 +	readpw(dpy, &rr, locks, nscreens, hash,crs,surfaces);
    191  
    192  	return 0;
    193  }