Annotation of src/usr.bin/tmux/server-window.c, Revision 1.18
1.18 ! nicm 1: /* $OpenBSD: server-window.c,v 1.17 2010/08/11 07:34:43 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.18 ! nicm 29: int server_window_check_silence(struct session *, struct winlink *);
1.1 nicm 30: int server_window_check_content(
1.15 nicm 31: struct session *, struct winlink *, struct window_pane *);
1.2 nicm 32:
1.1 nicm 33: /* Window functions that need to happen every loop. */
34: void
35: server_window_loop(void)
36: {
37: struct window *w;
1.15 nicm 38: struct winlink *wl;
1.1 nicm 39: struct window_pane *wp;
40: struct session *s;
41: u_int i, j;
42:
43: for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
44: w = ARRAY_ITEM(&windows, i);
45: if (w == NULL)
46: continue;
47:
48: for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
49: s = ARRAY_ITEM(&sessions, j);
1.15 nicm 50: if (s == NULL)
51: continue;
52: wl = session_has(s, w);
53: if (wl == NULL)
1.1 nicm 54: continue;
1.13 nicm 55:
1.15 nicm 56: if (server_window_check_bell(s, wl) ||
1.18 ! nicm 57: server_window_check_activity(s, wl) ||
! 58: server_window_check_silence(s, wl))
1.1 nicm 59: server_status_session(s);
60: TAILQ_FOREACH(wp, &w->panes, entry)
1.15 nicm 61: server_window_check_content(s, wl, wp);
1.1 nicm 62: }
1.15 nicm 63: w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY);
1.1 nicm 64: }
65: }
66:
67: /* Check for bell in window. */
68: int
1.15 nicm 69: server_window_check_bell(struct session *s, struct winlink *wl)
1.1 nicm 70: {
71: struct client *c;
1.15 nicm 72: struct window *w = wl->window;
1.1 nicm 73: u_int i;
74: int action, visual;
75:
1.15 nicm 76: if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
77: return (0);
1.16 nicm 78: if (s->curw != wl)
79: wl->flags |= WINLINK_BELL;
1.1 nicm 80:
81: action = options_get_number(&s->options, "bell-action");
82: switch (action) {
83: case BELL_ANY:
84: if (s->flags & SESSION_UNATTACHED)
85: break;
86: visual = options_get_number(&s->options, "visual-bell");
87: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
88: c = ARRAY_ITEM(&clients, i);
89: if (c == NULL || c->session != s)
90: continue;
91: if (!visual) {
92: tty_putcode(&c->tty, TTYC_BEL);
93: continue;
94: }
1.13 nicm 95: if (c->session->curw->window == w) {
1.1 nicm 96: status_message_set(c, "Bell in current window");
97: continue;
98: }
99: status_message_set(c, "Bell in window %u",
100: winlink_find_by_window(&s->windows, w)->idx);
101: }
102: break;
103: case BELL_CURRENT:
104: if (s->flags & SESSION_UNATTACHED)
105: break;
106: visual = options_get_number(&s->options, "visual-bell");
107: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
108: c = ARRAY_ITEM(&clients, i);
109: if (c == NULL || c->session != s)
110: continue;
1.13 nicm 111: if (c->session->curw->window != w)
1.1 nicm 112: continue;
113: if (!visual) {
114: tty_putcode(&c->tty, TTYC_BEL);
115: continue;
116: }
117: status_message_set(c, "Bell in current window");
118: }
119: break;
120: }
121:
122: return (1);
123: }
124:
125: /* Check for activity in window. */
126: int
1.15 nicm 127: server_window_check_activity(struct session *s, struct winlink *wl)
1.1 nicm 128: {
129: struct client *c;
1.15 nicm 130: struct window *w = wl->window;
1.1 nicm 131: u_int i;
132:
1.15 nicm 133: if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
1.1 nicm 134: return (0);
1.15 nicm 135: if (s->curw == wl)
1.1 nicm 136: return (0);
137:
1.13 nicm 138: if (!options_get_number(&w->options, "monitor-activity"))
1.1 nicm 139: return (0);
140:
1.15 nicm 141: wl->flags |= WINLINK_ACTIVITY;
1.1 nicm 142:
1.13 nicm 143: if (options_get_number(&s->options, "visual-activity")) {
1.1 nicm 144: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
145: c = ARRAY_ITEM(&clients, i);
146: if (c == NULL || c->session != s)
147: continue;
148: status_message_set(c, "Activity in window %u",
1.18 ! nicm 149: winlink_find_by_window(&s->windows, w)->idx);
! 150: }
! 151: }
! 152:
! 153: return (1);
! 154: }
! 155:
! 156: /* Check for silence in window. */
! 157: int
! 158: server_window_check_silence(struct session *s, struct winlink *wl)
! 159: {
! 160: struct client *c;
! 161: struct window *w = wl->window;
! 162: struct timeval timer;
! 163: u_int i;
! 164: int silence_interval, timer_difference;
! 165:
! 166: if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
! 167: return (0);
! 168:
! 169: if (s->curw == wl) {
! 170: /*
! 171: * Reset the timer for this window if we've focused it. We
! 172: * don't want the timer tripping as soon as we've switched away
! 173: * from this window.
! 174: */
! 175: if (gettimeofday(&w->silence_timer, NULL) != 0)
! 176: fatal("gettimeofday failed.");
! 177:
! 178: return (0);
! 179: }
! 180:
! 181: silence_interval = options_get_number(&w->options, "monitor-silence");
! 182: if (silence_interval == 0)
! 183: return (0);
! 184:
! 185: if (gettimeofday(&timer, NULL) != 0)
! 186: fatal("gettimeofday");
! 187: timer_difference = timer.tv_sec - w->silence_timer.tv_sec;
! 188: if (timer_difference <= silence_interval)
! 189: return (0);
! 190: wl->flags |= WINLINK_SILENCE;
! 191:
! 192: if (options_get_number(&s->options, "visual-silence")) {
! 193: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
! 194: c = ARRAY_ITEM(&clients, i);
! 195: if (c == NULL || c->session != s)
! 196: continue;
! 197: status_message_set(c, "Silence in window %u",
1.1 nicm 198: winlink_find_by_window(&s->windows, w)->idx);
199: }
200: }
201:
202: return (1);
203: }
204:
205: /* Check for content change in window. */
206: int
207: server_window_check_content(
1.15 nicm 208: struct session *s, struct winlink *wl, struct window_pane *wp)
1.1 nicm 209: {
210: struct client *c;
1.15 nicm 211: struct window *w = wl->window;
1.1 nicm 212: u_int i;
213: char *found, *ptr;
1.13 nicm 214:
1.15 nicm 215: /* Activity flag must be set for new content. */
216: if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_CONTENT)
1.1 nicm 217: return (0);
1.15 nicm 218: if (s->curw == wl)
1.1 nicm 219: return (0);
220:
221: ptr = options_get_string(&w->options, "monitor-content");
222: if (ptr == NULL || *ptr == '\0')
223: return (0);
224: if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
225: return (0);
1.13 nicm 226: xfree(found);
1.1 nicm 227:
1.15 nicm 228: wl->flags |= WINLINK_CONTENT;
229:
1.13 nicm 230: if (options_get_number(&s->options, "visual-content")) {
1.1 nicm 231: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
232: c = ARRAY_ITEM(&clients, i);
233: if (c == NULL || c->session != s)
234: continue;
235: status_message_set(c, "Content in window %u",
236: winlink_find_by_window(&s->windows, w)->idx);
237: }
238: }
239:
240: return (1);
241: }