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

Annotation of src/usr.bin/tmux/control-notify.c, Revision 1.26

1.26    ! nicm        1: /* $OpenBSD: control-notify.c,v 1.25 2019/12/12 11:39:56 nicm Exp $ */
1.1       nicm        2:
                      3: /*
1.16      nicm        4:  * Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1       nicm        5:  * Copyright (c) 2012 George Nachman <tmux@georgester.com>
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
                     16:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                     17:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: #include <sys/types.h>
                     21:
1.12      nicm       22: #include <stdlib.h>
                     23:
1.1       nicm       24: #include "tmux.h"
                     25:
                     26: #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \
                     27:        ((c) != NULL && ((c)->flags & CLIENT_CONTROL))
1.2       nicm       28:
                     29: void
                     30: control_notify_input(struct client *c, struct window_pane *wp,
1.23      nicm       31:     const u_char *buf, size_t len)
1.2       nicm       32: {
                     33:        struct evbuffer *message;
                     34:        u_int            i;
                     35:
                     36:        if (c->session == NULL)
                     37:            return;
1.24      nicm       38:
                     39:        if (c->flags & CLIENT_CONTROL_NOOUTPUT)
                     40:                return;
1.2       nicm       41:
                     42:        /*
                     43:         * Only write input if the window pane is linked to a window belonging
                     44:         * to the client's session.
                     45:         */
                     46:        if (winlink_find_by_window(&c->session->windows, wp->window) != NULL) {
                     47:                message = evbuffer_new();
1.22      nicm       48:                if (message == NULL)
                     49:                        fatalx("out of memory");
1.7       nicm       50:                evbuffer_add_printf(message, "%%output %%%u ", wp->id);
1.6       nicm       51:                for (i = 0; i < len; i++) {
                     52:                        if (buf[i] < ' ' || buf[i] == '\\')
                     53:                            evbuffer_add_printf(message, "\\%03o", buf[i]);
                     54:                        else
                     55:                            evbuffer_add_printf(message, "%c", buf[i]);
                     56:                }
1.26    ! nicm       57:                evbuffer_add(message, "", 1);
1.25      nicm       58:                control_write(c, "%s", EVBUFFER_DATA(message));
1.2       nicm       59:                evbuffer_free(message);
                     60:        }
                     61: }
1.1       nicm       62:
                     63: void
1.21      nicm       64: control_notify_pane_mode_changed(int pane)
                     65: {
                     66:        struct client   *c;
                     67:
                     68:        TAILQ_FOREACH(c, &clients, entry) {
                     69:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
                     70:                        continue;
                     71:
                     72:                control_write(c, "%%pane-mode-changed %%%u", pane);
                     73:        }
                     74: }
                     75:
                     76: void
1.1       nicm       77: control_notify_window_layout_changed(struct window *w)
                     78: {
1.21      nicm       79:        struct client   *c;
                     80:        struct session  *s;
                     81:        struct winlink  *wl;
                     82:        const char      *template;
                     83:        char            *cp;
1.12      nicm       84:
                     85:        template = "%layout-change #{window_id} #{window_layout} "
                     86:            "#{window_visible_layout} #{window_flags}";
1.1       nicm       87:
1.11      nicm       88:        TAILQ_FOREACH(c, &clients, entry) {
1.1       nicm       89:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                     90:                        continue;
                     91:                s = c->session;
                     92:
                     93:                if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
                     94:                        continue;
                     95:
                     96:                /*
                     97:                 * When the last pane in a window is closed it won't have a
                     98:                 * layout root and we don't need to inform the client about the
                     99:                 * layout change because the whole window will go away soon.
                    100:                 */
                    101:                if (w->layout_root == NULL)
                    102:                        continue;
                    103:
                    104:                wl = winlink_find_by_window(&s->windows, w);
                    105:                if (wl != NULL) {
1.20      nicm      106:                        cp = format_single(NULL, template, c, NULL, wl, NULL);
                    107:                        control_write(c, "%s", cp);
                    108:                        free(cp);
1.1       nicm      109:                }
                    110:        }
                    111: }
                    112:
                    113: void
1.21      nicm      114: control_notify_window_pane_changed(struct window *w)
                    115: {
                    116:        struct client   *c;
                    117:
                    118:        TAILQ_FOREACH(c, &clients, entry) {
                    119:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
                    120:                        continue;
                    121:
                    122:                control_write(c, "%%window-pane-changed @%u %%%u", w->id,
                    123:                    w->active->id);
                    124:        }
                    125: }
                    126:
                    127: void
