Annotation of src/usr.bin/tmux/server-window.c, Revision 1.15
1.15 ! nicm 1: /* $OpenBSD: server-window.c,v 1.14 2010/02/19 00:03:21 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
1.5 nicm 21: #include <event.h>
1.1 nicm 22: #include <unistd.h>
23:
24: #include "tmux.h"
25:
1.3 nicm 26: int server_window_backoff(struct window_pane *);
1.15 ! nicm 27: int server_window_check_bell(struct session *, struct winlink *);
! 28: int server_window_check_activity(struct session *, struct winlink *);
1.1 nicm 29: int server_window_check_content(
1.15 ! nicm 30: struct session *, struct winlink *, struct window_pane *);
1.2 nicm 31:
1.3 nicm 32: /* Check if this window should suspend reading. */
33: int
34: server_window_backoff(struct window_pane *wp)
35: {
36: struct client *c;
37: u_int i;
38:
39: if (!window_pane_visible(wp))
40: return (0);
41:
42: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
43: c = ARRAY_ITEM(&clients, i);
44: if (c == NULL || c->session == NULL)
1.4 nicm 45: continue;
46: if ((c->flags & (CLIENT_SUSPENDED|CLIENT_DEAD)) != 0)
1.3 nicm 47: continue;
48: if (c->session->curw->window != wp->window)
49: continue;
1.7 nicm 50:
51: if (EVBUFFER_LENGTH(c->tty.event->output) > BACKOFF_THRESHOLD)
1.3 nicm 52: return (1);
53: }
54: return (0);
1.2 nicm 55: }
1.1 nicm 56:
57: /* Window functions that need to happen every loop. */
58: void
59: server_window_loop(void)
60: {
61: struct window *w;
1.15 ! nicm 62: struct winlink *wl;
1.1 nicm 63: struct window_pane *wp;
64: struct session *s;
65: u_int i, j;
66:
67: for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
68: w = ARRAY_ITEM(&windows, i);
69: if (w == NULL)
70: continue;
1.9 nicm 71:
72: TAILQ_FOREACH(wp, &w->panes, entry) {
1.14 nicm 73: if (wp->fd == -1)
74: continue;
75: if (!(wp->flags & PANE_FREEZE)) {
1.11 nicm 76: if (server_window_backoff(wp))
77: bufferevent_disable(wp->event, EV_READ);
78: else
79: bufferevent_enable(wp->event, EV_READ);
80: }
1.9 nicm 81: }
1.1 nicm 82:
83: for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
84: s = ARRAY_ITEM(&sessions, j);
1.15 ! nicm 85: if (s == NULL)
! 86: continue;
! 87: wl = session_has(s, w);
! 88: if (wl == NULL)
1.1 nicm 89: continue;
1.13 nicm 90:
1.15 ! nicm 91: if (server_window_check_bell(s, wl) ||
! 92: server_window_check_activity(s, wl))
1.1 nicm 93: server_status_session(s);
94: TAILQ_FOREACH(wp, &w->panes, entry)
1.15 ! nicm 95: server_window_check_content(s, wl, wp);
1.1 nicm 96: }
1.15 ! nicm 97: w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY);
1.1 nicm 98: }
99: }
100:
101: /* Check for bell in window. */
102: int
1.15 ! nicm 103: server_window_check_bell(struct session *s, struct winlink *wl)
1.1 nicm 104: {
105: struct client *c;
1.15 ! nicm 106: struct window *w = wl->window;
1.1 nicm 107: u_int i;
108: int action, visual;
109:
1.15 ! nicm 110: if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
! 111: return (0);
! 112: if (s->curw == wl)
1.1 nicm 113: return (0);
114:
1.15 ! nicm 115: wl->flags |= WINLINK_BELL;
1.1 nicm 116:
117: action = options_get_number(&s->options, "bell-action");
118: switch (action) {
119: case BELL_ANY:
120: if (s->flags & SESSION_UNATTACHED)
121: break;
122: visual = options_get_number(&s->options, "visual-bell");
123: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
124: c = ARRAY_ITEM(&clients, i);
125: if (c == NULL || c->session != s)
126: continue;
127: if (!visual) {
128: tty_putcode(&c->tty, TTYC_BEL);
129: continue;
130: }
1.13 nicm 131: if (c->session->curw->window == w) {
1.1 nicm 132: status_message_set(c, "Bell in current window");
133: continue;
134: }
135: status_message_set(c, "Bell in window %u",
136: winlink_find_by_window(&s->windows, w)->idx);
137: }
138: break;
139: case BELL_CURRENT:
140: if (s->flags & SESSION_UNATTACHED)
141: break;
142: visual = options_get_number(&s->options, "visual-bell");
143: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
144: c = ARRAY_ITEM(&clients, i);
145: if (c == NULL || c->session != s)
146: continue;
1.13 nicm 147: if (c->session->curw->window != w)
1.1 nicm 148: continue;
149: if (!visual) {
150: tty_putcode(&c->tty, TTYC_BEL);
151: continue;
152: }
153: status_message_set(c, "Bell in current window");
154: }
155: break;
156: }
157:
158: return (1);
159: }
160:
161: /* Check for activity in window. */
162: int
1.15 ! nicm 163: server_window_check_activity(struct session *s, struct winlink *wl)
1.1 nicm 164: {
165: struct client *c;
1.15 ! nicm 166: struct window *w = wl->window;
1.1 nicm 167: u_int i;
168:
1.15 ! nicm 169: if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
1.1 nicm 170: return (0);
1.15 ! nicm 171: if (s->curw == wl)
1.1 nicm 172: return (0);
173:
1.13 nicm 174: if (!options_get_number(&w->options, "monitor-activity"))
1.1 nicm 175: return (0);
176:
1.15 ! nicm 177: wl->flags |= WINLINK_ACTIVITY;
1.1 nicm 178:
1.13 nicm 179: if (options_get_number(&s->options, "visual-activity")) {
1.1 nicm 180: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
181: c = ARRAY_ITEM(&clients, i);
182: if (c == NULL || c->session != s)
183: continue;
184: status_message_set(c, "Activity in window %u",
185: winlink_find_by_window(&s->windows, w)->idx);
186: }
187: }
188:
189: return (1);
190: }
191:
192: /* Check for content change in window. */
193: int
194: server_window_check_content(
1.15 ! nicm 195: struct session *s, struct winlink *wl, struct window_pane *wp)
1.1 nicm 196: {
197: struct client *c;
1.15 ! nicm 198: struct window *w = wl->window;
1.1 nicm 199: u_int i;
200: char *found, *ptr;
1.13 nicm 201:
1.15 ! nicm 202: /* Activity flag must be set for new content. */
! 203: if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_CONTENT)
1.1 nicm 204: return (0);
1.15 ! nicm 205: if (s->curw == wl)
1.1 nicm 206: return (0);
207:
208: ptr = options_get_string(&w->options, "monitor-content");
209: if (ptr == NULL || *ptr == '\0')
210: return (0);
211: if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
212: return (0);
1.13 nicm 213: xfree(found);
1.1 nicm 214:
1.15 ! nicm 215: wl->flags |= WINLINK_CONTENT;
! 216:
1.13 nicm 217: if (options_get_number(&s->options, "visual-content")) {
1.1 nicm 218: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
219: c = ARRAY_ITEM(&clients, i);
220: if (c == NULL || c->session != s)
221: continue;
222: status_message_set(c, "Content in window %u",
223: winlink_find_by_window(&s->windows, w)->idx);
224: }
225: }
226:
227: return (1);
228: }