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

Diff for /src/usr.bin/tmux/alerts.c between version 1.13 and 1.14

version 1.13, 2016/10/16 22:18:04 version 1.14, 2016/10/19 09:22:07
Line 19 
Line 19 
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <event.h>  #include <event.h>
   #include <stdlib.h>
   
 #include "tmux.h"  #include "tmux.h"
   
Line 29 
Line 30 
 static void     alerts_callback(int, short, void *);  static void     alerts_callback(int, short, void *);
 static void     alerts_reset(struct window *);  static void     alerts_reset(struct window *);
   
 static void     alerts_run_hook(struct session *, struct winlink *, int);  static int      alerts_check_all(struct window *);
 static int      alerts_check_all(struct session *, struct winlink *);  static int      alerts_check_bell(struct window *);
 static int      alerts_check_bell(struct session *, struct winlink *);  static int      alerts_check_activity(struct window *);
 static int      alerts_check_activity(struct session *, struct winlink *);  static int      alerts_check_silence(struct window *);
 static int      alerts_check_silence(struct session *, struct winlink *);  static void printflike(2, 3) alerts_set_message(struct session *, const char *,
                       ...);
 static void     alerts_ring_bell(struct session *);  static void     alerts_ring_bell(struct session *);
   
   static TAILQ_HEAD(, window) alerts_list = TAILQ_HEAD_INITIALIZER(alerts_list);
   
 static void  static void
 alerts_timer(__unused int fd, __unused short events, void *arg)  alerts_timer(__unused int fd, __unused short events, void *arg)
 {  {
Line 49 
Line 53 
 static void  static void
 alerts_callback(__unused int fd, __unused short events, __unused void *arg)  alerts_callback(__unused int fd, __unused short events, __unused void *arg)
 {  {
         struct window   *w;          struct window   *w, *w1;
         struct session  *s;          int              alerts;
         struct winlink  *wl;  
         int              flags, alerts;  
   
         RB_FOREACH(w, windows, &windows) {          TAILQ_FOREACH_SAFE(w, &alerts_list, alerts_entry, w1) {
                 RB_FOREACH(s, sessions, &sessions) {                  alerts = alerts_check_all(w);
                         RB_FOREACH(wl, winlinks, &s->windows) {                  log_debug("@%u alerts check, alerts %#x", w->id, alerts);
                                 if (wl->window != w)  
                                         continue;  
                                 flags = w->flags;  
   
                                 alerts = alerts_check_all(s, wl);                  w->alerts_queued = 0;
                   TAILQ_REMOVE(&alerts_list, w, alerts_entry);
                                 log_debug("%s:%d @%u alerts check, alerts %#x, "                  window_remove_ref(w);
                                     "flags %#x", s->name, wl->idx, w->id,  
                                     alerts, flags);  
                         }  
                 }  
         }          }
         alerts_fired = 0;          alerts_fired = 0;
 }  }
   
 static void  
 alerts_run_hook(struct session *s, struct winlink *wl, int flags)  
 {  
         if (flags & WINDOW_BELL)  
                 notify_winlink("alert-bell", s, wl);  
         if (flags & WINDOW_SILENCE)  
                 notify_winlink("alert-silence", s, wl);  
         if (flags & WINDOW_ACTIVITY)  
                 notify_winlink("alert-activity", s, wl);  
 }  
   
 static int  static int
 alerts_check_all(struct session *s, struct winlink *wl)  alerts_check_all(struct window *w)
 {  {
         int     alerts;          int     alerts;
   
         alerts  = alerts_check_bell(s, wl);          alerts  = alerts_check_bell(w);
         alerts |= alerts_check_activity(s, wl);          alerts |= alerts_check_activity(w);
         alerts |= alerts_check_silence(s, wl);          alerts |= alerts_check_silence(w);
         if (alerts != 0) {  
                 alerts_run_hook(s, wl, alerts);  
                 server_status_session(s);  
         }  
   
         return (alerts);          return (alerts);
 }  }
   
Line 105 
Line 84 
         struct winlink  *wl;          struct winlink  *wl;
   
         RB_FOREACH(wl, winlinks, &s->windows)          RB_FOREACH(wl, winlinks, &s->windows)
                 alerts_check_all(s, wl);                  alerts_check_all(wl->window);
 }  }
   
 static int  static int
