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_backoff(struct window_pane
*);
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
*);
32 /* Check if this window should suspend reading. */
34 server_window_backoff(struct window_pane
*wp
)
39 if (!window_pane_visible(wp
))
42 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
43 c
= ARRAY_ITEM(&clients
, i
);
44 if (c
== NULL
|| c
->session
== NULL
)
46 if ((c
->flags
& (CLIENT_SUSPENDED
|CLIENT_DEAD
)) != 0)
48 if (c
->session
->curw
->window
!= wp
->window
)
51 if (EVBUFFER_LENGTH(c
->tty
.event
->output
) > BACKOFF_THRESHOLD
)
57 /* Window functions that need to happen every loop. */
59 server_window_loop(void)
62 struct window_pane
*wp
;
66 for (i
= 0; i
< ARRAY_LENGTH(&windows
); i
++) {
67 w
= ARRAY_ITEM(&windows
, i
);
71 TAILQ_FOREACH(wp
, &w
->panes
, entry
) {
74 if (!(wp
->flags
& PANE_FREEZE
)) {
75 if (server_window_backoff(wp
))
76 bufferevent_disable(wp
->event
, EV_READ
);
78 bufferevent_enable(wp
->event
, EV_READ
);
82 for (j
= 0; j
< ARRAY_LENGTH(&sessions
); j
++) {
83 s
= ARRAY_ITEM(&sessions
, j
);
84 if (s
== NULL
|| !session_has(s
, w
))
87 if (server_window_check_bell(s
, w
) ||
88 server_window_check_activity(s
, w
))
89 server_status_session(s
);
90 TAILQ_FOREACH(wp
, &w
->panes
, entry
)
91 server_window_check_content(s
, w
, wp
);
93 w
->flags
&= ~(WINDOW_BELL
|WINDOW_ACTIVITY
|WINDOW_CONTENT
);
97 /* Check for bell in window. */
99 server_window_check_bell(struct session
*s
, struct window
*w
)
105 if (!(w
->flags
& WINDOW_BELL
))
108 if (session_alert_has_window(s
, w
, WINDOW_BELL
))
110 session_alert_add(s
, w
, WINDOW_BELL
);
112 action
= options_get_number(&s
->options
, "bell-action");
115 if (s
->flags
& SESSION_UNATTACHED
)
117 visual
= options_get_number(&s
->options
, "visual-bell");
118 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
119 c
= ARRAY_ITEM(&clients
, i
);
120 if (c
== NULL
|| c
->session
!= s
)
123 tty_putcode(&c
->tty
, TTYC_BEL
);
126 if (c
->session
->curw
->window
== w
) {
127 status_message_set(c
, "Bell in current window");
130 status_message_set(c
, "Bell in window %u",
131 winlink_find_by_window(&s
->windows
, w
)->idx
);
135 if (s
->flags
& SESSION_UNATTACHED
)
137 visual
= options_get_number(&s
->options
, "visual-bell");
138 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
139 c
= ARRAY_ITEM(&clients
, i
);
140 if (c
== NULL
|| c
->session
!= s
)
142 if (c
->session
->curw
->window
!= w
)
145 tty_putcode(&c
->tty
, TTYC_BEL
);
148 status_message_set(c
, "Bell in current window");
156 /* Check for activity in window. */
158 server_window_check_activity(struct session
*s
, struct window
*w
)
163 if (!(w
->flags
& WINDOW_ACTIVITY
))
165 if (s
->curw
->window
== w
)
168 if (!options_get_number(&w
->options
, "monitor-activity"))
171 if (session_alert_has_window(s
, w
, WINDOW_ACTIVITY
))
173 session_alert_add(s
, w
, WINDOW_ACTIVITY
);
175 if (s
->flags
& SESSION_UNATTACHED
)
177 if (options_get_number(&s
->options
, "visual-activity")) {
178 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
179 c
= ARRAY_ITEM(&clients
, i
);
180 if (c
== NULL
|| c
->session
!= s
)
182 status_message_set(c
, "Activity in window %u",
183 winlink_find_by_window(&s
->windows
, w
)->idx
);
190 /* Check for content change in window. */
192 server_window_check_content(
193 struct session
*s
, struct window
*w
, struct window_pane
*wp
)
199 if (!(w
->flags
& WINDOW_ACTIVITY
)) /* activity for new content */
201 if (s
->curw
->window
== w
)
204 ptr
= options_get_string(&w
->options
, "monitor-content");
205 if (ptr
== NULL
|| *ptr
== '\0')
208 if (session_alert_has_window(s
, w
, WINDOW_CONTENT
))
211 if ((found
= window_pane_search(wp
, ptr
, NULL
)) == NULL
)
215 session_alert_add(s
, w
, WINDOW_CONTENT
);
216 if (s
->flags
& SESSION_UNATTACHED
)
218 if (options_get_number(&s
->options
, "visual-content")) {
219 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
220 c
= ARRAY_ITEM(&clients
, i
);
221 if (c
== NULL
|| c
->session
!= s
)
223 status_message_set(c
, "Content in window %u",
224 winlink_find_by_window(&s
->windows
, w
)->idx
);