slock

Kris's build of slock (slock-flexipatch)
git clone git clone https://git.krisyotam.com/krisyotam/slock.git
Log | Files | Refs | README | LICENSE

colormessage.c (3204B)


      1 #include <X11/extensions/Xinerama.h>
      2 
      3 /* global count to prevent repeated error messages */
      4 int count_error = 0;
      5 
      6 static int
      7 readescapedint(const char *str, int *i) {
      8 	int n = 0;
      9 	if (str[*i])
     10 		++*i;
     11 	while(str[*i] && str[*i] != ';' && str[*i] != 'm') {
     12 		n = 10 * n + str[*i] - '0';
     13 		++*i;
     14 	}
     15 	return n;
     16 }
     17 
     18 static void
     19 writemessage(Display *dpy, Window win, int screen)
     20 {
     21 	int len, line_len, width, height, s_width, s_height, i, k, tab_size, r, g, b, escaped_int, curr_line_len;
     22 	XGCValues gr_values;
     23 	XFontStruct *fontinfo;
     24 	XColor color, dummy;
     25 	XineramaScreenInfo *xsi;
     26 	GC gc;
     27 	fontinfo = XLoadQueryFont(dpy, font_name);
     28 
     29 	if (fontinfo == NULL) {
     30 		if (count_error == 0) {
     31 			fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name);
     32 			fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n");
     33 			count_error++;
     34 		}
     35 		return;
     36 	}
     37 
     38 	tab_size = 8 * XTextWidth(fontinfo, " ", 1);
     39 
     40 	XAllocNamedColor(dpy, DefaultColormap(dpy, screen),
     41 		text_color, &color, &dummy);
     42 
     43 	gr_values.font = fontinfo->fid;
     44 	gr_values.foreground = color.pixel;
     45 	gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values);
     46 
     47 	/*  To prevent "Uninitialized" warnings. */
     48 	xsi = NULL;
     49 
     50 	/*
     51 	 * Start formatting and drawing text
     52 	 */
     53 
     54 	len = strlen(message);
     55 
     56 	/* Max max line length (cut at '\n') */
     57 	line_len = curr_line_len = 0;
     58 	k = 0;
     59 	for (i = 0; i < len; i++) {
     60 		if (message[i] == '\n') {
     61 			curr_line_len = 0;
     62 			k++;
     63 		} else if (message[i] == 0x1b) {
     64 			while (i < len && message[i] != 'm') {
     65 				i++;
     66 			}
     67 			if (i == len)
     68 				die("slock: unclosed escape sequence\n");
     69 		} else {
     70 			curr_line_len += XTextWidth(fontinfo, message + i, 1);
     71 			if (curr_line_len > line_len)
     72 				line_len = curr_line_len;
     73 		 }
     74 	}
     75 	/* If there is only one line */
     76 	if (line_len == 0)
     77 		line_len = len;
     78 
     79 	if (XineramaIsActive(dpy)) {
     80 		xsi = XineramaQueryScreens(dpy, &i);
     81 		s_width = xsi[0].width;
     82 		s_height = xsi[0].height;
     83 	} else {
     84 		s_width = DisplayWidth(dpy, screen);
     85 		s_height = DisplayHeight(dpy, screen);
     86 	}
     87 	height = s_height*3/7 - (k*20)/3;
     88 	width  = (s_width - line_len)/2;
     89 
     90 	line_len = 0;
     91 	/* print the text while parsing 24 bit color ANSI escape codes*/
     92 	for (i = k = 0; i < len; i++) {
     93 		switch (message[i]) {
     94 			case '\n':
     95 				line_len = 0;
     96 				while (message[i + 1] == '\t') {
     97 					line_len += tab_size;
     98 					i++;
     99 				}
    100 				k++;
    101 				break;
    102 			case 0x1b:
    103 				i++;
    104 				if (message[i] == '[') {
    105 					escaped_int = readescapedint(message, &i);
    106 					if (escaped_int == 39)
    107 						continue;
    108 					if (escaped_int != 38)
    109 						die("slock: unknown escape sequence%d\n", escaped_int);
    110 					if (readescapedint(message, &i) != 2)
    111 						die("slock: only 24 bit color supported\n");
    112 					r = readescapedint(message, &i) & 0xff;
    113 					g = readescapedint(message, &i) & 0xff;
    114 					b = readescapedint(message, &i) & 0xff;
    115 					XSetForeground(dpy, gc, r << 16 | g << 8 | b);
    116 				} else
    117 					die("slock: unknown escape sequence\n");
    118 				break;
    119 			default:
    120 				XDrawString(dpy, win, gc, width + line_len, height + 20 * k, message + i, 1);
    121 				line_len += XTextWidth(fontinfo, message + i, 1);
    122 		}
    123 	}
    124 
    125 	/* xsi should not be NULL anyway if Xinerama is active, but to be safe */
    126 	if (XineramaIsActive(dpy) && xsi != NULL)
    127 		XFree(xsi);
    128 }