Line 163 
Line 142 
                 log_debug("@%u alerts flags added %#x", w->id, flags);                  log_debug("@%u alerts flags added %#x", w->id, flags);
         }          }
   
           if (!w->alerts_queued) {
                   w->alerts_queued = 1;
                   TAILQ_INSERT_TAIL(&alerts_list, w, alerts_entry);
                   w->references++;
           }
   
         if (!alerts_fired && alerts_enabled(w, flags)) {          if (!alerts_fired && alerts_enabled(w, flags)) {
                 log_debug("alerts check queued (by @%u)", w->id);                  log_debug("alerts check queued (by @%u)", w->id);
                 event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);                  event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);
Line 171 
Line 156 
 }  }
   
 static int  static int
 alerts_check_bell(struct session *s, struct winlink *wl)  alerts_check_bell(struct window *w)
 {  {
           struct window   *ws;
           struct winlink  *wl;
           struct session  *s;
         struct client   *c;          struct client   *c;
         struct window   *w = wl->window;  
         int              action, visual;          int              action, visual;
   
         if (!(w->flags & WINDOW_BELL))          if (~w->flags & WINDOW_BELL)
                 return (0);                  return (0);
         if (s->curw != wl) {  
                 wl->flags |= WINLINK_BELL;  
                 w->flags &= ~WINDOW_BELL;  
         }  
         if (s->curw->window == w)  
                 w->flags &= ~WINDOW_BELL;  
   
         action = options_get_number(s->options, "bell-action");          TAILQ_FOREACH(wl, &w->winlinks, wentry)
         if (action == BELL_NONE)                  wl->session->flags &= ~SESSION_ALERTED;
                 return (0);  
   
         visual = options_get_number(s->options, "visual-bell");          TAILQ_FOREACH(wl, &w->winlinks, wentry) {
         TAILQ_FOREACH(c, &clients, entry) {                  if (wl->flags & WINLINK_BELL)
                 if (c->session != s || c->flags & CLIENT_CONTROL)  
                         continue;                          continue;
                 if (!visual) {                  s = wl->session;
                         if ((action == BELL_CURRENT &&                  if (s->curw != wl) {
                             c->session->curw->window == w) ||                          wl->flags |= WINLINK_BELL;
                             (action == BELL_OTHER &&                          notify_winlink("alert-bell", s, wl);
                             c->session->curw->window != w) ||                  }
                             action == BELL_ANY)  
                                 tty_putcode(&c->tty, TTYC_BEL);                  if (s->flags & SESSION_ALERTED)
                         continue;                          continue;
                   s->flags |= SESSION_ALERTED;
   
                   action = options_get_number(s->options, "bell-action");
                   if (action == BELL_NONE)
                           return (0);
   
                   visual = options_get_number(s->options, "visual-bell");
                   TAILQ_FOREACH(c, &clients, entry) {
                           if (c->session != s || c->flags & CLIENT_CONTROL)
                                   continue;
                           ws = c->session->curw->window;
   
                           if (action == BELL_CURRENT && ws != w)
                                   action = BELL_NONE;
                           if (action == BELL_OTHER && ws != w)
                                   action = BELL_NONE;
   
                           if (!visual) {
                                   if (action != BELL_NONE)
                                           tty_putcode(&c->tty, TTYC_BEL);
                                   continue;
                           }
                           if (action == BELL_CURRENT)
                                   status_message_set(c, "Bell in current window");
                           else if (action != BELL_NONE) {
                                   status_message_set(c, "Bell in window %d",
                                       wl->idx);
                           }
                 }                  }
                 if (action == BELL_CURRENT && c->session->curw->window == w)  
                         status_message_set(c, "Bell in current window");  
                 else if (action == BELL_ANY || (action == BELL_OTHER &&  
                     c->session->curw->window != w))  
                         status_message_set(c, "Bell in window %d", wl->idx);  
         }          }
   
         return (WINDOW_BELL);          return (WINDOW_BELL);
 }  }
   
 static int  static int
 alerts_check_activity(struct session *s, struct winlink *wl)  alerts_check_activity(struct window *w)
 {  {
         struct client   *c;          struct winlink  *wl;
         struct window   *w = wl->window;          struct session  *s;
   
         if (s->curw->window == w)          if (~w->flags & WINDOW_ACTIVITY)
                 w->flags &= ~WINDOW_ACTIVITY;  
   
         if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)  
                 return (0);                  return (0);
         if (s->curw == wl)  
                 return (0);  
   
         if (!options_get_number(w->options, "monitor-activity"))          if (!options_get_number(w->options, "monitor-activity"))
                 return (0);                  return (0);
   
         if (options_get_number(s->options, "bell-on-alert"))          TAILQ_FOREACH(wl, &w->winlinks, wentry)
                 alerts_ring_bell(s);                  wl->session->flags &= ~SESSION_ALERTED;
         wl->flags |= WINLINK_ACTIVITY;  
   
         if (options_get_number(s->options, "visual-activity")) {          TAILQ_FOREACH(wl, &w->winlinks, wentry) {
                 TAILQ_FOREACH(c, &clients, entry) {                  if (wl->flags & WINLINK_ACTIVITY)
                         if (c->session != s)                          continue;
                                 continue;                  s = wl->session;
                         status_message_set(c, "Activity in window %d", wl->idx);                  if (s->curw != wl) {
                           wl->flags |= WINLINK_ACTIVITY;
                           notify_winlink("alert-activity", s, wl);
                 }                  }
   
                   if (s->flags & SESSION_ALERTED)
                           continue;
                   s->flags |= SESSION_ALERTED;
   
                   if (options_get_number(s->options, "bell-on-alert"))
                           alerts_ring_bell(s);
                   if (options_get_number(s->options, "visual-activity"))
                           alerts_set_message(s, "Activity in window %d", wl->idx);
         }          }
   
         return (WINDOW_ACTIVITY);          return (WINDOW_ACTIVITY);
 }  }
   
 static int  static int
 alerts_check_silence(struct session *s, struct winlink *wl)  alerts_check_silence(struct window *w)
 {  {
         struct client   *c;          struct winlink  *wl;
         struct window   *w = wl->window;          struct session  *s;
   
         if (s->curw->window == w)          if (~w->flags & WINDOW_SILENCE)
                 w->flags &= ~WINDOW_SILENCE;  
   
         if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)  
                 return (0);                  return (0);
         if (s->curw == wl)          if (!options_get_number(w->options, "monitor-silence"))
                 return (0);                  return (0);
   
         if (options_get_number(w->options, "monitor-silence") == 0)          TAILQ_FOREACH(wl, &w->winlinks, wentry)
                 return (0);                  wl->session->flags &= ~SESSION_ALERTED;
   
         if (options_get_number(s->options, "bell-on-alert"))          TAILQ_FOREACH(wl, &w->winlinks, wentry) {
                 alerts_ring_bell(s);                  if (wl->flags & WINLINK_SILENCE)
         wl->flags |= WINLINK_SILENCE;                          continue;
                   s = wl->session;
         if (options_get_number(s->options, "visual-silence")) {                  if (s->curw != wl) {
                 TAILQ_FOREACH(c, &clients, entry) {                          wl->flags |= WINLINK_SILENCE;
                         if (c->session != s)                          notify_winlink("alert-silence", s, wl);
                                 continue;  
                         status_message_set(c, "Silence in window %d", wl->idx);  
                 }                  }
   
                   if (s->flags & SESSION_ALERTED)
                           continue;
                   s->flags |= SESSION_ALERTED;
   
                   if (options_get_number(s->options, "bell-on-alert"))
                           alerts_ring_bell(s);
   
                   if (!options_get_number(s->options, "visual-silence"))
                           alerts_set_message(s, "Silence in window %d", wl->idx);
         }          }
   
         return (WINDOW_SILENCE);          return (WINDOW_SILENCE);
   }
   
   static void
   alerts_set_message(struct session *s, const char *fmt, ...)
   {
           struct client   *c;
           va_list          ap;
           char            *message;
   
           va_start(ap, fmt);
           xvasprintf(&message, fmt, ap);
           va_end(ap);
   
           TAILQ_FOREACH(c, &clients, entry) {
                   if (c->session == s)
                           status_message_set(c, "%s", message);
           }
   
           free(message);
 }  }
   
 static void  static void

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14