Annotation of src/usr.bin/tmux/server-window.c, Revision 1.12
1.12 ! nicm 1: /* $OpenBSD: server-window.c,v 1.11 2009/11/06 10:42:06 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.1 nicm 27: int server_window_check_bell(struct session *, struct window *);
28: int server_window_check_activity(struct session *, struct window *);
29: int server_window_check_content(
30: struct session *, struct window *, 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;
62: struct window_pane *wp;
63: struct session *s;
64: u_int i, j;
65:
66: for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
67: w = ARRAY_ITEM(&windows, i);
68: if (w == NULL)
69: continue;
1.9 nicm 70:
71: TAILQ_FOREACH(wp, &w->panes, entry) {
1.11 nicm 72: if (wp->fd != -1) {
73: if (server_window_backoff(wp))
74: bufferevent_disable(wp->event, EV_READ);
75: else
76: bufferevent_enable(wp->event, EV_READ);
77: }
1.9 nicm 78: }
1.1 nicm 79:
80: for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
81: s = ARRAY_ITEM(&sessions, j);
82: if (s == NULL || !session_has(s, w))
83: continue;
84:
85: if (server_window_check_bell(s, w) ||
86: server_window_check_activity(s, w))
87: server_status_session(s);
88: TAILQ_FOREACH(wp, &w->panes, entry)
89: server_window_check_content(s, w, wp);
90: }
91: w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT);
92: }
93: }
94:
95: /* Check for bell in window. */
96: int
97: server_window_check_bell(struct session *s, struct window *w)
98: {
99: struct client *c;
100: u_int i;
101: int action, visual;
102:
103: if (!(w->flags & WINDOW_BELL))
104: return (0);
105:
106: if (session_alert_has_window(s, w, WINDOW_BELL))
107: return (0);
108: session_alert_add(s, w, WINDOW_BELL);
109:
110: action = options_get_number(&s->options, "bell-action");
111: switch (action) {
112: case BELL_ANY:
113: if (s->flags & SESSION_UNATTACHED)
114: break;
115: visual = options_get_number(&s->options, "visual-bell");
116: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
117: c = ARRAY_ITEM(&clients, i);
118: if (c == NULL || c->session != s)
119: continue;
120: if (!visual) {
121: tty_putcode(&c->tty, TTYC_BEL);
122: continue;
123: }
124: if (c->session->curw->window == w) {
125: status_message_set(c, "Bell in current window");
126: continue;
127: }
128: status_message_set(c, "Bell in window %u",
129: winlink_find_by_window(&s->windows, w)->idx);
130: }
131: break;
132: case BELL_CURRENT:
133: if (s->flags & SESSION_UNATTACHED)
134: break;
135: visual = options_get_number(&s->options, "visual-bell");
136: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
137: c = ARRAY_ITEM(&clients, i);
138: if (c == NULL || c->session != s)
139: continue;
140: if (c->session->curw->window != w)
141: continue;
142: if (!visual) {
143: tty_putcode(&c->tty, TTYC_BEL);
144: continue;
145: }
146: status_message_set(c, "Bell in current window");
147: }
148: break;
149: }
150:
151: return (1);
152: }
153:
154: /* Check for activity in window. */
155: int
156: server_window_check_activity(struct session *s, struct window *w)
157: {
158: struct client *c;
159: u_int i;
160:
161: if (!(w->flags & WINDOW_ACTIVITY))
162: return (0);
163: if (s->curw->window == w)
164: return (0);
165:
166: if (!options_get_number(&w->options, "monitor-activity"))
167: return (0);
168:
169: if (session_alert_has_window(s, w, WINDOW_ACTIVITY))
170: return (0);
171: session_alert_add(s, w, WINDOW_ACTIVITY);
172:
173: if (s->flags & SESSION_UNATTACHED)
174: return (0);
175: if (options_get_number(&s->options, "visual-activity")) {
176: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
177: c = ARRAY_ITEM(&clients, i);
178: if (c == NULL || c->session != s)
179: continue;
180: status_message_set(c, "Activity in window %u",
181: winlink_find_by_window(&s->windows, w)->idx);
182: }
183: }
184:
185: return (1);
186: }
187:
188: /* Check for content change in window. */
189: int
190: server_window_check_content(
191: struct session *s, struct window *w, struct window_pane *wp)
192: {
193: struct client *c;
194: u_int i;
195: char *found, *ptr;
196:
197: if (!(w->flags & WINDOW_ACTIVITY)) /* activity for new content */
198: return (0);
199: if (s->curw->window == w)
200: return (0);
201:
202: ptr = options_get_string(&w->options, "monitor-content");
203: if (ptr == NULL || *ptr == '\0')
204: return (0);
205:
206: if (session_alert_has_window(s, w, WINDOW_CONTENT))
207: return (0);
208:
209: if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
210: return (0);
211: xfree(found);
212:
213: session_alert_add(s, w, WINDOW_CONTENT);
214: if (s->flags & SESSION_UNATTACHED)
215: return (0);
216: if (options_get_number(&s->options, "visual-content")) {
217: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
218: c = ARRAY_ITEM(&clients, i);
219: if (c == NULL || c->session != s)
220: continue;
221: status_message_set(c, "Content in window %u",
222: winlink_find_by_window(&s->windows, w)->idx);
223: }
224: }
225:
226: return (1);
227: }