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

    1: /* $OpenBSD$ */
    2: 
    3: /*
    4:  * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.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 <ctype.h>
   22: #include <libgen.h>
   23: #include <stdlib.h>
   24: #include <string.h>
   25: 
   26: #include "tmux.h"
   27: 
   28: static void	 name_time_callback(int, short, void *);
   29: static int	 name_time_expired(struct window *, struct timeval *);
   30: 
   31: static char	*format_window_name(struct window *);
   32: 
   33: static void
   34: name_time_callback(__unused int fd, __unused short events, void *arg)
   35: {
   36: 	struct window	*w = arg;
   37: 
   38: 	/* The event loop will call check_window_name for us on the way out. */
   39: 	log_debug("@%u name timer expired", w->id);
   40: }
   41: 
   42: static int
   43: name_time_expired(struct window *w, struct timeval *tv)
   44: {
   45: 	struct timeval	offset;
   46: 
   47: 	timersub(tv, &w->name_time, &offset);
   48: 	if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL)
   49: 		return (0);
   50: 	return (NAME_INTERVAL - offset.tv_usec);
   51: }
   52: 
   53: void
   54: check_window_name(struct window *w)
   55: {
   56: 	struct timeval	 tv, next;
   57: 	char		*name;
   58: 	int		 left;
   59: 
   60: 	if (w->active == NULL)
   61: 		return;
   62: 
   63: 	if (!options_get_number(w->options, "automatic-rename"))
   64: 		return;
   65: 
   66: 	if (~w->active->flags & PANE_CHANGED) {
   67: 		log_debug("@%u active pane not changed", w->id);
   68: 		return;
   69: 	}
   70: 	log_debug("@%u active pane changed", w->id);
   71: 
   72: 	gettimeofday(&tv, NULL);
   73: 	left = name_time_expired(w, &tv);
   74: 	if (left != 0) {
   75: 		if (!event_initialized(&w->name_event))
   76: 			evtimer_set(&w->name_event, name_time_callback, w);
   77: 		if (!evtimer_pending(&w->name_event, NULL)) {
   78: 			log_debug("@%u name timer queued (%d left)", w->id,
   79: 			    left);
   80: 			timerclear(&next);
   81: 			next.tv_usec = left;
   82: 			event_add(&w->name_event, &next);
   83: 		} else {
   84: 			log_debug("@%u name timer already queued (%d left)",
   85: 			    w->id, left);
   86: 		}
   87: 		return;
   88: 	}
   89: 	memcpy(&w->name_time, &tv, sizeof w->name_time);
   90: 	if (event_initialized(&w->name_event))
   91: 		evtimer_del(&w->name_event);
   92: 
   93: 	w->active->flags &= ~PANE_CHANGED;
   94: 
   95: 	name = format_window_name(w);
   96: 	if (strcmp(name, w->name) != 0) {
   97: 		log_debug("@%u new name %s (was %s)", w->id, name, w->name);
   98: 		window_set_name(w, name);
   99: 		server_status_window(w);
  100: 	} else
  101: 		log_debug("@%u name not changed (still %s)", w->id, w->name);
  102: 
  103: 	free(name);
  104: }
  105: 
  106: char *
  107: default_window_name(struct window *w)
  108: {
  109: 	char    *cmd, *s;
  110: 
  111: 	cmd = cmd_stringify_argv(w->active->argc, w->active->argv);
  112: 	if (cmd != NULL && *cmd != '\0')
  113: 		s = parse_window_name(cmd);
  114: 	else
  115: 		s = parse_window_name(w->active->shell);
  116: 	free(cmd);
  117: 	return (s);
  118: }
  119: 
  120: static char *
  121: format_window_name(struct window *w)
  122: {
  123: 	struct format_tree	*ft;
  124: 	const char		*fmt;
  125: 	char			*name;
  126: 
  127: 	ft = format_create(NULL, FORMAT_WINDOW|w->id, 0);
  128: 	format_defaults_window(ft, w);
  129: 	format_defaults_pane(ft, w->active);
  130: 
  131: 	fmt = options_get_string(w->options, "automatic-rename-format");
  132: 	name = format_expand(ft, fmt);
  133: 
  134: 	format_free(ft);
  135: 	return (name);
  136: }
  137: 
  138: char *
  139: parse_window_name(const char *in)
  140: {
  141: 	char	*copy, *name, *ptr;
  142: 
  143: 	name = copy = xstrdup(in);
  144: 	if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0)
  145: 		name = name + (sizeof "exec ") - 1;
  146: 
  147: 	while (*name == ' ' || *name == '-')
  148: 		name++;
  149: 	if ((ptr = strchr(name, ' ')) != NULL)
  150: 		*ptr = '\0';
  151: 
  152: 	if (*name != '\0') {
  153: 		ptr = name + strlen(name) - 1;
  154: 		while (ptr > name && !isalnum((u_char)*ptr))
  155: 			*ptr-- = '\0';
  156: 	}
  157: 
  158: 	if (*name == '/')
  159: 		name = basename(name);
  160: 	name = xstrdup(name);
  161: 	free(copy);
  162: 	return (name);
  163: }

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