Skip to content

Instantly share code, notes, and snippets.

@la11111
Created November 11, 2012 12:52
Show Gist options
  • Select an option

  • Save la11111/4054818 to your computer and use it in GitHub Desktop.

Select an option

Save la11111/4054818 to your computer and use it in GitHub Desktop.
DWM patch - Ansi escape codes to colorize your status bar - 5.9 & 6.0 tested OK
--- dwm.c 2011-07-10 15:24:25.000000000 -0500
+++ dwm-ansistatuscolors.c 2012-11-12 22:59:41.975424068 -0600
@@ -53,6 +53,7 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height)
+#define STATUS_BUF_LEN 8192 //la11111
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@@ -247,7 +248,7 @@
/* variables */
static const char broken[] = "broken";
-static char stext[256];
+static char stext[STATUS_BUF_LEN]; //la11111
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -282,6 +283,24 @@
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+//////////////////////////// la11111
+enum { ansi_reset, ansi_fg, ansi_bg, ansi_text, ansi_last};
+
+struct ansi_node {
+ int type;
+ char * color;
+ char * text;
+ struct ansi_node *next;
+};
+
+static void drawcoloredtext(const char *text, unsigned long fg, unsigned long bg);
+static void ParseAnsiEsc(char * seq, char buffer[]);
+static void GetAnsiColor(int escapecode, char buffer[]);
+static int countchars(char c, char * buf);
+static struct ansi_node * addnode(struct ansi_node *head, int type, char * color, char * text);
+static void destroy_llist(struct ansi_node *head);
+static void drawstatus(Monitor *m);
+///////////////////////////////
/* function implementations */
void
applyrules(Client *c) {
@@ -747,13 +766,8 @@
dc.x += dc.w;
x = dc.x;
if(m == selmon) { /* status is only drawn on selected monitor */
- dc.w = TEXTW(stext);
- dc.x = m->ww - dc.w;
- if(dc.x < x) {
- dc.x = x;
- dc.w = m->ww - x;
- }
- drawtext(stext, dc.norm, False);
+
+ drawstatus(m); //la11111
}
else
dc.x = m->ww;
@@ -2067,3 +2081,449 @@
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}
+
+
+/*************************************************
+ansistatuscolors
+by la11111
+
+updated 11.12.12 - squashed my code together to
+patch better across versions - killed remaining memory
+leaks. removed some useless junk.
+
+put ansi escape codes in your status bar output to
+change the color. Note: full ansi spec not implemented
+at the moment. incorrect codes are ignored, even if they
+may be valid ansi codes (ie, changing up the order or something)
+
+*** escape code format:
+
+\e[<code>m
+
+ \e - ascii 27, hex 0x1b, octal 033
+ [ - literal bracket
+ m - literal 'm'
+
+*** codes supported:
+
+standard escape codes:
+
+n;m
+ n -
+ 0 - normal
+ 1 - 'bright'
+ m -
+ 30-37 - text foreground
+ 40-47 - text background
+
+0 -
+ reset formatting to default
+
+example (python):
+ print "\x1b[1;31mHello World!\x1b[0m"
+
+256-color escape codes (xterm):
+
+n;5;m
+ n -
+ 38 - text foreground
+ 48 - text background
+ m -
+ 0-15 - alias classic ansi colors
+ 16-231 - rgb grid color
+ 232-255 - grayscale ramp color
+
+example (python):
+ print "\x1b[38;5;196mHello World!\x1b[0m"
+
+for more info about escape sequences in general, see:
+http://www.frexx.de/xterm-256-notes/
+
+enjoy, my friends
+-la0x1f
+***************************************************/
+
+void
+drawcoloredtext(const char *text, unsigned long fg, unsigned long bg) {
+ char buf[256];
+ int x, y, h, olen, len;
+
+ XSetForeground(dpy, dc.gc, bg);
+
+ XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
+ if(!text)
+ return;
+ olen = strlen(text);
+ h = dc.font.ascent + dc.font.descent;
+ y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
+ x = dc.x;
+ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w; len--);
+ if(!len)
+ return;
+ memcpy(buf, text, len);
+
+ XSetForeground(dpy, dc.gc, fg);
+ if(dc.font.set)
+ XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
+ else
+ XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
+}
+
+struct
+ansi_node * addnode(struct ansi_node *head, int type, char * color, char * text) {
+ struct ansi_node* tmp;
+ if (head == NULL) {
+ head=(struct ansi_node *)malloc(sizeof(struct ansi_node));
+ if (head == NULL) {
+ // printf("you're out of memory, son\n");
+ exit(1);
+ }
+ head->next = head;
+ head->type = type;
+ head->color = color;
+ head->text = text;
+ } else {
+ tmp = head;
+ while(tmp->next != head)
+ tmp = tmp->next;
+ tmp->next = (struct ansi_node *)malloc(sizeof(struct ansi_node));
+ if (tmp->next == NULL) {
+ // printf("you're out of memory, son\n");
+ exit(1);
+ }
+ tmp = tmp->next;
+ tmp->next = head;
+ tmp->type = type;
+ tmp->color = color;
+ tmp->text = text;
+ }
+ return head;
+}
+
+void
+destroy_llist(struct ansi_node *head) {
+ struct ansi_node *current, *tmp;
+ current = head->next;
+ head->next = NULL;
+ while (current != NULL) {
+ tmp = current->next;
+ free(current);
+ current = tmp;
+ }
+}
+
+void
+drawstatus (Monitor *m) {
+ /*
+ this function makes 2 passes:
+ -chops status text into pieces based on esc codes
+ -puts esc codes & text blocks in a linked list
+ -goes back through and outputs those blocks one at a time
+ in the color specified by the preceding escape code
+ */
+ char * startpos = stext;
+ char * curpos = stext;
+ char * escstartpos = stext;
+ int inescape = 0;
+ int esc_len, text_len;
+ char * textbuf;
+ char * escbuf;
+ char plaintextbuf[1024] = "\0";
+ char color[16];
+ char * color_ptr;
+ int curpos_ctr = 0;
+ int input_len = strlen(stext);
+ int plain_text_len = 0;
+ unsigned long cur_fg = dc.norm[ColFG];
+ unsigned long cur_bg = dc.norm[ColBG];
+ struct ansi_node *head = NULL;
+ int x, x_orig;
+ struct ansi_node *curn;
+
+
+ while (curpos_ctr < input_len) {
+ if (*curpos == '\x1b') {
+ if (!(inescape)) {
+ inescape = 1;
+ escstartpos = curpos;
+ curpos++;
+ curpos_ctr++;
+ if (*curpos != '[') {
+ escstartpos = startpos;
+ inescape = 0;
+ } else {
+ curpos++;
+ curpos_ctr++;
+ }
+ } else {
+ escstartpos = startpos;
+ inescape = 0;
+ }
+ } else {
+ if (inescape) {
+ if ( ((*curpos >= '0' ) && (*curpos <= '9')) || (*curpos == ';') ) {
+ curpos++;
+ curpos_ctr++;
+ } else {
+ if (*curpos == 'm') {
+ esc_len = curpos - escstartpos;
+ escbuf = malloc(esc_len-1);
+ if (escbuf) { strncpy(escbuf, escstartpos+2, esc_len-2); }
+ escbuf[esc_len-2] = '\0';
+ ParseAnsiEsc(escbuf, color);
+ free(escbuf);
+ text_len= escstartpos - startpos;
+ if (text_len > 0) {
+ plain_text_len += text_len;
+ textbuf = malloc((text_len * sizeof(char))+ 1);
+ if (textbuf) { strncpy(textbuf, startpos, text_len);}
+ textbuf[text_len] = '\0';
+ strcat(plaintextbuf, textbuf);
+ head = addnode(head, ansi_text, "", strcpy(malloc(strlen(textbuf)+1), textbuf));
+ free(textbuf);
+ }
+ color_ptr = color;
+ if (color[0] == 'r') {
+ head = addnode(head, ansi_reset, strcpy( malloc(strlen(color)+1), color), "");
+ } else if (color[0] == 'f') { //chops off 'fg:'
+ head = addnode(head, ansi_fg, strcpy( malloc(strlen(color)-2), color_ptr+3),"");
+ } else if (color[0] == 'b') {
+ head = addnode(head, ansi_bg, strcpy(malloc(strlen(color)-2),color_ptr+3), "");
+ } else {
+ head = addnode(head, -1, "", "");
+ }
+ curpos++;
+ startpos = curpos;
+ escstartpos = curpos;
+ } else {
+ escstartpos = startpos;
+ curpos++;
+ curpos_ctr++;
+ }
+ inescape = 0;
+ }
+ } else {
+ curpos++;
+ curpos_ctr++;
+ }
+ }
+ }
+ if(strlen(startpos)) {
+ text_len= strlen(startpos);
+ textbuf = malloc((text_len * sizeof(char))+ 1);
+ if (textbuf) { strncpy(textbuf, startpos, text_len);}
+ textbuf[text_len] = '\0';
+ plain_text_len += strlen(startpos);
+ strcat(plaintextbuf, startpos);
+ head = addnode(head, ansi_text, "", strcpy(malloc(strlen(textbuf)+1), textbuf));
+ free(textbuf);
+ }
+ x = dc.x;
+ dc.x = m->ww - textnw(plaintextbuf, strlen(plaintextbuf));
+ // not sure what would happen here... something wierd probably
+ if(dc.x < x) {
+ dc.x = x;
+ dc.w = m->ww - x;
+ }
+ x_orig = dc.x; //reset dc.x after so the window title doesn't overwrite status
+ curn = head; //iterate linked list
+ if (curn != NULL) {
+ do {
+ if (curn->type == -1) continue;
+ if (curn->type == ansi_reset) {
+ cur_fg = dc.norm[ColFG];
+ cur_bg = dc.norm[ColBG];
+ free(curn->color);
+ } else if (curn->type == ansi_fg) {
+ cur_fg = getcolor(curn->color);
+ free(curn->color);
+ } else if (curn->type == ansi_bg) {
+ cur_bg = getcolor(curn->color);
+ free(curn->color);
+ } else if (curn->type == ansi_text) {
+ dc.w = textnw(curn->text, strlen(curn->text));
+ drawcoloredtext(curn->text, cur_fg, cur_bg);
+ dc.x += dc.w;
+
+ free(curn->text);
+
+
+
+ } else {
+ continue;
+ }
+ curn = curn->next;
+ } while (curn != head);
+ }
+ dc.x = x_orig;
+ destroy_llist(head);
+}
+
+int //count occurrences of c in buf
+countchars(char c, char * buf) {
+ char *ptr = buf;
+ int ctr = 0;
+ while(*ptr) {
+ if(*ptr == c) ctr++;
+ ptr++;
+ }
+ return ctr;
+}
+
+void
+ParseAnsiEsc(char * seq, char buffer[]){
+ char *cp, *token;
+ static char * standardcolors[2][8] = {
+ {"#000000\0","#800000\0","#008000\0","#808000\0","#000080\0","#800080\0","#008080\0","#c0c0c0\0"},
+ {"#808080\0","#ff0000\0","#00ff00\0","#ffff00\0","#0000ff\0","#ff00ff\0","#00ffff\0","#ffffff\0"}
+ };
+ char * retbuf = (void *)buffer;
+ retbuf[0] = '\0';
+
+ cp = malloc(strlen(seq) + 1);
+ if (cp) { strcpy(cp, seq); }
+
+ int semis = countchars(';',seq);
+ char *delim = ";";
+ char * toklist[semis + 1];
+ int tok_ctr = 0;
+ int arglist[semis + 1];
+ char color[8];
+ int r,c,i,j;
+ char * layer;
+
+ token = strtok(cp,delim);
+ while(token) {
+ toklist[tok_ctr] = token;
+ tok_ctr++;
+ token = strtok(NULL,delim);
+ }
+ if ((tok_ctr > 3) || (tok_ctr < 1)) {
+ free(cp);
+ return;
+ }
+ if (tok_ctr == 1) {
+ if (strlen(toklist[0]) != 1) return;
+ if (toklist[0][0] != '0') {
+ free(cp);
+ return;
+ } else {
+ sprintf(retbuf,"r"); //reset to default
+ free(cp);
+ return;
+ }
+ }
+ for (i=0; i < tok_ctr; i++) {
+ for(j=0; j < strlen(toklist[i]); j++){
+ if ((toklist[i][j] < '0') || (toklist[i][j] > '9')) {
+ free(cp);
+ return;
+ }
+ }
+ arglist[i] = atoi(toklist[i]);
+ }
+ if (tok_ctr == 3) {
+ if (!(
+ (arglist[1] == 5) &&
+ ((arglist[0] == 38) || (arglist[0] == 48)) &&
+ (arglist[2] >= 16) &&
+ (arglist[2] <= 255)
+ )) {
+ free(cp);
+ return;
+ } else {
+ if (arglist[0] == 38) {
+ sprintf(retbuf,"fg:");
+ } else {
+ sprintf(retbuf,"bg:");
+ }
+
+ GetAnsiColor(arglist[2], color);
+ strcat(retbuf, color);
+ free(cp);
+ return;
+ }
+ } else {
+ for (i = 0; i < tok_ctr; i++) {
+ if (!(
+ (arglist[i] == 0) ||
+ (arglist[i] == 1) ||
+ ((arglist[i] >= 30) && (arglist[i] <= 37)) ||
+ ((arglist[i] >= 40) && (arglist[i] <= 47))
+ )) {
+ free(cp);
+ return;
+ }
+ }
+ if ((arglist[0] < 30)
+ && (arglist[1] < 30)) {
+ free(cp);
+ return;
+ }
+ if ((arglist[0] > 1)
+ && (arglist[1] > 1)) {
+ free(cp);
+ return;
+ }
+ if (arglist[0] < 30) {
+ r = arglist[0];
+ c = arglist[1];
+ } else {
+ r = arglist[1];
+ c = arglist[0];
+ }
+ if (c > 37) {
+ layer = "bg:";
+ c -= 10;
+ } else {
+ layer = "fg:";
+ }
+ sprintf(retbuf, "%s%s", layer, standardcolors[r][c-30]);
+ free(cp);
+ }
+}
+
+void
+GetAnsiColor(int escapecode, char buffer[]){
+ char steps[6][3] = {
+ "00\0", "5f\0", "87\0", "af\0", "d6\0", "ff\0",
+ };
+ int i, panel, cell, col, row, val;
+ int cmin = 16;
+ int cmax = 231;
+ int gmax = 255;
+ int n = escapecode;
+ char * retbuf = (void *)buffer;
+
+ if (n < cmin) {
+ return;
+ } else if (n > gmax) {
+ return;
+ } else if (n <= cmax) {
+ i = n - 15;
+ panel = i / 36;
+ cell = i % 36;
+ if (cell == 0) {
+ cell = 36;
+ panel -= 1;
+ }
+ col = cell / 6;
+ row = cell % 6;
+ if (row == 0) {
+ col -= 1;
+ row = 5;
+ } else {
+ row -= 1;
+ }
+ sprintf(retbuf, "#%s%s%s", steps[panel], steps[col], steps[row]);
+ } else {
+ val = ((10*(n-232))+8);
+ sprintf(retbuf, "#%.2x%.2x%.2x",val,val,val);
+ }
+}
+
+/*************************************************
+end ansistatuscolors - la11111
+***************************************************/
+
+
--- dwm.c.orig 2011-12-19 09:02:46.000000000 -0600
+++ dwm.c 2012-11-12 23:04:14.383441523 -0600
@@ -54,6 +54,7 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height)
+#define STATUS_BUF_LEN 8192 //la11111
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@@ -254,7 +255,7 @@
/* variables */
static const char broken[] = "broken";
-static char stext[256];
+static char stext[STATUS_BUF_LEN]; //la11111
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -290,6 +291,24 @@
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+//////////////////////////// la11111
+enum { ansi_reset, ansi_fg, ansi_bg, ansi_text, ansi_last};
+
+struct ansi_node {
+ int type;
+ char * color;
+ char * text;
+ struct ansi_node *next;
+};
+
+static void drawcoloredtext(const char *text, unsigned long fg, unsigned long bg);
+static void ParseAnsiEsc(char * seq, char buffer[]);
+static void GetAnsiColor(int escapecode, char buffer[]);
+static int countchars(char c, char * buf);
+static struct ansi_node * addnode(struct ansi_node *head, int type, char * color, char * text);
+static void destroy_llist(struct ansi_node *head);
+static void drawstatus(Monitor *m);
+///////////////////////////////
/* function implementations */
void
applyrules(Client *c) {
@@ -741,13 +760,8 @@
dc.x += dc.w;
x = dc.x;
if(m == selmon) { /* status is only drawn on selected monitor */
- dc.w = TEXTW(stext);
- dc.x = m->ww - dc.w;
- if(dc.x < x) {
- dc.x = x;
- dc.w = m->ww - x;
- }
- drawtext(stext, dc.norm, False);
+
+ drawstatus(m); //la11111
}
else
dc.x = m->ww;
@@ -2144,3 +2158,449 @@
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}
+
+
+/*************************************************
+ansistatuscolors
+by la11111
+
+updated 11.12.12 - squashed my code together to
+patch better across versions - killed remaining memory
+leaks. removed some useless junk.
+
+put ansi escape codes in your status bar output to
+change the color. Note: full ansi spec not implemented
+at the moment. incorrect codes are ignored, even if they
+may be valid ansi codes (ie, changing up the order or something)
+
+*** escape code format:
+
+\e[<code>m
+
+ \e - ascii 27, hex 0x1b, octal 033
+ [ - literal bracket
+ m - literal 'm'
+
+*** codes supported:
+
+standard escape codes:
+
+n;m
+ n -
+ 0 - normal
+ 1 - 'bright'
+ m -
+ 30-37 - text foreground
+ 40-47 - text background
+
+0 -
+ reset formatting to default
+
+example (python):
+ print "\x1b[1;31mHello World!\x1b[0m"
+
+256-color escape codes (xterm):
+
+n;5;m
+ n -
+ 38 - text foreground
+ 48 - text background
+ m -
+ 0-15 - alias classic ansi colors
+ 16-231 - rgb grid color
+ 232-255 - grayscale ramp color
+
+example (python):
+ print "\x1b[38;5;196mHello World!\x1b[0m"
+
+for more info about escape sequences in general, see:
+http://www.frexx.de/xterm-256-notes/
+
+enjoy, my friends
+-la0x1f
+***************************************************/
+
+void
+drawcoloredtext(const char *text, unsigned long fg, unsigned long bg) {
+ char buf[256];
+ int x, y, h, olen, len;
+
+ XSetForeground(dpy, dc.gc, bg);
+
+ XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
+ if(!text)
+ return;
+ olen = strlen(text);
+ h = dc.font.ascent + dc.font.descent;
+ y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
+ x = dc.x;
+ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w; len--);
+ if(!len)
+ return;
+ memcpy(buf, text, len);
+
+ XSetForeground(dpy, dc.gc, fg);
+ if(dc.font.set)
+ XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
+ else
+ XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
+}
+
+struct
+ansi_node * addnode(struct ansi_node *head, int type, char * color, char * text) {
+ struct ansi_node* tmp;
+ if (head == NULL) {
+ head=(struct ansi_node *)malloc(sizeof(struct ansi_node));
+ if (head == NULL) {
+ // printf("you're out of memory, son\n");
+ exit(1);
+ }
+ head->next = head;
+ head->type = type;
+ head->color = color;
+ head->text = text;
+ } else {
+ tmp = head;
+ while(tmp->next != head)
+ tmp = tmp->next;
+ tmp->next = (struct ansi_node *)malloc(sizeof(struct ansi_node));
+ if (tmp->next == NULL) {
+ // printf("you're out of memory, son\n");
+ exit(1);
+ }
+ tmp = tmp->next;
+ tmp->next = head;
+ tmp->type = type;
+ tmp->color = color;
+ tmp->text = text;
+ }
+ return head;
+}
+
+void
+destroy_llist(struct ansi_node *head) {
+ struct ansi_node *current, *tmp;
+ current = head->next;
+ head->next = NULL;
+ while (current != NULL) {
+ tmp = current->next;
+ free(current);
+ current = tmp;
+ }
+}
+
+void
+drawstatus (Monitor *m) {
+ /*
+ this function makes 2 passes:
+ -chops status text into pieces based on esc codes
+ -puts esc codes & text blocks in a linked list
+ -goes back through and outputs those blocks one at a time
+ in the color specified by the preceding escape code
+ */
+ char * startpos = stext;
+ char * curpos = stext;
+ char * escstartpos = stext;
+ int inescape = 0;
+ int esc_len, text_len;
+ char * textbuf;
+ char * escbuf;
+ char plaintextbuf[1024] = "\0";
+ char color[16];
+ char * color_ptr;
+ int curpos_ctr = 0;
+ int input_len = strlen(stext);
+ int plain_text_len = 0;
+ unsigned long cur_fg = dc.norm[ColFG];
+ unsigned long cur_bg = dc.norm[ColBG];
+ struct ansi_node *head = NULL;
+ int x, x_orig;
+ struct ansi_node *curn;
+
+
+ while (curpos_ctr < input_len) {
+ if (*curpos == '\x1b') {
+ if (!(inescape)) {
+ inescape = 1;
+ escstartpos = curpos;
+ curpos++;
+ curpos_ctr++;
+ if (*curpos != '[') {
+ escstartpos = startpos;
+ inescape = 0;
+ } else {
+ curpos++;
+ curpos_ctr++;
+ }
+ } else {
+ escstartpos = startpos;
+ inescape = 0;
+ }
+ } else {
+ if (inescape) {
+ if ( ((*curpos >= '0' ) && (*curpos <= '9')) || (*curpos == ';') ) {
+ curpos++;
+ curpos_ctr++;
+ } else {
+ if (*curpos == 'm') {
+ esc_len = curpos - escstartpos;
+ escbuf = malloc(esc_len-1);
+ if (escbuf) { strncpy(escbuf, escstartpos+2, esc_len-2); }
+ escbuf[esc_len-2] = '\0';
+ ParseAnsiEsc(escbuf, color);
+ free(escbuf);
+ text_len= escstartpos - startpos;
+ if (text_len > 0) {
+ plain_text_len += text_len;
+ textbuf = malloc((text_len * sizeof(char))+ 1);
+ if (textbuf) { strncpy(textbuf, startpos, text_len);}
+ textbuf[text_len] = '\0';
+ strcat(plaintextbuf, textbuf);
+ head = addnode(head, ansi_text, "", strcpy(malloc(strlen(textbuf)+1), textbuf));
+ free(textbuf);
+ }
+ color_ptr = color;
+ if (color[0] == 'r') {
+ head = addnode(head, ansi_reset, strcpy( malloc(strlen(color)+1), color), "");
+ } else if (color[0] == 'f') { //chops off 'fg:'
+ head = addnode(head, ansi_fg, strcpy( malloc(strlen(color)-2), color_ptr+3),"");
+ } else if (color[0] == 'b') {
+ head = addnode(head, ansi_bg, strcpy(malloc(strlen(color)-2),color_ptr+3), "");
+ } else {
+ head = addnode(head, -1, "", "");
+ }
+ curpos++;
+ startpos = curpos;
+ escstartpos = curpos;
+ } else {
+ escstartpos = startpos;
+ curpos++;
+ curpos_ctr++;
+ }
+ inescape = 0;
+ }
+ } else {
+ curpos++;
+ curpos_ctr++;
+ }
+ }
+ }
+ if(strlen(startpos)) {
+ text_len= strlen(startpos);
+ textbuf = malloc((text_len * sizeof(char))+ 1);
+ if (textbuf) { strncpy(textbuf, startpos, text_len);}
+ textbuf[text_len] = '\0';
+ plain_text_len += strlen(startpos);
+ strcat(plaintextbuf, startpos);
+ head = addnode(head, ansi_text, "", strcpy(malloc(strlen(textbuf)+1), textbuf));
+ free(textbuf);
+ }
+ x = dc.x;
+ dc.x = m->ww - textnw(plaintextbuf, strlen(plaintextbuf));
+ // not sure what would happen here... something wierd probably
+ if(dc.x < x) {
+ dc.x = x;
+ dc.w = m->ww - x;
+ }
+ x_orig = dc.x; //reset dc.x after so the window title doesn't overwrite status
+ curn = head; //iterate linked list
+ if (curn != NULL) {
+ do {
+ if (curn->type == -1) continue;
+ if (curn->type == ansi_reset) {
+ cur_fg = dc.norm[ColFG];
+ cur_bg = dc.norm[ColBG];
+ free(curn->color);
+ } else if (curn->type == ansi_fg) {
+ cur_fg = getcolor(curn->color);
+ free(curn->color);
+ } else if (curn->type == ansi_bg) {
+ cur_bg = getcolor(curn->color);
+ free(curn->color);
+ } else if (curn->type == ansi_text) {
+ dc.w = textnw(curn->text, strlen(curn->text));
+ drawcoloredtext(curn->text, cur_fg, cur_bg);
+ dc.x += dc.w;
+
+ free(curn->text);
+
+
+
+ } else {
+ continue;
+ }
+ curn = curn->next;
+ } while (curn != head);
+ }
+ dc.x = x_orig;
+ destroy_llist(head);
+}
+
+int //count occurrences of c in buf
+countchars(char c, char * buf) {
+ char *ptr = buf;
+ int ctr = 0;
+ while(*ptr) {
+ if(*ptr == c) ctr++;
+ ptr++;
+ }
+ return ctr;
+}
+
+void
+ParseAnsiEsc(char * seq, char buffer[]){
+ char *cp, *token;
+ static char * standardcolors[2][8] = {
+ {"#000000\0","#800000\0","#008000\0","#808000\0","#000080\0","#800080\0","#008080\0","#c0c0c0\0"},
+ {"#808080\0","#ff0000\0","#00ff00\0","#ffff00\0","#0000ff\0","#ff00ff\0","#00ffff\0","#ffffff\0"}
+ };
+ char * retbuf = (void *)buffer;
+ retbuf[0] = '\0';
+
+ cp = malloc(strlen(seq) + 1);
+ if (cp) { strcpy(cp, seq); }
+
+ int semis = countchars(';',seq);
+ char *delim = ";";
+ char * toklist[semis + 1];
+ int tok_ctr = 0;
+ int arglist[semis + 1];
+ char color[8];
+ int r,c,i,j;
+ char * layer;
+
+ token = strtok(cp,delim);
+ while(token) {
+ toklist[tok_ctr] = token;
+ tok_ctr++;
+ token = strtok(NULL,delim);
+ }
+ if ((tok_ctr > 3) || (tok_ctr < 1)) {
+ free(cp);
+ return;
+ }
+ if (tok_ctr == 1) {
+ if (strlen(toklist[0]) != 1) return;
+ if (toklist[0][0] != '0') {
+ free(cp);
+ return;
+ } else {
+ sprintf(retbuf,"r"); //reset to default
+ free(cp);
+ return;
+ }
+ }
+ for (i=0; i < tok_ctr; i++) {
+ for(j=0; j < strlen(toklist[i]); j++){
+ if ((toklist[i][j] < '0') || (toklist[i][j] > '9')) {
+ free(cp);
+ return;
+ }
+ }
+ arglist[i] = atoi(toklist[i]);
+ }
+ if (tok_ctr == 3) {
+ if (!(
+ (arglist[1] == 5) &&
+ ((arglist[0] == 38) || (arglist[0] == 48)) &&
+ (arglist[2] >= 16) &&
+ (arglist[2] <= 255)
+ )) {
+ free(cp);
+ return;
+ } else {
+ if (arglist[0] == 38) {
+ sprintf(retbuf,"fg:");
+ } else {
+ sprintf(retbuf,"bg:");
+ }
+
+ GetAnsiColor(arglist[2], color);
+ strcat(retbuf, color);
+ free(cp);
+ return;
+ }
+ } else {
+ for (i = 0; i < tok_ctr; i++) {
+ if (!(
+ (arglist[i] == 0) ||
+ (arglist[i] == 1) ||
+ ((arglist[i] >= 30) && (arglist[i] <= 37)) ||
+ ((arglist[i] >= 40) && (arglist[i] <= 47))
+ )) {
+ free(cp);
+ return;
+ }
+ }
+ if ((arglist[0] < 30)
+ && (arglist[1] < 30)) {
+ free(cp);
+ return;
+ }
+ if ((arglist[0] > 1)
+ && (arglist[1] > 1)) {
+ free(cp);
+ return;
+ }
+ if (arglist[0] < 30) {
+ r = arglist[0];
+ c = arglist[1];
+ } else {
+ r = arglist[1];
+ c = arglist[0];
+ }
+ if (c > 37) {
+ layer = "bg:";
+ c -= 10;
+ } else {
+ layer = "fg:";
+ }
+ sprintf(retbuf, "%s%s", layer, standardcolors[r][c-30]);
+ free(cp);
+ }
+}
+
+void
+GetAnsiColor(int escapecode, char buffer[]){
+ char steps[6][3] = {
+ "00\0", "5f\0", "87\0", "af\0", "d6\0", "ff\0",
+ };
+ int i, panel, cell, col, row, val;
+ int cmin = 16;
+ int cmax = 231;
+ int gmax = 255;
+ int n = escapecode;
+ char * retbuf = (void *)buffer;
+
+ if (n < cmin) {
+ return;
+ } else if (n > gmax) {
+ return;
+ } else if (n <= cmax) {
+ i = n - 15;
+ panel = i / 36;
+ cell = i % 36;
+ if (cell == 0) {
+ cell = 36;
+ panel -= 1;
+ }
+ col = cell / 6;
+ row = cell % 6;
+ if (row == 0) {
+ col -= 1;
+ row = 5;
+ } else {
+ row -= 1;
+ }
+ sprintf(retbuf, "#%s%s%s", steps[panel], steps[col], steps[row]);
+ } else {
+ val = ((10*(n-232))+8);
+ sprintf(retbuf, "#%.2x%.2x%.2x",val,val,val);
+ }
+}
+
+/*************************************************
+end ansistatuscolors - la11111
+***************************************************/
+
+
@sayan01
Copy link
Copy Markdown

sayan01 commented Dec 24, 2020

will this wonderful patch not be updated to the latest dwm versions? I would really like to use this.

@la11111
Copy link
Copy Markdown
Author

la11111 commented Dec 24, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment