sites

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

dwm-ansistatuscolors-5.9.diff (15188B)


      1 --- dwm.c	2011-07-10 15:24:25.000000000 -0500
      2 +++ dwm-ansistatuscolors.c	2012-11-12 22:59:41.975424068 -0600
      3 @@ -53,6 +53,7 @@
      4  #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
      5  #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
      6  #define TEXTW(X)                (textnw(X, strlen(X)) + dc.font.height)
      7 +#define STATUS_BUF_LEN          8192 //la11111
      8  
      9  /* enums */
     10  enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
     11 @@ -247,7 +248,7 @@
     12  
     13  /* variables */
     14  static const char broken[] = "broken";
     15 -static char stext[256];
     16 +static char stext[STATUS_BUF_LEN]; //la11111
     17  static int screen;
     18  static int sw, sh;           /* X display screen geometry width, height */
     19  static int bh, blw = 0;      /* bar geometry */
     20 @@ -282,6 +283,24 @@
     21  /* compile-time check if all tags fit into an unsigned int bit array. */
     22  struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
     23  
     24 +//////////////////////////// la11111
     25 +enum { ansi_reset, ansi_fg, ansi_bg, ansi_text, ansi_last};
     26 +
     27 +struct ansi_node {
     28 +    int type;
     29 +    char * color;
     30 +    char * text; 
     31 +    struct ansi_node *next;
     32 +};
     33 +
     34 +static void drawcoloredtext(const char *text, unsigned long fg, unsigned long bg);
     35 +static void ParseAnsiEsc(char * seq, char buffer[]);
     36 +static void GetAnsiColor(int escapecode, char buffer[]);
     37 +static int countchars(char c, char * buf);
     38 +static struct ansi_node * addnode(struct ansi_node *head, int type, char * color, char * text);
     39 +static void destroy_llist(struct ansi_node *head);
     40 +static void drawstatus(Monitor *m);
     41 +///////////////////////////////
     42  /* function implementations */
     43  void
     44  applyrules(Client *c) {
     45 @@ -747,13 +766,8 @@
     46  	dc.x += dc.w;
     47  	x = dc.x;
     48  	if(m == selmon) { /* status is only drawn on selected monitor */
     49 -		dc.w = TEXTW(stext);
     50 -		dc.x = m->ww - dc.w;
     51 -		if(dc.x < x) {
     52 -			dc.x = x;
     53 -			dc.w = m->ww - x;
     54 -		}
     55 -		drawtext(stext, dc.norm, False);
     56 +
     57 +       drawstatus(m); //la11111
     58  	}
     59  	else
     60  		dc.x = m->ww;
     61 @@ -2067,3 +2081,449 @@
     62  	XCloseDisplay(dpy);
     63  	return EXIT_SUCCESS;
     64  }
     65 +
     66 +
     67 +/*************************************************
     68 +ansistatuscolors
     69 +by la11111
     70 +
     71 +updated 11.12.12 - squashed my code together to 
     72 +patch better across versions - killed remaining memory
     73 +leaks. removed some useless junk.
     74 +
     75 +put ansi escape codes in your status bar output to 
     76 +change the color. Note: full ansi spec not implemented
     77 +at the moment. incorrect codes are ignored, even if they
     78 +may be valid ansi codes (ie, changing up the order or something)
     79 +
     80 +*** escape code format:
     81 +
     82 +\e[<code>m
     83 +
     84 +    \e - ascii 27, hex 0x1b, octal 033
     85 +    [ - literal bracket
     86 +    m - literal 'm'
     87 +
     88 +*** codes supported:
     89 +
     90 +standard escape codes:
     91 +
     92 +n;m
     93 +    n - 
     94 +        0 - normal
     95 +        1 - 'bright'
     96 +    m -
     97 +        30-37 - text foreground
     98 +        40-47 - text background
     99 +
    100 +0 - 
    101 +    reset formatting to default
    102 +
    103 +example (python):
    104 +    print "\x1b[1;31mHello World!\x1b[0m"
    105 +
    106 +256-color escape codes (xterm):
    107 +
    108 +n;5;m
    109 +    n -
    110 +        38 - text foreground
    111 +        48 - text background
    112 +    m - 
    113 +        0-15 - alias classic ansi colors
    114 +        16-231 - rgb grid color
    115 +        232-255 - grayscale ramp color
    116 +
    117 +example (python):
    118 +    print "\x1b[38;5;196mHello World!\x1b[0m"
    119 +
    120 +for more info about escape sequences in general, see:
    121 +http://www.frexx.de/xterm-256-notes/
    122 +
    123 +enjoy, my friends
    124 +-la0x1f
    125 +***************************************************/
    126 +
    127 +void
    128 +drawcoloredtext(const char *text, unsigned long fg, unsigned long bg) {
    129 +	char buf[256];
    130 +	int x, y, h, olen, len;
    131 +
    132 +	XSetForeground(dpy, dc.gc, bg);
    133 +
    134 +	XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
    135 +	if(!text)
    136 +		return;
    137 +	olen = strlen(text);
    138 +	h = dc.font.ascent + dc.font.descent;
    139 +	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
    140 +	x = dc.x; 
    141 +	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w; len--);
    142 +	if(!len)
    143 +		return;
    144 +	memcpy(buf, text, len);
    145 +    
    146 +	XSetForeground(dpy, dc.gc, fg);
    147 +	if(dc.font.set)
    148 +		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
    149 +	else
    150 +		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
    151 +}
    152 +
    153 +struct 
    154 +ansi_node * addnode(struct ansi_node *head, int type, char * color, char * text) {
    155 +    struct ansi_node* tmp;
    156 +    if (head == NULL) {
    157 +        head=(struct ansi_node *)malloc(sizeof(struct ansi_node));
    158 +        if (head == NULL) {
    159 +        //    printf("you're out of memory, son\n");
    160 +            exit(1);
    161 +        }
    162 +        head->next = head;
    163 +        head->type = type;
    164 +        head->color = color;
    165 +        head->text = text; 
    166 +    } else {
    167 +        tmp = head;
    168 +        while(tmp->next != head) 
    169 +            tmp = tmp->next;
    170 +        tmp->next = (struct ansi_node *)malloc(sizeof(struct ansi_node));
    171 +        if (tmp->next == NULL) {
    172 +         //   printf("you're out of memory, son\n");
    173 +            exit(1);
    174 +        }
    175 +        tmp = tmp->next;
    176 +        tmp->next = head;
    177 +        tmp->type = type;
    178 +        tmp->color = color;
    179 +        tmp->text = text; 
    180 +    }
    181 +    return head;
    182 +}
    183 +
    184 +void 
    185 +destroy_llist(struct ansi_node *head) {
    186 +    struct ansi_node *current, *tmp;
    187 +    current = head->next;
    188 +    head->next = NULL;
    189 +    while (current != NULL) {
    190 +        tmp = current->next;
    191 +        free(current);
    192 +        current = tmp;
    193 +    }
    194 +}
    195 +
    196 +void 
    197 +drawstatus (Monitor *m) {
    198 +    /*
    199 +       this function makes 2 passes:
    200 +        -chops status text into pieces based on esc codes
    201 +        -puts esc codes & text blocks in a linked list
    202 +        -goes back through and outputs those blocks one at a time
    203 +            in the color specified by the preceding escape code 
    204 +    */
    205 +    char * startpos = stext;
    206 +    char * curpos = stext;
    207 +    char * escstartpos = stext;
    208 +    int inescape = 0;
    209 +    int esc_len, text_len;
    210 +    char * textbuf;
    211 +    char * escbuf;
    212 +    char plaintextbuf[1024] = "\0";
    213 +    char color[16];
    214 +    char * color_ptr;
    215 +    int curpos_ctr = 0;
    216 +    int input_len = strlen(stext);
    217 +    int plain_text_len = 0;
    218 +    unsigned long cur_fg = dc.norm[ColFG];
    219 +    unsigned long cur_bg = dc.norm[ColBG];
    220 +    struct ansi_node *head = NULL;
    221 +    int x, x_orig;
    222 +    struct ansi_node *curn;
    223 +
    224 +
    225 +    while (curpos_ctr < input_len) {
    226 +        if (*curpos == '\x1b') {
    227 +            if (!(inescape)) {
    228 +                inescape = 1;
    229 +                escstartpos = curpos;
    230 +                curpos++;
    231 +                curpos_ctr++;
    232 +                if (*curpos != '[') {
    233 +                    escstartpos = startpos;
    234 +                    inescape = 0;
    235 +                } else {
    236 +                    curpos++;
    237 +                    curpos_ctr++;
    238 +                }
    239 +            } else {
    240 +                escstartpos = startpos;
    241 +                inescape = 0;
    242 +            }
    243 +        } else {
    244 +            if (inescape) {
    245 +                if ( ((*curpos >= '0' ) && (*curpos <= '9')) || (*curpos == ';') ) {
    246 +                    curpos++;
    247 +                    curpos_ctr++;
    248 +                } else { 
    249 +                    if (*curpos == 'm') {
    250 +                        esc_len = curpos - escstartpos;
    251 +                        escbuf = malloc(esc_len-1);
    252 +                        if (escbuf) { strncpy(escbuf, escstartpos+2, esc_len-2);  }
    253 +                        escbuf[esc_len-2] = '\0';
    254 +                        ParseAnsiEsc(escbuf, color);
    255 +                        free(escbuf);
    256 +                        text_len= escstartpos - startpos;
    257 +                        if (text_len > 0) { 
    258 +                            plain_text_len += text_len;
    259 +                            textbuf = malloc((text_len * sizeof(char))+ 1);
    260 +                            if (textbuf) { strncpy(textbuf, startpos, text_len);}
    261 +                            textbuf[text_len] = '\0';
    262 +                            strcat(plaintextbuf, textbuf);
    263 +                            head = addnode(head, ansi_text, "", strcpy(malloc(strlen(textbuf)+1), textbuf));
    264 +                            free(textbuf);
    265 +                        }
    266 +                        color_ptr = color;
    267 +                        if (color[0] == 'r') { 
    268 +                            head = addnode(head, ansi_reset, strcpy( malloc(strlen(color)+1), color), ""); 
    269 +                        } else if (color[0] == 'f') { //chops off 'fg:'
    270 +                            head = addnode(head, ansi_fg, strcpy( malloc(strlen(color)-2), color_ptr+3),""); 
    271 +                        } else if (color[0] == 'b') {
    272 +                            head = addnode(head, ansi_bg, strcpy(malloc(strlen(color)-2),color_ptr+3), ""); 
    273 +                        } else {
    274 +                            head = addnode(head, -1, "", "");
    275 +                        }
    276 +                        curpos++;
    277 +                        startpos = curpos;
    278 +                        escstartpos = curpos;
    279 +                    } else {
    280 +                        escstartpos = startpos;
    281 +                        curpos++;
    282 +                        curpos_ctr++;
    283 +                    }
    284 +                    inescape = 0; 
    285 +                }
    286 +            } else {
    287 +                curpos++;
    288 +                curpos_ctr++;
    289 +            }
    290 +        }
    291 +    }
    292 +    if(strlen(startpos)) {
    293 +        text_len= strlen(startpos);
    294 +        textbuf = malloc((text_len * sizeof(char))+ 1);
    295 +        if (textbuf) { strncpy(textbuf, startpos, text_len);}
    296 +        textbuf[text_len] = '\0';
    297 +        plain_text_len += strlen(startpos);
    298 +        strcat(plaintextbuf, startpos);
    299 +        head = addnode(head, ansi_text, "", strcpy(malloc(strlen(textbuf)+1), textbuf));
    300 +        free(textbuf);
    301 +    } 
    302 +    x = dc.x;
    303 +    dc.x = m->ww - textnw(plaintextbuf, strlen(plaintextbuf));
    304 +    // not sure what would happen here... something wierd probably
    305 +    if(dc.x < x) {
    306 +        dc.x = x;
    307 +        dc.w = m->ww - x;
    308 +    }
    309 +    x_orig = dc.x; //reset dc.x after so the window title doesn't overwrite status
    310 +    curn = head; //iterate linked list
    311 +    if (curn != NULL) {
    312 +        do {
    313 +            if (curn->type == -1) continue;
    314 +            if (curn->type == ansi_reset) { 
    315 +                cur_fg = dc.norm[ColFG];
    316 +                cur_bg = dc.norm[ColBG]; 
    317 +                free(curn->color);
    318 +            } else if (curn->type == ansi_fg) {
    319 +                cur_fg = getcolor(curn->color);
    320 +                free(curn->color);
    321 +            } else if (curn->type == ansi_bg) {
    322 +                cur_bg = getcolor(curn->color);
    323 +                free(curn->color);
    324 +            } else if (curn->type == ansi_text) {
    325 +                dc.w = textnw(curn->text, strlen(curn->text));
    326 +                drawcoloredtext(curn->text, cur_fg, cur_bg);
    327 +                dc.x += dc.w;
    328 +            
    329 +                free(curn->text);
    330 +
    331 +
    332 +
    333 +            } else {
    334 +                continue;
    335 +            }    
    336 +            curn = curn->next;
    337 +        } while (curn != head);
    338 +    }
    339 +    dc.x = x_orig;
    340 +    destroy_llist(head);
    341 +}
    342 +
    343 +int //count occurrences of c in buf 
    344 +countchars(char c, char * buf) {
    345 +    char *ptr = buf;
    346 +    int ctr = 0;
    347 +    while(*ptr) {
    348 +        if(*ptr == c) ctr++;
    349 +        ptr++;
    350 +    }
    351 +    return ctr;
    352 +}
    353 +
    354 +void 
    355 +ParseAnsiEsc(char * seq, char buffer[]){
    356 +    char *cp, *token;
    357 +    static char * standardcolors[2][8] = {
    358 +        {"#000000\0","#800000\0","#008000\0","#808000\0","#000080\0","#800080\0","#008080\0","#c0c0c0\0"},
    359 +        {"#808080\0","#ff0000\0","#00ff00\0","#ffff00\0","#0000ff\0","#ff00ff\0","#00ffff\0","#ffffff\0"}
    360 +    };
    361 +    char * retbuf = (void *)buffer;
    362 +    retbuf[0] = '\0';
    363 +
    364 +    cp = malloc(strlen(seq) + 1);
    365 +    if (cp) { strcpy(cp, seq); }
    366 +
    367 +    int semis = countchars(';',seq);
    368 +    char *delim = ";";
    369 +    char * toklist[semis + 1];
    370 +    int tok_ctr = 0;
    371 +    int arglist[semis + 1];
    372 +    char color[8];
    373 +    int r,c,i,j;
    374 +    char * layer;
    375 +
    376 +    token = strtok(cp,delim);
    377 +    while(token) {
    378 +        toklist[tok_ctr] = token;
    379 +        tok_ctr++;
    380 +        token = strtok(NULL,delim);
    381 +    } 
    382 +    if ((tok_ctr > 3) || (tok_ctr < 1)) {
    383 +        free(cp);
    384 +         return;
    385 +    }
    386 +    if (tok_ctr == 1) { 
    387 +        if (strlen(toklist[0]) != 1) return;
    388 +        if (toklist[0][0] != '0') {
    389 +            free(cp);
    390 +            return;
    391 +        } else {
    392 +            sprintf(retbuf,"r"); //reset to default
    393 +            free(cp);
    394 +            return;
    395 +        }
    396 +    }
    397 +    for (i=0; i < tok_ctr; i++) {
    398 +        for(j=0; j < strlen(toklist[i]); j++){
    399 +            if ((toklist[i][j] < '0') || (toklist[i][j] > '9')) {
    400 +                free(cp);
    401 +                return;
    402 +            }
    403 +        }
    404 +        arglist[i] = atoi(toklist[i]);
    405 +    }
    406 +    if (tok_ctr == 3) {
    407 +        if (!(
    408 +            (arglist[1] == 5) && 
    409 +            ((arglist[0] == 38) || (arglist[0] == 48)) && 
    410 +            (arglist[2] >= 16) && 
    411 +            (arglist[2] <= 255)
    412 +        )) {
    413 +            free(cp);
    414 +            return;
    415 +        } else {
    416 +            if (arglist[0] == 38) {
    417 +                sprintf(retbuf,"fg:");
    418 +            } else {
    419 +                sprintf(retbuf,"bg:");
    420 +            }
    421 +           
    422 +            GetAnsiColor(arglist[2], color);
    423 +            strcat(retbuf, color);
    424 +            free(cp);
    425 +            return;
    426 +         }
    427 +    } else {
    428 +        for (i = 0; i < tok_ctr; i++) {
    429 +            if (!(
    430 +                (arglist[i] == 0) ||
    431 +                (arglist[i] == 1) ||
    432 +                ((arglist[i] >= 30) && (arglist[i] <= 37)) ||
    433 +                ((arglist[i] >= 40) && (arglist[i] <= 47))
    434 +            )) {
    435 +                free(cp);
    436 +                return;
    437 +            }
    438 +        } 
    439 +        if ((arglist[0] < 30) 
    440 +        && (arglist[1] < 30)) {
    441 +            free(cp);
    442 +            return;
    443 +        }
    444 +        if ((arglist[0] > 1) 
    445 +        && (arglist[1] > 1)) {
    446 +            free(cp);
    447 +            return;  
    448 +        }
    449 +        if (arglist[0] < 30) {
    450 +            r = arglist[0];
    451 +            c = arglist[1];
    452 +        } else {
    453 +            r = arglist[1];
    454 +            c = arglist[0];
    455 +        }
    456 +        if (c > 37) {
    457 +            layer = "bg:";
    458 +            c -= 10;
    459 +        } else {
    460 +            layer = "fg:";
    461 +        }
    462 +        sprintf(retbuf, "%s%s", layer, standardcolors[r][c-30]);
    463 +        free(cp);
    464 +    } 
    465 +}
    466 +
    467 +void 
    468 +GetAnsiColor(int escapecode, char buffer[]){
    469 +    char steps[6][3] = {
    470 +        "00\0", "5f\0", "87\0", "af\0", "d6\0", "ff\0",
    471 +    };
    472 +    int i, panel, cell, col, row, val;
    473 +    int cmin = 16;
    474 +    int cmax = 231;
    475 +    int gmax = 255;
    476 +    int n = escapecode;
    477 +    char * retbuf = (void *)buffer;
    478 +
    479 +    if (n < cmin) {
    480 +        return;
    481 +    } else if (n > gmax) {
    482 +        return;
    483 +    } else if (n <= cmax) {
    484 +        i = n - 15;
    485 +        panel = i / 36;
    486 +        cell = i % 36;
    487 +        if (cell == 0) {
    488 +            cell = 36;
    489 +            panel -= 1;
    490 +        }
    491 +        col = cell / 6;
    492 +        row = cell % 6;
    493 +        if (row == 0) {
    494 +            col -= 1;
    495 +            row = 5;
    496 +        } else {
    497 +            row -= 1;
    498 +        }
    499 +        sprintf(retbuf, "#%s%s%s", steps[panel], steps[col], steps[row]);
    500 +    } else {
    501 +        val = ((10*(n-232))+8);
    502 +        sprintf(retbuf, "#%.2x%.2x%.2x",val,val,val);
    503 +    }
    504 +}
    505 +
    506 +/*************************************************
    507 +end ansistatuscolors - la11111
    508 +***************************************************/
    509 +
    510 +