mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
Merge branch 'async-ptmx'
This commit is contained in:
commit
e1b6aa87fb
12 changed files with 210 additions and 88 deletions
8
csi.c
8
csi.c
|
|
@ -325,7 +325,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
case 0: {
|
||||
switch (final) {
|
||||
case 'c':
|
||||
vt_to_slave(term, "\033[?6c", 5);
|
||||
term_to_slave(term, "\033[?6c", 5);
|
||||
break;
|
||||
|
||||
case 'd': {
|
||||
|
|
@ -690,7 +690,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
snprintf(reply, sizeof(reply), "\x1b[%d;%dR",
|
||||
term->cursor.row + 1,
|
||||
term->cursor.col + 1);
|
||||
vt_to_slave(term, reply, strlen(reply));
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -910,7 +910,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
*/
|
||||
char reply[32];
|
||||
snprintf(reply, sizeof(reply), "\033[?%u;2$y", param);
|
||||
vt_to_slave(term, reply, strlen(reply));
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -965,7 +965,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
break;
|
||||
}
|
||||
|
||||
vt_to_slave(term, "\033[>41;347;0c", 12);
|
||||
term_to_slave(term, "\033[>41;347;0c", 12);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
80
fdm.c
80
fdm.c
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
struct handler {
|
||||
int fd;
|
||||
int events;
|
||||
fdm_handler_t callback;
|
||||
void *callback_data;
|
||||
bool deleted;
|
||||
|
|
@ -78,6 +79,7 @@ fdm_add(struct fdm *fdm, int fd, int events, fdm_handler_t handler, void *data)
|
|||
struct handler *fd_data = malloc(sizeof(*fd_data));
|
||||
*fd_data = (struct handler) {
|
||||
.fd = fd,
|
||||
.events = events,
|
||||
.callback = handler,
|
||||
.callback_data = data,
|
||||
.deleted = false,
|
||||
|
|
@ -91,7 +93,7 @@ fdm_add(struct fdm *fdm, int fd, int events, fdm_handler_t handler, void *data)
|
|||
};
|
||||
|
||||
if (epoll_ctl(fdm->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
|
||||
LOG_ERRNO("failed to register FD with epoll");
|
||||
LOG_ERRNO("failed to register FD=%d with epoll", fd);
|
||||
free(fd_data);
|
||||
tll_pop_back(fdm->fds);
|
||||
return false;
|
||||
|
|
@ -107,22 +109,23 @@ fdm_del_internal(struct fdm *fdm, int fd, bool close_fd)
|
|||
return true;
|
||||
|
||||
tll_foreach(fdm->fds, it) {
|
||||
if (it->item->fd == fd) {
|
||||
if (epoll_ctl(fdm->epoll_fd, EPOLL_CTL_DEL, fd, NULL) < 0)
|
||||
LOG_ERRNO("failed to unregister FD=%d from epoll", fd);
|
||||
if (it->item->fd != fd)
|
||||
continue;
|
||||
|
||||
if (close_fd)
|
||||
close(it->item->fd);
|
||||
if (epoll_ctl(fdm->epoll_fd, EPOLL_CTL_DEL, fd, NULL) < 0)
|
||||
LOG_ERRNO("failed to unregister FD=%d from epoll", fd);
|
||||
|
||||
it->item->deleted = true;
|
||||
if (fdm->is_polling)
|
||||
tll_push_back(fdm->deferred_delete, it->item);
|
||||
else
|
||||
free(it->item);
|
||||
if (close_fd)
|
||||
close(it->item->fd);
|
||||
|
||||
tll_remove(fdm->fds, it);
|
||||
return true;
|
||||
}
|
||||
it->item->deleted = true;
|
||||
if (fdm->is_polling)
|
||||
tll_push_back(fdm->deferred_delete, it->item);
|
||||
else
|
||||
free(it->item);
|
||||
|
||||
tll_remove(fdm->fds, it);
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_ERR("no such FD: %d", fd);
|
||||
|
|
@ -141,6 +144,55 @@ fdm_del_no_close(struct fdm *fdm, int fd)
|
|||
return fdm_del_internal(fdm, fd, false);
|
||||
}
|
||||
|
||||
static bool
|
||||
event_modify(struct fdm *fdm, struct handler *fd, int new_events)
|
||||
{
|
||||
if (new_events == fd->events)
|
||||
return true;
|
||||
|
||||
struct epoll_event ev = {
|
||||
.events = new_events,
|
||||
.data = {.ptr = fd},
|
||||
};
|
||||
|
||||
if (epoll_ctl(fdm->epoll_fd, EPOLL_CTL_MOD, fd->fd, &ev) < 0) {
|
||||
LOG_ERRNO("failed to modify FD=%d with epoll (events 0x%08x -> 0x%08x)",
|
||||
fd->fd, fd->events, new_events);
|
||||
return false;
|
||||
}
|
||||
|
||||
fd->events = new_events;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
fdm_event_add(struct fdm *fdm, int fd, int events)
|
||||
{
|
||||
tll_foreach(fdm->fds, it) {
|
||||
if (it->item->fd != fd)
|
||||
continue;
|
||||
|
||||
return event_modify(fdm, it->item, it->item->events | events);
|
||||
}
|
||||
|
||||
LOG_ERR("FD=%d not registered with the FDM", fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
fdm_event_del(struct fdm *fdm, int fd, int events)
|
||||
{
|
||||
tll_foreach(fdm->fds, it) {
|
||||
if (it->item->fd != fd)
|
||||
continue;
|
||||
|
||||
return event_modify(fdm, it->item, it->item->events & ~events);
|
||||
}
|
||||
|
||||
LOG_ERR("FD=%d not registered with the FDM", fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
fdm_poll(struct fdm *fdm)
|
||||
{
|
||||
|
|
|
|||
3
fdm.h
3
fdm.h
|
|
@ -13,4 +13,7 @@ bool fdm_add(struct fdm *fdm, int fd, int events, fdm_handler_t handler, void *d
|
|||
bool fdm_del(struct fdm *fdm, int fd);
|
||||
bool fdm_del_no_close(struct fdm *fdm, int fd);
|
||||
|
||||
bool fdm_event_add(struct fdm *fdm, int fd, int events);
|
||||
bool fdm_event_del(struct fdm *fdm, int fd, int events);
|
||||
|
||||
bool fdm_poll(struct fdm *fdm);
|
||||
|
|
|
|||
8
input.c
8
input.c
|
|
@ -258,7 +258,7 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
|||
info->keypad_keys_mode != term->keypad_keys_mode)
|
||||
continue;
|
||||
|
||||
vt_to_slave(term, info->seq, strlen(info->seq));
|
||||
term_to_slave(term, info->seq, strlen(info->seq));
|
||||
found_map = true;
|
||||
|
||||
term_reset_view(term);
|
||||
|
|
@ -314,14 +314,14 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
|||
|
||||
char reply[1024];
|
||||
snprintf(reply, sizeof(reply), "\x1b[27;%d;%d~", modify_param, sym);
|
||||
vt_to_slave(term, reply, strlen(reply));
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
}
|
||||
|
||||
else {
|
||||
if (effective_mods & alt)
|
||||
vt_to_slave(term, "\x1b", 1);
|
||||
term_to_slave(term, "\x1b", 1);
|
||||
|
||||
vt_to_slave(term, buf, count);
|
||||
term_to_slave(term, buf, count);
|
||||
}
|
||||
|
||||
term_reset_view(term);
|
||||
|
|
|
|||
18
osc.c
18
osc.c
|
|
@ -78,7 +78,7 @@ from_clipboard_cb(const char *text, size_t size, void *user)
|
|||
assert(chunk != NULL);
|
||||
assert(strlen(chunk) == 4);
|
||||
|
||||
vt_to_slave(term, chunk, 4);
|
||||
term_to_slave(term, chunk, 4);
|
||||
free(chunk);
|
||||
|
||||
ctx->idx = 0;
|
||||
|
|
@ -98,7 +98,7 @@ from_clipboard_cb(const char *text, size_t size, void *user)
|
|||
char *chunk = base64_encode((const uint8_t *)t, left / 3 * 3);
|
||||
assert(chunk != NULL);
|
||||
assert(strlen(chunk) % 4 == 0);
|
||||
vt_to_slave(term, chunk, strlen(chunk));
|
||||
term_to_slave(term, chunk, strlen(chunk));
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
|
|
@ -120,9 +120,9 @@ osc_from_clipboard(struct terminal *term, const char *source)
|
|||
if (src == 0)
|
||||
return;
|
||||
|
||||
vt_to_slave(term, "\033]52;", 5);
|
||||
vt_to_slave(term, &src, 1);
|
||||
vt_to_slave(term, ";", 1);
|
||||
term_to_slave(term, "\033]52;", 5);
|
||||
term_to_slave(term, &src, 1);
|
||||
term_to_slave(term, ";", 1);
|
||||
|
||||
struct clip_context ctx = {
|
||||
.term = term,
|
||||
|
|
@ -141,10 +141,10 @@ osc_from_clipboard(struct terminal *term, const char *source)
|
|||
if (ctx.idx > 0) {
|
||||
char res[4];
|
||||
base64_encode_final(ctx.buf, ctx.idx, res);
|
||||
vt_to_slave(term, res, 4);
|
||||
term_to_slave(term, res, 4);
|
||||
}
|
||||
|
||||
vt_to_slave(term, "\033\\", 2);
|
||||
term_to_slave(term, "\033\\", 2);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -343,7 +343,7 @@ osc_dispatch(struct terminal *term)
|
|||
char reply[32];
|
||||
snprintf(reply, sizeof(reply), "\033]4;%u;rgb:%02x/%02x/%02x\033\\",
|
||||
idx, r, g, b);
|
||||
vt_to_slave(term, reply, strlen(reply));
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ osc_dispatch(struct terminal *term)
|
|||
reply, sizeof(reply), "\033]%u;rgb:%02x/%02x/%02x\033\\",
|
||||
param, r, g, b);
|
||||
|
||||
vt_to_slave(term, reply, strlen(reply));
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
selection.c
10
selection.c
|
|
@ -533,7 +533,7 @@ static void
|
|||
from_clipboard_cb(const char *data, size_t size, void *user)
|
||||
{
|
||||
struct terminal *term = user;
|
||||
vt_to_slave(term, data, size);
|
||||
term_to_slave(term, data, size);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -544,12 +544,12 @@ selection_from_clipboard(struct terminal *term, uint32_t serial)
|
|||
return;
|
||||
|
||||
if (term->bracketed_paste)
|
||||
vt_to_slave(term, "\033[200~", 6);
|
||||
term_to_slave(term, "\033[200~", 6);
|
||||
|
||||
text_from_clipboard(term, serial, &from_clipboard_cb, term);
|
||||
|
||||
if (term->bracketed_paste)
|
||||
vt_to_slave(term, "\033[201~", 6);
|
||||
term_to_slave(term, "\033[201~", 6);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -675,12 +675,12 @@ selection_from_primary(struct terminal *term)
|
|||
return;
|
||||
|
||||
if (term->bracketed_paste)
|
||||
vt_to_slave(term, "\033[200~", 6);
|
||||
term_to_slave(term, "\033[200~", 6);
|
||||
|
||||
text_from_primary(term, &from_clipboard_cb, term);
|
||||
|
||||
if (term->bracketed_paste)
|
||||
vt_to_slave(term, "\033[201~", 6);
|
||||
term_to_slave(term, "\033[201~", 6);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
|||
5
server.c
5
server.c
|
|
@ -196,7 +196,6 @@ fdm_server(struct fdm *fdm, int fd, int events, void *data)
|
|||
};
|
||||
|
||||
if (!fdm_add(server->fdm, client_fd, EPOLLIN, &fdm_client, client)) {
|
||||
LOG_ERR("client FD=%d: failed to add client to FDM", client_fd);
|
||||
close(client_fd);
|
||||
free(client);
|
||||
return false;
|
||||
|
|
@ -321,10 +320,8 @@ server_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl)
|
|||
.clients = tll_init(),
|
||||
};
|
||||
|
||||
if (!fdm_add(fdm, fd, EPOLLIN, &fdm_server, server)) {
|
||||
LOG_ERR("failed to add server FD to the FDM");
|
||||
if (!fdm_add(fdm, fd, EPOLLIN, &fdm_server, server))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return server;
|
||||
|
||||
|
|
|
|||
125
terminal.c
125
terminal.c
|
|
@ -26,15 +26,103 @@
|
|||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
enum ptmx_write_status {PTMX_WRITE_DONE, PTMX_WRITE_REMAIN, PTMX_WRITE_ERR};
|
||||
|
||||
static enum ptmx_write_status
|
||||
to_slave(struct terminal *term, const void *_data, size_t len, size_t *idx)
|
||||
{
|
||||
const uint8_t *const data = _data;
|
||||
size_t left = len - *idx;
|
||||
|
||||
while (left > 0) {
|
||||
ssize_t ret = write(term->ptmx, &data[*idx], left);
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
return PTMX_WRITE_REMAIN;
|
||||
|
||||
LOG_ERRNO("failed to write to client");
|
||||
return PTMX_WRITE_ERR;
|
||||
}
|
||||
|
||||
*idx += ret;
|
||||
left -= left;
|
||||
}
|
||||
|
||||
return PTMX_WRITE_DONE;
|
||||
}
|
||||
|
||||
bool
|
||||
term_to_slave(struct terminal *term, const void *_data, size_t len)
|
||||
{
|
||||
if (tll_length(term->ptmx_buffer) > 0) {
|
||||
/* With a non-empty queue, EPOLLOUT has already been enabled */
|
||||
goto enqueue_data;
|
||||
}
|
||||
|
||||
switch (to_slave(term, _data, len, &(size_t){0})) {
|
||||
case PTMX_WRITE_REMAIN:
|
||||
if (!fdm_event_add(term->fdm, term->ptmx, EPOLLOUT))
|
||||
return false;
|
||||
goto enqueue_data;
|
||||
|
||||
case PTMX_WRITE_DONE: return true;
|
||||
case PTMX_WRITE_ERR: return false;
|
||||
}
|
||||
|
||||
enqueue_data:
|
||||
{
|
||||
void *copy = malloc(len);
|
||||
memcpy(copy, _data, len);
|
||||
|
||||
struct ptmx_buffer queued = {
|
||||
.data = copy,
|
||||
.len = len,
|
||||
.idx = 0,
|
||||
};
|
||||
tll_push_back(term->ptmx_buffer, queued);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
fdm_ptmx_out(struct fdm *fdm, int fd, int events, void *data)
|
||||
{
|
||||
struct terminal *term = data;
|
||||
assert(tll_length(term->ptmx_buffer) > 0);
|
||||
|
||||
tll_foreach(term->ptmx_buffer, it) {
|
||||
switch (to_slave(term, it->item.data, it->item.len, &it->item.idx)) {
|
||||
case PTMX_WRITE_DONE:
|
||||
free(it->item.data);
|
||||
tll_remove(term->ptmx_buffer, it);
|
||||
break;
|
||||
|
||||
case PTMX_WRITE_REMAIN: return true; /* to_slave() updated it->item.idx */
|
||||
case PTMX_WRITE_ERR: return false;
|
||||
}
|
||||
}
|
||||
|
||||
fdm_event_del(term->fdm, term->ptmx, EPOLLOUT);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
||||
{
|
||||
struct terminal *term = data;
|
||||
|
||||
if (events & EPOLLOUT) {
|
||||
if (!fdm_ptmx_out(fdm, fd, events, data))
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((events & EPOLLHUP) && !(events & EPOLLIN))
|
||||
return term_shutdown(term);
|
||||
|
||||
assert(events & EPOLLIN);
|
||||
if (!(events & EPOLLIN))
|
||||
return true;
|
||||
|
||||
uint8_t buf[24 * 1024];
|
||||
ssize_t count = read(term->ptmx, buf, sizeof(buf));
|
||||
|
|
@ -328,25 +416,20 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
|||
goto close_fds;
|
||||
}
|
||||
|
||||
if (!fdm_add(fdm, ptmx, EPOLLIN, &fdm_ptmx, term)) {
|
||||
LOG_ERR("failed to add ptmx to FDM");
|
||||
int ptmx_flags;
|
||||
if ((ptmx_flags = fcntl(ptmx, F_GETFL)) < 0 ||
|
||||
fcntl(ptmx, F_SETFL, ptmx_flags | O_NONBLOCK) < 0)
|
||||
{
|
||||
LOG_ERRNO("failed to configure ptmx as non-blocking");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!fdm_add(fdm, flash_fd, EPOLLIN, &fdm_flash, term)) {
|
||||
LOG_ERR("failed to add flash timer FD to FDM");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!fdm_add(fdm, blink_fd, EPOLLIN, &fdm_blink, term)) {
|
||||
LOG_ERR("failed to add blink tiemr FD to FDM");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!fdm_add(fdm, delay_lower_fd, EPOLLIN, &fdm_delayed_render, term) ||
|
||||
if (!fdm_add(fdm, ptmx, EPOLLIN, &fdm_ptmx, term) ||
|
||||
!fdm_add(fdm, flash_fd, EPOLLIN, &fdm_flash, term) ||
|
||||
!fdm_add(fdm, blink_fd, EPOLLIN, &fdm_blink, term) ||
|
||||
!fdm_add(fdm, delay_lower_fd, EPOLLIN, &fdm_delayed_render, term) ||
|
||||
!fdm_add(fdm, delay_upper_fd, EPOLLIN, &fdm_delayed_render, term))
|
||||
{
|
||||
LOG_ERR("failed to add delayed rendering timer FDs to FDM");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
@ -355,6 +438,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
|||
.fdm = fdm,
|
||||
.quit = false,
|
||||
.ptmx = ptmx,
|
||||
.ptmx_buffer = tll_init(),
|
||||
.cursor_keys_mode = CURSOR_KEYS_NORMAL,
|
||||
.keypad_keys_mode = KEYPAD_NUMERICAL,
|
||||
.auto_margin = true,
|
||||
|
|
@ -538,7 +622,6 @@ term_shutdown(struct terminal *term)
|
|||
}
|
||||
|
||||
if (!fdm_add(term->fdm, event_fd, EPOLLIN, &fdm_shutdown, term)) {
|
||||
LOG_ERR("failed to add terminal shutdown event FD to the FDM");
|
||||
close(event_fd);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -629,6 +712,10 @@ term_destroy(struct terminal *term)
|
|||
assert(tll_length(term->render.workers.queue) == 0);
|
||||
tll_free(term->render.workers.queue);
|
||||
|
||||
tll_foreach(term->ptmx_buffer, it)
|
||||
free(it->item.data);
|
||||
tll_free(term->ptmx_buffer);
|
||||
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
if (term->slave > 0) {
|
||||
|
|
@ -1070,7 +1157,7 @@ term_focus_in(struct terminal *term)
|
|||
{
|
||||
if (!term->focus_events)
|
||||
return;
|
||||
vt_to_slave(term, "\033[I", 3);
|
||||
term_to_slave(term, "\033[I", 3);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1078,7 +1165,7 @@ term_focus_out(struct terminal *term)
|
|||
{
|
||||
if (!term->focus_events)
|
||||
return;
|
||||
vt_to_slave(term, "\033[O", 3);
|
||||
term_to_slave(term, "\033[O", 3);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1152,7 +1239,7 @@ report_mouse_click(struct terminal *term, int encoded_button, int row, int col,
|
|||
return;
|
||||
}
|
||||
|
||||
vt_to_slave(term, response, strlen(response));
|
||||
term_to_slave(term, response, strlen(response));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -145,6 +145,12 @@ enum mouse_reporting {
|
|||
|
||||
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BAR };
|
||||
|
||||
struct ptmx_buffer {
|
||||
void *data;
|
||||
size_t len;
|
||||
size_t idx;
|
||||
};
|
||||
|
||||
struct terminal {
|
||||
struct fdm *fdm;
|
||||
|
||||
|
|
@ -152,6 +158,8 @@ struct terminal {
|
|||
int ptmx;
|
||||
bool quit;
|
||||
|
||||
tll(struct ptmx_buffer) ptmx_buffer;
|
||||
|
||||
enum cursor_keys cursor_keys_mode;
|
||||
enum keypad_keys keypad_keys_mode;
|
||||
bool reverse;
|
||||
|
|
@ -303,6 +311,7 @@ bool term_shutdown(struct terminal *term);
|
|||
int term_destroy(struct terminal *term);
|
||||
|
||||
void term_reset(struct terminal *term, bool hard);
|
||||
bool term_to_slave(struct terminal *term, const void *data, size_t len);
|
||||
|
||||
void term_damage_rows(struct terminal *term, int start, int end);
|
||||
void term_damage_rows_in_view(struct terminal *term, int start, int end);
|
||||
|
|
|
|||
20
vt.c
20
vt.c
|
|
@ -1015,23 +1015,3 @@ vt_from_slave(struct terminal *term, const uint8_t *data, size_t len)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
vt_to_slave(struct terminal *term, const void *_data, size_t len)
|
||||
{
|
||||
const uint8_t *data = _data;
|
||||
size_t left = len;
|
||||
|
||||
while (left > 0) {
|
||||
ssize_t ret = write(term->ptmx, data, left);
|
||||
if (ret < 0) {
|
||||
LOG_ERRNO("failed to write to client");
|
||||
return false;
|
||||
}
|
||||
|
||||
data += ret;
|
||||
left -= ret;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
1
vt.h
1
vt.h
|
|
@ -6,7 +6,6 @@
|
|||
#include "terminal.h"
|
||||
|
||||
void vt_from_slave(struct terminal *term, const uint8_t *data, size_t len);
|
||||
bool vt_to_slave(struct terminal *term, const void *data, size_t len);
|
||||
|
||||
static inline int
|
||||
vt_param_get(const struct terminal *term, size_t idx, int default_value)
|
||||
|
|
|
|||
11
wayland.c
11
wayland.c
|
|
@ -522,14 +522,9 @@ wayl_init(struct fdm *fdm)
|
|||
goto out;
|
||||
}
|
||||
|
||||
int wl_fd = wl_display_get_fd(wayl->display);
|
||||
if (!fdm_add(fdm, wl_fd, EPOLLIN, &fdm_wayl, wayl)) {
|
||||
LOG_ERR("failed to register Wayland connection with the FDM");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!fdm_add(fdm, wayl->kbd.repeat.fd, EPOLLIN, &fdm_repeat, wayl)) {
|
||||
LOG_ERR("failed to register keyboard repeat timer with the FDM");
|
||||
if (!fdm_add(fdm, wl_display_get_fd(wayl->display), EPOLLIN, &fdm_wayl, wayl) ||
|
||||
!fdm_add(fdm, wayl->kbd.repeat.fd, EPOLLIN, &fdm_repeat, wayl))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue