Rewrite of main() and a few other functions
it should have less sloc and better overall
This commit is contained in:
parent
2e81b185e2
commit
9215edb1c1
170
cowterm.c
170
cowterm.c
@ -1107,76 +1107,51 @@ static void key_press_cb(XKeyEvent *event, void *data) {
|
|||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
int master, slave;
|
int master, slave;
|
||||||
pid_t pid;
|
struct winsize ws = {.ws_row = 24,
|
||||||
|
.ws_col = 80,
|
||||||
|
.ws_xpixel = 80 * CHAR_WIDTH,
|
||||||
|
.ws_ypixel = 24 * CHAR_HEIGHT};
|
||||||
|
term_rows = ws.ws_row;
|
||||||
|
term_cols = ws.ws_col;
|
||||||
|
|
||||||
term_rows = 24;
|
gettimeofday(&last_blink, 0);
|
||||||
term_cols = 80;
|
gettimeofday(&last_refresh, 0);
|
||||||
|
|
||||||
gettimeofday(&last_blink, NULL);
|
if (!(terminal_buffer = calloc(term_rows, sizeof(char *))) ||
|
||||||
gettimeofday(&last_refresh, NULL);
|
!(color_buffer = calloc(term_rows, sizeof(unsigned long *))) ||
|
||||||
|
!(attr_buffer = calloc(term_rows, sizeof(int *))) ||
|
||||||
struct winsize ws = {.ws_row = term_rows,
|
!(bg_color_buffer = calloc(term_rows, sizeof(unsigned long *))))
|
||||||
.ws_col = term_cols,
|
|
||||||
.ws_xpixel = term_cols * CHAR_WIDTH,
|
|
||||||
.ws_ypixel = term_rows * CHAR_HEIGHT};
|
|
||||||
|
|
||||||
terminal_buffer = malloc(term_rows * sizeof(char *));
|
|
||||||
color_buffer = malloc(term_rows * sizeof(unsigned long *));
|
|
||||||
attr_buffer = malloc(term_rows * sizeof(int *));
|
|
||||||
bg_color_buffer = malloc(term_rows * sizeof(unsigned long *));
|
|
||||||
|
|
||||||
if (!terminal_buffer || !color_buffer || !attr_buffer || !bg_color_buffer) {
|
|
||||||
fprintf(stderr, "Failed to allocate memory for buffers\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < term_rows; i++) {
|
for (int i = 0; i < term_rows; i++) {
|
||||||
terminal_buffer[i] = malloc(term_cols * sizeof(char));
|
if (!(terminal_buffer[i] = calloc(term_cols, sizeof(char))) ||
|
||||||
color_buffer[i] = malloc(term_cols * sizeof(unsigned long));
|
!(color_buffer[i] = calloc(term_cols, sizeof(unsigned long))) ||
|
||||||
attr_buffer[i] = malloc(term_cols * sizeof(int));
|
!(attr_buffer[i] = calloc(term_cols, sizeof(int))) ||
|
||||||
bg_color_buffer[i] = malloc(term_cols * sizeof(unsigned long));
|
!(bg_color_buffer[i] = calloc(term_cols, sizeof(unsigned long))))
|
||||||
|
|
||||||
if (!terminal_buffer[i] || !color_buffer[i] || !attr_buffer[i] ||
|
|
||||||
!bg_color_buffer[i]) {
|
|
||||||
fprintf(stderr, "Failed to allocate memory for buffer row\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
memset(terminal_buffer[i], ' ', term_cols);
|
memset(terminal_buffer[i], ' ', term_cols);
|
||||||
memset(attr_buffer[i], 0, term_cols * sizeof(int));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
display = XOpenDisplay(NULL);
|
if (!(display = XOpenDisplay(0)))
|
||||||
if (!display) {
|
|
||||||
fprintf(stderr, "Cannot open display\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
|
|
||||||
current_color = XWhitePixel(display, DefaultScreen(display));
|
current_color = XWhitePixel(display, DefaultScreen(display));
|
||||||
current_bg_color = XBlackPixel(display, DefaultScreen(display));
|
current_bg_color = XBlackPixel(display, DefaultScreen(display));
|
||||||
current_attr = 0;
|
|
||||||
|
|
||||||
for (int y = 0; y < term_rows; y++) {
|
for (int i = 0; i < term_rows; i++)
|
||||||
for (int x = 0; x < term_cols; x++) {
|
for (int j = 0; j < term_cols; j++) {
|
||||||
bg_color_buffer[y][x] = current_bg_color;
|
bg_color_buffer[i][j] = current_bg_color;
|
||||||
}
|
color_buffer[i][j] = current_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = 0; y < term_rows; y++) {
|
XSizeHints hints = {.flags = PResizeInc | PMinSize,
|
||||||
for (int x = 0; x < term_cols; x++) {
|
.width_inc = CHAR_WIDTH,
|
||||||
color_buffer[y][x] = current_color;
|
.height_inc = CHAR_HEIGHT,
|
||||||
attr_buffer[y][x] = current_attr;
|
.min_width = CHAR_WIDTH * 4,
|
||||||
}
|
.min_height = CHAR_HEIGHT};
|
||||||
}
|
|
||||||
|
|
||||||
XSizeHints hints;
|
Window win = XCreateSimpleWindow(
|
||||||
hints.flags = PResizeInc | PMinSize;
|
|
||||||
hints.width_inc = CHAR_WIDTH;
|
|
||||||
hints.height_inc = CHAR_HEIGHT;
|
|
||||||
hints.min_width = CHAR_WIDTH * 4;
|
|
||||||
hints.min_height = CHAR_HEIGHT * 1;
|
|
||||||
|
|
||||||
Window window = XCreateSimpleWindow(
|
|
||||||
display, DefaultRootWindow(display), 0, 0, term_cols * CHAR_WIDTH,
|
display, DefaultRootWindow(display), 0, 0, term_cols * CHAR_WIDTH,
|
||||||
term_rows * CHAR_HEIGHT, 0, XBlackPixel(display, DefaultScreen(display)),
|
term_rows * CHAR_HEIGHT, 0, XBlackPixel(display, DefaultScreen(display)),
|
||||||
XBlackPixel(display, DefaultScreen(display)));
|
XBlackPixel(display, DefaultScreen(display)));
|
||||||
@ -1185,76 +1160,66 @@ int main(void) {
|
|||||||
term_cols * CHAR_WIDTH, term_rows * CHAR_HEIGHT,
|
term_cols * CHAR_WIDTH, term_rows * CHAR_HEIGHT,
|
||||||
DefaultDepth(display, DefaultScreen(display)));
|
DefaultDepth(display, DefaultScreen(display)));
|
||||||
|
|
||||||
XSetWMNormalHints(display, window, &hints);
|
XSetWMNormalHints(display, win, &hints);
|
||||||
XStoreName(display, window, window_name);
|
XStoreName(display, win, window_name);
|
||||||
XSelectInput(display, window,
|
XSelectInput(display, win,
|
||||||
KeyPressMask | ExposureMask | StructureNotifyMask |
|
KeyPressMask | ExposureMask | StructureNotifyMask |
|
||||||
FocusChangeMask);
|
FocusChangeMask);
|
||||||
XMapWindow(display, window);
|
XMapWindow(display, win);
|
||||||
|
|
||||||
if (openpty(&master, &slave, NULL, NULL, &ws) == -1) {
|
if (openpty(&master, &slave, 0, 0, &ws) == -1)
|
||||||
perror("openpty");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
master_fd = master;
|
master_fd = master;
|
||||||
|
|
||||||
pid = fork();
|
if ((child_pid = fork()) == -1)
|
||||||
if (pid < 0) {
|
|
||||||
perror("fork");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == 0) {
|
if (!child_pid) {
|
||||||
close(master);
|
close(master);
|
||||||
close(STDIN_FILENO);
|
for (int i = 0; i < 3; i++)
|
||||||
close(STDOUT_FILENO);
|
close(i);
|
||||||
close(STDERR_FILENO);
|
|
||||||
|
|
||||||
setsid();
|
setsid();
|
||||||
dup2(slave, 0);
|
for (int i = 0; i < 3; i++)
|
||||||
dup2(slave, 1);
|
if (dup2(slave, i) == -1)
|
||||||
dup2(slave, 2);
|
return 1;
|
||||||
|
|
||||||
if (slave > 2)
|
if (slave > 2)
|
||||||
close(slave);
|
close(slave);
|
||||||
|
|
||||||
char *shell = getenv("SHELL");
|
char *sh = getenv("SHELL");
|
||||||
if (!shell)
|
|
||||||
shell = "/bin/sh";
|
|
||||||
|
|
||||||
setenv("TERM", "xterm-256color", 1);
|
setenv("TERM", "xterm-256color", 1);
|
||||||
execlp(shell, shell, NULL);
|
execl(sh ? sh : "/bin/sh", sh ? sh : "sh", 0);
|
||||||
perror("execlp");
|
return 1;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
child_pid = pid;
|
|
||||||
close(slave);
|
close(slave);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Display *display;
|
Display *display;
|
||||||
Window window;
|
Window window;
|
||||||
} ctx = {display, window};
|
} ctx = {display, win};
|
||||||
|
|
||||||
XEvent event;
|
XEvent ev;
|
||||||
while (1) {
|
fd_set fds;
|
||||||
int status;
|
struct timeval tv = {0, 1000};
|
||||||
pid_t wpid = waitpid(child_pid, &status, WNOHANG);
|
|
||||||
if (wpid == child_pid) {
|
for (;;) {
|
||||||
destroy_cb(display, window);
|
if (waitpid(child_pid, 0, WNOHANG) == child_pid) {
|
||||||
|
destroy_cb(display, win);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (XPending(display)) {
|
while (XPending(display)) {
|
||||||
XNextEvent(display, &event);
|
XNextEvent(display, &ev);
|
||||||
switch (event.type) {
|
switch (ev.type) {
|
||||||
case ConfigureNotify: {
|
case ConfigureNotify: {
|
||||||
XConfigureEvent *ce = (XConfigureEvent *)&event;
|
XConfigureEvent *ce = &ev.xconfigure;
|
||||||
int new_rows = ce->height / CHAR_HEIGHT;
|
int nr = ce->height / CHAR_HEIGHT;
|
||||||
int new_cols = ce->width / CHAR_WIDTH;
|
int nc = ce->width / CHAR_WIDTH;
|
||||||
if (new_rows != term_rows || new_cols != term_cols) {
|
if (nr != term_rows || nc != term_cols) {
|
||||||
resize_buffers(new_rows, new_cols);
|
resize_buffers(nr, nc);
|
||||||
ws.ws_row = term_rows;
|
ws.ws_row = term_rows;
|
||||||
ws.ws_col = term_cols;
|
ws.ws_col = term_cols;
|
||||||
ws.ws_xpixel = term_cols * CHAR_WIDTH;
|
ws.ws_xpixel = term_cols * CHAR_WIDTH;
|
||||||
@ -1264,34 +1229,29 @@ int main(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
window_focused = 1;
|
window_focused = needs_refresh = 1;
|
||||||
needs_refresh = 1;
|
|
||||||
break;
|
break;
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
window_focused = 0;
|
window_focused = 0;
|
||||||
needs_refresh = 1;
|
needs_refresh = 1;
|
||||||
break;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
key_press_cb((XKeyEvent *)&event, &master);
|
if (!(ev.xkey.state & ControlMask) && ev.xkey.keycode < 128)
|
||||||
|
key_press_cb(&ev.xkey, &master);
|
||||||
break;
|
break;
|
||||||
case Expose:
|
case Expose:
|
||||||
needs_refresh = 1;
|
needs_refresh = 1;
|
||||||
check_refresh(display, window);
|
check_refresh(display, win);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_set fds;
|
|
||||||
struct timeval tv = {0, 1000}; // 1ms timeout for faster refresh
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(master, &fds);
|
FD_SET(master, &fds);
|
||||||
if (select(master + 1, &fds, NULL, NULL, &tv) > 0) {
|
if (select(master + 1, &fds, 0, 0, &tv) > 0)
|
||||||
master_cb(master, &ctx, window);
|
master_cb(master, &ctx, win);
|
||||||
}
|
|
||||||
|
|
||||||
check_refresh(display, window);
|
check_refresh(display, win);
|
||||||
update_cursor_state(display, window);
|
update_cursor_state(display, win);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user