window-clock.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /* $OpenBSD$ */
  2. /*
  3. * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.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 <string.h>
  20. #include <time.h>
  21. #include "tmux.h"
  22. struct screen *window_clock_init(struct window_pane *);
  23. void window_clock_free(struct window_pane *);
  24. void window_clock_resize(struct window_pane *, u_int, u_int);
  25. void window_clock_key(struct window_pane *, struct client *,
  26. struct session *, key_code, struct mouse_event *);
  27. void window_clock_timer_callback(int, short, void *);
  28. void window_clock_draw_screen(struct window_pane *);
  29. const struct window_mode window_clock_mode = {
  30. window_clock_init,
  31. window_clock_free,
  32. window_clock_resize,
  33. window_clock_key,
  34. };
  35. struct window_clock_mode_data {
  36. struct screen screen;
  37. time_t tim;
  38. struct event timer;
  39. };
  40. const char window_clock_table[14][5][5] = {
  41. { { 1,1,1,1,1 }, /* 0 */
  42. { 1,0,0,0,1 },
  43. { 1,0,0,0,1 },
  44. { 1,0,0,0,1 },
  45. { 1,1,1,1,1 } },
  46. { { 0,0,0,0,1 }, /* 1 */
  47. { 0,0,0,0,1 },
  48. { 0,0,0,0,1 },
  49. { 0,0,0,0,1 },
  50. { 0,0,0,0,1 } },
  51. { { 1,1,1,1,1 }, /* 2 */
  52. { 0,0,0,0,1 },
  53. { 1,1,1,1,1 },
  54. { 1,0,0,0,0 },
  55. { 1,1,1,1,1 } },
  56. { { 1,1,1,1,1 }, /* 3 */
  57. { 0,0,0,0,1 },
  58. { 1,1,1,1,1 },
  59. { 0,0,0,0,1 },
  60. { 1,1,1,1,1 } },
  61. { { 1,0,0,0,1 }, /* 4 */
  62. { 1,0,0,0,1 },
  63. { 1,1,1,1,1 },
  64. { 0,0,0,0,1 },
  65. { 0,0,0,0,1 } },
  66. { { 1,1,1,1,1 }, /* 5 */
  67. { 1,0,0,0,0 },
  68. { 1,1,1,1,1 },
  69. { 0,0,0,0,1 },
  70. { 1,1,1,1,1 } },
  71. { { 1,1,1,1,1 }, /* 6 */
  72. { 1,0,0,0,0 },
  73. { 1,1,1,1,1 },
  74. { 1,0,0,0,1 },
  75. { 1,1,1,1,1 } },
  76. { { 1,1,1,1,1 }, /* 7 */
  77. { 0,0,0,0,1 },
  78. { 0,0,0,0,1 },
  79. { 0,0,0,0,1 },
  80. { 0,0,0,0,1 } },
  81. { { 1,1,1,1,1 }, /* 8 */
  82. { 1,0,0,0,1 },
  83. { 1,1,1,1,1 },
  84. { 1,0,0,0,1 },
  85. { 1,1,1,1,1 } },
  86. { { 1,1,1,1,1 }, /* 9 */
  87. { 1,0,0,0,1 },
  88. { 1,1,1,1,1 },
  89. { 0,0,0,0,1 },
  90. { 1,1,1,1,1 } },
  91. { { 0,0,0,0,0 }, /* : */
  92. { 0,0,1,0,0 },
  93. { 0,0,0,0,0 },
  94. { 0,0,1,0,0 },
  95. { 0,0,0,0,0 } },
  96. { { 1,1,1,1,1 }, /* A */
  97. { 1,0,0,0,1 },
  98. { 1,1,1,1,1 },
  99. { 1,0,0,0,1 },
  100. { 1,0,0,0,1 } },
  101. { { 1,1,1,1,1 }, /* P */
  102. { 1,0,0,0,1 },
  103. { 1,1,1,1,1 },
  104. { 1,0,0,0,0 },
  105. { 1,0,0,0,0 } },
  106. { { 1,0,0,0,1 }, /* M */
  107. { 1,1,0,1,1 },
  108. { 1,0,1,0,1 },
  109. { 1,0,0,0,1 },
  110. { 1,0,0,0,1 } },
  111. };
  112. void
  113. window_clock_timer_callback(__unused int fd, __unused short events, void *arg)
  114. {
  115. struct window_pane *wp = arg;
  116. struct window_clock_mode_data *data = wp->modedata;
  117. struct tm now, then;
  118. time_t t;
  119. struct timeval tv = { .tv_sec = 1 };
  120. evtimer_del(&data->timer);
  121. evtimer_add(&data->timer, &tv);
  122. t = time(NULL);
  123. gmtime_r(&t, &now);
  124. gmtime_r(&data->tim, &then);
  125. if (now.tm_min == then.tm_min)
  126. return;
  127. data->tim = t;
  128. window_clock_draw_screen(wp);
  129. server_redraw_window(wp->window);
  130. }
  131. struct screen *
  132. window_clock_init(struct window_pane *wp)
  133. {
  134. struct window_clock_mode_data *data;
  135. struct screen *s;
  136. struct timeval tv = { .tv_sec = 1 };
  137. wp->modedata = data = xmalloc(sizeof *data);
  138. data->tim = time(NULL);
  139. evtimer_set(&data->timer, window_clock_timer_callback, wp);
  140. evtimer_add(&data->timer, &tv);
  141. s = &data->screen;
  142. screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
  143. s->mode &= ~MODE_CURSOR;
  144. window_clock_draw_screen(wp);
  145. return (s);
  146. }
  147. void
  148. window_clock_free(struct window_pane *wp)
  149. {
  150. struct window_clock_mode_data *data = wp->modedata;
  151. evtimer_del(&data->timer);
  152. screen_free(&data->screen);
  153. free(data);
  154. }
  155. void
  156. window_clock_resize(struct window_pane *wp, u_int sx, u_int sy)
  157. {
  158. struct window_clock_mode_data *data = wp->modedata;
  159. struct screen *s = &data->screen;
  160. screen_resize(s, sx, sy, 0);
  161. window_clock_draw_screen(wp);
  162. }
  163. void
  164. window_clock_key(struct window_pane *wp, __unused struct client *c,
  165. __unused struct session *sess, __unused key_code key,
  166. __unused struct mouse_event *m)
  167. {
  168. window_pane_reset_mode(wp);
  169. }
  170. void
  171. window_clock_draw_screen(struct window_pane *wp)
  172. {
  173. struct window_clock_mode_data *data = wp->modedata;
  174. struct screen_write_ctx ctx;
  175. int colour, style;
  176. struct screen *s = &data->screen;
  177. struct grid_cell gc;
  178. char tim[64], *ptr;
  179. time_t t;
  180. struct tm *tm;
  181. u_int i, j, x, y, idx;
  182. colour = options_get_number(wp->window->options, "clock-mode-colour");
  183. style = options_get_number(wp->window->options, "clock-mode-style");
  184. screen_write_start(&ctx, NULL, s);
  185. t = time(NULL);
  186. tm = localtime(&t);
  187. if (style == 0) {
  188. strftime(tim, sizeof tim, "%l:%M ", localtime(&t));
  189. if (tm->tm_hour >= 12)
  190. strlcat(tim, "PM", sizeof tim);
  191. else
  192. strlcat(tim, "AM", sizeof tim);
  193. } else
  194. strftime(tim, sizeof tim, "%H:%M", tm);
  195. screen_write_clearscreen(&ctx);
  196. if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) {
  197. if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) {
  198. x = (screen_size_x(s) / 2) - (strlen(tim) / 2);
  199. y = screen_size_y(s) / 2;
  200. screen_write_cursormove(&ctx, x, y);
  201. memcpy(&gc, &grid_default_cell, sizeof gc);
  202. colour_set_fg(&gc, colour);
  203. screen_write_puts(&ctx, &gc, "%s", tim);
  204. }
  205. screen_write_stop(&ctx);
  206. return;
  207. }
  208. x = (screen_size_x(s) / 2) - 3 * strlen(tim);
  209. y = (screen_size_y(s) / 2) - 3;
  210. memcpy(&gc, &grid_default_cell, sizeof gc);
  211. colour_set_bg(&gc, colour);
  212. for (ptr = tim; *ptr != '\0'; ptr++) {
  213. if (*ptr >= '0' && *ptr <= '9')
  214. idx = *ptr - '0';
  215. else if (*ptr == ':')
  216. idx = 10;
  217. else if (*ptr == 'A')
  218. idx = 11;
  219. else if (*ptr == 'P')
  220. idx = 12;
  221. else if (*ptr == 'M')
  222. idx = 13;
  223. else {
  224. x += 6;
  225. continue;
  226. }
  227. for (j = 0; j < 5; j++) {
  228. for (i = 0; i < 5; i++) {
  229. screen_write_cursormove(&ctx, x + i, y + j);
  230. if (window_clock_table[idx][j][i])
  231. screen_write_putc(&ctx, &gc, ' ');
  232. }
  233. }
  234. x += 6;
  235. }
  236. screen_write_stop(&ctx);
  237. }