File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / tmux / notify.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:22:44 2017 UTC (7 years ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>