vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: b14e800a97c108805665b3a769d834a40463ea59
Parent: fab540b6a860a098902b477d89aca29587fbda6d
Author: Randy Palamar
Date:   Wed,  4 Dec 2024 06:36:39 -0700

move many sycalls to the linux specific platform layer

the last remaining ones are not just simple syscall wrappers but will be moved soon

Diffstat:
Mdebug.c | 5+++--
Mos_unix.c | 174-------------------------------------------------------------------------------
Mplatform_linux_amd64.c | 9+++++++++
Mplatform_linux_common.c | 227++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mplatform_linux_x11.c | 10+++++-----
Mtests/test.c | 4++--
Mutil.c | 8++++++++
Mvtgl.c | 56++++++++++++++++++++++++++++----------------------------
Mvtgl.h | 4++--
9 files changed, 264 insertions(+), 233 deletions(-)

diff --git a/debug.c b/debug.c @@ -7,6 +7,7 @@ dump_lines_to_file(Term *t) stream_push_u64(&fname, current_time); stream_push_s8(&fname, s8("-lines.bin\0")); + /* TODO: just replace this with some giant buffer, this is debug code */ iptr file = os_open(buf, FA_WRITE); if (file == INVALID_FILE) return; @@ -41,7 +42,7 @@ dump_lines_to_file(Term *t) stream_push_s8(&out, l); if (out.errors) { /* TODO: cleanup */ - posix_write(file, stream_to_s8(&out), file_offset); + os_offset_write(file, stream_to_s8(&out), file_offset); file_offset += out.widx; out.widx = 0; stream_push_s8(&out, l); @@ -50,7 +51,7 @@ dump_lines_to_file(Term *t) stream_push_byte(&out, '\n'); /* TODO: cleanup */ - posix_write(file, stream_to_s8(&out), file_offset); + os_offset_write(file, stream_to_s8(&out), file_offset); os_close(file); } diff --git a/os_unix.c b/os_unix.c @@ -2,164 +2,9 @@ #include <fcntl.h> #include <pty.h> #include <pwd.h> -#include <sys/mman.h> #include <sys/select.h> -#include <sys/wait.h> -#include <time.h> #include <unistd.h> -#define OS_MAP_READ PROT_READ -#define OS_MAP_PRIVATE MAP_PRIVATE - -static f64 -os_get_time(void) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - f64 result = ts.tv_sec + ((f64)ts.tv_nsec) * 1e-9; - return result; -} - -static u32 -os_file_attribute_to_mode(u32 attr) -{ - u32 result = O_CREAT; - if (attr & FA_READ && attr & FA_WRITE) { - result |= O_RDWR; - } else if (attr & FA_READ) { - result |= O_RDONLY; - } else if (attr & FA_WRITE) { - result |= O_WRONLY; - } - - if (attr & FA_APPEND) - result |= O_APPEND; - - return result; -} - -static iptr -os_open(u8 *name, u32 attr) -{ - iptr result = open((char *)name, os_file_attribute_to_mode(attr), 0660); - if (result < 0) - result = INVALID_FILE; - return result; -} - -static PLATFORM_WRITE_FN(posix_write) -{ - size result; - /* NOTE: pwrite can't be used on forked child even with an offset of 0 :( thanks linux */ - if (offset > 0) result = pwrite(file, raw.data, raw.len, offset); - else result = write(file, raw.data, raw.len); - return result == raw.len; -} - -static void -os_close(iptr file) -{ - close(file); -} - -static PLATFORM_READ_FN(posix_read) -{ - size r = 0, remaining = buffer.len, total_bytes_read = 0; - - do { - remaining -= r; - total_bytes_read += r; - r = read(file, buffer.data + total_bytes_read, remaining); - } while (r != -1 && remaining != 0); - - return total_bytes_read; -} - -static PLATFORM_READ_FILE_FN(posix_read_file) -{ - s8 result = {0}; - - stat_buffer sb; - i64 status = syscall2(SYS_stat, (iptr)path, (iptr)sb); - i32 fd = open((c8 *)path, O_RDONLY); - - if (fd > 0 && status == 0) { - result = s8alloc(a, STAT_FILE_SIZE(sb)); - size rlen = posix_read(fd, result, 0); - close(fd); - if (result.len != rlen) - result.len = 0; - } - - return result; -} - -static os_mapped_file -os_map_file(char *path, i32 mode, i32 perm) -{ - os_mapped_file res = {0}; - - i32 open_mode = 0; - switch(mode) { - case OS_MAP_READ: open_mode = O_RDONLY; break; - default: ASSERT(0); - } - - stat_buffer sb; - i64 status = syscall2(SYS_stat, (iptr)path, (iptr)sb); - i32 fd = open(path, open_mode); - - if (fd != -1 && status == 0) { - res.data = mmap(NULL, STAT_FILE_SIZE(sb), mode, perm, fd, 0); - if (res.data != MAP_FAILED) - res.len = STAT_FILE_SIZE(sb); - close(fd); - } - - return res; -} - -static PLATFORM_ALLOCATE_RING_BUFFER_FN(posix_allocate_ring_buffer) -{ - size pagesize = PAGE_SIZE; - if (capacity % pagesize != 0) - capacity += pagesize - capacity % pagesize; - - ASSERT(capacity % pagesize == 0); - - char *mfd_name = "vtgl:rb"; - i32 fd = shm_open(mfd_name, O_RDWR|O_CREAT, 0600); - if (fd == -1) - os_fatal(s8("os_alloc_ring_buffer: failed to open mem_fd\n")); - shm_unlink(mfd_name); - ftruncate(fd, capacity); - - rb->widx = 0; - rb->filled = 0; - rb->cap = capacity; - rb->buf = mmap(0, 3 * rb->cap, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - - if (rb->buf == MAP_FAILED) - os_fatal(s8("os_alloc_ring_buffer: initial mmap failed\n")); - - for (i32 i = 0; i < 3; i++) { - void *ret = mmap(rb->buf + i * rb->cap, rb->cap, PROT_READ|PROT_WRITE, - MAP_FIXED|MAP_SHARED, fd, 0); - if (ret == MAP_FAILED) { - u8 buf[256]; - Stream err = {.buf = buf, .cap = sizeof(buf)}; - stream_push_s8(&err, s8("os_alloc_ring_buffer: mmap(")); - stream_push_u64(&err, i); - stream_push_s8(&err, s8(") failed\n")); - os_fatal(stream_to_s8(&err)); - } - } - close(fd); - - /* NOTE: start in the middle page */ - rb->buf += rb->cap; -} - static void execsh(char *defcmd) { @@ -210,22 +55,3 @@ os_fork_child(char *cmd) return (linux_platform_process){.process_id = pid, .handle = cfd}; } - -static b32 -os_child_exited(iptr pid) -{ - i32 r, status; - r = waitpid(pid, &status, WNOHANG); - return r == pid && WIFEXITED(status); -} - -static PLATFORM_SET_TERMINAL_SIZE_FN(posix_set_terminal_size) -{ - struct winsize ws; - ws.ws_col = columns; - ws.ws_row = rows; - ws.ws_xpixel = window_width; - ws.ws_ypixel = window_height; - if (ioctl(child, TIOCSWINSZ, &ws) < 0) - os_write_err_msg(s8("os_set_term_size\n")); -} diff --git a/platform_linux_amd64.c b/platform_linux_amd64.c @@ -8,20 +8,29 @@ #endif #endif +/* TODO: X macro that defines all of these with the appropriate function/macro */ #define SYS_read 0 #define SYS_write 1 #define SYS_open 2 #define SYS_close 3 #define SYS_stat 4 +#define SYS_fstat 5 #define SYS_mmap 9 +#define SYS_ioctl 16 +#define SYS_pwrite 18 +#define SYS_madvise 28 #define SYS_clone 56 +#define SYS_wait4 61 +#define SYS_ftruncate 77 #define SYS_prctl 157 #define SYS_futex 202 #define SYS_getdents64 217 +#define SYS_clock_gettime 228 #define SYS_exit_group 231 #define SYS_inotify_add_watch 254 #define SYS_inotify_rm_watch 255 #define SYS_inotify_init1 294 +#define SYS_memfd_create 319 #define PAGE_SIZE 4096 diff --git a/platform_linux_common.c b/platform_linux_common.c @@ -1,16 +1,30 @@ #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 +#define CLOCK_MONOTONIC 1 + #define PR_SET_NAME 15 +#define PROT_READ 0x01 #define PROT_RW 0x03 +#define MFD_CLOEXEC 0x01 + +#define MAP_SHARED 0x01 #define MAP_PRIVATE 0x02 #define MAP_FIXED 0x10 #define MAP_ANON 0x20 -#define O_CLOEXEC 0x80000 +#define MADV_HUGEPAGE 14 + +#define O_RDONLY 0x00000 +#define O_WRONLY 0x00001 +#define O_RDWR 0x00002 +#define O_CREAT 0x00040 +#define O_NOCTTY 0x00100 +#define O_APPEND 0x00400 #define O_NONBLOCK 0x00800 +#define O_CLOEXEC 0x80000 #define IN_CLOSE_WRITE 0x00000008 #define IN_CLOSE_NOWRITE 0x00000010 @@ -18,10 +32,20 @@ #define LINUX_INOTIFY_MASK (IN_CLOSE_WRITE|IN_CLOSE_NOWRITE|IN_MODIFY) +#define WNOHANG 1 +#define W_IF_EXITED(s) (!((s) & 0x7F)) + +#define TIOCSWINSZ 0x5414 +#define TIOCSPTLCK 0x145431 /* (un)lock pty */ +#define TIOCGPTN 0x245430 /* get pty number */ + #ifndef VERSION #define VERSION "unknown" #endif +#define OS_MAP_READ PROT_READ +#define OS_MAP_PRIVATE MAP_PRIVATE + #define atomic_exchange_n(ptr, val) __atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST) struct __attribute__((aligned(16))) stack_base { @@ -85,12 +109,90 @@ os_fatal(s8 msg) __builtin_unreachable(); } +static u32 +os_file_attribute_to_mode(u32 attr) +{ + u32 result = O_CREAT; + if (attr & FA_READ && attr & FA_WRITE) { + result |= O_RDWR; + } else if (attr & FA_READ) { + result |= O_RDONLY; + } else if (attr & FA_WRITE) { + result |= O_WRONLY; + } + + if (attr & FA_APPEND) + result |= O_APPEND; + + return result; +} + +static iptr +os_open(u8 *name, u32 attr) +{ + iptr result = syscall3(SYS_open, (iptr)name, os_file_attribute_to_mode(attr), 0660); + if (result > -4096UL) + result = INVALID_FILE; + return result; +} + +static b32 +os_offset_write(iptr file, s8 raw, size offset) +{ + size result = syscall4(SYS_pwrite, file, (iptr)raw.data, raw.len, offset); + return result == raw.len; +} + +static PLATFORM_WRITE_FN(os_write) +{ + size result = syscall3(SYS_write, file, (iptr)raw.data, raw.len); + return result == raw.len; +} + +static void +os_close(iptr file) +{ + syscall1(SYS_close, file); +} + +static PLATFORM_READ_FN(os_read) +{ + size r = 0, remaining = buffer.len, total_bytes_read = 0; + + do { + remaining -= r; + total_bytes_read += r; + r = syscall3(SYS_read, file, (iptr)(buffer.data + total_bytes_read), remaining); + } while (r <= -4096UL && remaining != 0); + + return total_bytes_read; +} + +static PLATFORM_READ_FILE_FN(os_read_file) +{ + s8 result = {0}; + + stat_buffer sb; + i32 fd = syscall3(SYS_open, (iptr)path, O_RDONLY, 0); + i64 status = syscall2(SYS_fstat, fd, (iptr)sb); + + if (fd <= -4096UL && status == 0) { + result = s8alloc(a, STAT_FILE_SIZE(sb)); + size rlen = os_read(fd, result); + syscall1(SYS_close, fd); + if (result.len != rlen) + result.len = 0; + } + + return result; +} static MemoryBlock linux_block_alloc(size requested_size) { MemoryBlock result = {0}; + /* TODO: query system for HUGETLB support and use those instead of page size */ size alloc_size = requested_size; if (alloc_size % PAGE_SIZE != 0) alloc_size += PAGE_SIZE - alloc_size % PAGE_SIZE; @@ -99,38 +201,102 @@ linux_block_alloc(size requested_size) if (memory <= -4096UL) { result.memory = (void *)memory; result.size = alloc_size; + syscall3(SYS_madvise, memory, alloc_size, MADV_HUGEPAGE); } return result; } -static struct stack_base * -new_stack(size capacity) +static f64 +os_get_time(void) { - i64 p = syscall6(SYS_mmap, 0, capacity, PROT_RW, MAP_ANON|MAP_PRIVATE, -1, 0); - if (p > -4096UL) - os_fatal(s8("new_stack: mmap failed\n")); - i64 count = capacity / sizeof(struct stack_base); - /* NOTE: remember the stack grows down; we want to start at the highest address */ - struct stack_base *result = (struct stack_base *)p + count - 1; + i64 timespec[2]; + syscall2(SYS_clock_gettime, CLOCK_MONOTONIC, (iptr)timespec); + f64 result = timespec[0] + ((f64)timespec[1]) * 1e-9; return result; } -static void -button_action(ButtonState *button, b32 pressed) +static os_mapped_file +os_map_file(char *path, i32 mode, i32 perm) { - if (pressed != button->ended_down) - button->transitions++; - button->ended_down = pressed; + os_mapped_file result = {0}; + + i32 open_mode = 0; + switch (mode) { + case OS_MAP_READ: open_mode = O_RDONLY; break; + default: ASSERT(0); + } + + stat_buffer sb; + i32 fd = syscall3(SYS_open, (iptr)path, open_mode, 0); + i64 status = syscall2(SYS_fstat, fd, (iptr)sb); + + if (fd <= -4096UL && status == 0) { + i64 memory = syscall6(SYS_mmap, 0, STAT_FILE_SIZE(sb), mode, perm, fd, 0); + if (memory <= -4096UL) { + result.data = (u8 *)memory; + result.len = STAT_FILE_SIZE(sb); + } + syscall1(SYS_close, fd); + } + + return result; } -static void -usage(char *argv0, Stream *err) +static PLATFORM_ALLOCATE_RING_BUFFER_FN(os_allocate_ring_buffer) { - stream_push_s8(err, s8("usage: ")); - stream_push_s8(err, c_str_to_s8(argv0)); - stream_push_s8(err, s8(" [-v] [-g COLxROW]\n")); - os_fatal(stream_to_s8(err)); + /* TODO: query system for HUGETLB support and use those instead of page size */ + if (capacity % PAGE_SIZE != 0) + capacity += PAGE_SIZE - capacity % PAGE_SIZE; + ASSERT(capacity % PAGE_SIZE == 0); + + i32 fd = syscall2(SYS_memfd_create, (iptr)"vtgl:rb", MFD_CLOEXEC); + if (fd > -4096UL) os_fatal(s8("os_alloc_ring_buffer: failed to open mem_fd\n")); + syscall2(SYS_ftruncate, fd, capacity); + + rb->widx = 0; + rb->filled = 0; + rb->cap = capacity; + rb->buf = (u8 *)syscall6(SYS_mmap, 0, (iptr)(3 * rb->cap), 0, MAP_ANON|MAP_PRIVATE, -1, 0); + if ((iptr)rb->buf > -4096UL) + os_fatal(s8("os_alloc_ring_buffer: initial mmap failed\n")); + syscall3(SYS_madvise, (iptr)rb->buf, 3 * rb->cap, MADV_HUGEPAGE); + + for (i32 i = 0; i < 3; i++) { + i64 memory = syscall6(SYS_mmap, (iptr)(rb->buf + i * rb->cap), rb->cap, PROT_RW, + MAP_FIXED|MAP_SHARED, fd, 0); + if (memory > -4096UL) { + u8 buf[256]; + Stream err = {.buf = buf, .cap = sizeof(buf)}; + stream_push_s8(&err, s8("os_alloc_ring_buffer: mmap(")); + stream_push_u64(&err, i); + stream_push_s8(&err, s8(") failed\n")); + os_fatal(stream_to_s8(&err)); + } + } + syscall1(SYS_close, fd); + + /* NOTE: start in the middle page */ + rb->buf += rb->cap; +} + +static b32 +os_child_exited(iptr pid) +{ + i64 status; + i64 r = syscall4(SYS_wait4, pid, (iptr)&status, WNOHANG, 0); + return r == pid && W_IF_EXITED(status); +} + +static PLATFORM_SET_TERMINAL_SIZE_FN(os_set_terminal_size) +{ + u16 win_size[4]; + win_size[0] = rows; + win_size[1] = columns; + win_size[2] = window_width; + win_size[3] = window_height; + if (syscall3(SYS_ioctl, child, TIOCSWINSZ, (iptr)win_size) > -4096UL) + os_write_err_msg(s8("os_set_term_size\n")); } static PLATFORM_ADD_FILE_WATCH_FN(linux_add_file_watch) @@ -196,4 +362,25 @@ dispatch_file_watch_events(PlatformCtx *ctx) } } +static struct stack_base * +new_stack(size capacity) +{ + i64 p = syscall6(SYS_mmap, 0, capacity, PROT_RW, MAP_ANON|MAP_PRIVATE, -1, 0); + if (p > -4096UL) + os_fatal(s8("new_stack: mmap failed\n")); + i64 count = capacity / sizeof(struct stack_base); + /* NOTE: remember the stack grows down; we want to start at the highest address */ + struct stack_base *result = (struct stack_base *)p + count - 1; + return result; +} + +static void +usage(char *argv0, Stream *err) +{ + stream_push_s8(err, s8("usage: ")); + stream_push_s8(err, c_str_to_s8(argv0)); + stream_push_s8(err, s8(" [-v] [-g COLxROW]\n")); + os_fatal(stream_to_s8(err)); +} + #include "os_unix.c" diff --git a/platform_linux_x11.c b/platform_linux_x11.c @@ -430,15 +430,15 @@ main(i32 argc, char *argv[], char *envp[]) #endif linux_ctx.memory.platform_api.add_file_watch = linux_add_file_watch; - linux_ctx.memory.platform_api.allocate_ring_buffer = posix_allocate_ring_buffer; + linux_ctx.memory.platform_api.allocate_ring_buffer = os_allocate_ring_buffer; linux_ctx.memory.platform_api.get_clipboard = x11_get_clipboard; linux_ctx.memory.platform_api.set_clipboard = x11_set_clipboard; - linux_ctx.memory.platform_api.read_file = posix_read_file; - linux_ctx.memory.platform_api.read = posix_read; - linux_ctx.memory.platform_api.set_terminal_size = posix_set_terminal_size; + linux_ctx.memory.platform_api.read_file = os_read_file; + linux_ctx.memory.platform_api.read = os_read; + linux_ctx.memory.platform_api.set_terminal_size = os_set_terminal_size; linux_ctx.memory.platform_api.get_window_title = x11_get_window_title; linux_ctx.memory.platform_api.set_window_title = x11_set_window_title; - linux_ctx.memory.platform_api.write = posix_write; + linux_ctx.memory.platform_api.write = os_write; linux_ctx.memory.platform_api.path_separator = '/'; if (!glfwInit()) diff --git a/tests/test.c b/tests/test.c @@ -342,10 +342,10 @@ main(void) cursor_alt(&term, 1); } - posix_allocate_ring_buffer(&term.views[0].log, BACKLOG_SIZE); + os_allocate_ring_buffer(&term.views[0].log, BACKLOG_SIZE); line_buf_alloc(&term.views[0].lines, &memory, term.views[0].log.buf, term.cursor.style, BACKLOG_LINES); - posix_allocate_ring_buffer(&term.views[1].log, ALT_BACKLOG_SIZE); + os_allocate_ring_buffer(&term.views[1].log, ALT_BACKLOG_SIZE); line_buf_alloc(&term.views[1].lines, &memory, term.views[1].log.buf, term.cursor.style, ALT_BACKLOG_LINES); diff --git a/util.c b/util.c @@ -443,6 +443,14 @@ all_mouse_up(TerminalInput *input) return result; } +static void +button_action(ButtonState *button, b32 pressed) +{ + if (pressed != button->ended_down) + button->transitions++; + button->ended_down = pressed; +} + static s8 utf8_encode(u32 cp) { diff --git a/vtgl.c b/vtgl.c @@ -710,7 +710,7 @@ KEYBIND_FN(paste) if (bracketed) stream_push_s8(&buf, s8("\033[201~")); if (success) - platform->write(t->child, stream_to_s8(&buf), 0); + platform->write(t->child, stream_to_s8(&buf)); return 1; } @@ -805,7 +805,7 @@ report_mouse(Term *t, TerminalInput *input, b32 released, b32 beginning) return; } - t->platform->write(t->child, stream_to_s8(&buf), 0); + t->platform->write(t->child, stream_to_s8(&buf)); } static void @@ -837,11 +837,11 @@ terminal_interaction(Term *t, PlatformAPI *platform, TerminalInput *input, u32 c if (t->mode.term & TM_ALTSCREEN) { iptr child = t->child; if (input->mouse_scroll.y > 0) { - if (shift_down) platform->write(child, s8("\x1B[5;2~"), 0); - else platform->write(child, s8("\x19"), 0); + if (shift_down) platform->write(child, s8("\x1B[5;2~")); + else platform->write(child, s8("\x19")); } else { - if (shift_down) platform->write(child, s8("\x1B[6;2~"), 0); - else platform->write(child, s8("\x05"), 0); + if (shift_down) platform->write(child, s8("\x1B[6;2~")); + else platform->write(child, s8("\x05")); } } else { Arg a = {.i = (i32)input->mouse_scroll.y}; @@ -895,11 +895,11 @@ DEBUG_EXPORT VTGL_HANDLE_KEYS_FN(vtgl_handle_keys) /* TODO: this is wrong. look up where 8-bit modifiers should be sent */ if (0 && t->mode.win & WM_8BIT) { if (key < 0x7F) { - platform->write(child, utf8_encode(key | 0x80), 0); + platform->write(child, utf8_encode(key | 0x80)); return; } } else if (BETWEEN(key, 0x40, 0x5F)) { - platform->write(child, utf8_encode(key - 0x40), 0); + platform->write(child, utf8_encode(key - 0x40)); return; } } @@ -908,59 +908,59 @@ DEBUG_EXPORT VTGL_HANDLE_KEYS_FN(vtgl_handle_keys) switch (ENCODE_KEY(action, 0, key)) { case ENCODE_KEY(ACT_PRESS, 0, KEY_ESCAPE): case ENCODE_KEY(ACT_REPEAT, 0, KEY_ESCAPE): - platform->write(child, s8("\x1B"), 0); + platform->write(child, s8("\x1B")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_TAB): case ENCODE_KEY(ACT_REPEAT, 0, KEY_TAB): - platform->write(child, s8("\t"), 0); + platform->write(child, s8("\t")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_ENTER): case ENCODE_KEY(ACT_REPEAT, 0, KEY_ENTER): - platform->write(child, s8("\r"), 0); + platform->write(child, s8("\r")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_BACKSPACE): case ENCODE_KEY(ACT_REPEAT, 0, KEY_BACKSPACE): - platform->write(child, s8("\x7F"), 0); + platform->write(child, s8("\x7F")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_UP): case ENCODE_KEY(ACT_REPEAT, 0, KEY_UP): if (t->mode.win & WM_APPCURSOR) - platform->write(child, s8("\x1BOA"), 0); + platform->write(child, s8("\x1BOA")); else - platform->write(child, s8("\x1B[A"), 0); + platform->write(child, s8("\x1B[A")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_DOWN): case ENCODE_KEY(ACT_REPEAT, 0, KEY_DOWN): if (t->mode.win & WM_APPCURSOR) - platform->write(child, s8("\x1BOB"), 0); + platform->write(child, s8("\x1BOB")); else - platform->write(child, s8("\x1B[B"), 0); + platform->write(child, s8("\x1B[B")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_RIGHT): case ENCODE_KEY(ACT_REPEAT, 0, KEY_RIGHT): if (t->mode.win & WM_APPCURSOR) - platform->write(child, s8("\x1BOC"), 0); + platform->write(child, s8("\x1BOC")); else - platform->write(child, s8("\x1B[C"), 0); + platform->write(child, s8("\x1B[C")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_LEFT): case ENCODE_KEY(ACT_REPEAT, 0, KEY_LEFT): if (t->mode.win & WM_APPCURSOR) - platform->write(child, s8("\x1BOD"), 0); + platform->write(child, s8("\x1BOD")); else - platform->write(child, s8("\x1B[D"), 0); + platform->write(child, s8("\x1B[D")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_PAGE_UP): case ENCODE_KEY(ACT_REPEAT, 0, KEY_PAGE_UP): - if (modifiers & MOD_CONTROL) platform->write(child, s8("\x1B[5;5~"), 0); - else if (modifiers & MOD_SHIFT) platform->write(child, s8("\x1B[5;2~"), 0); - else platform->write(child, s8("\x1B[5~"), 0); + if (modifiers & MOD_CONTROL) platform->write(child, s8("\x1B[5;5~")); + else if (modifiers & MOD_SHIFT) platform->write(child, s8("\x1B[5;2~")); + else platform->write(child, s8("\x1B[5~")); break; case ENCODE_KEY(ACT_PRESS, 0, KEY_PAGE_DOWN): case ENCODE_KEY(ACT_REPEAT, 0, KEY_PAGE_DOWN): - if (modifiers & MOD_CONTROL) platform->write(child, s8("\x1B[6;5~"), 0); - else if (modifiers & MOD_SHIFT) platform->write(child, s8("\x1B[6;2~"), 0); - else platform->write(child, s8("\x1B[6~"), 0); + if (modifiers & MOD_CONTROL) platform->write(child, s8("\x1B[6;5~")); + else if (modifiers & MOD_SHIFT) platform->write(child, s8("\x1B[6;2~")); + else platform->write(child, s8("\x1B[6~")); break; } } @@ -1345,7 +1345,7 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step) t->scroll_offset = 0; t->gl.flags |= NEEDS_REFILL; } - memory->platform_api.write(t->child, input->character_input, 0); + memory->platform_api.write(t->child, input->character_input); } handle_interactions(t, input, &memory->platform_api); @@ -1361,7 +1361,7 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step) RingBuf *rb = &t->views[t->view_idx].log; s8 buffer = {.len = rb->cap - t->unprocessed_bytes, .data = rb->buf + rb->widx}; - size bytes_read = memory->platform_api.read(t->child, buffer, 0); + size bytes_read = memory->platform_api.read(t->child, buffer); ASSERT(bytes_read <= rb->cap); commit_to_rb(t->views + t->view_idx, bytes_read); diff --git a/vtgl.h b/vtgl.h @@ -142,7 +142,7 @@ typedef PLATFORM_CLIPBOARD_FN(platform_clipboard_fn); typedef PLATFORM_READ_FILE_FN(platform_read_file_fn); /* TODO: this should possibly just take a stream buffer */ -#define PLATFORM_READ_FN(name) size name(iptr file, s8 buffer, size offset) +#define PLATFORM_READ_FN(name) size name(iptr file, s8 buffer) typedef PLATFORM_READ_FN(platform_read_fn); #define PLATFORM_SET_TERMINAL_SIZE_FN(name) void name(iptr child, i32 rows, i32 columns, \ @@ -152,7 +152,7 @@ typedef PLATFORM_SET_TERMINAL_SIZE_FN(platform_set_terminal_size_fn); #define PLATFORM_WINDOW_TITLE_FN(name) void name(Stream *buffer) typedef PLATFORM_WINDOW_TITLE_FN(platform_window_title_fn); -#define PLATFORM_WRITE_FN(name) b32 name(iptr file, s8 raw, size offset) +#define PLATFORM_WRITE_FN(name) b32 name(iptr file, s8 raw) typedef PLATFORM_WRITE_FN(platform_write_fn); typedef struct {