Annotation of src/usr.bin/tmux/control-notify.c, Revision 1.4
1.4 ! nicm 1: /* $OpenBSD: control-notify.c,v 1.3 2013/03/25 10:04:23 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net>
5: * Copyright (c) 2012 George Nachman <tmux@georgester.com>
6: *
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.
10: *
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.
18: */
19:
20: #include <sys/types.h>
21:
22: #include "tmux.h"
23:
24: #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \
25: ((c) != NULL && ((c)->flags & CLIENT_CONTROL))
1.2 nicm 26:
27: void
28: control_notify_input(struct client *c, struct window_pane *wp,
29: struct evbuffer *input)
30: {
31: u_char *buf;
32: size_t len;
33: struct evbuffer *message;
34: u_int i;
35:
36: if (c->session == NULL)
37: return;
38:
39: buf = EVBUFFER_DATA(input);
40: len = EVBUFFER_LENGTH(input);
41:
42: /*
43: * Only write input if the window pane is linked to a window belonging
44: * to the client's session.
45: */
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);
53: }
54: }
1.1 nicm 55:
56: void
57: control_notify_window_layout_changed(struct window *w)
58: {
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;
65:
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;
71:
72: if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
73: continue;
74:
75: /*
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.
79: */
80: if (w->layout_root == NULL)
81: continue;
82: template = "%layout-change #{window_id} #{window_layout}";
83:
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));
89: }
90: format_free(ft);
91: }
92: }
93:
94: void
95: control_notify_window_unlinked(unused struct session *s, struct window *w)
96: {
97: struct client *c;
98: struct session *cs;
99: u_int i;
100:
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;
106:
1.3 nicm 107: control_write(c, "%%window-close %u", w->id);
1.1 nicm 108: }
109: }
110:
111: void
112: control_notify_window_linked(unused struct session *s, struct window *w)
113: {
114: struct client *c;
115: struct session *cs;
116: u_int i;
117:
118: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
119: c = ARRAY_ITEM(&clients, i);
120: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
121: continue;
122: cs = c->session;
123:
124: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
125: control_write(c, "%%window-add %u", w->id);
126: else
127: control_write(c, "%%unlinked-window-add %u", w->id);
128: }
129: }
130:
131: void
132: control_notify_window_renamed(struct window *w)
133: {
134: struct client *c;
135: struct session *s;
136: u_int i;
137:
138: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
139: c = ARRAY_ITEM(&clients, i);
140: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
141: continue;
142: s = c->session;
143:
1.3 nicm 144: control_write(c, "%%window-renamed %u %s", w->id, w->name);
1.1 nicm 145: }
146: }
147:
148: void
149: control_notify_attached_session_changed(struct client *c)
150: {
151: struct session *s;
152:
153: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
154: return;
155: s = c->session;
156:
1.4 ! nicm 157: control_write(c, "%%session-changed %d %s", s->id, s->name);
1.1 nicm 158: }
159:
160: void
161: control_notify_session_renamed(struct session *s)
162: {
163: struct client *c;
164: u_int i;
165:
166: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
167: c = ARRAY_ITEM(&clients, i);
168: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session != s)
169: continue;
170:
171: control_write(c, "%%session-renamed %s", s->name);
172: }
173: }
174:
175: void
176: control_notify_session_created(unused struct session *s)
177: {
178: struct client *c;
179: u_int i;
180:
181: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
182: c = ARRAY_ITEM(&clients, i);
183: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
184: continue;
185:
186: control_write(c, "%%sessions-changed");
187: }
188: }
189:
190: void
191: control_notify_session_close(unused struct session *s)
192: {
193: struct client *c;
194: u_int i;
195:
196: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
197: c = ARRAY_ITEM(&clients, i);
198: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
199: continue;
200:
201: control_write(c, "%%sessions-changed");
202: }
203: }