4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
26 int server_window_check_bell(struct session
*, struct winlink
*);
27 int server_window_check_activity(struct session
*, struct winlink
*);
28 int server_window_check_silence(struct session
*, struct winlink
*);
29 int server_window_check_content(
30 struct session
*, struct winlink
*, struct window_pane
*);
31 void ring_bell(struct session
*);
33 /* Window functions that need to happen every loop. */
35 server_window_loop(void)
39 struct window_pane
*wp
;
43 for (i
= 0; i
< ARRAY_LENGTH(&windows
); i
++) {
44 w
= ARRAY_ITEM(&windows
, i
);
48 RB_FOREACH(s
, sessions
, &sessions
) {
49 wl
= session_has(s
, w
);
53 if (server_window_check_bell(s
, wl
) ||
54 server_window_check_activity(s
, wl
) ||
55 server_window_check_silence(s
, wl
))
56 server_status_session(s
);
57 TAILQ_FOREACH(wp
, &w
->panes
, entry
)
58 server_window_check_content(s
, wl
, wp
);
60 if (!(s
->flags
& SESSION_UNATTACHED
))
61 w
->flags
&= ~(WINDOW_BELL
|WINDOW_ACTIVITY
);
66 /* Check for bell in window. */
68 server_window_check_bell(struct session
*s
, struct winlink
*wl
)
71 struct window
*w
= wl
->window
;
75 if (!(w
->flags
& WINDOW_BELL
) || wl
->flags
& WINLINK_BELL
)
77 if (s
->curw
!= wl
|| s
->flags
& SESSION_UNATTACHED
)
78 wl
->flags
|= WINLINK_BELL
;
80 action
= options_get_number(&s
->options
, "bell-action");
83 if (s
->flags
& SESSION_UNATTACHED
)
85 visual
= options_get_number(&s
->options
, "visual-bell");
86 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
87 c
= ARRAY_ITEM(&clients
, i
);
88 if (c
== NULL
|| c
->session
!= s
)
94 if (c
->session
->curw
->window
== w
) {
95 status_message_set(c
, "Bell in current window");
98 status_message_set(c
, "Bell in window %u",
99 winlink_find_by_window(&s
->windows
, w
)->idx
);
103 if (s
->flags
& SESSION_UNATTACHED
)
105 visual
= options_get_number(&s
->options
, "visual-bell");
106 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
107 c
= ARRAY_ITEM(&clients
, i
);
108 if (c
== NULL
|| c
->session
!= s
)
110 if (c
->session
->curw
->window
!= w
)
116 status_message_set(c
, "Bell in current window");
124 /* Check for activity in window. */
126 server_window_check_activity(struct session
*s
, struct winlink
*wl
)
129 struct window
*w
= wl
->window
;
132 if (!(w
->flags
& WINDOW_ACTIVITY
) || wl
->flags
& WINLINK_ACTIVITY
)
134 if (s
->curw
== wl
&& !(s
->flags
& SESSION_UNATTACHED
))
137 if (!options_get_number(&w
->options
, "monitor-activity"))
140 if (options_get_number(&s
->options
, "bell-on-alert"))
142 wl
->flags
|= WINLINK_ACTIVITY
;
144 if (options_get_number(&s
->options
, "visual-activity")) {
145 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
146 c
= ARRAY_ITEM(&clients
, i
);
147 if (c
== NULL
|| c
->session
!= s
)
149 status_message_set(c
, "Activity in window %u",
150 winlink_find_by_window(&s
->windows
, w
)->idx
);
157 /* Check for silence in window. */
159 server_window_check_silence(struct session
*s
, struct winlink
*wl
)
162 struct window
*w
= wl
->window
;
163 struct timeval timer
;
165 int silence_interval
, timer_difference
;
167 if (!(w
->flags
& WINDOW_SILENCE
) || wl
->flags
& WINLINK_SILENCE
)
170 if (s
->curw
== wl
&& !(s
->flags
& SESSION_UNATTACHED
)) {
172 * Reset the timer for this window if we've focused it. We
173 * don't want the timer tripping as soon as we've switched away
176 if (gettimeofday(&w
->silence_timer
, NULL
) != 0)
177 fatal("gettimeofday failed.");
182 silence_interval
= options_get_number(&w
->options
, "monitor-silence");
183 if (silence_interval
== 0)
186 if (gettimeofday(&timer
, NULL
) != 0)
187 fatal("gettimeofday");
188 timer_difference
= timer
.tv_sec
- w
->silence_timer
.tv_sec
;
189 if (timer_difference
<= silence_interval
)
192 if (options_get_number(&s
->options
, "bell-on-alert"))
194 wl
->flags
|= WINLINK_SILENCE
;
196 if (options_get_number(&s
->options
, "visual-silence")) {
197 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
198 c
= ARRAY_ITEM(&clients
, i
);
199 if (c
== NULL
|| c
->session
!= s
)
201 status_message_set(c
, "Silence in window %u",
202 winlink_find_by_window(&s
->windows
, w
)->idx
);
209 /* Check for content change in window. */
211 server_window_check_content(
212 struct session
*s
, struct winlink
*wl
, struct window_pane
*wp
)
215 struct window
*w
= wl
->window
;
219 /* Activity flag must be set for new content. */
220 if (!(w
->flags
& WINDOW_ACTIVITY
) || wl
->flags
& WINLINK_CONTENT
)
222 if (s
->curw
== wl
&& !(s
->flags
& SESSION_UNATTACHED
))
225 ptr
= options_get_string(&w
->options
, "monitor-content");
226 if (ptr
== NULL
|| *ptr
== '\0')
228 if ((found
= window_pane_search(wp
, ptr
, NULL
)) == NULL
)
232 if (options_get_number(&s
->options
, "bell-on-alert"))
234 wl
->flags
|= WINLINK_CONTENT
;
236 if (options_get_number(&s
->options
, "visual-content")) {
237 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
238 c
= ARRAY_ITEM(&clients
, i
);
239 if (c
== NULL
|| c
->session
!= s
)
241 status_message_set(c
, "Content in window %u",
242 winlink_find_by_window(&s
->windows
, w
)->idx
);
249 /* Ring terminal bell. */
251 ring_bell(struct session
*s
)
256 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
257 c
= ARRAY_ITEM(&clients
, i
);
258 if (c
!= NULL
&& c
->session
== s
)