Add functions to allocate and free command contexts rather than doing it
[tmux-openbsd.git] / control-notify.c
blob87a25bb105cc290b2cc800dd3d196f0a17a75c95
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net>
5 * Copyright (c) 2012 George Nachman <tmux@georgester.com>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/types.h>
22 #include "tmux.h"
24 #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \
25 ((c) != NULL && ((c)->flags & CLIENT_CONTROL))
27 void
28 control_notify_input(struct client *c, struct window_pane *wp,
29 struct evbuffer *input)
31 u_char *buf;
32 size_t len;
33 struct evbuffer *message;
34 u_int i;
36 if (c->session == NULL)
37 return;
39 buf = EVBUFFER_DATA(input);
40 len = EVBUFFER_LENGTH(input);
43 * Only write input if the window pane is linked to a window belonging
44 * to the client's session.
46 if (winlink_find_by_window(&c->session->windows, wp->window) != NULL) {
47 message = evbuffer_new();
48 evbuffer_add_printf(message, "%%output %%%u ", wp->id);
49 for (i = 0; i < len; i++)
50 evbuffer_add_printf(message, "%02hhx", buf[i]);
51 control_write_buffer(c, message);
52 evbuffer_free(message);
56 void
57 control_notify_window_layout_changed(struct window *w)
59 struct client *c;
60 struct session *s;
61 struct format_tree *ft;
62 struct winlink *wl;
63 u_int i;
64 const char *template;
66 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
67 c = ARRAY_ITEM(&clients, i);
68 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
69 continue;
70 s = c->session;
72 if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
73 continue;
76 * When the last pane in a window is closed it won't have a
77 * layout root and we don't need to inform the client about the
78 * layout change because the whole window will go away soon.
80 if (w->layout_root == NULL)
81 continue;
82 template = "%layout-change #{window_id} #{window_layout}";
84 ft = format_create();
85 wl = winlink_find_by_window(&s->windows, w);
86 if (wl != NULL) {
87 format_winlink(ft, c->session, wl);
88 control_write(c, "%s", format_expand(ft, template));
90 format_free(ft);
94 void
95 control_notify_window_unlinked(unused struct session *s, struct window *w)
97 struct client *c;
98 struct session *cs;
99 u_int i;
101 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
102 c = ARRAY_ITEM(&clients, i);
103 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
104 continue;
105 cs = c->session;
107 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
108 control_write(c, "%%window-close %u", w->id);
109 else
110 control_write(c, "%%unlinked-window-close %u", w->id);
114 void
115 control_notify_window_linked(unused struct session *s, struct window *w)
117 struct client *c;
118 struct session *cs;
119 u_int i;
121 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
122 c = ARRAY_ITEM(&clients, i);
123 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
124 continue;
125 cs = c->session;
127 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
128 control_write(c, "%%window-add %u", w->id);
129 else
130 control_write(c, "%%unlinked-window-add %u", w->id);
134 void
135 control_notify_window_renamed(struct window *w)
137 struct client *c;
138 struct session *s;
139 u_int i;
141 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
142 c = ARRAY_ITEM(&clients, i);
143 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
144 continue;
145 s = c->session;
147 if (winlink_find_by_window_id(&s->windows, w->id) != NULL) {
148 control_write(c, "%%window-renamed %u %s",
149 w->id, w->name);
150 } else {
151 control_write(c, "%%unlinked-window-renamed %u %s",
152 w->id, w->name);
157 void
158 control_notify_attached_session_changed(struct client *c)
160 struct session *s;
162 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
163 return;
164 s = c->session;
166 control_write(c, "%%session-changed %d %s", s->idx, s->name);
169 void
170 control_notify_session_renamed(struct session *s)
172 struct client *c;
173 u_int i;
175 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
176 c = ARRAY_ITEM(&clients, i);
177 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session != s)
178 continue;
180 control_write(c, "%%session-renamed %s", s->name);
184 void
185 control_notify_session_created(unused struct session *s)
187 struct client *c;
188 u_int i;
190 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
191 c = ARRAY_ITEM(&clients, i);
192 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
193 continue;
195 control_write(c, "%%sessions-changed");
199 void
200 control_notify_session_close(unused struct session *s)
202 struct client *c;
203 u_int i;
205 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
206 c = ARRAY_ITEM(&clients, i);
207 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
208 continue;
210 control_write(c, "%%sessions-changed");