1.13      nicm      128: control_notify_window_unlinked(__unused struct session *s, struct window *w)
1.1       nicm      129: {
                    130:        struct client   *c;
1.9       nicm      131:        struct session  *cs;
1.1       nicm      132:
1.11      nicm      133:        TAILQ_FOREACH(c, &clients, entry) {
1.1       nicm      134:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                    135:                        continue;
1.9       nicm      136:                cs = c->session;
1.1       nicm      137:
1.9       nicm      138:                if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
                    139:                        control_write(c, "%%window-close @%u", w->id);
                    140:                else
                    141:                        control_write(c, "%%unlinked-window-close @%u", w->id);
1.1       nicm      142:        }
                    143: }
                    144:
                    145: void
1.13      nicm      146: control_notify_window_linked(__unused struct session *s, struct window *w)
1.1       nicm      147: {
                    148:        struct client   *c;
                    149:        struct session  *cs;
                    150:
1.11      nicm      151:        TAILQ_FOREACH(c, &clients, entry) {
1.1       nicm      152:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                    153:                        continue;
                    154:                cs = c->session;
                    155:
                    156:                if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
1.7       nicm      157:                        control_write(c, "%%window-add @%u", w->id);
1.1       nicm      158:                else
1.7       nicm      159:                        control_write(c, "%%unlinked-window-add @%u", w->id);
1.1       nicm      160:        }
                    161: }
                    162:
                    163: void
                    164: control_notify_window_renamed(struct window *w)
                    165: {
                    166:        struct client   *c;
1.9       nicm      167:        struct session  *cs;
1.1       nicm      168:
1.11      nicm      169:        TAILQ_FOREACH(c, &clients, entry) {
1.1       nicm      170:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                    171:                        continue;
1.9       nicm      172:                cs = c->session;
1.1       nicm      173:
1.9       nicm      174:                if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) {
                    175:                        control_write(c, "%%window-renamed @%u %s", w->id,
                    176:                            w->name);
                    177:                } else {
                    178:                        control_write(c, "%%unlinked-window-renamed @%u %s",
                    179:                            w->id, w->name);
                    180:                }
1.1       nicm      181:        }
                    182: }
                    183:
                    184: void
1.21      nicm      185: control_notify_client_session_changed(struct client *cc)
1.1       nicm      186: {
1.21      nicm      187:        struct client   *c;
1.1       nicm      188:        struct session  *s;
                    189:
1.21      nicm      190:        if (cc->session == NULL)
1.1       nicm      191:                return;
1.21      nicm      192:        s = cc->session;
1.1       nicm      193:
1.21      nicm      194:        TAILQ_FOREACH(c, &clients, entry) {
                    195:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                    196:                        continue;
                    197:
                    198:                if (cc == c) {
                    199:                        control_write(c, "%%session-changed $%u %s", s->id,
                    200:                            s->name);
                    201:                } else {
                    202:                        control_write(c, "%%client-session-changed %s $%u %s",
                    203:                            cc->name, s->id, s->name);
                    204:                }
                    205:        }
1.1       nicm      206: }
                    207:
                    208: void
                    209: control_notify_session_renamed(struct session *s)
                    210: {
                    211:        struct client   *c;
                    212:
1.11      nicm      213:        TAILQ_FOREACH(c, &clients, entry) {
1.7       nicm      214:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
1.1       nicm      215:                        continue;
                    216:
1.7       nicm      217:                control_write(c, "%%session-renamed $%u %s", s->id, s->name);
1.1       nicm      218:        }
                    219: }
                    220:
                    221: void
1.13      nicm      222: control_notify_session_created(__unused struct session *s)
1.1       nicm      223: {
                    224:        struct client   *c;
                    225:
1.11      nicm      226:        TAILQ_FOREACH(c, &clients, entry) {
1.7       nicm      227:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
1.1       nicm      228:                        continue;
                    229:
                    230:                control_write(c, "%%sessions-changed");
                    231:        }
                    232: }
                    233:
                    234: void
1.17      nicm      235: control_notify_session_closed(__unused struct session *s)
1.1       nicm      236: {
                    237:        struct client   *c;
                    238:
1.11      nicm      239:        TAILQ_FOREACH(c, &clients, entry) {
1.7       nicm      240:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
1.1       nicm      241:                        continue;
                    242:
                    243:                control_write(c, "%%sessions-changed");
1.21      nicm      244:        }
                    245: }
                    246:
                    247: void
                    248: control_notify_session_window_changed(struct session *s)
                    249: {
                    250:        struct client   *c;
                    251:
                    252:        TAILQ_FOREACH(c, &clients, entry) {
                    253:                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
                    254:                        continue;
                    255:
                    256:                control_write(c, "%%session-window-changed $%u @%u", s->id,
                    257:                    s->curw->window->id);
1.1       nicm      258:        }
                    259: }