Annotation of embedaddon/tmux/notify.c, revision 1.1.1.1

1.1       misho       1: /* $OpenBSD$ */
                      2: 
                      3: /*
                      4:  * Copyright (c) 2012 George Nachman <tmux@georgester.com>
                      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 <stdlib.h>
                     22: #include <string.h>
                     23: 
                     24: #include "tmux.h"
                     25: 
                     26: struct notify_entry {
                     27:        const char              *name;
                     28: 
                     29:        struct client           *client;
                     30:        struct session          *session;
                     31:        struct window           *window;
                     32:        int                      pane;
                     33: 
                     34:        struct cmd_find_state    fs;
                     35: };
                     36: 
                     37: static void
                     38: notify_hook(struct cmdq_item *item, struct notify_entry *ne)
                     39: {
                     40:        struct cmd_find_state    fs;
                     41:        struct hook             *hook;
                     42:        struct cmdq_item        *new_item;
                     43:        struct session          *s = ne->session;
                     44:        struct window           *w = ne->window;
                     45: 
                     46:        cmd_find_clear_state(&fs, NULL, 0);
                     47:        if (cmd_find_empty_state(&ne->fs) || !cmd_find_valid_state(&ne->fs))
                     48:                cmd_find_current(&fs, item, CMD_FIND_QUIET);
                     49:        else
                     50:                cmd_find_copy_state(&fs, &ne->fs);
                     51: 
                     52:        hook = hooks_find(hooks_get(fs.s), ne->name);
                     53:        if (hook == NULL)
                     54:                return;
                     55:        log_debug("notify hook %s", ne->name);
                     56: 
                     57:        new_item = cmdq_get_command(hook->cmdlist, &fs, NULL, CMDQ_NOHOOKS);
                     58:        cmdq_format(new_item, "hook", "%s", ne->name);
                     59: 
                     60:        if (s != NULL) {
                     61:                cmdq_format(new_item, "hook_session", "$%u", s->id);
                     62:                cmdq_format(new_item, "hook_session_name", "%s", s->name);
                     63:        }
                     64:        if (w != NULL) {
                     65:                cmdq_format(new_item, "hook_window", "@%u", w->id);
                     66:                cmdq_format(new_item, "hook_window_name", "%s", w->name);
                     67:        }
                     68:        if (ne->pane != -1)
                     69:                cmdq_format(new_item, "hook_pane", "%%%d", ne->pane);
                     70: 
                     71:        cmdq_insert_after(item, new_item);
                     72: }
                     73: 
                     74: static enum cmd_retval
                     75: notify_callback(struct cmdq_item *item, void *data)
                     76: {
                     77:        struct notify_entry     *ne = data;
                     78: 
                     79:        log_debug("%s: %s", __func__, ne->name);
                     80: 
                     81:        if (strcmp(ne->name, "window-layout-changed") == 0)
                     82:                control_notify_window_layout_changed(ne->window);
                     83:        if (strcmp(ne->name, "window-unlinked") == 0)
                     84:                control_notify_window_unlinked(ne->session, ne->window);
                     85:        if (strcmp(ne->name, "window-linked") == 0)
                     86:                control_notify_window_linked(ne->session, ne->window);
                     87:        if (strcmp(ne->name, "window-renamed") == 0)
                     88:                control_notify_window_renamed(ne->window);
                     89:        if (strcmp(ne->name, "client-session-changed") == 0)
                     90:                control_notify_client_session_changed(ne->client);
                     91:        if (strcmp(ne->name, "session-renamed") == 0)
                     92:                control_notify_session_renamed(ne->session);
                     93:        if (strcmp(ne->name, "session-created") == 0)
                     94:                control_notify_session_created(ne->session);
                     95:        if (strcmp(ne->name, "session-closed") == 0)
                     96:                control_notify_session_closed(ne->session);
                     97: 
                     98:        notify_hook(item, ne);
                     99: 
                    100:        if (ne->client != NULL)
                    101:                server_client_unref(ne->client);
                    102:        if (ne->session != NULL)
                    103:                session_unref(ne->session);
                    104:        if (ne->window != NULL)
                    105:                window_remove_ref(ne->window);
                    106: 
                    107:        if (ne->fs.s != NULL)
                    108:                session_unref(ne->fs.s);
                    109: 
                    110:        free((void *)ne->name);
                    111:        free(ne);
                    112: 
                    113:        return (CMD_RETURN_NORMAL);
                    114: }
                    115: 
                    116: static void
                    117: notify_add(const char *name, struct cmd_find_state *fs, struct client *c,
                    118:     struct session *s, struct window *w, struct window_pane *wp)
                    119: {
                    120:        struct notify_entry     *ne;
                    121:        struct cmdq_item        *new_item;
                    122: 
                    123:        ne = xcalloc(1, sizeof *ne);
                    124:        ne->name = xstrdup(name);
                    125: 
                    126:        ne->client = c;
                    127:        ne->session = s;
                    128:        ne->window = w;
                    129: 
                    130:        if (wp != NULL)
                    131:                ne->pane = wp->id;
                    132:        else
                    133:                ne->pane = -1;
                    134: 
                    135:        if (c != NULL)
                    136:                c->references++;
                    137:        if (s != NULL)
                    138:                s->references++;
                    139:        if (w != NULL)
                    140:                w->references++;
                    141: 
                    142:        cmd_find_copy_state(&ne->fs, fs);
                    143:        if (ne->fs.s != NULL)
                    144:                ne->fs.s->references++; /* cmd_find_valid_state need session */
                    145: 
                    146:        new_item = cmdq_get_callback(notify_callback, ne);
                    147:        cmdq_append(NULL, new_item);
                    148: }
                    149: 
                    150: void
                    151: notify_input(struct window_pane *wp, struct evbuffer *input)
                    152: {
                    153:        struct client   *c;
                    154: 
                    155:        TAILQ_FOREACH(c, &clients, entry) {
                    156:                if (c->flags & CLIENT_CONTROL)
                    157:                        control_notify_input(c, wp, input);
                    158:        }
                    159: }
                    160: 
                    161: void
                    162: notify_client(const char *name, struct client *c)
                    163: {
                    164:        struct cmd_find_state   fs;
                    165: 
                    166:        if (c->session != NULL)
                    167:                cmd_find_from_session(&fs, c->session);
                    168:        else
                    169:                cmd_find_current(&fs, NULL, CMD_FIND_QUIET);
                    170:        notify_add(name, &fs, c, NULL, NULL, NULL);
                    171: }
                    172: 
                    173: void
                    174: notify_session(const char *name, struct session *s)
                    175: {
                    176:        struct cmd_find_state   fs;
                    177: 
                    178:        if (session_alive(s))
                    179:                cmd_find_from_session(&fs, s);
                    180:        else
                    181:                cmd_find_current(&fs, NULL, CMD_FIND_QUIET);
                    182:        notify_add(name, &fs, NULL, s, NULL, NULL);
                    183: }
                    184: 
                    185: void
                    186: notify_winlink(const char *name, struct session *s, struct winlink *wl)
                    187: {
                    188:        struct cmd_find_state   fs;
                    189: 
                    190:        cmd_find_from_winlink(&fs, s, wl);
                    191:        notify_add(name, &fs, NULL, s, wl->window, NULL);
                    192: }
                    193: 
                    194: void
                    195: notify_session_window(const char *name, struct session *s, struct window *w)
                    196: {
                    197:        struct cmd_find_state   fs;
                    198: 
                    199:        cmd_find_from_session_window(&fs, s, w);
                    200:        notify_add(name, &fs, NULL, s, w, NULL);
                    201: }
                    202: 
                    203: void
                    204: notify_window(const char *name, struct window *w)
                    205: {
                    206:        struct cmd_find_state   fs;
                    207: 
                    208:        cmd_find_from_window(&fs, w);
                    209:        notify_add(name, &fs, NULL, NULL, w, NULL);
                    210: }
                    211: 
                    212: void
                    213: notify_pane(const char *name, struct window_pane *wp)
                    214: {
                    215:        struct cmd_find_state   fs;
                    216: 
                    217:        cmd_find_from_pane(&fs, wp);
                    218:        notify_add(name, &fs, NULL, NULL, NULL, wp);
                    219: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>