aboutsummaryrefslogtreecommitdiffstats
path: root/com32/cmenu
diff options
context:
space:
mode:
authorPierre-Alexandre Meyer <pierre@mouraf.org>2009-08-20 23:00:25 -0700
committerPierre-Alexandre Meyer <pierre@mouraf.org>2009-09-01 11:43:37 -0700
commit0f35e6ef1d7667eb82babf7ff9b14e67fca69c2b (patch)
tree9a51be35f9abf72025798d0fdf065abfea668d42 /com32/cmenu
parentd15e5d31c7dccc4d051ff5e12886506d942cdbfb (diff)
downloadsyslinux-0f35e6ef1d7667eb82babf7ff9b14e67fca69c2b.tar.gz
syslinux-0f35e6ef1d7667eb82babf7ff9b14e67fca69c2b.tar.xz
syslinux-0f35e6ef1d7667eb82babf7ff9b14e67fca69c2b.zip
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 <pierre@mouraf.org>
Diffstat (limited to 'com32/cmenu')
-rw-r--r--com32/cmenu/libmenu/com32io.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/com32/cmenu/libmenu/com32io.c b/com32/cmenu/libmenu/com32io.c
index 8a44a77e..330bcb93 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 */