Annotation of embedaddon/tmux/control-notify.c, revision 1.1.1.1
1.1 misho 1: /* $OpenBSD$ */
2:
3: /*
4: * Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
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 <stdlib.h>
23:
24: #include "tmux.h"
25:
26: #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \
27: ((c) != NULL && ((c)->flags & CLIENT_CONTROL))
28:
29: void
30: control_notify_input(struct client *c, struct window_pane *wp,
31: struct evbuffer *input)
32: {
33: u_char *buf;
34: size_t len;
35: struct evbuffer *message;
36: u_int i;
37:
38: if (c->session == NULL)
39: return;
40:
41: buf = EVBUFFER_DATA(input);
42: len = EVBUFFER_LENGTH(input);
43:
44: /*
45: * Only write input if the window pane is linked to a window belonging
46: * to the client's session.
47: */
48: if (winlink_find_by_window(&c->session->windows, wp->window) != NULL) {
49: message = evbuffer_new();
50: evbuffer_add_printf(message, "%%output %%%u ", wp->id);
51: for (i = 0; i < len; i++) {
52: if (buf[i] < ' ' || buf[i] == '\\')
53: evbuffer_add_printf(message, "\\%03o", buf[i]);
54: else
55: evbuffer_add_printf(message, "%c", buf[i]);
56: }
57: control_write_buffer(c, message);
58: evbuffer_free(message);
59: }
60: }
61:
62: void
63: control_notify_window_layout_changed(struct window *w)
64: {
65: struct client *c;
66: struct session *s;
67: struct winlink *wl;
68: const char *template;
69: char *cp;
70:
71: template = "%layout-change #{window_id} #{window_layout} "
72: "#{window_visible_layout} #{window_flags}";
73:
74: TAILQ_FOREACH(c, &clients, entry) {
75: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
76: continue;
77: s = c->session;
78:
79: if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
80: continue;
81:
82: /*
83: * When the last pane in a window is closed it won't have a
84: * layout root and we don't need to inform the client about the
85: * layout change because the whole window will go away soon.
86: */
87: if (w->layout_root == NULL)
88: continue;
89:
90: wl = winlink_find_by_window(&s->windows, w);
91: if (wl != NULL) {
92: cp = format_single(NULL, template, c, NULL, wl, NULL);
93: control_write(c, "%s", cp);
94: free(cp);
95: }
96: }
97: }
98:
99: void
100: control_notify_window_unlinked(__unused struct session *s, struct window *w)
101: {
102: struct client *c;
103: struct session *cs;
104:
105: TAILQ_FOREACH(c, &clients, entry) {
106: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
107: continue;
108: cs = c->session;
109:
110: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
111: control_write(c, "%%window-close @%u", w->id);
112: else
113: control_write(c, "%%unlinked-window-close @%u", w->id);
114: }
115: }
116:
117: void
118: control_notify_window_linked(__unused struct session *s, struct window *w)
119: {
120: struct client *c;
121: struct session *cs;
122:
123: TAILQ_FOREACH(c, &clients, entry) {
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 *cs;
140:
141: TAILQ_FOREACH(c, &clients, entry) {
142: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
143: continue;
144: cs = c->session;
145:
146: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) {
147: control_write(c, "%%window-renamed @%u %s", w->id,
148: w->name);
149: } else {
150: control_write(c, "%%unlinked-window-renamed @%u %s",
151: w->id, w->name);
152: }
153: }
154: }
155:
156: void
157: control_notify_client_session_changed(struct client *c)
158: {
159: struct session *s;
160:
161: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
162: return;
163: s = c->session;
164:
165: control_write(c, "%%session-changed $%u %s", s->id, s->name);
166: }
167:
168: void
169: control_notify_session_renamed(struct session *s)
170: {
171: struct client *c;
172:
173: TAILQ_FOREACH(c, &clients, entry) {
174: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
175: continue;
176:
177: control_write(c, "%%session-renamed $%u %s", s->id, s->name);
178: }
179: }
180:
181: void
182: control_notify_session_created(__unused struct session *s)
183: {
184: struct client *c;
185:
186: TAILQ_FOREACH(c, &clients, entry) {
187: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
188: continue;
189:
190: control_write(c, "%%sessions-changed");
191: }
192: }
193:
194: void
195: control_notify_session_closed(__unused struct session *s)
196: {
197: struct client *c;
198:
199: TAILQ_FOREACH(c, &clients, entry) {
200: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
201: continue;
202:
203: control_write(c, "%%sessions-changed");
204: }
205: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>