[BACK]Return to server-window.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/server-window.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD: tmux.h,v 1.145 2009/10/21 20:11:47 nicm Exp $ */
        !             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:
        !            21: #include <unistd.h>
        !            22:
        !            23: #include "tmux.h"
        !            24:
        !            25: int    server_window_check_bell(struct session *, struct window *);
        !            26: int    server_window_check_activity(struct session *, struct window *);
        !            27: int    server_window_check_content(
        !            28:            struct session *, struct window *, struct window_pane *);
        !            29: void   server_window_check_alive(struct window *);
        !            30:
        !            31: /* Process a single window pane event. */
        !            32: void
        !            33: server_window_callback(int fd, int events, void *data)
        !            34: {
        !            35:        struct window_pane      *wp = data;
        !            36:
        !            37:        if (wp->fd == -1)
        !            38:                return;
        !            39:
        !            40:        if (fd == wp->fd) {
        !            41:                if (buffer_poll(fd, events, wp->in, wp->out) != 0) {
        !            42:                        close(wp->fd);
        !            43:                        wp->fd = -1;
        !            44:                } else
        !            45:                        window_pane_parse(wp);
        !            46:        }
        !            47:
        !            48:        if (fd == wp->pipe_fd) {
        !            49:                if (buffer_poll(fd, events, NULL, wp->pipe_buf) != 0) {
        !            50:                        buffer_destroy(wp->pipe_buf);
        !            51:                        close(wp->pipe_fd);
        !            52:                        wp->pipe_fd = -1;
        !            53:                }
        !            54:        }
        !            55: }
        !            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;
        !            70:
        !            71:                for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
        !            72:                        s = ARRAY_ITEM(&sessions, j);
        !            73:                        if (s == NULL || !session_has(s, w))
        !            74:                                continue;
        !            75:
        !            76:                        if (server_window_check_bell(s, w) ||
        !            77:                            server_window_check_activity(s, w))
        !            78:                                server_status_session(s);
        !            79:                        TAILQ_FOREACH(wp, &w->panes, entry)
        !            80:                                server_window_check_content(s, w, wp);
        !            81:                }
        !            82:                w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT);
        !            83:
        !            84:                server_window_check_alive(w);
        !            85:        }
        !            86:
        !            87:        set_window_names();
        !            88: }
        !            89:
        !            90: /* Check for bell in window. */
        !            91: int
        !            92: server_window_check_bell(struct session *s, struct window *w)
        !            93: {
        !            94:        struct client   *c;
        !            95:        u_int            i;
        !            96:        int              action, visual;
        !            97:
        !            98:        if (!(w->flags & WINDOW_BELL))
        !            99:                return (0);
        !           100:
        !           101:        if (session_alert_has_window(s, w, WINDOW_BELL))
        !           102:                return (0);
        !           103:        session_alert_add(s, w, WINDOW_BELL);
        !           104:
        !           105:        action = options_get_number(&s->options, "bell-action");
        !           106:        switch (action) {
        !           107:        case BELL_ANY:
        !           108:                if (s->flags & SESSION_UNATTACHED)
        !           109:                        break;
        !           110:                visual = options_get_number(&s->options, "visual-bell");
        !           111:                for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
        !           112:                        c = ARRAY_ITEM(&clients, i);
        !           113:                        if (c == NULL || c->session != s)
        !           114:                                continue;
        !           115:                        if (!visual) {
        !           116:                                tty_putcode(&c->tty, TTYC_BEL);
        !           117:                                continue;
        !           118:                        }
        !           119:                        if (c->session->curw->window == w) {
        !           120:                                status_message_set(c, "Bell in current window");
        !           121:                                continue;
        !           122:                        }
        !           123:                        status_message_set(c, "Bell in window %u",
        !           124:                            winlink_find_by_window(&s->windows, w)->idx);
        !           125:                }
        !           126:                break;
        !           127:        case BELL_CURRENT:
        !           128:                if (s->flags & SESSION_UNATTACHED)
        !           129:                        break;
        !           130:                visual = options_get_number(&s->options, "visual-bell");
        !           131:                for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
        !           132:                        c = ARRAY_ITEM(&clients, i);
        !           133:                        if (c == NULL || c->session != s)
        !           134:                                continue;
        !           135:                        if (c->session->curw->window != w)
        !           136:                                continue;
        !           137:                        if (!visual) {
        !           138:                                tty_putcode(&c->tty, TTYC_BEL);
        !           139:                                continue;
        !           140:                        }
        !           141:                        status_message_set(c, "Bell in current window");
        !           142:                }
        !           143:                break;
        !           144:        }
        !           145:
        !           146:        return (1);
        !           147: }
        !           148:
        !           149: /* Check for activity in window. */
        !           150: int
        !           151: server_window_check_activity(struct session *s, struct window *w)
        !           152: {
        !           153:        struct client   *c;
        !           154:        u_int            i;
        !           155:
        !           156:        if (!(w->flags & WINDOW_ACTIVITY))
        !           157:                return (0);
        !           158:        if (s->curw->window == w)
        !           159:                return (0);
        !           160:
        !           161:        if (!options_get_number(&w->options, "monitor-activity"))
        !           162:                return (0);
        !           163:
        !           164:        if (session_alert_has_window(s, w, WINDOW_ACTIVITY))
        !           165:                return (0);
        !           166:        session_alert_add(s, w, WINDOW_ACTIVITY);
        !           167:
        !           168:        if (s->flags & SESSION_UNATTACHED)
        !           169:                return (0);
        !           170:        if (options_get_number(&s->options, "visual-activity")) {
        !           171:                for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
        !           172:                        c = ARRAY_ITEM(&clients, i);
        !           173:                        if (c == NULL || c->session != s)
        !           174:                                continue;
        !           175:                        status_message_set(c, "Activity in window %u",
        !           176:                            winlink_find_by_window(&s->windows, w)->idx);
        !           177:                }
        !           178:        }
        !           179:
        !           180:        return (1);
        !           181: }
        !           182:
        !           183: /* Check for content change in window. */
        !           184: int
        !           185: server_window_check_content(
        !           186:     struct session *s, struct window *w, struct window_pane *wp)
        !           187: {
        !           188:        struct client   *c;
        !           189:        u_int            i;
        !           190:        char            *found, *ptr;
        !           191:
        !           192:        if (!(w->flags & WINDOW_ACTIVITY))      /* activity for new content */
        !           193:                return (0);
        !           194:        if (s->curw->window == w)
        !           195:                return (0);
        !           196:
        !           197:        ptr = options_get_string(&w->options, "monitor-content");
        !           198:        if (ptr == NULL || *ptr == '\0')
        !           199:                return (0);
        !           200:
        !           201:        if (session_alert_has_window(s, w, WINDOW_CONTENT))
        !           202:                return (0);
        !           203:
        !           204:        if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
        !           205:                return (0);
        !           206:        xfree(found);
        !           207:
        !           208:        session_alert_add(s, w, WINDOW_CONTENT);
        !           209:        if (s->flags & SESSION_UNATTACHED)
        !           210:                return (0);
        !           211:        if (options_get_number(&s->options, "visual-content")) {
        !           212:                for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
        !           213:                        c = ARRAY_ITEM(&clients, i);
        !           214:                        if (c == NULL || c->session != s)
        !           215:                                continue;
        !           216:                        status_message_set(c, "Content in window %u",
        !           217:                            winlink_find_by_window(&s->windows, w)->idx);
        !           218:                }
        !           219:        }
        !           220:
        !           221:        return (1);
        !           222: }
        !           223:
        !           224: /* Check if window still exists. */
        !           225: void
        !           226: server_window_check_alive(struct window *w)
        !           227: {
        !           228:        struct window_pane      *wp, *wq;
        !           229:        struct options          *oo = &w->options;
        !           230:        struct session          *s;
        !           231:        struct winlink          *wl;
        !           232:        u_int                    i;
        !           233:        int                      destroyed;
        !           234:
        !           235:        destroyed = 1;
        !           236:
        !           237:        wp = TAILQ_FIRST(&w->panes);
        !           238:        while (wp != NULL) {
        !           239:                wq = TAILQ_NEXT(wp, entry);
        !           240:                /*
        !           241:                 * If the pane has died and the remain-on-exit flag is not set,
        !           242:                 * remove the pane; otherwise, if the flag is set, don't allow
        !           243:                 * the window to be destroyed (or it'll close when the last
        !           244:                 * pane dies).
        !           245:                 */
        !           246:                if (wp->fd == -1 && !options_get_number(oo, "remain-on-exit")) {
        !           247:                        layout_close_pane(wp);
        !           248:                        window_remove_pane(w, wp);
        !           249:                        server_redraw_window(w);
        !           250:                } else
        !           251:                        destroyed = 0;
        !           252:                wp = wq;
        !           253:        }
        !           254:
        !           255:        if (!destroyed)
        !           256:                return;
        !           257:
        !           258:        for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
        !           259:                s = ARRAY_ITEM(&sessions, i);
        !           260:                if (s == NULL)
        !           261:                        continue;
        !           262:                if (!session_has(s, w))
        !           263:                        continue;
        !           264:
        !           265:        restart:
        !           266:                /* Detach window and either redraw or kill clients. */
        !           267:                RB_FOREACH(wl, winlinks, &s->windows) {
        !           268:                        if (wl->window != w)
        !           269:                                continue;
        !           270:                        if (session_detach(s, wl)) {
        !           271:                                server_destroy_session_group(s);
        !           272:                                break;
        !           273:                        }
        !           274:                        server_redraw_session(s);
        !           275:                        server_status_session_group(s);
        !           276:                        goto restart;
        !           277:                }
        !           278:        }
        !           279:
        !           280:        recalculate_sizes();
        !           281: }