tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

screen.c
Go to the documentation of this file.
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2007 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 <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 
25 #include "tmux.h"
26 
27 /* Selected area in screen. */
28 struct screen_sel {
29  int hidden;
30  int rectangle;
31  int modekeys;
32 
33  u_int sx;
34  u_int sy;
35 
36  u_int ex;
37  u_int ey;
38 
39  struct grid_cell cell;
40 };
41 
42 /* Entry on title stack. */
44  char *text;
45 
46  TAILQ_ENTRY(screen_title_entry) entry;
47 };
49 
50 static void screen_resize_y(struct screen *, u_int, int, u_int *);
51 static void screen_reflow(struct screen *, u_int, u_int *, u_int *, int);
52 
53 /* Free titles stack. */
54 static void
56 {
57  struct screen_title_entry *title_entry;
58 
59  if (s->titles == NULL)
60  return;
61 
62  while ((title_entry = TAILQ_FIRST(s->titles)) != NULL) {
63  TAILQ_REMOVE(s->titles, title_entry, entry);
64  free(title_entry->text);
65  free(title_entry);
66  }
67 
68  free(s->titles);
69  s->titles = NULL;
70 }
71 
72 /* Create a new screen. */
73 void
74 screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
75 {
76  s->grid = grid_create(sx, sy, hlimit);
77  s->saved_grid = NULL;
78 
79  s->title = xstrdup("");
80  s->titles = NULL;
81  s->path = NULL;
82 
83  s->cstyle = 0;
84  s->ccolour = xstrdup("");
85  s->tabs = NULL;
86  s->sel = NULL;
87 
88  s->write_list = NULL;
89 
90  screen_reinit(s);
91 }
92 
93 /* Reinitialise screen. */
94 void
96 {
97  s->cx = 0;
98  s->cy = 0;
99 
100  s->rupper = 0;
101  s->rlower = screen_size_y(s) - 1;
102 
104  if (options_get_number(global_options, "extended-keys") == 2)
105  s->mode |= MODE_KEXTENDED;
106 
107  if (s->saved_grid != NULL)
108  screen_alternate_off(s, NULL, 0);
109  s->saved_cx = UINT_MAX;
110  s->saved_cy = UINT_MAX;
111 
113 
114  grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8);
115 
118 }
119 
120 /* Destroy a screen. */
121 void
122 screen_free(struct screen *s)
123 {
124  free(s->sel);
125  free(s->tabs);
126  free(s->path);
127  free(s->title);
128  free(s->ccolour);
129 
130  if (s->write_list != NULL)
132 
133  if (s->saved_grid != NULL)
135  grid_destroy(s->grid);
136 
138 }
139 
140 /* Reset tabs to default, eight spaces apart. */
141 void
143 {
144  u_int i;
145 
146  free(s->tabs);
147 
148  if ((s->tabs = bit_alloc(screen_size_x(s))) == NULL)
149  fatal("bit_alloc failed");
150  for (i = 8; i < screen_size_x(s); i += 8)
151  bit_set(s->tabs, i);
152 }
153 
154 /* Set screen cursor style. */
155 void
157 {
158  if (style <= 6) {
159  s->cstyle = style;
160  s->mode &= ~~MODE_BLINKING;
161  }
162 }
163 
164 /* Set screen cursor colour. */
165 void
166 screen_set_cursor_colour(struct screen *s, const char *colour)
167 {
168  free(s->ccolour);
169  s->ccolour = xstrdup(colour);
170 }
171 
172 /* Set screen title. */
173 int
174 screen_set_title(struct screen *s, const char *title)
175 {
176  if (!utf8_isvalid(title))
177  return (0);
178  free(s->title);
179  s->title = xstrdup(title);
180  return (1);
181 }
182 
183 /* Set screen path. */
184 void
185 screen_set_path(struct screen *s, const char *path)
186 {
187  free(s->path);
188  utf8_stravis(&s->path, path, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
189 }
190 
191 /* Push the current title onto the stack. */
192 void
194 {
195  struct screen_title_entry *title_entry;
196 
197  if (s->titles == NULL) {
198  s->titles = xmalloc(sizeof *s->titles);
199  TAILQ_INIT(s->titles);
200  }
201  title_entry = xmalloc(sizeof *title_entry);
202  title_entry->text = xstrdup(s->title);
203  TAILQ_INSERT_HEAD(s->titles, title_entry, entry);
204 }
205 
206 /*
207  * Pop a title from the stack and set it as the screen title. If the stack is
208  * empty, do nothing.
209  */
210 void
212 {
213  struct screen_title_entry *title_entry;
214 
215  if (s->titles == NULL)
216  return;
217 
218  title_entry = TAILQ_FIRST(s->titles);
219  if (title_entry != NULL) {
220  screen_set_title(s, title_entry->text);
221 
222  TAILQ_REMOVE(s->titles, title_entry, entry);
223  free(title_entry->text);
224  free(title_entry);
225  }
226 }
227 
228 /* Resize screen with options. */
229 void
230 screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
231  int eat_empty, int cursor)
232 {
233  u_int cx = s->cx, cy = s->grid->hsize + s->cy;
234 
235  if (s->write_list != NULL)
237 
238  log_debug("%s: new size %ux%u, now %ux%u (cursor %u,%u = %u,%u)",
239  __func__, sx, sy, screen_size_x(s), screen_size_y(s), s->cx, s->cy,
240  cx, cy);
241 
242  if (sx < 1)
243  sx = 1;
244  if (sy < 1)
245  sy = 1;
246 
247  if (sx != screen_size_x(s)) {
248  s->grid->sx = sx;
250  } else
251  reflow = 0;
252 
253  if (sy != screen_size_y(s))
254  screen_resize_y(s, sy, eat_empty, &cy);
255 
256  if (reflow)
257  screen_reflow(s, sx, &cx, &cy, cursor);
258 
259  if (cy >= s->grid->hsize) {
260  s->cx = cx;
261  s->cy = cy - s->grid->hsize;
262  } else {
263  s->cx = 0;
264  s->cy = 0;
265  }
266 
267  log_debug("%s: cursor finished at %u,%u = %u,%u", __func__, s->cx,
268  s->cy, cx, cy);
269 
270  if (s->write_list != NULL)
272 }
273 
274 /* Resize screen. */
275 void
276 screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
277 {
278  screen_resize_cursor(s, sx, sy, reflow, 1, 1);
279 }
280 
281 static void
282 screen_resize_y(struct screen *s, u_int sy, int eat_empty, u_int *cy)
283 {
284  struct grid *gd = s->grid;
285  u_int needed, available, oldy, i;
286 
287  if (sy == 0)
288  fatalx("zero size");
289  oldy = screen_size_y(s);
290 
291  /*
292  * When resizing:
293  *
294  * If the height is decreasing, delete lines from the bottom until
295  * hitting the cursor, then push lines from the top into the history.
296  *
297  * When increasing, pull as many lines as possible from scrolled
298  * history (not explicitly cleared from view) to the top, then fill the
299  * remaining with blanks at the bottom.
300  */
301 
302  /* Size decreasing. */
303  if (sy < oldy) {
304  needed = oldy - sy;
305 
306  /* Delete as many lines as possible from the bottom. */
307  if (eat_empty) {
308  available = oldy - 1 - s->cy;
309  if (available > 0) {
310  if (available > needed)
311  available = needed;
312  grid_view_delete_lines(gd, oldy - available,
313  available, 8);
314  }
315  needed -= available;
316  }
317 
318  /*
319  * Now just increase the history size, if possible, to take
320  * over the lines which are left. If history is off, delete
321  * lines from the top.
322  */
323  available = s->cy;
324  if (gd->flags & GRID_HISTORY) {
325  gd->hscrolled += needed;
326  gd->hsize += needed;
327  } else if (needed > 0 && available > 0) {
328  if (available > needed)
329  available = needed;
330  grid_view_delete_lines(gd, 0, available, 8);
331  (*cy) -= available;
332  }
333  }
334 
335  /* Resize line array. */
336  grid_adjust_lines(gd, gd->hsize + sy);
337 
338  /* Size increasing. */
339  if (sy > oldy) {
340  needed = sy - oldy;
341 
342  /*
343  * Try to pull as much as possible out of scrolled history, if
344  * is is enabled.
345  */
346  available = gd->hscrolled;
347  if (gd->flags & GRID_HISTORY && available > 0) {
348  if (available > needed)
349  available = needed;
350  gd->hscrolled -= available;
351  gd->hsize -= available;
352  } else
353  available = 0;
354  needed -= available;
355 
356  /* Then fill the rest in with blanks. */
357  for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++)
358  grid_empty_line(gd, i, 8);
359  }
360 
361  /* Set the new size, and reset the scroll region. */
362  gd->sy = sy;
363  s->rupper = 0;
364  s->rlower = screen_size_y(s) - 1;
365 }
366 
367 /* Set selection. */
368 void
369 screen_set_selection(struct screen *s, u_int sx, u_int sy,
370  u_int ex, u_int ey, u_int rectangle, int modekeys, struct grid_cell *gc)
371 {
372  if (s->sel == NULL)
373  s->sel = xcalloc(1, sizeof *s->sel);
374 
375  memcpy(&s->sel->cell, gc, sizeof s->sel->cell);
376  s->sel->hidden = 0;
377  s->sel->rectangle = rectangle;
378  s->sel->modekeys = modekeys;
379 
380  s->sel->sx = sx;
381  s->sel->sy = sy;
382  s->sel->ex = ex;
383  s->sel->ey = ey;
384 }
385 
386 /* Clear selection. */
387 void
389 {
390  free(s->sel);
391  s->sel = NULL;
392 }
393 
394 /* Hide selection. */
395 void
397 {
398  if (s->sel != NULL)
399  s->sel->hidden = 1;
400 }
401 
402 /* Check if cell in selection. */
403 int
404 screen_check_selection(struct screen *s, u_int px, u_int py)
405 {
406  struct screen_sel *sel = s->sel;
407  u_int xx;
408 
409  if (sel == NULL || sel->hidden)
410  return (0);
411 
412  if (sel->rectangle) {
413  if (sel->sy < sel->ey) {
414  /* start line < end line -- downward selection. */
415  if (py < sel->sy || py > sel->ey)
416  return (0);
417  } else if (sel->sy > sel->ey) {
418  /* start line > end line -- upward selection. */
419  if (py > sel->sy || py < sel->ey)
420  return (0);
421  } else {
422  /* starting line == ending line. */
423  if (py != sel->sy)
424  return (0);
425  }
426 
427  /*
428  * Need to include the selection start row, but not the cursor
429  * row, which means the selection changes depending on which
430  * one is on the left.
431  */
432  if (sel->ex < sel->sx) {
433  /* Cursor (ex) is on the left. */
434  if (px < sel->ex)
435  return (0);
436 
437  if (px > sel->sx)
438  return (0);
439  } else {
440  /* Selection start (sx) is on the left. */
441  if (px < sel->sx)
442  return (0);
443 
444  if (px > sel->ex)
445  return (0);
446  }
447  } else {
448  /*
449  * Like emacs, keep the top-left-most character, and drop the
450  * bottom-right-most, regardless of copy direction.
451  */
452  if (sel->sy < sel->ey) {
453  /* starting line < ending line -- downward selection. */
454  if (py < sel->sy || py > sel->ey)
455  return (0);
456 
457  if (py == sel->sy && px < sel->sx)
458  return (0);
459 
460  if (sel->modekeys == MODEKEY_EMACS)
461  xx = (sel->ex == 0 ? 0 : sel->ex - 1);
462  else
463  xx = sel->ex;
464  if (py == sel->ey && px > xx)
465  return (0);
466  } else if (sel->sy > sel->ey) {
467  /* starting line > ending line -- upward selection. */
468  if (py > sel->sy || py < sel->ey)
469  return (0);
470 
471  if (py == sel->ey && px < sel->ex)
472  return (0);
473 
474  if (sel->modekeys == MODEKEY_EMACS)
475  xx = sel->sx - 1;
476  else
477  xx = sel->sx;
478  if (py == sel->sy && (sel->sx == 0 || px > xx))
479  return (0);
480  } else {
481  /* starting line == ending line. */
482  if (py != sel->sy)
483  return (0);
484 
485  if (sel->ex < sel->sx) {
486  /* cursor (ex) is on the left */
487  if (sel->modekeys == MODEKEY_EMACS)
488  xx = sel->sx - 1;
489  else
490  xx = sel->sx;
491  if (px > xx || px < sel->ex)
492  return (0);
493  } else {
494  /* selection start (sx) is on the left */
495  if (sel->modekeys == MODEKEY_EMACS)
496  xx = (sel->ex == 0 ? 0 : sel->ex - 1);
497  else
498  xx = sel->ex;
499  if (px < sel->sx || px > xx)
500  return (0);
501  }
502  }
503  }
504 
505  return (1);
506 }
507 
508 /* Get selected grid cell. */
509 void
510 screen_select_cell(struct screen *s, struct grid_cell *dst,
511  const struct grid_cell *src)
512 {
513  if (s->sel == NULL || s->sel->hidden)
514  return;
515 
516  memcpy(dst, &s->sel->cell, sizeof *dst);
517 
518  utf8_copy(&dst->data, &src->data);
519  dst->attr = dst->attr & ~~GRID_ATTR_CHARSET;
520  dst->attr |= src->attr & GRID_ATTR_CHARSET;
521  dst->flags = src->flags;
522 }
523 
524 /* Reflow wrapped lines. */
525 static void
526 screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy, int cursor)
527 {
528  u_int wx, wy;
529 
530  if (cursor) {
531  grid_wrap_position(s->grid, *cx, *cy, &wx, &wy);
532  log_debug("%s: cursor %u,%u is %u,%u", __func__, *cx, *cy, wx,
533  wy);
534  }
535 
536  grid_reflow(s->grid, new_x);
537 
538  if (cursor) {
539  grid_unwrap_position(s->grid, cx, cy, wx, wy);
540  log_debug("%s: new cursor is %u,%u", __func__, *cx, *cy);
541  }
542  else {
543  *cx = 0;
544  *cy = s->grid->hsize;
545  }
546 }
547 
548 /*
549  * Enter alternative screen mode. A copy of the visible screen is saved and the
550  * history is not updated.
551  */
552 void
553 screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
554 {
555  u_int sx, sy;
556 
557  if (s->saved_grid != NULL)
558  return;
559  sx = screen_size_x(s);
560  sy = screen_size_y(s);
561 
562  s->saved_grid = grid_create(sx, sy, 0);
564  if (cursor) {
565  s->saved_cx = s->cx;
566  s->saved_cy = s->cy;
567  }
568  memcpy(&s->saved_cell, gc, sizeof s->saved_cell);
569 
570  grid_view_clear(s->grid, 0, 0, sx, sy, 8);
571 
572  s->saved_flags = s->grid->flags;
573  s->grid->flags &= ~~GRID_HISTORY;
574 }
575 
576 /* Exit alternate screen mode and restore the copied grid. */
577 void
578 screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
579 {
580  u_int sx = screen_size_x(s), sy = screen_size_y(s);
581 
582  /*
583  * If the current size is different, temporarily resize to the old size
584  * before copying back.
585  */
586  if (s->saved_grid != NULL)
587  screen_resize(s, s->saved_grid->sx, s->saved_grid->sy, 1);
588 
589  /*
590  * Restore the cursor position and cell. This happens even if not
591  * currently in the alternate screen.
592  */
593  if (cursor && s->saved_cx != UINT_MAX && s->saved_cy != UINT_MAX) {
594  s->cx = s->saved_cx;
595  s->cy = s->saved_cy;
596  if (gc != NULL)
597  memcpy(gc, &s->saved_cell, sizeof *gc);
598  }
599 
600  /* If not in the alternate screen, do nothing more. */
601  if (s->saved_grid == NULL) {
602  if (s->cx > screen_size_x(s) - 1)
603  s->cx = screen_size_x(s) - 1;
604  if (s->cy > screen_size_y(s) - 1)
605  s->cy = screen_size_y(s) - 1;
606  return;
607  }
608 
609  /* Restore the saved grid. */
611  s->saved_grid->sy);
612 
613  /*
614  * Turn history back on (so resize can use it) and then resize back to
615  * the current size.
616  */
617  if (s->saved_flags & GRID_HISTORY)
618  s->grid->flags |= GRID_HISTORY;
619  screen_resize(s, sx, sy, 1);
620 
622  s->saved_grid = NULL;
623 
624  if (s->cx > screen_size_x(s) - 1)
625  s->cx = screen_size_x(s) - 1;
626  if (s->cy > screen_size_y(s) - 1)
627  s->cy = screen_size_y(s) - 1;
628 }
void grid_view_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg)
Definition: grid-view.c:95
void grid_view_delete_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
Definition: grid-view.c:167
void grid_clear_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
Definition: grid.c:639
void grid_empty_line(struct grid *gd, u_int py, u_int bg)
Definition: grid.c:477
void grid_destroy(struct grid *gd)
Definition: grid.c:299
void grid_adjust_lines(struct grid *gd, u_int lines)
Definition: grid.c:188
void grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy, u_int ny)
Definition: grid.c:1024
struct grid * grid_create(u_int sx, u_int sy, u_int hlimit)
Definition: grid.c:272
void grid_reflow(struct grid *gd, u_int sx)
Definition: grid.c:1274
void grid_unwrap_position(struct grid *gd, u_int *px, u_int *py, u_int wx, u_int wy)
Definition: grid.c:1381
void grid_wrap_position(struct grid *gd, u_int px, u_int py, u_int *wx, u_int *wy)
Definition: grid.c:1359
void fatal(const char *msg,...)
Definition: log.c:144
void fatalx(const char *msg,...)
Definition: log.c:159
void log_debug(const char *msg,...)
Definition: log.c:130
long long options_get_number(struct options *oo, const char *name)
Definition: options.c:699
void screen_write_make_list(struct screen *s)
Definition: screen-write.c:213
void screen_write_free_list(struct screen *s)
Definition: screen-write.c:224
int screen_set_title(struct screen *s, const char *title)
Definition: screen.c:174
void screen_select_cell(struct screen *s, struct grid_cell *dst, const struct grid_cell *src)
Definition: screen.c:510
void screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
Definition: screen.c:553
void screen_clear_selection(struct screen *s)
Definition: screen.c:388
void screen_reset_tabs(struct screen *s)
Definition: screen.c:142
void screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow, int eat_empty, int cursor)
Definition: screen.c:230
void screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
Definition: screen.c:578
void screen_push_title(struct screen *s)
Definition: screen.c:193
TAILQ_HEAD(screen_titles, screen_title_entry)
static void screen_free_titles(struct screen *s)
Definition: screen.c:55
void screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
Definition: screen.c:276
void screen_set_cursor_style(struct screen *s, u_int style)
Definition: screen.c:156
void screen_hide_selection(struct screen *s)
Definition: screen.c:396
void screen_reinit(struct screen *s)
Definition: screen.c:95
void screen_pop_title(struct screen *s)
Definition: screen.c:211
void screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
Definition: screen.c:74
void screen_free(struct screen *s)
Definition: screen.c:122
void screen_set_cursor_colour(struct screen *s, const char *colour)
Definition: screen.c:166
void screen_set_path(struct screen *s, const char *path)
Definition: screen.c:185
void screen_set_selection(struct screen *s, u_int sx, u_int sy, u_int ex, u_int ey, u_int rectangle, int modekeys, struct grid_cell *gc)
Definition: screen.c:369
static void screen_reflow(struct screen *, u_int, u_int *, u_int *, int)
Definition: screen.c:526
static void screen_resize_y(struct screen *, u_int, int, u_int *)
Definition: screen.c:282
int screen_check_selection(struct screen *s, u_int px, u_int py)
Definition: screen.c:404
u_char flags
Definition: tmux.h:691
struct utf8_data data
Definition: tmux.h:689
u_short attr
Definition: tmux.h:690
Definition: tmux.h:734
u_int hsize
Definition: tmux.h:742
u_int sy
Definition: tmux.h:739
u_int hscrolled
Definition: tmux.h:741
int flags
Definition: tmux.h:735
u_int sx
Definition: tmux.h:738
struct grid_cell cell
Definition: screen.c:39
u_int ex
Definition: screen.c:36
int modekeys
Definition: screen.c:31
u_int sx
Definition: screen.c:33
int hidden
Definition: screen.c:29
int rectangle
Definition: screen.c:30
u_int ey
Definition: screen.c:37
u_int sy
Definition: screen.c:34
Definition: screen.c:43
char * text
Definition: screen.c:44
Definition: tmux.h:816
u_int saved_cx
Definition: tmux.h:834
u_int cy
Definition: tmux.h:824
struct grid_cell saved_cell
Definition: tmux.h:837
int mode
Definition: tmux.h:832
struct screen_sel * sel
Definition: tmux.h:841
int saved_flags
Definition: tmux.h:838
struct screen_titles * titles
Definition: tmux.h:819
struct screen_write_cline * write_list
Definition: tmux.h:843
u_int cx
Definition: tmux.h:823
char * title
Definition: tmux.h:817
struct grid * saved_grid
Definition: tmux.h:836
u_int saved_cy
Definition: tmux.h:835
bitstr_t * tabs
Definition: tmux.h:840
char * path
Definition: tmux.h:818
u_int rupper
Definition: tmux.h:829
u_int rlower
Definition: tmux.h:830
char * ccolour
Definition: tmux.h:827
u_int cstyle
Definition: tmux.h:826
struct grid * grid
Definition: tmux.h:821
Definition: tmux.h:799
struct options * global_options
Definition: tmux.c:36
#define GRID_ATTR_CHARSET
Definition: tmux.h:657
int utf8_isvalid(const char *)
Definition: utf8.c:380
void utf8_copy(struct utf8_data *, const struct utf8_data *)
Definition: utf8.c:203
#define screen_size_y(s)
Definition: tmux.h:882
#define MODE_CURSOR
Definition: tmux.h:598
int utf8_stravis(char **, const char *, int)
Definition: utf8.c:352
#define screen_size_x(s)
Definition: tmux.h:881
#define GRID_HISTORY
Definition: tmux.h:736
#define MODEKEY_EMACS
Definition: tmux.h:594
#define MODE_KEXTENDED
Definition: tmux.h:613
#define MODE_WRAP
Definition: tmux.h:602
#define screen_hsize(s)
Definition: tmux.h:883
void * xmalloc(size_t size)
Definition: xmalloc.c:27
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89