summaryrefslogtreecommitdiffstats
path: root/window.c
diff options
context:
space:
mode:
authornicm <nicm>2020-05-21 07:24:13 +0000
committernicm <nicm>2020-05-21 07:24:13 +0000
commit31e3f2d530090793815d145a16a1ce3b469c4266 (patch)
treecdca6cd9bcf0eea85d61053f1bb4aa2d2d1c81a7 /window.c
parent6bde1c183766d0637633c1460cf6b17b57bc0280 (diff)
Support code for control mode flow control: allow clients to have
separate offsets (used and acknowleged) into the pane buffers; turn off reading from panes when no clients can accept the data; and add a -A flag to refresh-client to let clients turn receiving a pane on and off.
Diffstat (limited to 'window.c')
-rw-r--r--window.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/window.c b/window.c
index 2427bd6e..c7a17551 100644
--- a/window.c
+++ b/window.c
@@ -881,7 +881,6 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->sy = wp->osx = sy;
wp->pipe_fd = -1;
- wp->pipe_off = 0;
wp->pipe_event = NULL;
screen_init(&wp->base, sx, sy, hlimit);
@@ -933,22 +932,28 @@ window_pane_destroy(struct window_pane *wp)
static void
window_pane_read_callback(__unused struct bufferevent *bufev, void *data)
{
- struct window_pane *wp = data;
- struct evbuffer *evb = wp->event->input;
- size_t size = EVBUFFER_LENGTH(evb);
- char *new_data;
- size_t new_size;
+ struct window_pane *wp = data;
+ struct evbuffer *evb = wp->event->input;
+ struct window_pane_offset *wpo = &wp->pipe_offset;
+ size_t size = EVBUFFER_LENGTH(evb);
+ char *new_data;
+ size_t new_size;
+ struct client *c;
- new_size = size - wp->pipe_off;
- if (wp->pipe_fd != -1 && new_size > 0) {
- new_data = EVBUFFER_DATA(evb) + wp->pipe_off;
- bufferevent_write(wp->pipe_event, new_data, new_size);
+ if (wp->pipe_fd != -1) {
+ new_data = window_pane_get_new_data(wp, wpo, &new_size);
+ if (new_size > 0) {
+ bufferevent_write(wp->pipe_event, new_data, new_size);
+ window_pane_update_used_data(wp, wpo, new_size, 1);
+ }
}
log_debug("%%%u has %zu bytes", wp->id, size);
+ TAILQ_FOREACH(c, &clients, entry) {
+ if (c->session != NULL && c->flags & CLIENT_CONTROL)
+ control_write_output(c, wp);
+ }
input_parse_pane(wp);
-
- wp->pipe_off = EVBUFFER_LENGTH(evb);
}
static void
@@ -1541,3 +1546,40 @@ window_pane_start_input(struct window_pane *wp, struct cmdq_item *item,
return (0);
}
+
+void *
+window_pane_get_new_data(struct window_pane *wp,
+ struct window_pane_offset *wpo, size_t *size)
+{
+ size_t used = wpo->used - wp->base_offset;
+
+ *size = EVBUFFER_LENGTH(wp->event->input) - used;
+ return (EVBUFFER_DATA(wp->event->input) + used);
+}
+
+void
+window_pane_update_used_data(struct window_pane *wp,
+ struct window_pane_offset *wpo, size_t size, int acknowledge)
+{
+ size_t used = wpo->used - wp->base_offset;
+
+ if (size > EVBUFFER_LENGTH(wp->event->input) - used)
+ size = EVBUFFER_LENGTH(wp->event->input) - used;
+ wpo->used += size;
+
+ if (acknowledge)
+ window_pane_acknowledge_data(wp, wpo, size);
+}
+
+void
+window_pane_acknowledge_data(struct window_pane *wp,
+ struct window_pane_offset *wpo, size_t size)
+{
+ size_t acknowledged = wpo->acknowledged - wp->base_offset;
+
+ if (size > EVBUFFER_LENGTH(wp->event->input) - acknowledged)
+ size = EVBUFFER_LENGTH(wp->event->input) - acknowledged;
+ wpo->acknowledged += size;
+ if (wpo->acknowledged > wpo->used)
+ wpo->acknowledged = wpo->used;
+}