notify.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* $OpenBSD$ */
  2. /*
  3. * Copyright (c) 2012 George Nachman <tmux@georgester.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
  14. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  15. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/types.h>
  18. #include <stdlib.h>
  19. #include "tmux.h"
  20. enum notify_type {
  21. NOTIFY_WINDOW_LAYOUT_CHANGED,
  22. NOTIFY_WINDOW_UNLINKED,
  23. NOTIFY_WINDOW_LINKED,
  24. NOTIFY_WINDOW_RENAMED,
  25. NOTIFY_ATTACHED_SESSION_CHANGED,
  26. NOTIFY_SESSION_RENAMED,
  27. NOTIFY_SESSION_CREATED,
  28. NOTIFY_SESSION_CLOSED
  29. };
  30. struct notify_entry {
  31. enum notify_type type;
  32. struct client *client;
  33. struct session *session;
  34. struct window *window;
  35. TAILQ_ENTRY(notify_entry) entry;
  36. };
  37. TAILQ_HEAD(, notify_entry) notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue);
  38. int notify_enabled = 1;
  39. void notify_drain(void);
  40. void notify_add(enum notify_type, struct client *, struct session *,
  41. struct window *);
  42. void
  43. notify_enable(void)
  44. {
  45. notify_enabled = 1;
  46. notify_drain();
  47. }
  48. void
  49. notify_disable(void)
  50. {
  51. notify_enabled = 0;
  52. }
  53. void
  54. notify_add(enum notify_type type, struct client *c, struct session *s,
  55. struct window *w)
  56. {
  57. struct notify_entry *ne;
  58. ne = xcalloc(1, sizeof *ne);
  59. ne->type = type;
  60. ne->client = c;
  61. ne->session = s;
  62. ne->window = w;
  63. TAILQ_INSERT_TAIL(&notify_queue, ne, entry);
  64. if (c != NULL)
  65. c->references++;
  66. if (s != NULL)
  67. s->references++;
  68. if (w != NULL)
  69. w->references++;
  70. }
  71. void
  72. notify_drain(void)
  73. {
  74. struct notify_entry *ne, *ne1;
  75. if (!notify_enabled)
  76. return;
  77. TAILQ_FOREACH_SAFE(ne, &notify_queue, entry, ne1) {
  78. switch (ne->type) {
  79. case NOTIFY_WINDOW_LAYOUT_CHANGED:
  80. control_notify_window_layout_changed(ne->window);
  81. break;
  82. case NOTIFY_WINDOW_UNLINKED:
  83. control_notify_window_unlinked(ne->session, ne->window);
  84. break;
  85. case NOTIFY_WINDOW_LINKED:
  86. control_notify_window_linked(ne->session, ne->window);
  87. break;
  88. case NOTIFY_WINDOW_RENAMED:
  89. control_notify_window_renamed(ne->window);
  90. break;
  91. case NOTIFY_ATTACHED_SESSION_CHANGED:
  92. control_notify_attached_session_changed(ne->client);
  93. break;
  94. case NOTIFY_SESSION_RENAMED:
  95. control_notify_session_renamed(ne->session);
  96. break;
  97. case NOTIFY_SESSION_CREATED:
  98. control_notify_session_created(ne->session);
  99. break;
  100. case NOTIFY_SESSION_CLOSED:
  101. control_notify_session_close(ne->session);
  102. break;
  103. }
  104. if (ne->client != NULL)
  105. server_client_unref(ne->client);
  106. if (ne->session != NULL)
  107. session_unref(ne->session);
  108. if (ne->window != NULL)
  109. window_remove_ref(ne->window);
  110. TAILQ_REMOVE(&notify_queue, ne, entry);
  111. free(ne);
  112. }
  113. }
  114. void
  115. notify_input(struct window_pane *wp, struct evbuffer *input)
  116. {
  117. struct client *c;
  118. /*
  119. * notify_input() is not queued and only does anything when
  120. * notifications are enabled.
  121. */
  122. if (!notify_enabled)
  123. return;
  124. TAILQ_FOREACH(c, &clients, entry) {
  125. if (c->flags & CLIENT_CONTROL)
  126. control_notify_input(c, wp, input);
  127. }
  128. }
  129. void
  130. notify_window_layout_changed(struct window *w)
  131. {
  132. notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w);
  133. notify_drain();
  134. }
  135. void
  136. notify_window_unlinked(struct session *s, struct window *w)
  137. {
  138. notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w);
  139. notify_drain();
  140. }
  141. void
  142. notify_window_linked(struct session *s, struct window *w)
  143. {
  144. notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w);
  145. notify_drain();
  146. }
  147. void
  148. notify_window_renamed(struct window *w)
  149. {
  150. notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w);
  151. notify_drain();
  152. }
  153. void
  154. notify_attached_session_changed(struct client *c)
  155. {
  156. notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL);
  157. notify_drain();
  158. }
  159. void
  160. notify_session_renamed(struct session *s)
  161. {
  162. notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL);
  163. notify_drain();
  164. }
  165. void
  166. notify_session_created(struct session *s)
  167. {
  168. notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL);
  169. notify_drain();
  170. }
  171. void
  172. notify_session_closed(struct session *s)
  173. {
  174. notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL);
  175. notify_drain();
  176. }