1 /* $OpenBSD: control-notify.c,v 1.1 2012/09/03 09:32:38 nicm Exp $ */ 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)) 26 27 void 28 control_notify_window_layout_changed(struct window *w) 29 { 30 struct client *c; 31 struct session *s; 32 struct format_tree *ft; 33 struct winlink *wl; 34 u_int i; 35 const char *template; 36 37 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 38 c = ARRAY_ITEM(&clients, i); 39 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 40 continue; 41 s = c->session; 42 43 if (winlink_find_by_window_id(&s->windows, w->id) == NULL) 44 continue; 45 46 /* 47 * When the last pane in a window is closed it won't have a 48 * layout root and we don't need to inform the client about the 49 * layout change because the whole window will go away soon. 50 */ 51 if (w->layout_root == NULL) 52 continue; 53 template = "%layout-change #{window_id} #{window_layout}"; 54 55 ft = format_create(); 56 wl = winlink_find_by_window(&s->windows, w); 57 if (wl != NULL) { 58 format_winlink(ft, c->session, wl); 59 control_write(c, "%s", format_expand(ft, template)); 60 } 61 format_free(ft); 62 } 63 } 64 65 void 66 control_notify_window_unlinked(unused struct session *s, struct window *w) 67 { 68 struct client *c; 69 struct session *cs; 70 u_int i; 71 72 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 73 c = ARRAY_ITEM(&clients, i); 74 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 75 continue; 76 cs = c->session; 77 78 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) 79 control_write(c, "%%window-close %u", w->id); 80 else 81 control_write(c, "%%unlinked-window-close %u", w->id); 82 } 83 } 84 85 void 86 control_notify_window_linked(unused struct session *s, struct window *w) 87 { 88 struct client *c; 89 struct session *cs; 90 u_int i; 91 92 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 93 c = ARRAY_ITEM(&clients, i); 94 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 95 continue; 96 cs = c->session; 97 98 if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) 99 control_write(c, "%%window-add %u", w->id); 100 else 101 control_write(c, "%%unlinked-window-add %u", w->id); 102 } 103 } 104 105 void 106 control_notify_window_renamed(struct window *w) 107 { 108 struct client *c; 109 struct session *s; 110 u_int i; 111 112 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 113 c = ARRAY_ITEM(&clients, i); 114 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 115 continue; 116 s = c->session; 117 118 if (winlink_find_by_window_id(&s->windows, w->id) != NULL) { 119 control_write(c, "%%window-renamed %u %s", 120 w->id, w->name); 121 } else { 122 control_write(c, "%%unlinked-window-renamed %u %s", 123 w->id, w->name); 124 } 125 } 126 } 127 128 void 129 control_notify_attached_session_changed(struct client *c) 130 { 131 struct session *s; 132 133 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 134 return; 135 s = c->session; 136 137 control_write(c, "%%session-changed %d %s", s->idx, s->name); 138 } 139 140 void 141 control_notify_session_renamed(struct session *s) 142 { 143 struct client *c; 144 u_int i; 145 146 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 147 c = ARRAY_ITEM(&clients, i); 148 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session != s) 149 continue; 150 151 control_write(c, "%%session-renamed %s", s->name); 152 } 153 } 154 155 void 156 control_notify_session_created(unused struct session *s) 157 { 158 struct client *c; 159 u_int i; 160 161 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 162 c = ARRAY_ITEM(&clients, i); 163 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 164 continue; 165 166 control_write(c, "%%sessions-changed"); 167 } 168 } 169 170 void 171 control_notify_session_close(unused struct session *s) 172 { 173 struct client *c; 174 u_int i; 175 176 for (i = 0; i < ARRAY_LENGTH(&clients); i++) { 177 c = ARRAY_ITEM(&clients, i); 178 if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) 179 continue; 180 181 control_write(c, "%%sessions-changed"); 182 } 183 } 184