Unicode support!
Took a lot of debugging...
This commit is contained in:
parent
63522a14fc
commit
14296c3b6b
6
config.h
6
config.h
@ -33,11 +33,11 @@ static const unsigned long int LIGHT_CYAN = 0x80FFFF;
|
|||||||
// "-bitstream-terminal-medium-r-normal--18-140-100-100-c-110-iso8859-1"
|
// "-bitstream-terminal-medium-r-normal--18-140-100-100-c-110-iso8859-1"
|
||||||
// Use 'xlsfonts' command to list available fonts
|
// Use 'xlsfonts' command to list available fonts
|
||||||
static const char REGULAR_FONT[] =
|
static const char REGULAR_FONT[] =
|
||||||
"-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1";
|
"-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso10646-1";
|
||||||
static const char BOLD_FONT[] =
|
static const char BOLD_FONT[] =
|
||||||
"-misc-fixed-bold-r-normal--13-120-75-75-c-70-iso8859-1";
|
"-misc-fixed-bold-r-normal--13-120-75-75-c-70-iso10646-1";
|
||||||
static const char ITALICS_FONT[] =
|
static const char ITALICS_FONT[] =
|
||||||
"-misc-fixed-medium-o-normal--13-120-75-75-c-70-iso8859-1";
|
"-misc-fixed-medium-o-normal--13-120-75-75-c-70-iso10646-1";
|
||||||
|
|
||||||
// Change the window name to whatever you want lmao
|
// Change the window name to whatever you want lmao
|
||||||
static const char window_name[] = "CowTerm";
|
static const char window_name[] = "CowTerm";
|
||||||
|
149
cowterm.c
149
cowterm.c
@ -4,6 +4,7 @@
|
|||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <locale.h>
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@ -26,7 +28,7 @@
|
|||||||
|
|
||||||
// General window/terminal stuff
|
// General window/terminal stuff
|
||||||
static pid_t child_pid;
|
static pid_t child_pid;
|
||||||
static char **terminal_buffer = NULL;
|
static wchar_t **terminal_buffer = NULL;
|
||||||
static unsigned long **color_buffer = NULL;
|
static unsigned long **color_buffer = NULL;
|
||||||
static int **attr_buffer = NULL;
|
static int **attr_buffer = NULL;
|
||||||
static int term_rows;
|
static int term_rows;
|
||||||
@ -58,7 +60,7 @@ static unsigned long current_bg_color;
|
|||||||
static unsigned long **bg_color_buffer = NULL;
|
static unsigned long **bg_color_buffer = NULL;
|
||||||
|
|
||||||
// Alternatives to handle the ANSI escape codes
|
// Alternatives to handle the ANSI escape codes
|
||||||
static char **saved_terminal = NULL;
|
static wchar_t **saved_terminal = NULL;
|
||||||
static unsigned long **saved_colors = NULL;
|
static unsigned long **saved_colors = NULL;
|
||||||
static int **saved_attrs = NULL;
|
static int **saved_attrs = NULL;
|
||||||
static int saved_cursor_x = 0;
|
static int saved_cursor_x = 0;
|
||||||
@ -155,12 +157,12 @@ static void resize_buffers(int new_rows, int new_cols) {
|
|||||||
if (new_cols < 1)
|
if (new_cols < 1)
|
||||||
new_cols = 1;
|
new_cols = 1;
|
||||||
|
|
||||||
size_t row_size = ((new_cols * sizeof(char) + 15) & ~15);
|
size_t row_size = ((new_cols * sizeof(wchar_t) + 15) & ~15);
|
||||||
size_t color_row_size = ((new_cols * sizeof(unsigned long) + 15) & ~15);
|
size_t color_row_size = ((new_cols * sizeof(unsigned long) + 15) & ~15);
|
||||||
size_t attr_row_size = ((new_cols * sizeof(int) + 15) & ~15);
|
size_t attr_row_size = ((new_cols * sizeof(int) + 15) & ~15);
|
||||||
size_t bg_color_row_size = ((new_cols * sizeof(unsigned long) + 15) & ~15);
|
size_t bg_color_row_size = ((new_cols * sizeof(unsigned long) + 15) & ~15);
|
||||||
|
|
||||||
char **new_term_buffer = malloc(new_rows * sizeof(char *));
|
wchar_t **new_term_buffer = malloc(new_rows * sizeof(char *));
|
||||||
unsigned long **new_color_buffer = malloc(new_rows * sizeof(unsigned long *));
|
unsigned long **new_color_buffer = malloc(new_rows * sizeof(unsigned long *));
|
||||||
int **new_attr_buffer = malloc(new_rows * sizeof(int *));
|
int **new_attr_buffer = malloc(new_rows * sizeof(int *));
|
||||||
unsigned long **new_bg_color_buffer =
|
unsigned long **new_bg_color_buffer =
|
||||||
@ -198,23 +200,22 @@ static void resize_buffers(int new_rows, int new_cols) {
|
|||||||
if (i < term_rows && i < new_rows && terminal_buffer && color_buffer &&
|
if (i < term_rows && i < new_rows && terminal_buffer && color_buffer &&
|
||||||
attr_buffer && bg_color_buffer) {
|
attr_buffer && bg_color_buffer) {
|
||||||
int copy_cols = (new_cols < term_cols) ? new_cols : term_cols;
|
int copy_cols = (new_cols < term_cols) ? new_cols : term_cols;
|
||||||
memcpy(new_term_buffer[i], terminal_buffer[i], copy_cols * sizeof(char));
|
memcpy(new_term_buffer[i], terminal_buffer[i],
|
||||||
|
copy_cols * sizeof(wchar_t));
|
||||||
memcpy(new_color_buffer[i], color_buffer[i],
|
memcpy(new_color_buffer[i], color_buffer[i],
|
||||||
copy_cols * sizeof(unsigned long));
|
copy_cols * sizeof(unsigned long));
|
||||||
memcpy(new_attr_buffer[i], attr_buffer[i], copy_cols * sizeof(int));
|
memcpy(new_attr_buffer[i], attr_buffer[i], copy_cols * sizeof(int));
|
||||||
memcpy(new_bg_color_buffer[i], bg_color_buffer[i],
|
memcpy(new_bg_color_buffer[i], bg_color_buffer[i],
|
||||||
copy_cols * sizeof(unsigned long));
|
copy_cols * sizeof(unsigned long));
|
||||||
if (new_cols > term_cols) {
|
for (int x = term_cols; x < new_cols; x++) {
|
||||||
memset(new_term_buffer[i] + term_cols, ' ', new_cols - term_cols);
|
new_term_buffer[i][x] = L' ';
|
||||||
for (int x = term_cols; x < new_cols; x++) {
|
new_color_buffer[i][x] = current_color;
|
||||||
new_color_buffer[i][x] = current_color;
|
new_attr_buffer[i][x] = current_attr;
|
||||||
new_attr_buffer[i][x] = current_attr;
|
new_bg_color_buffer[i][x] = current_bg_color;
|
||||||
new_bg_color_buffer[i][x] = current_bg_color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memset(new_term_buffer[i], ' ', new_cols);
|
|
||||||
for (int x = 0; x < new_cols; x++) {
|
for (int x = 0; x < new_cols; x++) {
|
||||||
|
new_term_buffer[i][x] = L' ';
|
||||||
new_color_buffer[i][x] = current_color;
|
new_color_buffer[i][x] = current_color;
|
||||||
new_attr_buffer[i][x] = current_attr;
|
new_attr_buffer[i][x] = current_attr;
|
||||||
new_bg_color_buffer[i][x] = current_bg_color;
|
new_bg_color_buffer[i][x] = current_bg_color;
|
||||||
@ -223,16 +224,32 @@ static void resize_buffers(int new_rows, int new_cols) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Free old buffers after successful allocation
|
// Free old buffers after successful allocation
|
||||||
if (terminal_buffer && color_buffer && attr_buffer && bg_color_buffer) {
|
if (terminal_buffer) {
|
||||||
for (int i = 0; i < term_rows; i++) {
|
for (int i = 0; i < term_rows; i++) {
|
||||||
free(terminal_buffer[i]);
|
if (terminal_buffer[i])
|
||||||
free(color_buffer[i]);
|
free(terminal_buffer[i]);
|
||||||
free(attr_buffer[i]);
|
|
||||||
free(bg_color_buffer[i]);
|
|
||||||
}
|
}
|
||||||
free(terminal_buffer);
|
free(terminal_buffer);
|
||||||
|
}
|
||||||
|
if (color_buffer) {
|
||||||
|
for (int i = 0; i < term_rows; i++) {
|
||||||
|
if (color_buffer[i])
|
||||||
|
free(color_buffer[i]);
|
||||||
|
}
|
||||||
free(color_buffer);
|
free(color_buffer);
|
||||||
|
}
|
||||||
|
if (attr_buffer) {
|
||||||
|
for (int i = 0; i < term_rows; i++) {
|
||||||
|
if (attr_buffer[i])
|
||||||
|
free(attr_buffer[i]);
|
||||||
|
}
|
||||||
free(attr_buffer);
|
free(attr_buffer);
|
||||||
|
}
|
||||||
|
if (bg_color_buffer) {
|
||||||
|
for (int i = 0; i < term_rows; i++) {
|
||||||
|
if (bg_color_buffer[i])
|
||||||
|
free(bg_color_buffer[i]);
|
||||||
|
}
|
||||||
free(bg_color_buffer);
|
free(bg_color_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,9 +322,14 @@ static void draw_char(Display *display, Drawable d, int x, int y) {
|
|||||||
if (x < 0 || x >= term_cols || y < 0 || y >= term_rows)
|
if (x < 0 || x >= term_cols || y < 0 || y >= term_rows)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char c = terminal_buffer[y][x];
|
wchar_t c = terminal_buffer[y][x];
|
||||||
if (c < 32 || c > 126) // Only allow printable ASCII characters
|
char utf8_buf[8] = {0};
|
||||||
return;
|
if (c == 0 || c == L' ') {
|
||||||
|
utf8_buf[0] = ' ';
|
||||||
|
} else {
|
||||||
|
wchar_t wstr[2] = {c, 0};
|
||||||
|
wcstombs(utf8_buf, wstr, sizeof(utf8_buf));
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long fg = color_buffer[y][x];
|
unsigned long fg = color_buffer[y][x];
|
||||||
unsigned long bg = bg_color_buffer[y][x];
|
unsigned long bg = bg_color_buffer[y][x];
|
||||||
@ -333,7 +355,6 @@ static void draw_char(Display *display, Drawable d, int x, int y) {
|
|||||||
|
|
||||||
XSetForeground(display, gc, fg);
|
XSetForeground(display, gc, fg);
|
||||||
|
|
||||||
char str[2] = {c, '\0'};
|
|
||||||
XFontStruct *font = regular_font;
|
XFontStruct *font = regular_font;
|
||||||
|
|
||||||
if (attr & ATTR_BOLD)
|
if (attr & ATTR_BOLD)
|
||||||
@ -342,8 +363,8 @@ static void draw_char(Display *display, Drawable d, int x, int y) {
|
|||||||
font = italic_font;
|
font = italic_font;
|
||||||
|
|
||||||
XSetFont(display, gc, font->fid);
|
XSetFont(display, gc, font->fid);
|
||||||
XDrawString(display, d, gc, x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 4, str,
|
XDrawString(display, d, gc, x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 4,
|
||||||
1);
|
utf8_buf, strlen(utf8_buf));
|
||||||
|
|
||||||
if (attr & ATTR_UNDERLINE) {
|
if (attr & ATTR_UNDERLINE) {
|
||||||
XDrawLine(display, d, gc, x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 1,
|
XDrawLine(display, d, gc, x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 1,
|
||||||
@ -415,7 +436,8 @@ static void scroll_region_up(int amount) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = start; i <= end - amount; i++) {
|
for (int i = start; i <= end - amount; i++) {
|
||||||
memcpy(terminal_buffer[i], terminal_buffer[i + amount], term_cols);
|
memcpy(terminal_buffer[i], terminal_buffer[i + amount],
|
||||||
|
term_cols * sizeof(wchar_t));
|
||||||
memcpy(color_buffer[i], color_buffer[i + amount],
|
memcpy(color_buffer[i], color_buffer[i + amount],
|
||||||
term_cols * sizeof(unsigned long));
|
term_cols * sizeof(unsigned long));
|
||||||
memcpy(attr_buffer[i], attr_buffer[i + amount], term_cols * sizeof(int));
|
memcpy(attr_buffer[i], attr_buffer[i + amount], term_cols * sizeof(int));
|
||||||
@ -424,8 +446,8 @@ static void scroll_region_up(int amount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = end - amount + 1; i <= end; i++) {
|
for (int i = end - amount + 1; i <= end; i++) {
|
||||||
memset(terminal_buffer[i], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[i][x] = L' ';
|
||||||
color_buffer[i][x] = current_color;
|
color_buffer[i][x] = current_color;
|
||||||
attr_buffer[i][x] = current_attr;
|
attr_buffer[i][x] = current_attr;
|
||||||
bg_color_buffer[i][x] = current_bg_color;
|
bg_color_buffer[i][x] = current_bg_color;
|
||||||
@ -441,7 +463,7 @@ static void scroll_region_down(int amount) {
|
|||||||
if (end >= term_rows)
|
if (end >= term_rows)
|
||||||
end = term_rows - 1;
|
end = term_rows - 1;
|
||||||
|
|
||||||
char **tbuf = malloc(term_rows * sizeof(char *));
|
wchar_t **tbuf = malloc(term_rows * sizeof(wchar_t *));
|
||||||
unsigned long **cbuf = malloc(term_rows * sizeof(unsigned long *));
|
unsigned long **cbuf = malloc(term_rows * sizeof(unsigned long *));
|
||||||
int **abuf = malloc(term_rows * sizeof(int *));
|
int **abuf = malloc(term_rows * sizeof(int *));
|
||||||
unsigned long **bbuf = malloc(term_rows * sizeof(unsigned long *));
|
unsigned long **bbuf = malloc(term_rows * sizeof(unsigned long *));
|
||||||
@ -452,7 +474,7 @@ static void scroll_region_down(int amount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < term_rows; i++) {
|
for (int i = 0; i < term_rows; i++) {
|
||||||
tbuf[i] = malloc(term_cols);
|
tbuf[i] = malloc(term_cols * sizeof(wchar_t));
|
||||||
cbuf[i] = malloc(term_cols * sizeof(unsigned long));
|
cbuf[i] = malloc(term_cols * sizeof(unsigned long));
|
||||||
abuf[i] = malloc(term_cols * sizeof(int));
|
abuf[i] = malloc(term_cols * sizeof(int));
|
||||||
bbuf[i] = malloc(term_cols * sizeof(unsigned long));
|
bbuf[i] = malloc(term_cols * sizeof(unsigned long));
|
||||||
@ -465,21 +487,21 @@ static void scroll_region_down(int amount) {
|
|||||||
|
|
||||||
if (scroll_top == 0 && scroll_bottom == 0) {
|
if (scroll_top == 0 && scroll_bottom == 0) {
|
||||||
for (int i = 0; i < term_rows; i++) {
|
for (int i = 0; i < term_rows; i++) {
|
||||||
memcpy(tbuf[i], terminal_buffer[i], term_cols);
|
memcpy(tbuf[i], terminal_buffer[i], term_cols * sizeof(wchar_t));
|
||||||
memcpy(cbuf[i], color_buffer[i], term_cols * sizeof(unsigned long));
|
memcpy(cbuf[i], color_buffer[i], term_cols * sizeof(unsigned long));
|
||||||
memcpy(abuf[i], attr_buffer[i], term_cols * sizeof(int));
|
memcpy(abuf[i], attr_buffer[i], term_cols * sizeof(int));
|
||||||
memcpy(bbuf[i], bg_color_buffer[i], term_cols * sizeof(unsigned long));
|
memcpy(bbuf[i], bg_color_buffer[i], term_cols * sizeof(unsigned long));
|
||||||
}
|
}
|
||||||
for (int j = 0; j < amount; j++) {
|
for (int j = 0; j < amount; j++) {
|
||||||
for (int y = term_rows - 1; y > 0; y--) {
|
for (int y = term_rows - 1; y > 0; y--) {
|
||||||
memcpy(terminal_buffer[y], tbuf[y - 1], term_cols);
|
memcpy(terminal_buffer[y], tbuf[y - 1], term_cols * sizeof(wchar_t));
|
||||||
memcpy(color_buffer[y], cbuf[y - 1], term_cols * sizeof(unsigned long));
|
memcpy(color_buffer[y], cbuf[y - 1], term_cols * sizeof(unsigned long));
|
||||||
memcpy(attr_buffer[y], abuf[y - 1], term_cols * sizeof(int));
|
memcpy(attr_buffer[y], abuf[y - 1], term_cols * sizeof(int));
|
||||||
memcpy(bg_color_buffer[y], bbuf[y - 1],
|
memcpy(bg_color_buffer[y], bbuf[y - 1],
|
||||||
term_cols * sizeof(unsigned long));
|
term_cols * sizeof(unsigned long));
|
||||||
}
|
}
|
||||||
memset(terminal_buffer[0], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[0][x] = L' ';
|
||||||
color_buffer[0][x] = current_color;
|
color_buffer[0][x] = current_color;
|
||||||
attr_buffer[0][x] = current_attr;
|
attr_buffer[0][x] = current_attr;
|
||||||
bg_color_buffer[0][x] = current_bg_color;
|
bg_color_buffer[0][x] = current_bg_color;
|
||||||
@ -487,21 +509,21 @@ static void scroll_region_down(int amount) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < term_rows; i++) {
|
for (int i = 0; i < term_rows; i++) {
|
||||||
memcpy(tbuf[i], terminal_buffer[i], term_cols);
|
memcpy(tbuf[i], terminal_buffer[i], term_cols * sizeof(wchar_t));
|
||||||
memcpy(cbuf[i], color_buffer[i], term_cols * sizeof(unsigned long));
|
memcpy(cbuf[i], color_buffer[i], term_cols * sizeof(unsigned long));
|
||||||
memcpy(abuf[i], attr_buffer[i], term_cols * sizeof(int));
|
memcpy(abuf[i], attr_buffer[i], term_cols * sizeof(int));
|
||||||
memcpy(bbuf[i], bg_color_buffer[i], term_cols * sizeof(unsigned long));
|
memcpy(bbuf[i], bg_color_buffer[i], term_cols * sizeof(unsigned long));
|
||||||
}
|
}
|
||||||
for (int j = 0; j < amount; j++) {
|
for (int j = 0; j < amount; j++) {
|
||||||
for (int y = end; y > start; y--) {
|
for (int y = end; y > start; y--) {
|
||||||
memcpy(terminal_buffer[y], tbuf[y - 1], term_cols);
|
memcpy(terminal_buffer[y], tbuf[y - 1], term_cols * sizeof(wchar_t));
|
||||||
memcpy(color_buffer[y], cbuf[y - 1], term_cols * sizeof(unsigned long));
|
memcpy(color_buffer[y], cbuf[y - 1], term_cols * sizeof(unsigned long));
|
||||||
memcpy(attr_buffer[y], abuf[y - 1], term_cols * sizeof(int));
|
memcpy(attr_buffer[y], abuf[y - 1], term_cols * sizeof(int));
|
||||||
memcpy(bg_color_buffer[y], bbuf[y - 1],
|
memcpy(bg_color_buffer[y], bbuf[y - 1],
|
||||||
term_cols * sizeof(unsigned long));
|
term_cols * sizeof(unsigned long));
|
||||||
}
|
}
|
||||||
memset(terminal_buffer[start], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[start][x] = L' ';
|
||||||
color_buffer[start][x] = current_color;
|
color_buffer[start][x] = current_color;
|
||||||
attr_buffer[start][x] = current_attr;
|
attr_buffer[start][x] = current_attr;
|
||||||
bg_color_buffer[start][x] = current_bg_color;
|
bg_color_buffer[start][x] = current_bg_color;
|
||||||
@ -936,7 +958,7 @@ static void parse_ansi_code(const char *buf, int *idx, int max_len,
|
|||||||
switch (params[0]) {
|
switch (params[0]) {
|
||||||
case 0: // Clear from cursor to end of line
|
case 0: // Clear from cursor to end of line
|
||||||
for (int x = cursor_x; x < term_cols; x++) {
|
for (int x = cursor_x; x < term_cols; x++) {
|
||||||
terminal_buffer[cursor_y][x] = ' ';
|
terminal_buffer[cursor_y][x] = L' ';
|
||||||
color_buffer[cursor_y][x] = current_color;
|
color_buffer[cursor_y][x] = current_color;
|
||||||
attr_buffer[cursor_y][x] = current_attr;
|
attr_buffer[cursor_y][x] = current_attr;
|
||||||
bg_color_buffer[cursor_y][x] = current_bg_color;
|
bg_color_buffer[cursor_y][x] = current_bg_color;
|
||||||
@ -944,15 +966,15 @@ static void parse_ansi_code(const char *buf, int *idx, int max_len,
|
|||||||
break;
|
break;
|
||||||
case 1: // Clear from cursor to beginning of line
|
case 1: // Clear from cursor to beginning of line
|
||||||
for (int x = 0; x <= cursor_x; x++) {
|
for (int x = 0; x <= cursor_x; x++) {
|
||||||
terminal_buffer[cursor_y][x] = ' ';
|
terminal_buffer[cursor_y][x] = L' ';
|
||||||
color_buffer[cursor_y][x] = current_color;
|
color_buffer[cursor_y][x] = current_color;
|
||||||
attr_buffer[cursor_y][x] = current_attr;
|
attr_buffer[cursor_y][x] = current_attr;
|
||||||
bg_color_buffer[cursor_y][x] = current_bg_color;
|
bg_color_buffer[cursor_y][x] = current_bg_color;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // Clear entire line
|
case 2: // Clear entire line
|
||||||
memset(terminal_buffer[cursor_y], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[cursor_y][x] = L' ';
|
||||||
color_buffer[cursor_y][x] = current_color;
|
color_buffer[cursor_y][x] = current_color;
|
||||||
attr_buffer[cursor_y][x] = current_attr;
|
attr_buffer[cursor_y][x] = current_attr;
|
||||||
bg_color_buffer[cursor_y][x] = current_bg_color;
|
bg_color_buffer[cursor_y][x] = current_bg_color;
|
||||||
@ -960,46 +982,45 @@ static void parse_ansi_code(const char *buf, int *idx, int max_len,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
needs_refresh = 1;
|
needs_refresh = 1;
|
||||||
|
draw_terminal(display, window);
|
||||||
break;
|
break;
|
||||||
case 'J': // Clear screen
|
case 'J': // Clear screen
|
||||||
switch (params[0]) {
|
switch (params[0]) {
|
||||||
case 0: // Clear from cursor to end of screen
|
case 0: // Clear from cursor to end of screen
|
||||||
// Clear current line from cursor
|
// Clear current line from cursor
|
||||||
for (int x = cursor_x; x < term_cols; x++) {
|
for (int x = cursor_x; x < term_cols; x++) {
|
||||||
terminal_buffer[cursor_y][x] = ' ';
|
terminal_buffer[cursor_y][x] = L' ';
|
||||||
color_buffer[cursor_y][x] = current_color;
|
color_buffer[cursor_y][x] = current_color;
|
||||||
attr_buffer[cursor_y][x] = current_attr;
|
attr_buffer[cursor_y][x] = current_attr;
|
||||||
bg_color_buffer[cursor_y][x] = current_bg_color;
|
bg_color_buffer[cursor_y][x] = current_bg_color;
|
||||||
}
|
}
|
||||||
// Clear all lines below cursor
|
// Clear all lines below cursor
|
||||||
for (int y = cursor_y + 1; y < term_rows; y++) {
|
for (int y = cursor_y + 1; y < term_rows; y++) {
|
||||||
memset(terminal_buffer[y], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[y][x] = L' ';
|
||||||
color_buffer[y][x] = current_color;
|
color_buffer[y][x] = current_color;
|
||||||
attr_buffer[y][x] = current_attr;
|
attr_buffer[y][x] = current_attr;
|
||||||
bg_color_buffer[y][x] = current_bg_color;
|
bg_color_buffer[y][x] = current_bg_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
needs_refresh = 1;
|
|
||||||
break;
|
break;
|
||||||
case 1: // Clear from cursor to beginning of screen
|
case 1: // Clear from cursor to beginning of screen
|
||||||
// Clear current line up to cursor
|
// Clear current line up to cursor
|
||||||
for (int x = 0; x <= cursor_x; x++) {
|
for (int x = 0; x <= cursor_x; x++) {
|
||||||
terminal_buffer[cursor_y][x] = ' ';
|
terminal_buffer[cursor_y][x] = L' ';
|
||||||
color_buffer[cursor_y][x] = current_color;
|
color_buffer[cursor_y][x] = current_color;
|
||||||
attr_buffer[cursor_y][x] = current_attr;
|
attr_buffer[cursor_y][x] = current_attr;
|
||||||
bg_color_buffer[cursor_y][x] = current_bg_color;
|
bg_color_buffer[cursor_y][x] = current_bg_color;
|
||||||
}
|
}
|
||||||
// Clear all lines above cursor
|
// Clear all lines above cursor
|
||||||
for (int y = 0; y < cursor_y; y++) {
|
for (int y = 0; y < cursor_y; y++) {
|
||||||
memset(terminal_buffer[y], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[y][x] = L' ';
|
||||||
color_buffer[y][x] = current_color;
|
color_buffer[y][x] = current_color;
|
||||||
attr_buffer[y][x] = current_attr;
|
attr_buffer[y][x] = current_attr;
|
||||||
bg_color_buffer[y][x] = current_bg_color;
|
bg_color_buffer[y][x] = current_bg_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
needs_refresh = 1;
|
|
||||||
break;
|
break;
|
||||||
case 2: // Clear entire screen
|
case 2: // Clear entire screen
|
||||||
case 3: // Clear entire screen and scrollback (treat same as 2)
|
case 3: // Clear entire screen and scrollback (treat same as 2)
|
||||||
@ -1007,16 +1028,19 @@ static void parse_ansi_code(const char *buf, int *idx, int max_len,
|
|||||||
current_bg_color = XBlackPixel(display, DefaultScreen(display));
|
current_bg_color = XBlackPixel(display, DefaultScreen(display));
|
||||||
current_attr = 0;
|
current_attr = 0;
|
||||||
for (int y = 0; y < term_rows; y++) {
|
for (int y = 0; y < term_rows; y++) {
|
||||||
memset(terminal_buffer[y], ' ', term_cols);
|
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int x = 0; x < term_cols; x++) {
|
||||||
|
terminal_buffer[y][x] = L' ';
|
||||||
color_buffer[y][x] = current_color;
|
color_buffer[y][x] = current_color;
|
||||||
attr_buffer[y][x] = current_attr;
|
attr_buffer[y][x] = current_attr;
|
||||||
bg_color_buffer[y][x] = current_bg_color;
|
bg_color_buffer[y][x] = current_bg_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
needs_refresh = 1;
|
cursor_x = 0;
|
||||||
|
cursor_y = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
needs_refresh = 1;
|
||||||
|
draw_terminal(display, window);
|
||||||
break;
|
break;
|
||||||
case 'r': // Set scrolling region
|
case 'r': // Set scrolling region
|
||||||
if (param_idx == 0) {
|
if (param_idx == 0) {
|
||||||
@ -1194,7 +1218,7 @@ static int master_cb(int fd, void *data, Window window) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((buf[i] >= 32 && buf[i] <= 126) || buf[i] == '\n' || buf[i] == '\r' ||
|
if ((buf[i] >= 32 && buf[i] <= 126) || buf[i] == '\n' || buf[i] == '\r' ||
|
||||||
buf[i] == '\b' || buf[i] == '\t') {
|
buf[i] == '\b' || buf[i] == '\t' || (buf[i] & 0x80)) {
|
||||||
switch (buf[i]) {
|
switch (buf[i]) {
|
||||||
case '\n':
|
case '\n':
|
||||||
cursor_x = 0;
|
cursor_x = 0;
|
||||||
@ -1239,6 +1263,27 @@ static int master_cb(int fd, void *data, Window window) {
|
|||||||
cursor_y = term_rows - 1;
|
cursor_y = term_rows - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (buf[i] & 0x80) { // UTF-8
|
||||||
|
mbstate_t ps;
|
||||||
|
memset(&ps, 0, sizeof(ps));
|
||||||
|
wchar_t wc;
|
||||||
|
size_t len = mbrtowc(&wc, buf + i, n - i, &ps);
|
||||||
|
|
||||||
|
if (len != (size_t)-1 && len != (size_t)-2 && len != 0) {
|
||||||
|
terminal_buffer[cursor_y][cursor_x] = wc;
|
||||||
|
color_buffer[cursor_y][cursor_x] = current_color;
|
||||||
|
attr_buffer[cursor_y][cursor_x] = current_attr;
|
||||||
|
bg_color_buffer[cursor_y][cursor_x] = current_bg_color;
|
||||||
|
needs_refresh = 1;
|
||||||
|
if (++cursor_x >= term_cols) {
|
||||||
|
cursor_x = 0;
|
||||||
|
if (++cursor_y >= term_rows) {
|
||||||
|
scroll_region_up(1);
|
||||||
|
cursor_y = term_rows - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += len - 1; // -1 because loop will increment i
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1331,19 +1376,24 @@ int main(void) {
|
|||||||
gettimeofday(&last_blink, 0);
|
gettimeofday(&last_blink, 0);
|
||||||
gettimeofday(&last_refresh, 0);
|
gettimeofday(&last_refresh, 0);
|
||||||
|
|
||||||
if (!(terminal_buffer = calloc(term_rows, sizeof(char *))) ||
|
if (!(terminal_buffer = calloc(term_rows, sizeof(wchar_t *))) ||
|
||||||
!(color_buffer = calloc(term_rows, sizeof(unsigned long *))) ||
|
!(color_buffer = calloc(term_rows, sizeof(unsigned long *))) ||
|
||||||
!(attr_buffer = calloc(term_rows, sizeof(int *))) ||
|
!(attr_buffer = calloc(term_rows, sizeof(int *))) ||
|
||||||
!(bg_color_buffer = calloc(term_rows, sizeof(unsigned long *))))
|
!(bg_color_buffer = calloc(term_rows, sizeof(unsigned long *))))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (int i = 0; i < term_rows; i++) {
|
for (int i = 0; i < term_rows; i++) {
|
||||||
if (!(terminal_buffer[i] = calloc(term_cols, sizeof(char))) ||
|
if (!(terminal_buffer[i] = calloc(term_cols, sizeof(wchar_t))) ||
|
||||||
!(color_buffer[i] = calloc(term_cols, sizeof(unsigned long))) ||
|
!(color_buffer[i] = calloc(term_cols, sizeof(unsigned long))) ||
|
||||||
!(attr_buffer[i] = calloc(term_cols, sizeof(int))) ||
|
!(attr_buffer[i] = calloc(term_cols, sizeof(int))) ||
|
||||||
!(bg_color_buffer[i] = calloc(term_cols, sizeof(unsigned long))))
|
!(bg_color_buffer[i] = calloc(term_cols, sizeof(unsigned long))))
|
||||||
return 1;
|
return 1;
|
||||||
memset(terminal_buffer[i], ' ', term_cols);
|
for (int j = 0; j < term_cols; j++) {
|
||||||
|
terminal_buffer[i][j] = L' ';
|
||||||
|
color_buffer[i][j] = current_color;
|
||||||
|
attr_buffer[i][j] = current_attr;
|
||||||
|
bg_color_buffer[i][j] = current_bg_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(display = XOpenDisplay(0)))
|
if (!(display = XOpenDisplay(0)))
|
||||||
@ -1402,6 +1452,7 @@ int main(void) {
|
|||||||
if (slave > 2)
|
if (slave > 2)
|
||||||
close(slave);
|
close(slave);
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
char *sh = getenv("SHELL");
|
char *sh = getenv("SHELL");
|
||||||
#if COLOR_256_SUPPORT
|
#if COLOR_256_SUPPORT
|
||||||
setenv("TERM", "xterm-256color", 1);
|
setenv("TERM", "xterm-256color", 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user