Merge branch 'obsd-master'
[tmux.git] / control-notify.c
blob30f94194cfdddb887e48ca18b466f66b8e3d931a
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
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 <stdlib.h>
24 #include "tmux.h"
26 #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \
27 ((c) != NULL && ((c)->flags & CLIENT_CONTROL))
29 void
30 control_notify_pane_mode_changed(int pane)
32 struct client *c;
34 TAILQ_FOREACH(c, &clients, entry) {
35 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
36 continue;
38 control_write(c, "%%pane-mode-changed %%%u", pane);
42 void
43 control_notify_window_layout_changed(struct window *w)
45 struct client *c;
46 struct session *s;
47 struct winlink *wl;
48 const char *template;
49 char *cp;
51 template = "%layout-change #{window_id} #{window_layout} "
52 "#{window_visible_layout} #{window_raw_flags}";
54 TAILQ_FOREACH(c, &clients, entry) {
55 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
56 continue;
57 s = c->session;
59 if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
60 continue;
63 * When the last pane in a window is closed it won't have a
64 * layout root and we don't need to inform the client about the
65 * layout change because the whole window will go away soon.
67 if (w->layout_root == NULL)
68 continue;
70 wl = winlink_find_by_window(&s->windows, w);
71 if (wl != NULL) {
72 cp = format_single(NULL, template, c, NULL, wl, NULL);
73 control_write(c, "%s", cp);
74 free(cp);
79 void
80 control_notify_window_pane_changed(struct window *w)
82 struct client *c;
84 TAILQ_FOREACH(c, &clients, entry) {
85 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
86 continue;
88 control_write(c, "%%window-pane-changed @%u %%%u", w->id,
89 w->active->id);
93 void
94 control_notify_window_unlinked(__unused struct session *s, struct window *w)
96 struct client *c;
97 struct session *cs;
99 TAILQ_FOREACH(c, &clients, entry) {
100 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
101 continue;
102 cs = c->session;
104 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
105 control_write(c, "%%window-close @%u", w->id);
106 else
107 control_write(c, "%%unlinked-window-close @%u", w->id);
111 void
112 control_notify_window_linked(__unused struct session *s, struct window *w)
114 struct client *c;
115 struct session *cs;
117 TAILQ_FOREACH(c, &clients, entry) {
118 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
119 continue;
120 cs = c->session;
122 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
123 control_write(c, "%%window-add @%u", w->id);
124 else
125 control_write(c, "%%unlinked-window-add @%u", w->id);
129 void
130 control_notify_window_renamed(struct window *w)
132 struct client *c;
133 struct session *cs;
135 TAILQ_FOREACH(c, &clients, entry) {
136 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
137 continue;
138 cs = c->session;
140 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) {
141 control_write(c, "%%window-renamed @%u %s", w->id,
142 w->name);
143 } else {
144 control_write(c, "%%unlinked-window-renamed @%u %s",
145 w->id, w->name);
150 void
151 control_notify_client_session_changed(struct client *cc)
153 struct client *c;
154 struct session *s;
156 if (cc->session == NULL)
157 return;
158 s = cc->session;
160 TAILQ_FOREACH(c, &clients, entry) {
161 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
162 continue;
164 if (cc == c) {
165 control_write(c, "%%session-changed $%u %s", s->id,
166 s->name);
167 } else {
168 control_write(c, "%%client-session-changed %s $%u %s",
169 cc->name, s->id, s->name);
174 void
175 control_notify_client_detached(struct client *cc)
177 struct client *c;
179 TAILQ_FOREACH(c, &clients, entry) {
180 if (CONTROL_SHOULD_NOTIFY_CLIENT(c))
181 control_write(c, "%%client-detached %s", cc->name);
185 void
186 control_notify_session_renamed(struct session *s)
188 struct client *c;
190 TAILQ_FOREACH(c, &clients, entry) {
191 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
192 continue;
194 control_write(c, "%%session-renamed $%u %s", s->id, s->name);
198 void
199 control_notify_session_created(__unused struct session *s)
201 struct client *c;
203 TAILQ_FOREACH(c, &clients, entry) {
204 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
205 continue;
207 control_write(c, "%%sessions-changed");
211 void
212 control_notify_session_closed(__unused struct session *s)
214 struct client *c;
216 TAILQ_FOREACH(c, &clients, entry) {
217 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
218 continue;
220 control_write(c, "%%sessions-changed");
224 void
225 control_notify_session_window_changed(struct session *s)
227 struct client *c;
229 TAILQ_FOREACH(c, &clients, entry) {
230 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
231 continue;
233 control_write(c, "%%session-window-changed $%u @%u", s->id,
234 s->curw->window->id);
238 void
239 control_notify_paste_buffer_changed(const char *name)
241 struct client *c;
243 TAILQ_FOREACH(c, &clients, entry) {
244 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
245 continue;
247 control_write(c, "%%paste-buffer-changed %s", name);
251 void
252 control_notify_paste_buffer_deleted(const char *name)
254 struct client *c;
256 TAILQ_FOREACH(c, &clients, entry) {
257 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
258 continue;
260 control_write(c, "%%paste-buffer-deleted %s", name);