256-color SUPPORT + extra stuff too ig

very epico update, makes it much much more usable
This commit is contained in:
cowmonk 2025-01-21 18:31:58 -07:00
parent 264f53a342
commit 63522a14fc
2 changed files with 88 additions and 21 deletions

View File

@ -5,6 +5,9 @@
// Change as suited for your monitor
#define REFRESH_INTERVAL 16666
// Support for 256 colors
#define COLOR_256_SUPPORT 1 // Who the hell wants to use 16 colors in 2025?
// Colors are just configured like RBG, if you don't recognize
// this color format, search it up and find it out yourself
static const unsigned long int RED = 0xFF0000;

106
cowterm.c
View File

@ -68,6 +68,7 @@ static int using_alternate = 0;
#define ATTR_BOLD (1 << 0)
#define ATTR_ITALIC (1 << 1)
#define ATTR_REVERSE (1 << 2)
#define ATTR_UNDERLINE (1 << 3)
#define ATTR_DIM (1 << 4)
#define ATTR_BLINK (1 << 5)
@ -343,6 +344,11 @@ static void draw_char(Display *display, Drawable d, int x, int y) {
XSetFont(display, gc, font->fid);
XDrawString(display, d, gc, x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 4, str,
1);
if (attr & ATTR_UNDERLINE) {
XDrawLine(display, d, gc, x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 1,
(x + 1) * CHAR_WIDTH - 1, (y + 1) * CHAR_HEIGHT - 1);
}
}
static void draw_terminal(Display *display, Window window) {
@ -718,6 +724,28 @@ static unsigned long get_bright_ansi_color(int index) {
return colors[index & 7];
}
#if COLOR_256_SUPPORT
static unsigned long get_256_color(int index) {
// Basic 16 colors
if (index < 16)
return index < 8 ? get_ansi_color(index) : get_bright_ansi_color(index - 8);
// 216 color cube
if (index < 232) {
index -= 16;
int r = (index / 36) * 51;
int g = ((index % 36) / 6) * 51;
int b = (index % 6) * 51;
return (r << 16) | (g << 8) | b;
}
// Grayscale
index -= 232;
int gray = index * 10 + 8;
return (gray << 16) | (gray << 8) | gray;
}
#endif
// Handles those pesky ANSI color escape codes that terminals use.
// When \033[<number>m is sent to the terminal, it changes text color:
// 30 = Black 31 = Red 32 = Green 33 = Yellow
@ -1043,7 +1071,8 @@ static void parse_ansi_code(const char *buf, int *idx, int max_len,
break;
}
for (int i = 0; i < (int)param_idx; i++) {
if (params[i] == 0) { // Reset Everything
switch (params[i]) {
case 0: /* Reset */
current_color = XWhitePixel(display, DefaultScreen(display));
current_bg_color = XBlackPixel(display, DefaultScreen(display));
current_attr = 0;
@ -1054,38 +1083,69 @@ static void parse_ansi_code(const char *buf, int *idx, int max_len,
attr_buffer[cursor_y][x] = current_attr;
}
}
} else if (params[i] == 1) { // Apply ATTRS
break;
case 1: // Bold
current_attr |= ATTR_BOLD;
} else if (params[i] == 2) {
break;
case 2: // Dim
current_attr |= ATTR_DIM;
} else if (params[i] == 3) {
break;
case 3: // Italic
current_attr |= ATTR_ITALIC;
} else if (params[i] == 5) { // Slow blink
break;
case 5: // Blink (slow)
current_attr |= ATTR_BLINK;
} else if (params[i] == 7) {
break;
case 7: // Reverse
current_attr |= ATTR_REVERSE;
} else if (params[i] == 22) { // Reset ATTRS
current_attr &= ~ATTR_BOLD;
} else if (params[i] == 23) {
break;
case 22: // Reset Bold and Dim
current_attr &= ~(ATTR_BOLD | ATTR_DIM);
break;
case 23: // Reset Italic
current_attr &= ~ATTR_ITALIC;
} else if (params[i] == 25) {
break;
case 25: // Reset Blink
current_attr &= ~ATTR_BLINK;
} else if (params[i] == 27) {
break;
case 27: // Reset Reverse
current_attr &= ~ATTR_REVERSE;
} else if (params[i] >= 30 && params[i] <= 37) { // Foreground colors
current_color = get_ansi_color(params[i] - 30);
} else if (params[i] == 39) { // Reset foreground color
break;
case 38: // Extended foreground color
#if COLOR_256_SUPPORT
if (i + 2 < (int)param_idx && params[i + 1] == 5) {
current_color = get_256_color(params[i + 2]);
i += 2;
}
#endif
break;
case 39: // Default foreground
current_color = XWhitePixel(display, DefaultScreen(display));
} else if (params[i] >= 40 && params[i] <= 47) { // Background colors
current_bg_color = get_ansi_color(params[i] - 40);
} else if (params[i] == 49) { // Reset background color
break;
case 48: // Extended background color
#if COLOR_256_SUPPORT
if (i + 2 < (int)param_idx && params[i + 1] == 5) {
current_bg_color = get_256_color(params[i + 2]);
i += 2;
}
#endif
break;
case 49: // Default background color
current_bg_color = XBlackPixel(display, DefaultScreen(display));
} else if (params[i] >= 90 && params[i] <= 97) { // Bright foreground
current_color = get_bright_ansi_color(params[i] - 90);
} else if (params[i] >= 100 && params[i] <= 107) { // Bright background
current_bg_color = get_bright_ansi_color(params[i] - 100);
break;
default:
if (params[i] >= 30 && params[i] <= 37)
current_color = get_ansi_color(params[i] - 30);
else if (params[i] >= 40 && params[i] <= 47)
current_bg_color = get_ansi_color(params[i] - 40);
else if (params[i] >= 90 && params[i] <= 97)
current_color = get_bright_ansi_color(params[i] - 90);
else if (params[i] >= 100 && params[i] <= 107)
current_bg_color = get_bright_ansi_color(params[i] - 100);
break;
}
}
needs_refresh = 1;
break;
}
}
@ -1343,7 +1403,11 @@ int main(void) {
close(slave);
char *sh = getenv("SHELL");
#if COLOR_256_SUPPORT
setenv("TERM", "xterm-256color", 1);
#else
setenv("TERM", "xterm", 1);
#endif
execl(sh ? sh : "/bin/sh", sh ? sh : "sh", 0);
return 1;
}