Annotation of src/usr.bin/tmux/control-notify.c, Revision 1.6
1.6 ! nicm 1: /* $OpenBSD: control-notify.c,v 1.5 2013/03/25 11:38:43 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();
1.5 nicm 48: evbuffer_add_printf(message, "%%output %u ", wp->id);
1.6 ! nicm 49: for (i = 0; i < len; i++) {
! 50: if (buf[i] < ' ' || buf[i] == '\\')
! 51: evbuffer_add_printf(message, "\\%03o", buf[i]);
! 52: else
! 53: evbuffer_add_printf(message, "%c", buf[i]);
! 54: }
1.2 nicm 55: control_write_buffer(c, message);
56: evbuffer_free(message);
57: }
58: }
1.1 nicm 59:
60: void
61: control_notify_window_layout_changed(struct window *w)
62: {
63: struct client *c;
64: struct session *s;
65: struct format_tree *ft;
66: struct winlink *wl;
67: u_int i;
68: const char *template;
69:
70: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
71: c = ARRAY_ITEM(&clients, i);
72: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
73: continue;
74: s = c->session;
75:
76: if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
77: continue;
78:
79: /*
80: * When the last pane in a window is closed it won't have a
81: * layout root and we don't need to inform the client about the
82: * layout change because the whole window will go away soon.
83: */
84: if (w->layout_root == NULL)
85: continue;
86: template = "%layout-change #{window_id} #{window_layout}";
87:
88: ft = format_create();
89: wl = winlink_find_by_window(&s->windows, w);
90: if (wl != NULL) {
91: format_winlink(ft, c->session, wl);
92: control_write(c, "%s", format_expand(ft, template));
93: }
94: format_free(ft);
95: }
96: }
97:
98: void
99: control_notify_window_unlinked(unused struct session *s, struct window *w)
100: {
101: struct client *c;
102: struct session *cs;
103: u_int i;
104:
105: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
106: c = ARRAY_ITEM(&clients, i);
107: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
108: continue;
109: cs = c->session;
110:
1.3 nicm 111: control_write(c, "%%window-close %u", w->id);
1.1 nicm 112: }
113: }
114:
115: void
116: control_notify_window_linked(unused struct session *s, struct window *w)
117: {
118: struct client *c;
119: struct session *cs;
120: u_int i;
121:
122: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
123: c = ARRAY_ITEM(&clients, i);
124: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
125: continue;
126: cs = c->session;
127:
128: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
129: control_write(c, "%%window-add %u", w->id);
130: else
131: control_write(c, "%%unlinked-window-add %u", w->id);
132: }
133: }
134:
135: void
136: control_notify_window_renamed(struct window *w)
137: {
138: struct client *c;
139: struct session *s;
140: u_int i;
141:
142: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
143: c = ARRAY_ITEM(&clients, i);
144: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
145: continue;
146: s = c->session;
147:
1.5 nicm 148: control_write(c, "%%window-renamed %u %s", w->id, w->name);
1.1 nicm 149: }
150: }
151:
152: void
153: control_notify_attached_session_changed(struct client *c)
154: {
155: struct session *s;
156:
157: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
158: return;
159: s = c->session;
160:
1.5 nicm 161: control_write(c, "%%session-changed %u %s", s->id, s->name);
1.1 nicm 162: }
163:
164: void
165: control_notify_session_renamed(struct session *s)
166: {
167: struct client *c;
168: u_int i;
169:
170: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
171: c = ARRAY_ITEM(&clients, i);
172: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session != s)
173: continue;
174:
175: control_write(c, "%%session-renamed %s", s->name);
176: }
177: }
178:
179: void
180: control_notify_session_created(unused struct session *s)
181: {
182: struct client *c;
183: u_int i;
184:
185: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
186: c = ARRAY_ITEM(&clients, i);
187: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
188: continue;
189:
190: control_write(c, "%%sessions-changed");
191: }
192: }
193:
194: void
195: control_notify_session_close(unused struct session *s)
196: {
197: struct client *c;
198: u_int i;
199:
200: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
201: c = ARRAY_ITEM(&clients, i);
202: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
203: continue;
204:
205: control_write(c, "%%sessions-changed");
206: }
207: }