aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornicm <nicm>2020-05-22 11:07:04 +0000
committernicm <nicm>2020-05-22 11:07:04 +0000
commit9a0763c3a06e589bd5d27046655603faea8c667f (patch)
tree7b99d37c74e989b02f0cd8998b52b32f47edb718
parent31e3f2d530090793815d145a16a1ce3b469c4266 (diff)
downloadrtmux-9a0763c3a06e589bd5d27046655603faea8c667f.tar.gz
rtmux-9a0763c3a06e589bd5d27046655603faea8c667f.tar.bz2
rtmux-9a0763c3a06e589bd5d27046655603faea8c667f.zip
Move client offset stuff into control.c since only control clients will
need it.
-rw-r--r--cmd-refresh-client.c6
-rw-r--r--control.c125
-rw-r--r--server-client.c84
-rw-r--r--tmux.h25
4 files changed, 157 insertions, 83 deletions
diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c
index 65537917..4eb8417b 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -46,7 +46,6 @@ static void
cmd_refresh_client_update_offset(struct client *tc, const char *value)
{
struct window_pane *wp;
- struct client_offset *co;
char *copy, *colon;
u_int pane;
@@ -63,11 +62,10 @@ cmd_refresh_client_update_offset(struct client *tc, const char *value)
if (wp == NULL)
goto out;
- co = server_client_add_pane_offset(tc, wp);
if (strcmp(colon, "on") == 0)
- co->flags &= ~CLIENT_OFFSET_OFF;
+ control_set_pane_on(tc, wp);
else if (strcmp(colon, "off") == 0)
- co->flags |= CLIENT_OFFSET_OFF;
+ control_set_pane_off(tc, wp);
out:
free(copy);
diff --git a/control.c b/control.c
index b1bcd2c1..24c26fea 100644
--- a/control.c
+++ b/control.c
@@ -26,6 +26,124 @@
#include "tmux.h"
+/* Control offsets. */
+struct control_offset {
+ u_int pane;
+
+ struct window_pane_offset offset;
+ int flags;
+#define CONTROL_OFFSET_OFF 0x1
+
+ RB_ENTRY(control_offset) entry;
+};
+RB_HEAD(control_offsets, control_offset);
+
+/* Compare client offsets. */
+static int
+control_offset_cmp(struct control_offset *co1, struct control_offset *co2)
+{
+ if (co1->pane < co2->pane)
+ return (-1);
+ if (co1->pane > co2->pane)
+ return (1);
+ return (0);
+}
+RB_GENERATE_STATIC(control_offsets, control_offset, entry, control_offset_cmp);
+
+/* Get pane offsets for this client. */
+static struct control_offset *
+control_get_offset(struct client *c, struct window_pane *wp)
+{
+ struct control_offset co = { .pane = wp->id };
+
+ if (c->offsets == NULL)
+ return (NULL);
+ return (RB_FIND(control_offsets, c->offsets, &co));
+}
+
+/* Add pane offsets for this client. */
+static struct control_offset *
+control_add_offset(struct client *c, struct window_pane *wp)
+{
+ struct control_offset *co;
+
+ co = control_get_offset(c, wp);
+ if (co != NULL)
+ return (co);
+
+ if (c->offsets == NULL) {
+ c->offsets = xmalloc(sizeof *c->offsets);
+ RB_INIT(c->offsets);
+ }
+
+ co = xcalloc(1, sizeof *co);
+ co->pane = wp->id;
+ RB_INSERT(control_offsets, c->offsets, co);
+ memcpy(&co->offset, &wp->offset, sizeof co->offset);
+ return (co);
+}
+
+/* Free control offsets. */
+void
+control_free_offsets(struct client *c)
+{
+ struct control_offset *co, *co1;
+
+ if (c->offsets == NULL)
+ return;
+ RB_FOREACH_SAFE(co, control_offsets, c->offsets, co1) {
+ RB_REMOVE(control_offsets, c->offsets, co);
+ free(co);
+ }
+ free(c->offsets);
+}
+
+/* Get offsets for client. */
+struct window_pane_offset *
+control_pane_offset(struct client *c, struct window_pane *wp, int *off)
+{
+ struct control_offset *co;
+
+ if (c->flags & CLIENT_CONTROL_NOOUTPUT) {
+ *off = 0;
+ return (NULL);
+ }
+
+ co = control_get_offset(c, wp);
+ if (co == NULL) {
+ *off = 0;
+ return (NULL);
+ }
+ if (co->flags & CONTROL_OFFSET_OFF) {
+ *off = 1;
+ return (NULL);
+ }
+ return (&co->offset);
+}
+
+/* Set pane as on. */
+void
+control_set_pane_on(struct client *c, struct window_pane *wp)
+{
+ struct control_offset *co;
+
+ co = control_get_offset(c, wp);
+ if (co != NULL) {
+ co->flags &= ~CONTROL_OFFSET_OFF;
+ memcpy(&co->offset, &wp->offset, sizeof co->offset);
+ }
+}
+
+/* Set pane as off. */
+void
+control_set_pane_off(struct client *c, struct window_pane *wp)
+{
+ struct control_offset *co;
+
+ co = control_add_offset(c, wp);
+ co->flags |= CONTROL_OFFSET_OFF;
+}
+
/* Write a line. */
void
control_write(struct client *c, const char *fmt, ...)
@@ -42,7 +160,7 @@ control_write(struct client *c, const char *fmt, ...)
void
control_write_output(struct client *c, struct window_pane *wp)
{
- struct client_offset *co;
+ struct control_offset *co;
struct evbuffer *message;
u_char *new_data;
size_t new_size, i;
@@ -57,8 +175,8 @@ control_write_output(struct client *c, struct window_pane *wp)
if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
return;
- co = server_client_add_pane_offset(c, wp);
- if (co->flags & CLIENT_OFFSET_OFF) {
+ co = control_add_offset(c, wp);
+ if (co->flags & CONTROL_OFFSET_OFF) {
window_pane_update_used_data(wp, &co->offset, SIZE_MAX, 1);
return;
}
@@ -133,6 +251,7 @@ control_callback(__unused struct client *c, __unused const char *path,
}
}
+/* Initialize for control mode. */
void
control_start(struct client *c)
{
diff --git a/server-client.c b/server-client.c
index 02abd73a..1f0ac66f 100644
--- a/server-client.c
+++ b/server-client.c
@@ -71,43 +71,6 @@ server_client_window_cmp(struct client_window *cw1,
}
RB_GENERATE(client_windows, client_window, entry, server_client_window_cmp);
-/* Compare client offsets. */
-static int
-server_client_offset_cmp(struct client_offset *co1, struct client_offset *co2)
-{
- if (co1->pane < co2->pane)
- return (-1);
- if (co1->pane > co2->pane)
- return (1);
- return (0);
-}
-RB_GENERATE(client_offsets, client_offset, entry, server_client_offset_cmp);
-
-/* Get pane offsets for this client. */
-struct client_offset *
-server_client_get_pane_offset(struct client *c, struct window_pane *wp)
-{
- struct client_offset co = { .pane = wp->id };
-
- return (RB_FIND(client_offsets, &c->offsets, &co));
-}
-
-/* Add pane offsets for this client. */
-struct client_offset *
-server_client_add_pane_offset(struct client *c, struct window_pane *wp)
-{
- struct client_offset *co;
-
- co = server_client_get_pane_offset(c, wp);
- if (co != NULL)
- return (co);
- co = xcalloc(1, sizeof *co);
- co->pane = wp->id;
- RB_INSERT(client_offsets, &c->offsets, co);
- memcpy(&co->offset, &wp->offset, sizeof co->offset);
- return (co);
-}
-
/* Number of attached clients. */
u_int
server_client_how_many(void)
@@ -264,7 +227,6 @@ server_client_create(int fd)
c->queue = cmdq_new();
RB_INIT(&c->windows);
- RB_INIT(&c->offsets);
RB_INIT(&c->files);
c->tty.fd = -1;
@@ -325,7 +287,6 @@ server_client_lost(struct client *c)
{
struct client_file *cf, *cf1;
struct client_window *cw, *cw1;
- struct client_offset *co, *co1;
c->flags |= CLIENT_DEAD;
@@ -341,10 +302,7 @@ server_client_lost(struct client *c)
RB_REMOVE(client_windows, &c->windows, cw);
free(cw);
}
- RB_FOREACH_SAFE(co, client_offsets, &c->offsets, co1) {
- RB_REMOVE(client_offsets, &c->offsets, co);
- free(co);
- }
+ control_free_offsets(c);
TAILQ_REMOVE(&clients, c, entry);
log_debug("lost client %p", c);
@@ -1542,8 +1500,9 @@ server_client_check_pane_buffer(struct window_pane *wp)
struct evbuffer *evb = wp->event->input;
size_t minimum;
struct client *c;
- struct client_offset *co;
- int off = !TAILQ_EMPTY(&clients);
+ struct window_pane_offset *wpo;
+ int off = 1, flag;
+ u_int attached_clients = 0;
/*
* Work out the minimum acknowledged size. This is the most that can be
@@ -1555,20 +1514,28 @@ server_client_check_pane_buffer(struct window_pane *wp)
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL)
continue;
- if ((~c->flags & CLIENT_CONTROL) ||
- (c->flags & CLIENT_CONTROL_NOOUTPUT) ||
- (co = server_client_get_pane_offset(c, wp)) == NULL) {
+ attached_clients++;
+
+ if (~c->flags & CLIENT_CONTROL) {
+ off = 0;
+ continue;
+ }
+ wpo = control_pane_offset(c, wp, &flag);
+ if (wpo == NULL) {
off = 0;
continue;
}
- if (~co->flags & CLIENT_OFFSET_OFF)
+ if (!flag)
off = 0;
+
log_debug("%s: %s has %zu bytes used, %zu bytes acknowledged "
- "for %%%u", __func__, c->name, co->offset.used,
- co->offset.acknowledged, wp->id);
- if (co->offset.acknowledged < minimum)
- minimum = co->offset.acknowledged;
+ "for %%%u", __func__, c->name, wpo->used, wpo->acknowledged,
+ wp->id);
+ if (wpo->acknowledged < minimum)
+ minimum = wpo->acknowledged;
}
+ if (attached_clients == 0)
+ off = 0;
minimum -= wp->base_offset;
if (minimum == 0)
goto out;
@@ -1593,10 +1560,10 @@ server_client_check_pane_buffer(struct window_pane *wp)
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL || (~c->flags & CLIENT_CONTROL))
continue;
- co = server_client_get_pane_offset(c, wp);
- if (co != NULL) {
- co->offset.acknowledged -= wp->base_offset;
- co->offset.used -= wp->base_offset;
+ wpo = control_pane_offset(c, wp, &flag);
+ if (wpo != NULL && !flag) {
+ wpo->acknowledged -= wp->base_offset;
+ wpo->used -= wp->base_offset;
}
}
wp->base_offset = minimum;
@@ -2394,9 +2361,10 @@ server_client_set_flags(struct client *c, const char *flags)
c->flags &= ~flag;
else
c->flags |= flag;
+ if (flag == CLIENT_CONTROL_NOOUTPUT)
+ control_free_offsets(c);
}
free(copy);
-
}
/* Get client flags. This is only flags useful to show to users. */
diff --git a/tmux.h b/tmux.h
index cfb63e36..6965f132 100644
--- a/tmux.h
+++ b/tmux.h
@@ -45,6 +45,7 @@ struct cmdq_item;
struct cmdq_list;
struct cmdq_state;
struct cmds;
+struct control_offsets;
struct environ;
struct format_job_tree;
struct format_tree;
@@ -1549,18 +1550,6 @@ struct client_window {
};
RB_HEAD(client_windows, client_window);
-/* Client offsets. */
-struct client_offset {
- u_int pane;
-
- struct window_pane_offset offset;
- int flags;
-#define CLIENT_OFFSET_OFF 0x1
-
- RB_ENTRY(client_offset) entry;
-};
-RB_HEAD(client_offsets, client_offset);
-
/* Client connection. */
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
typedef void (*prompt_free_cb)(void *);
@@ -1575,7 +1564,7 @@ struct client {
struct cmdq_list *queue;
struct client_windows windows;
- struct client_offsets offsets;
+ struct control_offsets *offsets;
pid_t pid;
int fd;
@@ -2359,11 +2348,6 @@ void printflike(1, 2) server_add_message(const char *, ...);
/* server-client.c */
RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp);
-RB_PROTOTYPE(client_offsets, client_offset, entry, server_client_offset_cmp);
-struct client_offset *server_client_get_pane_offset(struct client *,
- struct window_pane *);
-struct client_offset *server_client_add_pane_offset(struct client *,
- struct window_pane *);
u_int server_client_how_many(void);
void server_client_set_overlay(struct client *, u_int, overlay_check_cb,
overlay_mode_cb, overlay_draw_cb, overlay_key_cb,
@@ -2830,6 +2814,11 @@ char *parse_window_name(const char *);
/* control.c */
void control_start(struct client *);
+void control_set_pane_on(struct client *, struct window_pane *);
+void control_set_pane_off(struct client *, struct window_pane *);
+struct window_pane_offset *control_pane_offset(struct client *,
+ struct window_pane *, int *);
+void control_free_offsets(struct client *);
void printflike(2, 3) control_write(struct client *, const char *, ...);
void control_write_output(struct client *, struct window_pane *);