Fix color support to work everywhere via hacky static variable
This commit is contained in:
parent
f00ab71fb5
commit
47a176223b
|
@ -17,6 +17,7 @@ KERN_SRCFILES := kern/entry.S \
|
||||||
kern/entrypgdir.c \
|
kern/entrypgdir.c \
|
||||||
kern/init.c \
|
kern/init.c \
|
||||||
kern/console.c \
|
kern/console.c \
|
||||||
|
kern/ansi.c \
|
||||||
kern/monitor.c \
|
kern/monitor.c \
|
||||||
kern/pmap.c \
|
kern/pmap.c \
|
||||||
kern/env.c \
|
kern/env.c \
|
||||||
|
|
49
kern/ansi.c
Normal file
49
kern/ansi.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include <kern/ansi.h>
|
||||||
|
|
||||||
|
uint8_t vga_colors[8] = {
|
||||||
|
[0] = 0,
|
||||||
|
[1] = 4,
|
||||||
|
[2] = 2,
|
||||||
|
[3] = 6,
|
||||||
|
[4] = 1,
|
||||||
|
[5] = 5,
|
||||||
|
[6] = 3,
|
||||||
|
[7] = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
ansi_step(void (*putcf)(int), int c, struct AttrState* s) {
|
||||||
|
switch(s->state) {
|
||||||
|
case NORMAL:
|
||||||
|
if(c != 27) putcf(c | (s->cattrs << 8));
|
||||||
|
else s->state = ESC;
|
||||||
|
return;
|
||||||
|
case ESC:
|
||||||
|
s->state = (c == '[') ? BRACKET : NORMAL;
|
||||||
|
return;
|
||||||
|
case BRACKET:
|
||||||
|
if(c == '3') {
|
||||||
|
s->state = COLOR_FG;
|
||||||
|
} else if(c == '0') {
|
||||||
|
s->state = COLOR;
|
||||||
|
s->attrs = 0;
|
||||||
|
} else {
|
||||||
|
s->state = NORMAL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case COLOR_FG:
|
||||||
|
if(c >= '0' && c <= '9') {
|
||||||
|
s->attrs = (s->attrs & ~(0x07)) | vga_colors[c - '0'];
|
||||||
|
c |= ((c - '0') << 8);
|
||||||
|
s->state = COLOR;
|
||||||
|
} else {
|
||||||
|
s->state = NORMAL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case COLOR:
|
||||||
|
s->state = (c == ';') ? BRACKET : NORMAL;
|
||||||
|
if(c == 'm') s->cattrs = s->attrs;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
kern/ansi.h
Normal file
20
kern/ansi.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef _ANSI_H_
|
||||||
|
#define _ANSI_H_
|
||||||
|
|
||||||
|
#include <inc/types.h>
|
||||||
|
|
||||||
|
struct AttrState {
|
||||||
|
uint8_t cattrs;
|
||||||
|
uint8_t attrs;
|
||||||
|
enum {
|
||||||
|
NORMAL,
|
||||||
|
ESC,
|
||||||
|
BRACKET,
|
||||||
|
COLOR_FG,
|
||||||
|
COLOR
|
||||||
|
} state;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ansi_step(void (*putcf)(int), int c, struct AttrState* s);
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,6 +7,7 @@
|
||||||
#include <inc/assert.h>
|
#include <inc/assert.h>
|
||||||
|
|
||||||
#include <kern/console.h>
|
#include <kern/console.h>
|
||||||
|
#include <kern/ansi.h>
|
||||||
|
|
||||||
static void cons_intr(int (*proc)(void));
|
static void cons_intr(int (*proc)(void));
|
||||||
static void cons_putc(int c);
|
static void cons_putc(int c);
|
||||||
|
@ -128,6 +129,7 @@ lpt_putc(int c)
|
||||||
static unsigned addr_6845;
|
static unsigned addr_6845;
|
||||||
static uint16_t *crt_buf;
|
static uint16_t *crt_buf;
|
||||||
static uint16_t crt_pos;
|
static uint16_t crt_pos;
|
||||||
|
static struct AttrState attst;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cga_init(void)
|
cga_init(void)
|
||||||
|
@ -136,6 +138,10 @@ cga_init(void)
|
||||||
uint16_t was;
|
uint16_t was;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
|
attst.cattrs = 0;
|
||||||
|
attst.attrs = 0;
|
||||||
|
attst.state = NORMAL;
|
||||||
|
|
||||||
cp = (uint16_t*) (KERNBASE + CGA_BUF);
|
cp = (uint16_t*) (KERNBASE + CGA_BUF);
|
||||||
was = *cp;
|
was = *cp;
|
||||||
*cp = (uint16_t) 0xA55A;
|
*cp = (uint16_t) 0xA55A;
|
||||||
|
@ -157,10 +163,15 @@ cga_init(void)
|
||||||
crt_pos = pos;
|
crt_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cga_putc_internal(int c);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cga_putc(int c)
|
cga_putc(int c){
|
||||||
|
ansi_step(cga_putc_internal, c, &attst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cga_putc_internal(int c)
|
||||||
{
|
{
|
||||||
// if no attribute given, then use black on white
|
// if no attribute given, then use black on white
|
||||||
if (!(c & ~0xFF))
|
if (!(c & ~0xFF))
|
||||||
|
|
|
@ -79,54 +79,6 @@ getint(va_list *ap, int lflag)
|
||||||
// Main function to format and print a string.
|
// Main function to format and print a string.
|
||||||
void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...);
|
void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...);
|
||||||
|
|
||||||
struct AttrState {
|
|
||||||
uint8_t cattrs;
|
|
||||||
uint8_t attrs;
|
|
||||||
enum {
|
|
||||||
NORMAL,
|
|
||||||
ESC,
|
|
||||||
BRACKET,
|
|
||||||
COLOR_FG,
|
|
||||||
COLOR
|
|
||||||
} state;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
putchw(void (*putch)(int, void*), int c, void* data, struct AttrState* s) {
|
|
||||||
switch(s->state) {
|
|
||||||
case NORMAL:
|
|
||||||
if(c != 27) putch(c | (s->cattrs << 8), data);
|
|
||||||
else s->state = ESC;
|
|
||||||
return;
|
|
||||||
case ESC:
|
|
||||||
s->state = (c == '[') ? BRACKET : NORMAL;
|
|
||||||
return;
|
|
||||||
case BRACKET:
|
|
||||||
if(c == '3') {
|
|
||||||
s->state = COLOR_FG;
|
|
||||||
} else if(c == '0') {
|
|
||||||
s->state = COLOR;
|
|
||||||
s->attrs = 0;
|
|
||||||
} else {
|
|
||||||
s->state = NORMAL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case COLOR_FG:
|
|
||||||
if(c >= '0' && c <= '9') {
|
|
||||||
s->attrs = (s->attrs & ~(0x07)) | (c - '0');
|
|
||||||
c |= ((c - '0') << 8);
|
|
||||||
s->state = COLOR;
|
|
||||||
} else {
|
|
||||||
s->state = NORMAL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case COLOR:
|
|
||||||
s->state = (c == ';') ? BRACKET : NORMAL;
|
|
||||||
if(c == 'm') s->cattrs = s->attrs;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
|
@ -135,17 +87,12 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||||
unsigned long long num;
|
unsigned long long num;
|
||||||
int base, lflag, width, precision, altflag;
|
int base, lflag, width, precision, altflag;
|
||||||
char padc;
|
char padc;
|
||||||
struct AttrState attst;
|
|
||||||
|
|
||||||
attst.state = NORMAL;
|
|
||||||
attst.cattrs = 0;
|
|
||||||
attst.attrs = 0;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while ((ch = *(unsigned char *) fmt++) != '%') {
|
while ((ch = *(unsigned char *) fmt++) != '%') {
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
return;
|
return;
|
||||||
putchw(putch, ch, putdat, &attst);
|
putch(ch, putdat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process a %-escape sequence
|
// Process a %-escape sequence
|
||||||
|
|
Loading…
Reference in New Issue
Block a user