From: Pierre-Alexandre Meyer Date: Fri, 21 Aug 2009 06:00:25 +0000 (-0700) Subject: cmenu: better implementation of vga->ansi X-Git-Tag: syslinux-3.84-pre1~37^2~26^2~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f35e6ef1d7667eb82babf7ff9b14e67fca69c2b;p=platform%2Fupstream%2Fsyslinux.git cmenu: better implementation of vga->ansi hpa suggested a better implementation, that also fixes some color issues and invalid ANSI codes. Thanks hpa! Signed-off-by: Pierre-Alexandre Meyer --- diff --git a/com32/cmenu/libmenu/com32io.c b/com32/cmenu/libmenu/com32io.c index 8a44a77..330bcb9 100644 --- a/com32/cmenu/libmenu/com32io.c +++ b/com32/cmenu/libmenu/com32io.c @@ -29,27 +29,46 @@ static unsigned int bit_reverse(unsigned int code, int len) void cprint_vga2ansi(char chr, char attr) { - /* The VGA attribute looks like: X B B B I F F F */ - unsigned int ansi_attr; - - /* Bit reverse Background/Foreground */ - ansi_attr = bit_reverse(attr, 7); - - /* Blinking attribute? */ - if (! (ansi_attr & 0x80)) - printf(CSI "%d;3%d;4%dm%c", ansi_attr & 0x8, - ansi_attr & 0x70, - ansi_attr & 0x7, chr); - else { - if (ansi_attr & 0x8) - printf(CSI "%d;4;3%d;4%dm%c", ansi_attr & 0x8, - ansi_attr & 0x70, - ansi_attr & 0x7, chr); - else - printf(CSI "%d;3%d;4%dm%c", ansi_attr & 0x8, - ansi_attr & 0x70, - ansi_attr & 0x7, chr); + static const char ansi_char[8] = "04261537"; + static uint8_t last_attr = 0x07; + char buf[16], *p; + + if (attr != last_attr) { + p = buf; + *p++ = '\033'; + *p++ = '['; + + if (last_attr & ~attr & 0x88) { + *p++ = '0'; + *p++ = ';'; + } + if (attr & 0x08) { + *p++ = '1'; + *p++ = ';'; + } + if (attr & 0x80) { + *p++ = '4'; + *p++ = ';'; + } + if ((attr ^ last_attr) & 0x07) { + *p++ = '3'; + *p++ = ansi_char[attr & 7]; + *p++ = ';'; + } + if ((attr ^ last_attr) & 0x70) { + *p++ = '4'; + *p++ = ansi_char[(attr >> 4) & 7]; + *p++ = ';'; + } + p[-1] = 'm'; /* We'll have generated at least one semicolon */ + p[0] = '\0'; + + last_attr = attr; + + fputs(buf, stdout); } + + putchar(chr); } /* Print character and attribute at cursor */