Bug Summary

File:src/usr.bin/tmux/window.c
Warning:line 1133, column 46
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name window.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/tmux/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.bin/tmux -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/tmux/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.bin/tmux/window.c
1/* $OpenBSD: window.c,v 1.287 2023/10/23 08:12:00 nicm Exp $ */
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#include <sys/ioctl.h>
21
22#include <ctype.h>
23#include <errno(*__errno()).h>
24#include <fcntl.h>
25#include <fnmatch.h>
26#include <regex.h>
27#include <signal.h>
28#include <stdint.h>
29#include <stdlib.h>
30#include <string.h>
31#include <time.h>
32#include <unistd.h>
33#include <util.h>
34#include <vis.h>
35
36#include "tmux.h"
37
38/*
39 * Each window is attached to a number of panes, each of which is a pty. This
40 * file contains code to handle them.
41 *
42 * A pane has two buffers attached, these are filled and emptied by the main
43 * server poll loop. Output data is received from pty's in screen format,
44 * translated and returned as a series of escape sequences and strings via
45 * input_parse (in input.c). Input data is received as key codes and written
46 * directly via input_key.
47 *
48 * Each pane also has a "virtual" screen (screen.c) which contains the current
49 * state and is redisplayed when the window is reattached to a client.
50 *
51 * Windows are stored directly on a global array and wrapped in any number of
52 * winlink structs to be linked onto local session RB trees. A reference count
53 * is maintained and a window removed from the global list and destroyed when
54 * it reaches zero.
55 */
56
57/* Global window list. */
58struct windows windows;
59
60/* Global panes tree. */
61struct window_pane_tree all_window_panes;
62static u_int next_window_pane_id;
63static u_int next_window_id;
64static u_int next_active_point;
65
66struct window_pane_input_data {
67 struct cmdq_item *item;
68 u_int wp;
69 struct client_file *file;
70};
71
72static struct window_pane *window_pane_create(struct window *, u_int, u_int,
73 u_int);
74static void window_pane_destroy(struct window_pane *);
75
76RB_GENERATE(windows, window, entry, window_cmp)void windows_RB_INSERT_COLOR(struct windows *head, struct window
*elm) { struct window *parent, *gparent, *tmp; while ((parent
= (elm)->entry.rbe_parent) && (parent)->entry.
rbe_color == 1) { gparent = (parent)->entry.rbe_parent; if
(parent == (gparent)->entry.rbe_left) { tmp = (gparent)->
entry.rbe_right; if (tmp && (tmp)->entry.rbe_color
== 1) { (tmp)->entry.rbe_color = 0; do { (parent)->entry
.rbe_color = 0; (gparent)->entry.rbe_color = 1; } while (0
); elm = gparent; continue; } if ((parent)->entry.rbe_right
== elm) { do { (tmp) = (parent)->entry.rbe_right; if (((parent
)->entry.rbe_right = (tmp)->entry.rbe_left)) { ((tmp)->
entry.rbe_left)->entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->entry.rbe_parent = (parent)->entry.rbe_parent
)) { if ((parent) == ((parent)->entry.rbe_parent)->entry
.rbe_left) ((parent)->entry.rbe_parent)->entry.rbe_left
= (tmp); else ((parent)->entry.rbe_parent)->entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->entry
.rbe_left = (parent); (parent)->entry.rbe_parent = (tmp); do
{} while (0); if (((tmp)->entry.rbe_parent)) do {} while (
0); } while (0); tmp = parent; parent = elm; elm = tmp; } do {
(parent)->entry.rbe_color = 0; (gparent)->entry.rbe_color
= 1; } while (0); do { (tmp) = (gparent)->entry.rbe_left;
if (((gparent)->entry.rbe_left = (tmp)->entry.rbe_right
)) { ((tmp)->entry.rbe_right)->entry.rbe_parent = (gparent
); } do {} while (0); if (((tmp)->entry.rbe_parent = (gparent
)->entry.rbe_parent)) { if ((gparent) == ((gparent)->entry
.rbe_parent)->entry.rbe_left) ((gparent)->entry.rbe_parent
)->entry.rbe_left = (tmp); else ((gparent)->entry.rbe_parent
)->entry.rbe_right = (tmp); } else (head)->rbh_root = (
tmp); (tmp)->entry.rbe_right = (gparent); (gparent)->entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->entry.rbe_parent
)) do {} while (0); } while (0); } else { tmp = (gparent)->
entry.rbe_left; if (tmp && (tmp)->entry.rbe_color ==
1) { (tmp)->entry.rbe_color = 0; do { (parent)->entry.
rbe_color = 0; (gparent)->entry.rbe_color = 1; } while (0)
; elm = gparent; continue; } if ((parent)->entry.rbe_left ==
elm) { do { (tmp) = (parent)->entry.rbe_left; if (((parent
)->entry.rbe_left = (tmp)->entry.rbe_right)) { ((tmp)->
entry.rbe_right)->entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->entry.rbe_parent = (parent)->entry.rbe_parent
)) { if ((parent) == ((parent)->entry.rbe_parent)->entry
.rbe_left) ((parent)->entry.rbe_parent)->entry.rbe_left
= (tmp); else ((parent)->entry.rbe_parent)->entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->entry
.rbe_right = (parent); (parent)->entry.rbe_parent = (tmp);
do {} while (0); if (((tmp)->entry.rbe_parent)) do {} while
(0); } while (0); tmp = parent; parent = elm; elm = tmp; } do
{ (parent)->entry.rbe_color = 0; (gparent)->entry.rbe_color
= 1; } while (0); do { (tmp) = (gparent)->entry.rbe_right
; if (((gparent)->entry.rbe_right = (tmp)->entry.rbe_left
)) { ((tmp)->entry.rbe_left)->entry.rbe_parent = (gparent
); } do {} while (0); if (((tmp)->entry.rbe_parent = (gparent
)->entry.rbe_parent)) { if ((gparent) == ((gparent)->entry
.rbe_parent)->entry.rbe_left) ((gparent)->entry.rbe_parent
)->entry.rbe_left = (tmp); else ((gparent)->entry.rbe_parent
)->entry.rbe_right = (tmp); } else (head)->rbh_root = (
tmp); (tmp)->entry.rbe_left = (gparent); (gparent)->entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->entry.rbe_parent
)) do {} while (0); } while (0); } } (head->rbh_root)->
entry.rbe_color = 0; } void windows_RB_REMOVE_COLOR(struct windows
*head, struct window *parent, struct window *elm) { struct window
*tmp; while ((elm == ((void *)0) || (elm)->entry.rbe_color
== 0) && elm != (head)->rbh_root) { if ((parent)->
entry.rbe_left == elm) { tmp = (parent)->entry.rbe_right; if
((tmp)->entry.rbe_color == 1) { do { (tmp)->entry.rbe_color
= 0; (parent)->entry.rbe_color = 1; } while (0); do { (tmp
) = (parent)->entry.rbe_right; if (((parent)->entry.rbe_right
= (tmp)->entry.rbe_left)) { ((tmp)->entry.rbe_left)->
entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->
entry.rbe_parent = (parent)->entry.rbe_parent)) { if ((parent
) == ((parent)->entry.rbe_parent)->entry.rbe_left) ((parent
)->entry.rbe_parent)->entry.rbe_left = (tmp); else ((parent
)->entry.rbe_parent)->entry.rbe_right = (tmp); } else (
head)->rbh_root = (tmp); (tmp)->entry.rbe_left = (parent
); (parent)->entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->entry.rbe_parent)) do {} while (0); } while (0);
tmp = (parent)->entry.rbe_right; } if (((tmp)->entry.rbe_left
== ((void *)0) || ((tmp)->entry.rbe_left)->entry.rbe_color
== 0) && ((tmp)->entry.rbe_right == ((void *)0) ||
((tmp)->entry.rbe_right)->entry.rbe_color == 0)) { (tmp
)->entry.rbe_color = 1; elm = parent; parent = (elm)->entry
.rbe_parent; } else { if ((tmp)->entry.rbe_right == ((void
*)0) || ((tmp)->entry.rbe_right)->entry.rbe_color == 0
) { struct window *oleft; if ((oleft = (tmp)->entry.rbe_left
)) (oleft)->entry.rbe_color = 0; (tmp)->entry.rbe_color
= 1; do { (oleft) = (tmp)->entry.rbe_left; if (((tmp)->
entry.rbe_left = (oleft)->entry.rbe_right)) { ((oleft)->
entry.rbe_right)->entry.rbe_parent = (tmp); } do {} while (
0); if (((oleft)->entry.rbe_parent = (tmp)->entry.rbe_parent
)) { if ((tmp) == ((tmp)->entry.rbe_parent)->entry.rbe_left
) ((tmp)->entry.rbe_parent)->entry.rbe_left = (oleft); else
((tmp)->entry.rbe_parent)->entry.rbe_right = (oleft); }
else (head)->rbh_root = (oleft); (oleft)->entry.rbe_right
= (tmp); (tmp)->entry.rbe_parent = (oleft); do {} while (
0); if (((oleft)->entry.rbe_parent)) do {} while (0); } while
(0); tmp = (parent)->entry.rbe_right; } (tmp)->entry.rbe_color
= (parent)->entry.rbe_color; (parent)->entry.rbe_color
= 0; if ((tmp)->entry.rbe_right) ((tmp)->entry.rbe_right
)->entry.rbe_color = 0; do { (tmp) = (parent)->entry.rbe_right
; if (((parent)->entry.rbe_right = (tmp)->entry.rbe_left
)) { ((tmp)->entry.rbe_left)->entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->entry.rbe_parent = (parent
)->entry.rbe_parent)) { if ((parent) == ((parent)->entry
.rbe_parent)->entry.rbe_left) ((parent)->entry.rbe_parent
)->entry.rbe_left = (tmp); else ((parent)->entry.rbe_parent
)->entry.rbe_right = (tmp); } else (head)->rbh_root = (
tmp); (tmp)->entry.rbe_left = (parent); (parent)->entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->entry.rbe_parent
)) do {} while (0); } while (0); elm = (head)->rbh_root; break
; } } else { tmp = (parent)->entry.rbe_left; if ((tmp)->
entry.rbe_color == 1) { do { (tmp)->entry.rbe_color = 0; (
parent)->entry.rbe_color = 1; } while (0); do { (tmp) = (parent
)->entry.rbe_left; if (((parent)->entry.rbe_left = (tmp
)->entry.rbe_right)) { ((tmp)->entry.rbe_right)->entry
.rbe_parent = (parent); } do {} while (0); if (((tmp)->entry
.rbe_parent = (parent)->entry.rbe_parent)) { if ((parent) ==
((parent)->entry.rbe_parent)->entry.rbe_left) ((parent
)->entry.rbe_parent)->entry.rbe_left = (tmp); else ((parent
)->entry.rbe_parent)->entry.rbe_right = (tmp); } else (
head)->rbh_root = (tmp); (tmp)->entry.rbe_right = (parent
); (parent)->entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->entry.rbe_parent)) do {} while (0); } while (0);
tmp = (parent)->entry.rbe_left; } if (((tmp)->entry.rbe_left
== ((void *)0) || ((tmp)->entry.rbe_left)->entry.rbe_color
== 0) && ((tmp)->entry.rbe_right == ((void *)0) ||
((tmp)->entry.rbe_right)->entry.rbe_color == 0)) { (tmp
)->entry.rbe_color = 1; elm = parent; parent = (elm)->entry
.rbe_parent; } else { if ((tmp)->entry.rbe_left == ((void *
)0) || ((tmp)->entry.rbe_left)->entry.rbe_color == 0) {
struct window *oright; if ((oright = (tmp)->entry.rbe_right
)) (oright)->entry.rbe_color = 0; (tmp)->entry.rbe_color
= 1; do { (oright) = (tmp)->entry.rbe_right; if (((tmp)->
entry.rbe_right = (oright)->entry.rbe_left)) { ((oright)->
entry.rbe_left)->entry.rbe_parent = (tmp); } do {} while (
0); if (((oright)->entry.rbe_parent = (tmp)->entry.rbe_parent
)) { if ((tmp) == ((tmp)->entry.rbe_parent)->entry.rbe_left
) ((tmp)->entry.rbe_parent)->entry.rbe_left = (oright);
else ((tmp)->entry.rbe_parent)->entry.rbe_right = (oright
); } else (head)->rbh_root = (oright); (oright)->entry.
rbe_left = (tmp); (tmp)->entry.rbe_parent = (oright); do {
} while (0); if (((oright)->entry.rbe_parent)) do {} while
(0); } while (0); tmp = (parent)->entry.rbe_left; } (tmp)
->entry.rbe_color = (parent)->entry.rbe_color; (parent)
->entry.rbe_color = 0; if ((tmp)->entry.rbe_left) ((tmp
)->entry.rbe_left)->entry.rbe_color = 0; do { (tmp) = (
parent)->entry.rbe_left; if (((parent)->entry.rbe_left =
(tmp)->entry.rbe_right)) { ((tmp)->entry.rbe_right)->
entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->
entry.rbe_parent = (parent)->entry.rbe_parent)) { if ((parent
) == ((parent)->entry.rbe_parent)->entry.rbe_left) ((parent
)->entry.rbe_parent)->entry.rbe_left = (tmp); else ((parent
)->entry.rbe_parent)->entry.rbe_right = (tmp); } else (
head)->rbh_root = (tmp); (tmp)->entry.rbe_right = (parent
); (parent)->entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->entry.rbe_parent)) do {} while (0); } while (0);
elm = (head)->rbh_root; break; } } } if (elm) (elm)->entry
.rbe_color = 0; } struct window * windows_RB_REMOVE(struct windows
*head, struct window *elm) { struct window *child, *parent, *
old = elm; int color; if ((elm)->entry.rbe_left == ((void *
)0)) child = (elm)->entry.rbe_right; else if ((elm)->entry
.rbe_right == ((void *)0)) child = (elm)->entry.rbe_left; else
{ struct window *left; elm = (elm)->entry.rbe_right; while
((left = (elm)->entry.rbe_left)) elm = left; child = (elm
)->entry.rbe_right; parent = (elm)->entry.rbe_parent; color
= (elm)->entry.rbe_color; if (child) (child)->entry.rbe_parent
= parent; if (parent) { if ((parent)->entry.rbe_left == elm
) (parent)->entry.rbe_left = child; else (parent)->entry
.rbe_right = child; do {} while (0); } else (head)->rbh_root
= child; if ((elm)->entry.rbe_parent == old) parent = elm
; (elm)->entry = (old)->entry; if ((old)->entry.rbe_parent
) { if (((old)->entry.rbe_parent)->entry.rbe_left == old
) ((old)->entry.rbe_parent)->entry.rbe_left = elm; else
((old)->entry.rbe_parent)->entry.rbe_right = elm; do {
} while (0); } else (head)->rbh_root = elm; ((old)->entry
.rbe_left)->entry.rbe_parent = elm; if ((old)->entry.rbe_right
) ((old)->entry.rbe_right)->entry.rbe_parent = elm; if (
parent) { left = parent; do { do {} while (0); } while ((left
= (left)->entry.rbe_parent)); } goto color; } parent = (elm
)->entry.rbe_parent; color = (elm)->entry.rbe_color; if
(child) (child)->entry.rbe_parent = parent; if (parent) {
if ((parent)->entry.rbe_left == elm) (parent)->entry.rbe_left
= child; else (parent)->entry.rbe_right = child; do {} while
(0); } else (head)->rbh_root = child; color: if (color ==
0) windows_RB_REMOVE_COLOR(head, parent, child); return (old
); } struct window * windows_RB_INSERT(struct windows *head, struct
window *elm) { struct window *tmp; struct window *parent = (
(void *)0); int comp = 0; tmp = (head)->rbh_root; while (tmp
) { parent = tmp; comp = (window_cmp)(elm, parent); if (comp <
0) tmp = (tmp)->entry.rbe_left; else if (comp > 0) tmp
= (tmp)->entry.rbe_right; else return (tmp); } do { (elm)
->entry.rbe_parent = parent; (elm)->entry.rbe_left = (elm
)->entry.rbe_right = ((void *)0); (elm)->entry.rbe_color
= 1; } while (0); if (parent != ((void *)0)) { if (comp <
0) (parent)->entry.rbe_left = elm; else (parent)->entry
.rbe_right = elm; do {} while (0); } else (head)->rbh_root
= elm; windows_RB_INSERT_COLOR(head, elm); return (((void *)
0)); } struct window * windows_RB_FIND(struct windows *head, struct
window *elm) { struct window *tmp = (head)->rbh_root; int
comp; while (tmp) { comp = window_cmp(elm, tmp); if (comp <
0) tmp = (tmp)->entry.rbe_left; else if (comp > 0) tmp
= (tmp)->entry.rbe_right; else return (tmp); } return (((
void *)0)); } struct window * windows_RB_NFIND(struct windows
*head, struct window *elm) { struct window *tmp = (head)->
rbh_root; struct window *res = ((void *)0); int comp; while (
tmp) { comp = window_cmp(elm, tmp); if (comp < 0) { res = tmp
; tmp = (tmp)->entry.rbe_left; } else if (comp > 0) tmp
= (tmp)->entry.rbe_right; else return (tmp); } return (res
); } struct window * windows_RB_NEXT(struct window *elm) { if
((elm)->entry.rbe_right) { elm = (elm)->entry.rbe_right
; while ((elm)->entry.rbe_left) elm = (elm)->entry.rbe_left
; } else { if ((elm)->entry.rbe_parent && (elm == (
(elm)->entry.rbe_parent)->entry.rbe_left)) elm = (elm)->
entry.rbe_parent; else { while ((elm)->entry.rbe_parent &&
(elm == ((elm)->entry.rbe_parent)->entry.rbe_right)) elm
= (elm)->entry.rbe_parent; elm = (elm)->entry.rbe_parent
; } } return (elm); } struct window * windows_RB_PREV(struct window
*elm) { if ((elm)->entry.rbe_left) { elm = (elm)->entry
.rbe_left; while ((elm)->entry.rbe_right) elm = (elm)->
entry.rbe_right; } else { if ((elm)->entry.rbe_parent &&
(elm == ((elm)->entry.rbe_parent)->entry.rbe_right)) elm
= (elm)->entry.rbe_parent; else { while ((elm)->entry.
rbe_parent && (elm == ((elm)->entry.rbe_parent)->
entry.rbe_left)) elm = (elm)->entry.rbe_parent; elm = (elm
)->entry.rbe_parent; } } return (elm); } struct window * windows_RB_MINMAX
(struct windows *head, int val) { struct window *tmp = (head)
->rbh_root; struct window *parent = ((void *)0); while (tmp
) { parent = tmp; if (val < 0) tmp = (tmp)->entry.rbe_left
; else tmp = (tmp)->entry.rbe_right; } return (parent); }
;
77RB_GENERATE(winlinks, winlink, entry, winlink_cmp)void winlinks_RB_INSERT_COLOR(struct winlinks *head, struct winlink
*elm) { struct winlink *parent, *gparent, *tmp; while ((parent
= (elm)->entry.rbe_parent) && (parent)->entry.
rbe_color == 1) { gparent = (parent)->entry.rbe_parent; if
(parent == (gparent)->entry.rbe_left) { tmp = (gparent)->
entry.rbe_right; if (tmp && (tmp)->entry.rbe_color
== 1) { (tmp)->entry.rbe_color = 0; do { (parent)->entry
.rbe_color = 0; (gparent)->entry.rbe_color = 1; } while (0
); elm = gparent; continue; } if ((parent)->entry.rbe_right
== elm) { do { (tmp) = (parent)->entry.rbe_right; if (((parent
)->entry.rbe_right = (tmp)->entry.rbe_left)) { ((tmp)->
entry.rbe_left)->entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->entry.rbe_parent = (parent)->entry.rbe_parent
)) { if ((parent) == ((parent)->entry.rbe_parent)->entry
.rbe_left) ((parent)->entry.rbe_parent)->entry.rbe_left
= (tmp); else ((parent)->entry.rbe_parent)->entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->entry
.rbe_left = (parent); (parent)->entry.rbe_parent = (tmp); do
{} while (0); if (((tmp)->entry.rbe_parent)) do {} while (
0); } while (0); tmp = parent; parent = elm; elm = tmp; } do {
(parent)->entry.rbe_color = 0; (gparent)->entry.rbe_color
= 1; } while (0); do { (tmp) = (gparent)->entry.rbe_left;
if (((gparent)->entry.rbe_left = (tmp)->entry.rbe_right
)) { ((tmp)->entry.rbe_right)->entry.rbe_parent = (gparent
); } do {} while (0); if (((tmp)->entry.rbe_parent = (gparent
)->entry.rbe_parent)) { if ((gparent) == ((gparent)->entry
.rbe_parent)->entry.rbe_left) ((gparent)->entry.rbe_parent
)->entry.rbe_left = (tmp); else ((gparent)->entry.rbe_parent
)->entry.rbe_right = (tmp); } else (head)->rbh_root = (
tmp); (tmp)->entry.rbe_right = (gparent); (gparent)->entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->entry.rbe_parent
)) do {} while (0); } while (0); } else { tmp = (gparent)->
entry.rbe_left; if (tmp && (tmp)->entry.rbe_color ==
1) { (tmp)->entry.rbe_color = 0; do { (parent)->entry.
rbe_color = 0; (gparent)->entry.rbe_color = 1; } while (0)
; elm = gparent; continue; } if ((parent)->entry.rbe_left ==
elm) { do { (tmp) = (parent)->entry.rbe_left; if (((parent
)->entry.rbe_left = (tmp)->entry.rbe_right)) { ((tmp)->
entry.rbe_right)->entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->entry.rbe_parent = (parent)->entry.rbe_parent
)) { if ((parent) == ((parent)->entry.rbe_parent)->entry
.rbe_left) ((parent)->entry.rbe_parent)->entry.rbe_left
= (tmp); else ((parent)->entry.rbe_parent)->entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->entry
.rbe_right = (parent); (parent)->entry.rbe_parent = (tmp);
do {} while (0); if (((tmp)->entry.rbe_parent)) do {} while
(0); } while (0); tmp = parent; parent = elm; elm = tmp; } do
{ (parent)->entry.rbe_color = 0; (gparent)->entry.rbe_color
= 1; } while (0); do { (tmp) = (gparent)->entry.rbe_right
; if (((gparent)->entry.rbe_right = (tmp)->entry.rbe_left
)) { ((tmp)->entry.rbe_left)->entry.rbe_parent = (gparent
); } do {} while (0); if (((tmp)->entry.rbe_parent = (gparent
)->entry.rbe_parent)) { if ((gparent) == ((gparent)->entry
.rbe_parent)->entry.rbe_left) ((gparent)->entry.rbe_parent
)->entry.rbe_left = (tmp); else ((gparent)->entry.rbe_parent
)->entry.rbe_right = (tmp); } else (head)->rbh_root = (
tmp); (tmp)->entry.rbe_left = (gparent); (gparent)->entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->entry.rbe_parent
)) do {} while (0); } while (0); } } (head->rbh_root)->
entry.rbe_color = 0; } void winlinks_RB_REMOVE_COLOR(struct winlinks
*head, struct winlink *parent, struct winlink *elm) { struct
winlink *tmp; while ((elm == ((void *)0) || (elm)->entry.
rbe_color == 0) && elm != (head)->rbh_root) { if (
(parent)->entry.rbe_left == elm) { tmp = (parent)->entry
.rbe_right; if ((tmp)->entry.rbe_color == 1) { do { (tmp)->
entry.rbe_color = 0; (parent)->entry.rbe_color = 1; } while
(0); do { (tmp) = (parent)->entry.rbe_right; if (((parent
)->entry.rbe_right = (tmp)->entry.rbe_left)) { ((tmp)->
entry.rbe_left)->entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->entry.rbe_parent = (parent)->entry.rbe_parent
)) { if ((parent) == ((parent)->entry.rbe_parent)->entry
.rbe_left) ((parent)->entry.rbe_parent)->entry.rbe_left
= (tmp); else ((parent)->entry.rbe_parent)->entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->entry
.rbe_left = (parent); (parent)->entry.rbe_parent = (tmp); do
{} while (0); if (((tmp)->entry.rbe_parent)) do {} while (
0); } while (0); tmp = (parent)->entry.rbe_right; } if (((
tmp)->entry.rbe_left == ((void *)0) || ((tmp)->entry.rbe_left
)->entry.rbe_color == 0) && ((tmp)->entry.rbe_right
== ((void *)0) || ((tmp)->entry.rbe_right)->entry.rbe_color
== 0)) { (tmp)->entry.rbe_color = 1; elm = parent; parent
= (elm)->entry.rbe_parent; } else { if ((tmp)->entry.rbe_right
== ((void *)0) || ((tmp)->entry.rbe_right)->entry.rbe_color
== 0) { struct winlink *oleft; if ((oleft = (tmp)->entry.
rbe_left)) (oleft)->entry.rbe_color = 0; (tmp)->entry.rbe_color
= 1; do { (oleft) = (tmp)->entry.rbe_left; if (((tmp)->
entry.rbe_left = (oleft)->entry.rbe_right)) { ((oleft)->
entry.rbe_right)->entry.rbe_parent = (tmp); } do {} while (
0); if (((oleft)->entry.rbe_parent = (tmp)->entry.rbe_parent
)) { if ((tmp) == ((tmp)->entry.rbe_parent)->entry.rbe_left
) ((tmp)->entry.rbe_parent)->entry.rbe_left = (oleft); else
((tmp)->entry.rbe_parent)->entry.rbe_right = (oleft); }
else (head)->rbh_root = (oleft); (oleft)->entry.rbe_right
= (tmp); (tmp)->entry.rbe_parent = (oleft); do {} while (
0); if (((oleft)->entry.rbe_parent)) do {} while (0); } while
(0); tmp = (parent)->entry.rbe_right; } (tmp)->entry.rbe_color
= (parent)->entry.rbe_color; (parent)->entry.rbe_color
= 0; if ((tmp)->entry.rbe_right) ((tmp)->entry.rbe_right
)->entry.rbe_color = 0; do { (tmp) = (parent)->entry.rbe_right
; if (((parent)->entry.rbe_right = (tmp)->entry.rbe_left
)) { ((tmp)->entry.rbe_left)->entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->entry.rbe_parent = (parent
)->entry.rbe_parent)) { if ((parent) == ((parent)->entry
.rbe_parent)->entry.rbe_left) ((parent)->entry.rbe_parent
)->entry.rbe_left = (tmp); else ((parent)->entry.rbe_parent
)->entry.rbe_right = (tmp); } else (head)->rbh_root = (
tmp); (tmp)->entry.rbe_left = (parent); (parent)->entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->entry.rbe_parent
)) do {} while (0); } while (0); elm = (head)->rbh_root; break
; } } else { tmp = (parent)->entry.rbe_left; if ((tmp)->
entry.rbe_color == 1) { do { (tmp)->entry.rbe_color = 0; (
parent)->entry.rbe_color = 1; } while (0); do { (tmp) = (parent
)->entry.rbe_left; if (((parent)->entry.rbe_left = (tmp
)->entry.rbe_right)) { ((tmp)->entry.rbe_right)->entry
.rbe_parent = (parent); } do {} while (0); if (((tmp)->entry
.rbe_parent = (parent)->entry.rbe_parent)) { if ((parent) ==
((parent)->entry.rbe_parent)->entry.rbe_left) ((parent
)->entry.rbe_parent)->entry.rbe_left = (tmp); else ((parent
)->entry.rbe_parent)->entry.rbe_right = (tmp); } else (
head)->rbh_root = (tmp); (tmp)->entry.rbe_right = (parent
); (parent)->entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->entry.rbe_parent)) do {} while (0); } while (0);
tmp = (parent)->entry.rbe_left; } if (((tmp)->entry.rbe_left
== ((void *)0) || ((tmp)->entry.rbe_left)->entry.rbe_color
== 0) && ((tmp)->entry.rbe_right == ((void *)0) ||
((tmp)->entry.rbe_right)->entry.rbe_color == 0)) { (tmp
)->entry.rbe_color = 1; elm = parent; parent = (elm)->entry
.rbe_parent; } else { if ((tmp)->entry.rbe_left == ((void *
)0) || ((tmp)->entry.rbe_left)->entry.rbe_color == 0) {
struct winlink *oright; if ((oright = (tmp)->entry.rbe_right
)) (oright)->entry.rbe_color = 0; (tmp)->entry.rbe_color
= 1; do { (oright) = (tmp)->entry.rbe_right; if (((tmp)->
entry.rbe_right = (oright)->entry.rbe_left)) { ((oright)->
entry.rbe_left)->entry.rbe_parent = (tmp); } do {} while (
0); if (((oright)->entry.rbe_parent = (tmp)->entry.rbe_parent
)) { if ((tmp) == ((tmp)->entry.rbe_parent)->entry.rbe_left
) ((tmp)->entry.rbe_parent)->entry.rbe_left = (oright);
else ((tmp)->entry.rbe_parent)->entry.rbe_right = (oright
); } else (head)->rbh_root = (oright); (oright)->entry.
rbe_left = (tmp); (tmp)->entry.rbe_parent = (oright); do {
} while (0); if (((oright)->entry.rbe_parent)) do {} while
(0); } while (0); tmp = (parent)->entry.rbe_left; } (tmp)
->entry.rbe_color = (parent)->entry.rbe_color; (parent)
->entry.rbe_color = 0; if ((tmp)->entry.rbe_left) ((tmp
)->entry.rbe_left)->entry.rbe_color = 0; do { (tmp) = (
parent)->entry.rbe_left; if (((parent)->entry.rbe_left =
(tmp)->entry.rbe_right)) { ((tmp)->entry.rbe_right)->
entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->
entry.rbe_parent = (parent)->entry.rbe_parent)) { if ((parent
) == ((parent)->entry.rbe_parent)->entry.rbe_left) ((parent
)->entry.rbe_parent)->entry.rbe_left = (tmp); else ((parent
)->entry.rbe_parent)->entry.rbe_right = (tmp); } else (
head)->rbh_root = (tmp); (tmp)->entry.rbe_right = (parent
); (parent)->entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->entry.rbe_parent)) do {} while (0); } while (0);
elm = (head)->rbh_root; break; } } } if (elm) (elm)->entry
.rbe_color = 0; } struct winlink * winlinks_RB_REMOVE(struct winlinks
*head, struct winlink *elm) { struct winlink *child, *parent
, *old = elm; int color; if ((elm)->entry.rbe_left == ((void
*)0)) child = (elm)->entry.rbe_right; else if ((elm)->
entry.rbe_right == ((void *)0)) child = (elm)->entry.rbe_left
; else { struct winlink *left; elm = (elm)->entry.rbe_right
; while ((left = (elm)->entry.rbe_left)) elm = left; child
= (elm)->entry.rbe_right; parent = (elm)->entry.rbe_parent
; color = (elm)->entry.rbe_color; if (child) (child)->entry
.rbe_parent = parent; if (parent) { if ((parent)->entry.rbe_left
== elm) (parent)->entry.rbe_left = child; else (parent)->
entry.rbe_right = child; do {} while (0); } else (head)->rbh_root
= child; if ((elm)->entry.rbe_parent == old) parent = elm
; (elm)->entry = (old)->entry; if ((old)->entry.rbe_parent
) { if (((old)->entry.rbe_parent)->entry.rbe_left == old
) ((old)->entry.rbe_parent)->entry.rbe_left = elm; else
((old)->entry.rbe_parent)->entry.rbe_right = elm; do {
} while (0); } else (head)->rbh_root = elm; ((old)->entry
.rbe_left)->entry.rbe_parent = elm; if ((old)->entry.rbe_right
) ((old)->entry.rbe_right)->entry.rbe_parent = elm; if (
parent) { left = parent; do { do {} while (0); } while ((left
= (left)->entry.rbe_parent)); } goto color; } parent = (elm
)->entry.rbe_parent; color = (elm)->entry.rbe_color; if
(child) (child)->entry.rbe_parent = parent; if (parent) {
if ((parent)->entry.rbe_left == elm) (parent)->entry.rbe_left
= child; else (parent)->entry.rbe_right = child; do {} while
(0); } else (head)->rbh_root = child; color: if (color ==
0) winlinks_RB_REMOVE_COLOR(head, parent, child); return (old
); } struct winlink * winlinks_RB_INSERT(struct winlinks *head
, struct winlink *elm) { struct winlink *tmp; struct winlink *
parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root
; while (tmp) { parent = tmp; comp = (winlink_cmp)(elm, parent
); if (comp < 0) tmp = (tmp)->entry.rbe_left; else if (
comp > 0) tmp = (tmp)->entry.rbe_right; else return (tmp
); } do { (elm)->entry.rbe_parent = parent; (elm)->entry
.rbe_left = (elm)->entry.rbe_right = ((void *)0); (elm)->
entry.rbe_color = 1; } while (0); if (parent != ((void *)0)) {
if (comp < 0) (parent)->entry.rbe_left = elm; else (parent
)->entry.rbe_right = elm; do {} while (0); } else (head)->
rbh_root = elm; winlinks_RB_INSERT_COLOR(head, elm); return (
((void *)0)); } struct winlink * winlinks_RB_FIND(struct winlinks
*head, struct winlink *elm) { struct winlink *tmp = (head)->
rbh_root; int comp; while (tmp) { comp = winlink_cmp(elm, tmp
); if (comp < 0) tmp = (tmp)->entry.rbe_left; else if (
comp > 0) tmp = (tmp)->entry.rbe_right; else return (tmp
); } return (((void *)0)); } struct winlink * winlinks_RB_NFIND
(struct winlinks *head, struct winlink *elm) { struct winlink
*tmp = (head)->rbh_root; struct winlink *res = ((void *)0
); int comp; while (tmp) { comp = winlink_cmp(elm, tmp); if (
comp < 0) { res = tmp; tmp = (tmp)->entry.rbe_left; } else
if (comp > 0) tmp = (tmp)->entry.rbe_right; else return
(tmp); } return (res); } struct winlink * winlinks_RB_NEXT(struct
winlink *elm) { if ((elm)->entry.rbe_right) { elm = (elm)
->entry.rbe_right; while ((elm)->entry.rbe_left) elm = (
elm)->entry.rbe_left; } else { if ((elm)->entry.rbe_parent
&& (elm == ((elm)->entry.rbe_parent)->entry.rbe_left
)) elm = (elm)->entry.rbe_parent; else { while ((elm)->
entry.rbe_parent && (elm == ((elm)->entry.rbe_parent
)->entry.rbe_right)) elm = (elm)->entry.rbe_parent; elm
= (elm)->entry.rbe_parent; } } return (elm); } struct winlink
* winlinks_RB_PREV(struct winlink *elm) { if ((elm)->entry
.rbe_left) { elm = (elm)->entry.rbe_left; while ((elm)->
entry.rbe_right) elm = (elm)->entry.rbe_right; } else { if
((elm)->entry.rbe_parent && (elm == ((elm)->entry
.rbe_parent)->entry.rbe_right)) elm = (elm)->entry.rbe_parent
; else { while ((elm)->entry.rbe_parent && (elm ==
((elm)->entry.rbe_parent)->entry.rbe_left)) elm = (elm
)->entry.rbe_parent; elm = (elm)->entry.rbe_parent; } }
return (elm); } struct winlink * winlinks_RB_MINMAX(struct winlinks
*head, int val) { struct winlink *tmp = (head)->rbh_root;
struct winlink *parent = ((void *)0); while (tmp) { parent =
tmp; if (val < 0) tmp = (tmp)->entry.rbe_left; else tmp
= (tmp)->entry.rbe_right; } return (parent); }
;
78RB_GENERATE(window_pane_tree, window_pane, tree_entry, window_pane_cmp)void window_pane_tree_RB_INSERT_COLOR(struct window_pane_tree
*head, struct window_pane *elm) { struct window_pane *parent
, *gparent, *tmp; while ((parent = (elm)->tree_entry.rbe_parent
) && (parent)->tree_entry.rbe_color == 1) { gparent
= (parent)->tree_entry.rbe_parent; if (parent == (gparent
)->tree_entry.rbe_left) { tmp = (gparent)->tree_entry.rbe_right
; if (tmp && (tmp)->tree_entry.rbe_color == 1) { (
tmp)->tree_entry.rbe_color = 0; do { (parent)->tree_entry
.rbe_color = 0; (gparent)->tree_entry.rbe_color = 1; } while
(0); elm = gparent; continue; } if ((parent)->tree_entry.
rbe_right == elm) { do { (tmp) = (parent)->tree_entry.rbe_right
; if (((parent)->tree_entry.rbe_right = (tmp)->tree_entry
.rbe_left)) { ((tmp)->tree_entry.rbe_left)->tree_entry.
rbe_parent = (parent); } do {} while (0); if (((tmp)->tree_entry
.rbe_parent = (parent)->tree_entry.rbe_parent)) { if ((parent
) == ((parent)->tree_entry.rbe_parent)->tree_entry.rbe_left
) ((parent)->tree_entry.rbe_parent)->tree_entry.rbe_left
= (tmp); else ((parent)->tree_entry.rbe_parent)->tree_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->tree_entry.rbe_left = (parent); (parent)->tree_entry.
rbe_parent = (tmp); do {} while (0); if (((tmp)->tree_entry
.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent
= elm; elm = tmp; } do { (parent)->tree_entry.rbe_color =
0; (gparent)->tree_entry.rbe_color = 1; } while (0); do {
(tmp) = (gparent)->tree_entry.rbe_left; if (((gparent)->
tree_entry.rbe_left = (tmp)->tree_entry.rbe_right)) { ((tmp
)->tree_entry.rbe_right)->tree_entry.rbe_parent = (gparent
); } do {} while (0); if (((tmp)->tree_entry.rbe_parent = (
gparent)->tree_entry.rbe_parent)) { if ((gparent) == ((gparent
)->tree_entry.rbe_parent)->tree_entry.rbe_left) ((gparent
)->tree_entry.rbe_parent)->tree_entry.rbe_left = (tmp);
else ((gparent)->tree_entry.rbe_parent)->tree_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->tree_entry
.rbe_right = (gparent); (gparent)->tree_entry.rbe_parent =
(tmp); do {} while (0); if (((tmp)->tree_entry.rbe_parent
)) do {} while (0); } while (0); } else { tmp = (gparent)->
tree_entry.rbe_left; if (tmp && (tmp)->tree_entry.
rbe_color == 1) { (tmp)->tree_entry.rbe_color = 0; do { (parent
)->tree_entry.rbe_color = 0; (gparent)->tree_entry.rbe_color
= 1; } while (0); elm = gparent; continue; } if ((parent)->
tree_entry.rbe_left == elm) { do { (tmp) = (parent)->tree_entry
.rbe_left; if (((parent)->tree_entry.rbe_left = (tmp)->
tree_entry.rbe_right)) { ((tmp)->tree_entry.rbe_right)->
tree_entry.rbe_parent = (parent); } do {} while (0); if (((tmp
)->tree_entry.rbe_parent = (parent)->tree_entry.rbe_parent
)) { if ((parent) == ((parent)->tree_entry.rbe_parent)->
tree_entry.rbe_left) ((parent)->tree_entry.rbe_parent)->
tree_entry.rbe_left = (tmp); else ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_right = (tmp); } else (head)->rbh_root
= (tmp); (tmp)->tree_entry.rbe_right = (parent); (parent)
->tree_entry.rbe_parent = (tmp); do {} while (0); if (((tmp
)->tree_entry.rbe_parent)) do {} while (0); } while (0); tmp
= parent; parent = elm; elm = tmp; } do { (parent)->tree_entry
.rbe_color = 0; (gparent)->tree_entry.rbe_color = 1; } while
(0); do { (tmp) = (gparent)->tree_entry.rbe_right; if (((
gparent)->tree_entry.rbe_right = (tmp)->tree_entry.rbe_left
)) { ((tmp)->tree_entry.rbe_left)->tree_entry.rbe_parent
= (gparent); } do {} while (0); if (((tmp)->tree_entry.rbe_parent
= (gparent)->tree_entry.rbe_parent)) { if ((gparent) == (
(gparent)->tree_entry.rbe_parent)->tree_entry.rbe_left)
((gparent)->tree_entry.rbe_parent)->tree_entry.rbe_left
= (tmp); else ((gparent)->tree_entry.rbe_parent)->tree_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->tree_entry.rbe_left = (gparent); (gparent)->tree_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->tree_entry
.rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root
)->tree_entry.rbe_color = 0; } void window_pane_tree_RB_REMOVE_COLOR
(struct window_pane_tree *head, struct window_pane *parent, struct
window_pane *elm) { struct window_pane *tmp; while ((elm == (
(void *)0) || (elm)->tree_entry.rbe_color == 0) &&
elm != (head)->rbh_root) { if ((parent)->tree_entry.rbe_left
== elm) { tmp = (parent)->tree_entry.rbe_right; if ((tmp)
->tree_entry.rbe_color == 1) { do { (tmp)->tree_entry.rbe_color
= 0; (parent)->tree_entry.rbe_color = 1; } while (0); do {
(tmp) = (parent)->tree_entry.rbe_right; if (((parent)->
tree_entry.rbe_right = (tmp)->tree_entry.rbe_left)) { ((tmp
)->tree_entry.rbe_left)->tree_entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->tree_entry.rbe_parent = (
parent)->tree_entry.rbe_parent)) { if ((parent) == ((parent
)->tree_entry.rbe_parent)->tree_entry.rbe_left) ((parent
)->tree_entry.rbe_parent)->tree_entry.rbe_left = (tmp);
else ((parent)->tree_entry.rbe_parent)->tree_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->tree_entry
.rbe_left = (parent); (parent)->tree_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->tree_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->tree_entry.rbe_right
; } if (((tmp)->tree_entry.rbe_left == ((void *)0) || ((tmp
)->tree_entry.rbe_left)->tree_entry.rbe_color == 0) &&
((tmp)->tree_entry.rbe_right == ((void *)0) || ((tmp)->
tree_entry.rbe_right)->tree_entry.rbe_color == 0)) { (tmp)
->tree_entry.rbe_color = 1; elm = parent; parent = (elm)->
tree_entry.rbe_parent; } else { if ((tmp)->tree_entry.rbe_right
== ((void *)0) || ((tmp)->tree_entry.rbe_right)->tree_entry
.rbe_color == 0) { struct window_pane *oleft; if ((oleft = (tmp
)->tree_entry.rbe_left)) (oleft)->tree_entry.rbe_color =
0; (tmp)->tree_entry.rbe_color = 1; do { (oleft) = (tmp)->
tree_entry.rbe_left; if (((tmp)->tree_entry.rbe_left = (oleft
)->tree_entry.rbe_right)) { ((oleft)->tree_entry.rbe_right
)->tree_entry.rbe_parent = (tmp); } do {} while (0); if ((
(oleft)->tree_entry.rbe_parent = (tmp)->tree_entry.rbe_parent
)) { if ((tmp) == ((tmp)->tree_entry.rbe_parent)->tree_entry
.rbe_left) ((tmp)->tree_entry.rbe_parent)->tree_entry.rbe_left
= (oleft); else ((tmp)->tree_entry.rbe_parent)->tree_entry
.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (
oleft)->tree_entry.rbe_right = (tmp); (tmp)->tree_entry
.rbe_parent = (oleft); do {} while (0); if (((oleft)->tree_entry
.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->
tree_entry.rbe_right; } (tmp)->tree_entry.rbe_color = (parent
)->tree_entry.rbe_color; (parent)->tree_entry.rbe_color
= 0; if ((tmp)->tree_entry.rbe_right) ((tmp)->tree_entry
.rbe_right)->tree_entry.rbe_color = 0; do { (tmp) = (parent
)->tree_entry.rbe_right; if (((parent)->tree_entry.rbe_right
= (tmp)->tree_entry.rbe_left)) { ((tmp)->tree_entry.rbe_left
)->tree_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->tree_entry.rbe_parent = (parent)->tree_entry.
rbe_parent)) { if ((parent) == ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_left) ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_left = (tmp); else ((parent)->tree_entry
.rbe_parent)->tree_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->tree_entry.rbe_left = (parent); (
parent)->tree_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->tree_entry.rbe_parent)) do {} while (0); } while
(0); elm = (head)->rbh_root; break; } } else { tmp = (parent
)->tree_entry.rbe_left; if ((tmp)->tree_entry.rbe_color
== 1) { do { (tmp)->tree_entry.rbe_color = 0; (parent)->
tree_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->
tree_entry.rbe_left; if (((parent)->tree_entry.rbe_left = (
tmp)->tree_entry.rbe_right)) { ((tmp)->tree_entry.rbe_right
)->tree_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->tree_entry.rbe_parent = (parent)->tree_entry.
rbe_parent)) { if ((parent) == ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_left) ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_left = (tmp); else ((parent)->tree_entry
.rbe_parent)->tree_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->tree_entry.rbe_right = (parent); (
parent)->tree_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->tree_entry.rbe_parent)) do {} while (0); } while
(0); tmp = (parent)->tree_entry.rbe_left; } if (((tmp)->
tree_entry.rbe_left == ((void *)0) || ((tmp)->tree_entry.rbe_left
)->tree_entry.rbe_color == 0) && ((tmp)->tree_entry
.rbe_right == ((void *)0) || ((tmp)->tree_entry.rbe_right)
->tree_entry.rbe_color == 0)) { (tmp)->tree_entry.rbe_color
= 1; elm = parent; parent = (elm)->tree_entry.rbe_parent;
} else { if ((tmp)->tree_entry.rbe_left == ((void *)0) ||
((tmp)->tree_entry.rbe_left)->tree_entry.rbe_color == 0
) { struct window_pane *oright; if ((oright = (tmp)->tree_entry
.rbe_right)) (oright)->tree_entry.rbe_color = 0; (tmp)->
tree_entry.rbe_color = 1; do { (oright) = (tmp)->tree_entry
.rbe_right; if (((tmp)->tree_entry.rbe_right = (oright)->
tree_entry.rbe_left)) { ((oright)->tree_entry.rbe_left)->
tree_entry.rbe_parent = (tmp); } do {} while (0); if (((oright
)->tree_entry.rbe_parent = (tmp)->tree_entry.rbe_parent
)) { if ((tmp) == ((tmp)->tree_entry.rbe_parent)->tree_entry
.rbe_left) ((tmp)->tree_entry.rbe_parent)->tree_entry.rbe_left
= (oright); else ((tmp)->tree_entry.rbe_parent)->tree_entry
.rbe_right = (oright); } else (head)->rbh_root = (oright);
(oright)->tree_entry.rbe_left = (tmp); (tmp)->tree_entry
.rbe_parent = (oright); do {} while (0); if (((oright)->tree_entry
.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->
tree_entry.rbe_left; } (tmp)->tree_entry.rbe_color = (parent
)->tree_entry.rbe_color; (parent)->tree_entry.rbe_color
= 0; if ((tmp)->tree_entry.rbe_left) ((tmp)->tree_entry
.rbe_left)->tree_entry.rbe_color = 0; do { (tmp) = (parent
)->tree_entry.rbe_left; if (((parent)->tree_entry.rbe_left
= (tmp)->tree_entry.rbe_right)) { ((tmp)->tree_entry.rbe_right
)->tree_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->tree_entry.rbe_parent = (parent)->tree_entry.
rbe_parent)) { if ((parent) == ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_left) ((parent)->tree_entry.rbe_parent
)->tree_entry.rbe_left = (tmp); else ((parent)->tree_entry
.rbe_parent)->tree_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->tree_entry.rbe_right = (parent); (
parent)->tree_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->tree_entry.rbe_parent)) do {} while (0); } while
(0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->
tree_entry.rbe_color = 0; } struct window_pane * window_pane_tree_RB_REMOVE
(struct window_pane_tree *head, struct window_pane *elm) { struct
window_pane *child, *parent, *old = elm; int color; if ((elm
)->tree_entry.rbe_left == ((void *)0)) child = (elm)->tree_entry
.rbe_right; else if ((elm)->tree_entry.rbe_right == ((void
*)0)) child = (elm)->tree_entry.rbe_left; else { struct window_pane
*left; elm = (elm)->tree_entry.rbe_right; while ((left = (
elm)->tree_entry.rbe_left)) elm = left; child = (elm)->
tree_entry.rbe_right; parent = (elm)->tree_entry.rbe_parent
; color = (elm)->tree_entry.rbe_color; if (child) (child)->
tree_entry.rbe_parent = parent; if (parent) { if ((parent)->
tree_entry.rbe_left == elm) (parent)->tree_entry.rbe_left =
child; else (parent)->tree_entry.rbe_right = child; do {}
while (0); } else (head)->rbh_root = child; if ((elm)->
tree_entry.rbe_parent == old) parent = elm; (elm)->tree_entry
= (old)->tree_entry; if ((old)->tree_entry.rbe_parent)
{ if (((old)->tree_entry.rbe_parent)->tree_entry.rbe_left
== old) ((old)->tree_entry.rbe_parent)->tree_entry.rbe_left
= elm; else ((old)->tree_entry.rbe_parent)->tree_entry
.rbe_right = elm; do {} while (0); } else (head)->rbh_root
= elm; ((old)->tree_entry.rbe_left)->tree_entry.rbe_parent
= elm; if ((old)->tree_entry.rbe_right) ((old)->tree_entry
.rbe_right)->tree_entry.rbe_parent = elm; if (parent) { left
= parent; do { do {} while (0); } while ((left = (left)->
tree_entry.rbe_parent)); } goto color; } parent = (elm)->tree_entry
.rbe_parent; color = (elm)->tree_entry.rbe_color; if (child
) (child)->tree_entry.rbe_parent = parent; if (parent) { if
((parent)->tree_entry.rbe_left == elm) (parent)->tree_entry
.rbe_left = child; else (parent)->tree_entry.rbe_right = child
; do {} while (0); } else (head)->rbh_root = child; color:
if (color == 0) window_pane_tree_RB_REMOVE_COLOR(head, parent
, child); return (old); } struct window_pane * window_pane_tree_RB_INSERT
(struct window_pane_tree *head, struct window_pane *elm) { struct
window_pane *tmp; struct window_pane *parent = ((void *)0); int
comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp
; comp = (window_pane_cmp)(elm, parent); if (comp < 0) tmp
= (tmp)->tree_entry.rbe_left; else if (comp > 0) tmp =
(tmp)->tree_entry.rbe_right; else return (tmp); } do { (elm
)->tree_entry.rbe_parent = parent; (elm)->tree_entry.rbe_left
= (elm)->tree_entry.rbe_right = ((void *)0); (elm)->tree_entry
.rbe_color = 1; } while (0); if (parent != ((void *)0)) { if (
comp < 0) (parent)->tree_entry.rbe_left = elm; else (parent
)->tree_entry.rbe_right = elm; do {} while (0); } else (head
)->rbh_root = elm; window_pane_tree_RB_INSERT_COLOR(head, elm
); return (((void *)0)); } struct window_pane * window_pane_tree_RB_FIND
(struct window_pane_tree *head, struct window_pane *elm) { struct
window_pane *tmp = (head)->rbh_root; int comp; while (tmp
) { comp = window_pane_cmp(elm, tmp); if (comp < 0) tmp = (
tmp)->tree_entry.rbe_left; else if (comp > 0) tmp = (tmp
)->tree_entry.rbe_right; else return (tmp); } return (((void
*)0)); } struct window_pane * window_pane_tree_RB_NFIND(struct
window_pane_tree *head, struct window_pane *elm) { struct window_pane
*tmp = (head)->rbh_root; struct window_pane *res = ((void
*)0); int comp; while (tmp) { comp = window_pane_cmp(elm, tmp
); if (comp < 0) { res = tmp; tmp = (tmp)->tree_entry.rbe_left
; } else if (comp > 0) tmp = (tmp)->tree_entry.rbe_right
; else return (tmp); } return (res); } struct window_pane * window_pane_tree_RB_NEXT
(struct window_pane *elm) { if ((elm)->tree_entry.rbe_right
) { elm = (elm)->tree_entry.rbe_right; while ((elm)->tree_entry
.rbe_left) elm = (elm)->tree_entry.rbe_left; } else { if (
(elm)->tree_entry.rbe_parent && (elm == ((elm)->
tree_entry.rbe_parent)->tree_entry.rbe_left)) elm = (elm)->
tree_entry.rbe_parent; else { while ((elm)->tree_entry.rbe_parent
&& (elm == ((elm)->tree_entry.rbe_parent)->tree_entry
.rbe_right)) elm = (elm)->tree_entry.rbe_parent; elm = (elm
)->tree_entry.rbe_parent; } } return (elm); } struct window_pane
* window_pane_tree_RB_PREV(struct window_pane *elm) { if ((elm
)->tree_entry.rbe_left) { elm = (elm)->tree_entry.rbe_left
; while ((elm)->tree_entry.rbe_right) elm = (elm)->tree_entry
.rbe_right; } else { if ((elm)->tree_entry.rbe_parent &&
(elm == ((elm)->tree_entry.rbe_parent)->tree_entry.rbe_right
)) elm = (elm)->tree_entry.rbe_parent; else { while ((elm)
->tree_entry.rbe_parent && (elm == ((elm)->tree_entry
.rbe_parent)->tree_entry.rbe_left)) elm = (elm)->tree_entry
.rbe_parent; elm = (elm)->tree_entry.rbe_parent; } } return
(elm); } struct window_pane * window_pane_tree_RB_MINMAX(struct
window_pane_tree *head, int val) { struct window_pane *tmp =
(head)->rbh_root; struct window_pane *parent = ((void *)0
); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->
tree_entry.rbe_left; else tmp = (tmp)->tree_entry.rbe_right
; } return (parent); }
;
79
80int
81window_cmp(struct window *w1, struct window *w2)
82{
83 return (w1->id - w2->id);
84}
85
86int
87winlink_cmp(struct winlink *wl1, struct winlink *wl2)
88{
89 return (wl1->idx - wl2->idx);
90}
91
92int
93window_pane_cmp(struct window_pane *wp1, struct window_pane *wp2)
94{
95 return (wp1->id - wp2->id);
96}
97
98struct winlink *
99winlink_find_by_window(struct winlinks *wwl, struct window *w)
100{
101 struct winlink *wl;
102
103 RB_FOREACH(wl, winlinks, wwl)for ((wl) = winlinks_RB_MINMAX(wwl, -1); (wl) != ((void *)0);
(wl) = winlinks_RB_NEXT(wl))
{
104 if (wl->window == w)
105 return (wl);
106 }
107
108 return (NULL((void *)0));
109}
110
111struct winlink *
112winlink_find_by_index(struct winlinks *wwl, int idx)
113{
114 struct winlink wl;
115
116 if (idx < 0)
117 fatalx("bad index");
118
119 wl.idx = idx;
120 return (RB_FIND(winlinks, wwl, &wl)winlinks_RB_FIND(wwl, &wl));
121}
122
123struct winlink *
124winlink_find_by_window_id(struct winlinks *wwl, u_int id)
125{
126 struct winlink *wl;
127
128 RB_FOREACH(wl, winlinks, wwl)for ((wl) = winlinks_RB_MINMAX(wwl, -1); (wl) != ((void *)0);
(wl) = winlinks_RB_NEXT(wl))
{
129 if (wl->window->id == id)
130 return (wl);
131 }
132 return (NULL((void *)0));
133}
134
135static int
136winlink_next_index(struct winlinks *wwl, int idx)
137{
138 int i;
139
140 i = idx;
141 do {
142 if (winlink_find_by_index(wwl, i) == NULL((void *)0))
143 return (i);
144 if (i == INT_MAX0x7fffffff)
145 i = 0;
146 else
147 i++;
148 } while (i != idx);
149 return (-1);
150}
151
152u_int
153winlink_count(struct winlinks *wwl)
154{
155 struct winlink *wl;
156 u_int n;
157
158 n = 0;
159 RB_FOREACH(wl, winlinks, wwl)for ((wl) = winlinks_RB_MINMAX(wwl, -1); (wl) != ((void *)0);
(wl) = winlinks_RB_NEXT(wl))
160 n++;
161
162 return (n);
163}
164
165struct winlink *
166winlink_add(struct winlinks *wwl, int idx)
167{
168 struct winlink *wl;
169
170 if (idx < 0) {
171 if ((idx = winlink_next_index(wwl, -idx - 1)) == -1)
172 return (NULL((void *)0));
173 } else if (winlink_find_by_index(wwl, idx) != NULL((void *)0))
174 return (NULL((void *)0));
175
176 wl = xcalloc(1, sizeof *wl);
177 wl->idx = idx;
178 RB_INSERT(winlinks, wwl, wl)winlinks_RB_INSERT(wwl, wl);
179
180 return (wl);
181}
182
183void
184winlink_set_window(struct winlink *wl, struct window *w)
185{
186 if (wl->window != NULL((void *)0)) {
187 TAILQ_REMOVE(&wl->window->winlinks, wl, wentry)do { if (((wl)->wentry.tqe_next) != ((void *)0)) (wl)->
wentry.tqe_next->wentry.tqe_prev = (wl)->wentry.tqe_prev
; else (&wl->window->winlinks)->tqh_last = (wl)->
wentry.tqe_prev; *(wl)->wentry.tqe_prev = (wl)->wentry.
tqe_next; ; ; } while (0)
;
188 window_remove_ref(wl->window, __func__);
189 }
190 TAILQ_INSERT_TAIL(&w->winlinks, wl, wentry)do { (wl)->wentry.tqe_next = ((void *)0); (wl)->wentry.
tqe_prev = (&w->winlinks)->tqh_last; *(&w->winlinks
)->tqh_last = (wl); (&w->winlinks)->tqh_last = &
(wl)->wentry.tqe_next; } while (0)
;
191 wl->window = w;
192 window_add_ref(w, __func__);
193}
194
195void
196winlink_remove(struct winlinks *wwl, struct winlink *wl)
197{
198 struct window *w = wl->window;
199
200 if (w != NULL((void *)0)) {
201 TAILQ_REMOVE(&w->winlinks, wl, wentry)do { if (((wl)->wentry.tqe_next) != ((void *)0)) (wl)->
wentry.tqe_next->wentry.tqe_prev = (wl)->wentry.tqe_prev
; else (&w->winlinks)->tqh_last = (wl)->wentry.tqe_prev
; *(wl)->wentry.tqe_prev = (wl)->wentry.tqe_next; ; ; }
while (0)
;
202 window_remove_ref(w, __func__);
203 }
204
205 RB_REMOVE(winlinks, wwl, wl)winlinks_RB_REMOVE(wwl, wl);
206 free(wl);
207}
208
209struct winlink *
210winlink_next(struct winlink *wl)
211{
212 return (RB_NEXT(winlinks, wwl, wl)winlinks_RB_NEXT(wl));
213}
214
215struct winlink *
216winlink_previous(struct winlink *wl)
217{
218 return (RB_PREV(winlinks, wwl, wl)winlinks_RB_PREV(wl));
219}
220
221struct winlink *
222winlink_next_by_number(struct winlink *wl, struct session *s, int n)
223{
224 for (; n > 0; n--) {
225 if ((wl = RB_NEXT(winlinks, wwl, wl)winlinks_RB_NEXT(wl)) == NULL((void *)0))
226 wl = RB_MIN(winlinks, &s->windows)winlinks_RB_MINMAX(&s->windows, -1);
227 }
228
229 return (wl);
230}
231
232struct winlink *
233winlink_previous_by_number(struct winlink *wl, struct session *s, int n)
234{
235 for (; n > 0; n--) {
236 if ((wl = RB_PREV(winlinks, wwl, wl)winlinks_RB_PREV(wl)) == NULL((void *)0))
237 wl = RB_MAX(winlinks, &s->windows)winlinks_RB_MINMAX(&s->windows, 1);
238 }
239
240 return (wl);
241}
242
243void
244winlink_stack_push(struct winlink_stack *stack, struct winlink *wl)
245{
246 if (wl == NULL((void *)0))
247 return;
248
249 winlink_stack_remove(stack, wl);
250 TAILQ_INSERT_HEAD(stack, wl, sentry)do { if (((wl)->sentry.tqe_next = (stack)->tqh_first) !=
((void *)0)) (stack)->tqh_first->sentry.tqe_prev = &
(wl)->sentry.tqe_next; else (stack)->tqh_last = &(wl
)->sentry.tqe_next; (stack)->tqh_first = (wl); (wl)->
sentry.tqe_prev = &(stack)->tqh_first; } while (0)
;
251 wl->flags |= WINLINK_VISITED0x8;
252}
253
254void
255winlink_stack_remove(struct winlink_stack *stack, struct winlink *wl)
256{
257 if (wl != NULL((void *)0) && (wl->flags & WINLINK_VISITED0x8)) {
258 TAILQ_REMOVE(stack, wl, sentry)do { if (((wl)->sentry.tqe_next) != ((void *)0)) (wl)->
sentry.tqe_next->sentry.tqe_prev = (wl)->sentry.tqe_prev
; else (stack)->tqh_last = (wl)->sentry.tqe_prev; *(wl)
->sentry.tqe_prev = (wl)->sentry.tqe_next; ; ; } while (
0)
;
259 wl->flags &= ~WINLINK_VISITED0x8;
260 }
261}
262
263struct window *
264window_find_by_id_str(const char *s)
265{
266 const char *errstr;
267 u_int id;
268
269 if (*s != '@')
270 return (NULL((void *)0));
271
272 id = strtonum(s + 1, 0, UINT_MAX0xffffffffU, &errstr);
273 if (errstr != NULL((void *)0))
274 return (NULL((void *)0));
275 return (window_find_by_id(id));
276}
277
278struct window *
279window_find_by_id(u_int id)
280{
281 struct window w;
282
283 w.id = id;
284 return (RB_FIND(windows, &windows, &w)windows_RB_FIND(&windows, &w));
285}
286
287void
288window_update_activity(struct window *w)
289{
290 gettimeofday(&w->activity_time, NULL((void *)0));
291 alerts_queue(w, WINDOW_ACTIVITY0x2);
292}
293
294struct window *
295window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
296{
297 struct window *w;
298
299 if (xpixel == 0)
300 xpixel = DEFAULT_XPIXEL16;
301 if (ypixel == 0)
302 ypixel = DEFAULT_YPIXEL32;
303
304 w = xcalloc(1, sizeof *w);
305 w->name = xstrdup("");
306 w->flags = 0;
307
308 TAILQ_INIT(&w->panes)do { (&w->panes)->tqh_first = ((void *)0); (&w->
panes)->tqh_last = &(&w->panes)->tqh_first; }
while (0)
;
309 TAILQ_INIT(&w->last_panes)do { (&w->last_panes)->tqh_first = ((void *)0); (&
w->last_panes)->tqh_last = &(&w->last_panes)
->tqh_first; } while (0)
;
310 w->active = NULL((void *)0);
311
312 w->lastlayout = -1;
313 w->layout_root = NULL((void *)0);
314
315 w->sx = sx;
316 w->sy = sy;
317 w->manual_sx = sx;
318 w->manual_sy = sy;
319 w->xpixel = xpixel;
320 w->ypixel = ypixel;
321
322 w->options = options_create(global_w_options);
323
324 w->references = 0;
325 TAILQ_INIT(&w->winlinks)do { (&w->winlinks)->tqh_first = ((void *)0); (&
w->winlinks)->tqh_last = &(&w->winlinks)->
tqh_first; } while (0)
;
326
327 w->id = next_window_id++;
328 RB_INSERT(windows, &windows, w)windows_RB_INSERT(&windows, w);
329
330 window_set_fill_character(w);
331 window_update_activity(w);
332
333 log_debug("%s: @%u create %ux%u (%ux%u)", __func__, w->id, sx, sy,
334 w->xpixel, w->ypixel);
335 return (w);
336}
337
338static void
339window_destroy(struct window *w)
340{
341 log_debug("window @%u destroyed (%d references)", w->id, w->references);
342
343 window_unzoom(w);
344 RB_REMOVE(windows, &windows, w)windows_RB_REMOVE(&windows, w);
345
346 if (w->layout_root != NULL((void *)0))
347 layout_free_cell(w->layout_root);
348 if (w->saved_layout_root != NULL((void *)0))
349 layout_free_cell(w->saved_layout_root);
350 free(w->old_layout);
351
352 window_destroy_panes(w);
353
354 if (event_initialized(&w->name_event)((&w->name_event)->ev_flags & 0x80))
355 evtimer_del(&w->name_event)event_del(&w->name_event);
356
357 if (event_initialized(&w->alerts_timer)((&w->alerts_timer)->ev_flags & 0x80))
358 evtimer_del(&w->alerts_timer)event_del(&w->alerts_timer);
359 if (event_initialized(&w->offset_timer)((&w->offset_timer)->ev_flags & 0x80))
360 event_del(&w->offset_timer);
361
362 options_free(w->options);
363 free(w->fill_character);
364
365 free(w->name);
366 free(w);
367}
368
369int
370window_pane_destroy_ready(struct window_pane *wp)
371{
372 int n;
373
374 if (wp->pipe_fd != -1) {
375 if (EVBUFFER_LENGTH(wp->pipe_event->output)(wp->pipe_event->output)->off != 0)
376 return (0);
377 if (ioctl(wp->fd, FIONREAD((unsigned long)0x40000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('f')) << 8) | ((127)))
, &n) != -1 && n > 0)
378 return (0);
379 }
380
381 if (~wp->flags & PANE_EXITED0x100)
382 return (0);
383 return (1);
384}
385
386void
387window_add_ref(struct window *w, const char *from)
388{
389 w->references++;
390 log_debug("%s: @%u %s, now %d", __func__, w->id, from, w->references);
391}
392
393void
394window_remove_ref(struct window *w, const char *from)
395{
396 w->references--;
397 log_debug("%s: @%u %s, now %d", __func__, w->id, from, w->references);
398
399 if (w->references == 0)
400 window_destroy(w);
401}
402
403void
404window_set_name(struct window *w, const char *new_name)
405{
406 free(w->name);
407 utf8_stravis(&w->name, new_name, VIS_OCTAL0x01|VIS_CSTYLE0x02|VIS_TAB0x08|VIS_NL0x10);
408 notify_window("window-renamed", w);
409}
410
411void
412window_resize(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
413{
414 if (xpixel == 0)
415 xpixel = DEFAULT_XPIXEL16;
416 if (ypixel == 0)
417 ypixel = DEFAULT_YPIXEL32;
418
419 log_debug("%s: @%u resize %ux%u (%ux%u)", __func__, w->id, sx, sy,
420 xpixel == -1 ? w->xpixel : (u_int)xpixel,
421 ypixel == -1 ? w->ypixel : (u_int)ypixel);
422 w->sx = sx;
423 w->sy = sy;
424 if (xpixel != -1)
425 w->xpixel = xpixel;
426 if (ypixel != -1)
427 w->ypixel = ypixel;
428}
429
430void
431window_pane_send_resize(struct window_pane *wp, u_int sx, u_int sy)
432{
433 struct window *w = wp->window;
434 struct winsize ws;
435
436 if (wp->fd == -1)
437 return;
438
439 log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, sx, sy);
440
441 memset(&ws, 0, sizeof ws);
442 ws.ws_col = sx;
443 ws.ws_row = sy;
444 ws.ws_xpixel = w->xpixel * ws.ws_col;
445 ws.ws_ypixel = w->ypixel * ws.ws_row;
446 if (ioctl(wp->fd, TIOCSWINSZ((unsigned long)0x80000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((103)))
, &ws) == -1)
447 fatal("ioctl failed");
448}
449
450int
451window_has_pane(struct window *w, struct window_pane *wp)
452{
453 struct window_pane *wp1;
454
455 TAILQ_FOREACH(wp1, &w->panes, entry)for((wp1) = ((&w->panes)->tqh_first); (wp1) != ((void
*)0); (wp1) = ((wp1)->entry.tqe_next))
{
456 if (wp1 == wp)
457 return (1);
458 }
459 return (0);
460}
461
462void
463window_update_focus(struct window *w)
464{
465 if (w != NULL((void *)0)) {
466 log_debug("%s: @%u", __func__, w->id);
467 window_pane_update_focus(w->active);
468 }
469}
470
471void
472window_pane_update_focus(struct window_pane *wp)
473{
474 struct client *c;
475 int focused = 0;
476
477 if (wp != NULL((void *)0)) {
478 if (wp != wp->window->active)
479 focused = 0;
480 else {
481 TAILQ_FOREACH(c, &clients, entry)for((c) = ((&clients)->tqh_first); (c) != ((void *)0);
(c) = ((c)->entry.tqe_next))
{
482 if (c->session != NULL((void *)0) &&
483 c->session->attached != 0 &&
484 (c->flags & CLIENT_FOCUSED0x8000) &&
485 c->session->curw->window == wp->window) {
486 focused = 1;
487 break;
488 }
489 }
490 }
491 if (!focused && (wp->flags & PANE_FOCUSED0x4)) {
492 log_debug("%s: %%%u focus out", __func__, wp->id);
493 if (wp->base.mode & MODE_FOCUSON0x800)
494 bufferevent_write(wp->event, "\033[O", 3);
495 notify_pane("pane-focus-out", wp);
496 wp->flags &= ~PANE_FOCUSED0x4;
497 } else if (focused && (~wp->flags & PANE_FOCUSED0x4)) {
498 log_debug("%s: %%%u focus in", __func__, wp->id);
499 if (wp->base.mode & MODE_FOCUSON0x800)
500 bufferevent_write(wp->event, "\033[I", 3);
501 notify_pane("pane-focus-in", wp);
502 wp->flags |= PANE_FOCUSED0x4;
503 } else
504 log_debug("%s: %%%u focus unchanged", __func__, wp->id);
505 }
506}
507
508int
509window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
510{
511 struct window_pane *lastwp;
512
513 log_debug("%s: pane %%%u", __func__, wp->id);
514
515 if (wp == w->active)
516 return (0);
517 lastwp = w->active;
518
519 window_pane_stack_remove(&w->last_panes, wp);
520 window_pane_stack_push(&w->last_panes, lastwp);
521
522 w->active = wp;
523 w->active->active_point = next_active_point++;
524 w->active->flags |= PANE_CHANGED0x80;
525
526 if (options_get_number(global_options, "focus-events")) {
527 window_pane_update_focus(lastwp);
528 window_pane_update_focus(w->active);
529 }
530
531 tty_update_window_offset(w);
532
533 if (notify)
534 notify_window("window-pane-changed", w);
535 return (1);
536}
537
538static int
539window_pane_get_palette(struct window_pane *wp, int c)
540{
541 if (wp == NULL((void *)0))
542 return (-1);
543 return (colour_palette_get(&wp->palette, c));
544}
545
546void
547window_redraw_active_switch(struct window *w, struct window_pane *wp)
548{
549 struct grid_cell *gc1, *gc2;
550 int c1, c2;
551
552 if (wp == w->active)
553 return;
554
555 for (;;) {
556 /*
557 * If the active and inactive styles or palettes are different,
558 * need to redraw the panes.
559 */
560 gc1 = &wp->cached_gc;
561 gc2 = &wp->cached_active_gc;
562 if (!grid_cells_look_equal(gc1, gc2))
563 wp->flags |= PANE_REDRAW0x1;
564 else {
565 c1 = window_pane_get_palette(wp, gc1->fg);
566 c2 = window_pane_get_palette(wp, gc2->fg);
567 if (c1 != c2)
568 wp->flags |= PANE_REDRAW0x1;
569 else {
570 c1 = window_pane_get_palette(wp, gc1->bg);
571 c2 = window_pane_get_palette(wp, gc2->bg);
572 if (c1 != c2)
573 wp->flags |= PANE_REDRAW0x1;
574 }
575 }
576 if (wp == w->active)
577 break;
578 wp = w->active;
579 }
580}
581
582struct window_pane *
583window_get_active_at(struct window *w, u_int x, u_int y)
584{
585 struct window_pane *wp;
586
587 TAILQ_FOREACH(wp, &w->panes, entry)for((wp) = ((&w->panes)->tqh_first); (wp) != ((void
*)0); (wp) = ((wp)->entry.tqe_next))
{
588 if (!window_pane_visible(wp))
589 continue;
590 if (x < wp->xoff || x > wp->xoff + wp->sx)
591 continue;
592 if (y < wp->yoff || y > wp->yoff + wp->sy)
593 continue;
594 return (wp);
595 }
596 return (NULL((void *)0));
597}
598
599struct window_pane *
600window_find_string(struct window *w, const char *s)
601{
602 u_int x, y, top = 0, bottom = w->sy - 1;
603 int status;
604
605 x = w->sx / 2;
606 y = w->sy / 2;
607
608 status = options_get_number(w->options, "pane-border-status");
609 if (status == PANE_STATUS_TOP1)
610 top++;
611 else if (status == PANE_STATUS_BOTTOM2)
612 bottom--;
613
614 if (strcasecmp(s, "top") == 0)
615 y = top;
616 else if (strcasecmp(s, "bottom") == 0)
617 y = bottom;
618 else if (strcasecmp(s, "left") == 0)
619 x = 0;
620 else if (strcasecmp(s, "right") == 0)
621 x = w->sx - 1;
622 else if (strcasecmp(s, "top-left") == 0) {
623 x = 0;
624 y = top;
625 } else if (strcasecmp(s, "top-right") == 0) {
626 x = w->sx - 1;
627 y = top;
628 } else if (strcasecmp(s, "bottom-left") == 0) {
629 x = 0;
630 y = bottom;
631 } else if (strcasecmp(s, "bottom-right") == 0) {
632 x = w->sx - 1;
633 y = bottom;
634 } else
635 return (NULL((void *)0));
636
637 return (window_get_active_at(w, x, y));
638}
639
640int
641window_zoom(struct window_pane *wp)
642{
643 struct window *w = wp->window;
644 struct window_pane *wp1;
645
646 if (w->flags & WINDOW_ZOOMED0x8)
647 return (-1);
648
649 if (window_count_panes(w) == 1)
650 return (-1);
651
652 if (w->active != wp)
653 window_set_active_pane(w, wp, 1);
654
655 TAILQ_FOREACH(wp1, &w->panes, entry)for((wp1) = ((&w->panes)->tqh_first); (wp1) != ((void
*)0); (wp1) = ((wp1)->entry.tqe_next))
{
656 wp1->saved_layout_cell = wp1->layout_cell;
657 wp1->layout_cell = NULL((void *)0);
658 }
659
660 w->saved_layout_root = w->layout_root;
661 layout_init(w, wp);
662 w->flags |= WINDOW_ZOOMED0x8;
663 notify_window("window-layout-changed", w);
664
665 return (0);
666}
667
668int
669window_unzoom(struct window *w)
670{
671 struct window_pane *wp;
672
673 if (!(w->flags & WINDOW_ZOOMED0x8))
674 return (-1);
675
676 w->flags &= ~WINDOW_ZOOMED0x8;
677 layout_free(w);
678 w->layout_root = w->saved_layout_root;
679 w->saved_layout_root = NULL((void *)0);
680
681 TAILQ_FOREACH(wp, &w->panes, entry)for((wp) = ((&w->panes)->tqh_first); (wp) != ((void
*)0); (wp) = ((wp)->entry.tqe_next))
{
682 wp->layout_cell = wp->saved_layout_cell;
683 wp->saved_layout_cell = NULL((void *)0);
684 }
685 layout_fix_panes(w, NULL((void *)0));
686 notify_window("window-layout-changed", w);
687
688 return (0);
689}
690
691int
692window_push_zoom(struct window *w, int always, int flag)
693{
694 log_debug("%s: @%u %d", __func__, w->id,
695 flag && (w->flags & WINDOW_ZOOMED0x8));
696 if (flag && (always || (w->flags & WINDOW_ZOOMED0x8)))
697 w->flags |= WINDOW_WASZOOMED0x10;
698 else
699 w->flags &= ~WINDOW_WASZOOMED0x10;
700 return (window_unzoom(w) == 0);
701}
702
703int
704window_pop_zoom(struct window *w)
705{
706 log_debug("%s: @%u %d", __func__, w->id,
707 !!(w->flags & WINDOW_WASZOOMED0x10));
708 if (w->flags & WINDOW_WASZOOMED0x10)
709 return (window_zoom(w->active) == 0);
710 return (0);
711}
712
713struct window_pane *
714window_add_pane(struct window *w, struct window_pane *other, u_int hlimit,
715 int flags)
716{
717 struct window_pane *wp;
718
719 if (other == NULL((void *)0))
720 other = w->active;
721
722 wp = window_pane_create(w, w->sx, w->sy, hlimit);
723 if (TAILQ_EMPTY(&w->panes)(((&w->panes)->tqh_first) == ((void *)0))) {
724 log_debug("%s: @%u at start", __func__, w->id);
725 TAILQ_INSERT_HEAD(&w->panes, wp, entry)do { if (((wp)->entry.tqe_next = (&w->panes)->tqh_first
) != ((void *)0)) (&w->panes)->tqh_first->entry.
tqe_prev = &(wp)->entry.tqe_next; else (&w->panes
)->tqh_last = &(wp)->entry.tqe_next; (&w->panes
)->tqh_first = (wp); (wp)->entry.tqe_prev = &(&
w->panes)->tqh_first; } while (0)
;
726 } else if (flags & SPAWN_BEFORE0x8) {
727 log_debug("%s: @%u before %%%u", __func__, w->id, wp->id);
728 if (flags & SPAWN_FULLSIZE0x20)
729 TAILQ_INSERT_HEAD(&w->panes, wp, entry)do { if (((wp)->entry.tqe_next = (&w->panes)->tqh_first
) != ((void *)0)) (&w->panes)->tqh_first->entry.
tqe_prev = &(wp)->entry.tqe_next; else (&w->panes
)->tqh_last = &(wp)->entry.tqe_next; (&w->panes
)->tqh_first = (wp); (wp)->entry.tqe_prev = &(&
w->panes)->tqh_first; } while (0)
;
730 else
731 TAILQ_INSERT_BEFORE(other, wp, entry)do { (wp)->entry.tqe_prev = (other)->entry.tqe_prev; (wp
)->entry.tqe_next = (other); *(other)->entry.tqe_prev =
(wp); (other)->entry.tqe_prev = &(wp)->entry.tqe_next
; } while (0)
;
732 } else {
733 log_debug("%s: @%u after %%%u", __func__, w->id, wp->id);
734 if (flags & SPAWN_FULLSIZE0x20)
735 TAILQ_INSERT_TAIL(&w->panes, wp, entry)do { (wp)->entry.tqe_next = ((void *)0); (wp)->entry.tqe_prev
= (&w->panes)->tqh_last; *(&w->panes)->tqh_last
= (wp); (&w->panes)->tqh_last = &(wp)->entry
.tqe_next; } while (0)
;
736 else
737 TAILQ_INSERT_AFTER(&w->panes, other, wp, entry)do { if (((wp)->entry.tqe_next = (other)->entry.tqe_next
) != ((void *)0)) (wp)->entry.tqe_next->entry.tqe_prev =
&(wp)->entry.tqe_next; else (&w->panes)->tqh_last
= &(wp)->entry.tqe_next; (other)->entry.tqe_next =
(wp); (wp)->entry.tqe_prev = &(other)->entry.tqe_next
; } while (0)
;
738 }
739 return (wp);
740}
741
742void
743window_lost_pane(struct window *w, struct window_pane *wp)
744{
745 log_debug("%s: @%u pane %%%u", __func__, w->id, wp->id);
746
747 if (wp == marked_pane.wp)
748 server_clear_marked();
749
750 window_pane_stack_remove(&w->last_panes, wp);
751 if (wp == w->active) {
752 w->active = TAILQ_FIRST(&w->last_panes)((&w->last_panes)->tqh_first);
753 if (w->active == NULL((void *)0)) {
754 w->active = TAILQ_PREV(wp, window_panes, entry)(*(((struct window_panes *)((wp)->entry.tqe_prev))->tqh_last
))
;
755 if (w->active == NULL((void *)0))
756 w->active = TAILQ_NEXT(wp, entry)((wp)->entry.tqe_next);
757 }
758 if (w->active != NULL((void *)0)) {
759 window_pane_stack_remove(&w->last_panes, w->active);
760 w->active->flags |= PANE_CHANGED0x80;
761 notify_window("window-pane-changed", w);
762 window_update_focus(w);
763 }
764 }
765}
766
767void
768window_remove_pane(struct window *w, struct window_pane *wp)
769{
770 window_lost_pane(w, wp);
771
772 TAILQ_REMOVE(&w->panes, wp, entry)do { if (((wp)->entry.tqe_next) != ((void *)0)) (wp)->entry
.tqe_next->entry.tqe_prev = (wp)->entry.tqe_prev; else (
&w->panes)->tqh_last = (wp)->entry.tqe_prev; *(wp
)->entry.tqe_prev = (wp)->entry.tqe_next; ; ; } while (
0)
;
1
Assuming field 'tqe_next' is equal to null
2
Taking false branch
3
Loop condition is false. Exiting loop
773 window_pane_destroy(wp);
4
Calling 'window_pane_destroy'
774}
775
776struct window_pane *
777window_pane_at_index(struct window *w, u_int idx)
778{
779 struct window_pane *wp;
780 u_int n;
781
782 n = options_get_number(w->options, "pane-base-index");
783 TAILQ_FOREACH(wp, &w->panes, entry)for((wp) = ((&w->panes)->tqh_first); (wp) != ((void
*)0); (wp) = ((wp)->entry.tqe_next))
{
784 if (n == idx)
785 return (wp);
786 n++;
787 }
788 return (NULL((void *)0));
789}
790
791struct window_pane *
792window_pane_next_by_number(struct window *w, struct window_pane *wp, u_int n)
793{
794 for (; n > 0; n--) {
795 if ((wp = TAILQ_NEXT(wp, entry)((wp)->entry.tqe_next)) == NULL((void *)0))
796 wp = TAILQ_FIRST(&w->panes)((&w->panes)->tqh_first);
797 }
798
799 return (wp);
800}
801
802struct window_pane *
803window_pane_previous_by_number(struct window *w, struct window_pane *wp,
804 u_int n)
805{
806 for (; n > 0; n--) {
807 if ((wp = TAILQ_PREV(wp, window_panes, entry)(*(((struct window_panes *)((wp)->entry.tqe_prev))->tqh_last
))
) == NULL((void *)0))
808 wp = TAILQ_LAST(&w->panes, window_panes)(*(((struct window_panes *)((&w->panes)->tqh_last))
->tqh_last))
;
809 }
810
811 return (wp);
812}
813
814int
815window_pane_index(struct window_pane *wp, u_int *i)
816{
817 struct window_pane *wq;
818 struct window *w = wp->window;
819
820 *i = options_get_number(w->options, "pane-base-index");
821 TAILQ_FOREACH(wq, &w->panes, entry)for((wq) = ((&w->panes)->tqh_first); (wq) != ((void
*)0); (wq) = ((wq)->entry.tqe_next))
{
822 if (wp == wq) {
823 return (0);
824 }
825 (*i)++;
826 }
827
828 return (-1);
829}
830
831u_int
832window_count_panes(struct window *w)
833{
834 struct window_pane *wp;
835 u_int n;
836
837 n = 0;
838 TAILQ_FOREACH(wp, &w->panes, entry)for((wp) = ((&w->panes)->tqh_first); (wp) != ((void
*)0); (wp) = ((wp)->entry.tqe_next))
839 n++;
840 return (n);
841}
842
843void
844window_destroy_panes(struct window *w)
845{
846 struct window_pane *wp;
847
848 while (!TAILQ_EMPTY(&w->last_panes)(((&w->last_panes)->tqh_first) == ((void *)0))) {
849 wp = TAILQ_FIRST(&w->last_panes)((&w->last_panes)->tqh_first);
850 window_pane_stack_remove(&w->last_panes, wp);
851 }
852
853 while (!TAILQ_EMPTY(&w->panes)(((&w->panes)->tqh_first) == ((void *)0))) {
854 wp = TAILQ_FIRST(&w->panes)((&w->panes)->tqh_first);
855 TAILQ_REMOVE(&w->panes, wp, entry)do { if (((wp)->entry.tqe_next) != ((void *)0)) (wp)->entry
.tqe_next->entry.tqe_prev = (wp)->entry.tqe_prev; else (
&w->panes)->tqh_last = (wp)->entry.tqe_prev; *(wp
)->entry.tqe_prev = (wp)->entry.tqe_next; ; ; } while (
0)
;
856 window_pane_destroy(wp);
857 }
858}
859
860const char *
861window_printable_flags(struct winlink *wl, int escape)
862{
863 struct session *s = wl->session;
864 static char flags[32];
865 int pos;
866
867 pos = 0;
868 if (wl->flags & WINLINK_ACTIVITY0x2) {
869 flags[pos++] = '#';
870 if (escape)
871 flags[pos++] = '#';
872 }
873 if (wl->flags & WINLINK_BELL0x1)
874 flags[pos++] = '!';
875 if (wl->flags & WINLINK_SILENCE0x4)
876 flags[pos++] = '~';
877 if (wl == s->curw)
878 flags[pos++] = '*';
879 if (wl == TAILQ_FIRST(&s->lastw)((&s->lastw)->tqh_first))
880 flags[pos++] = '-';
881 if (server_check_marked() && wl == marked_pane.wl)
882 flags[pos++] = 'M';
883 if (wl->window->flags & WINDOW_ZOOMED0x8)
884 flags[pos++] = 'Z';
885 flags[pos] = '\0';
886 return (flags);
887}
888
889struct window_pane *
890window_pane_find_by_id_str(const char *s)
891{
892 const char *errstr;
893 u_int id;
894
895 if (*s != '%')
896 return (NULL((void *)0));
897
898 id = strtonum(s + 1, 0, UINT_MAX0xffffffffU, &errstr);
899 if (errstr != NULL((void *)0))
900 return (NULL((void *)0));
901 return (window_pane_find_by_id(id));
902}
903
904struct window_pane *
905window_pane_find_by_id(u_int id)
906{
907 struct window_pane wp;
908
909 wp.id = id;
910 return (RB_FIND(window_pane_tree, &all_window_panes, &wp)window_pane_tree_RB_FIND(&all_window_panes, &wp));
911}
912
913static struct window_pane *
914window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
915{
916 struct window_pane *wp;
917 char host[HOST_NAME_MAX255 + 1];
918
919 wp = xcalloc(1, sizeof *wp);
920 wp->window = w;
921 wp->options = options_create(w->options);
922 wp->flags = PANE_STYLECHANGED0x1000;
923
924 wp->id = next_window_pane_id++;
925 RB_INSERT(window_pane_tree, &all_window_panes, wp)window_pane_tree_RB_INSERT(&all_window_panes, wp);
926
927 wp->fd = -1;
928
929 TAILQ_INIT(&wp->modes)do { (&wp->modes)->tqh_first = ((void *)0); (&wp
->modes)->tqh_last = &(&wp->modes)->tqh_first
; } while (0)
;
930
931 TAILQ_INIT (&wp->resize_queue)do { (&wp->resize_queue)->tqh_first = ((void *)0); (
&wp->resize_queue)->tqh_last = &(&wp->resize_queue
)->tqh_first; } while (0)
;
932
933 wp->sx = sx;
934 wp->sy = sy;
935
936 wp->pipe_fd = -1;
937
938 colour_palette_init(&wp->palette);
939 colour_palette_from_option(&wp->palette, wp->options);
940
941 screen_init(&wp->base, sx, sy, hlimit);
942 wp->screen = &wp->base;
943 window_pane_default_cursor(wp);
944
945 screen_init(&wp->status_screen, 1, 1, 0);
946
947 if (gethostname(host, sizeof host) == 0)
948 screen_set_title(&wp->base, host);
949
950 return (wp);
951}
952
953static void
954window_pane_destroy(struct window_pane *wp)
955{
956 struct window_pane_resize *r;
957 struct window_pane_resize *r1;
958
959 window_pane_reset_mode_all(wp);
5
Calling 'window_pane_reset_mode_all'
960 free(wp->searchstr);
961
962 if (wp->fd != -1) {
963 bufferevent_free(wp->event);
964 close(wp->fd);
965 }
966 if (wp->ictx != NULL((void *)0))
967 input_free(wp->ictx);
968
969 screen_free(&wp->status_screen);
970
971 screen_free(&wp->base);
972
973 if (wp->pipe_fd != -1) {
974 bufferevent_free(wp->pipe_event);
975 close(wp->pipe_fd);
976 }
977
978 if (event_initialized(&wp->resize_timer)((&wp->resize_timer)->ev_flags & 0x80))
979 event_del(&wp->resize_timer);
980 TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1)for ((r) = ((&wp->resize_queue)->tqh_first); (r) !=
((void *)0) && ((r1) = ((r)->entry.tqe_next), 1);
(r) = (r1))
{
981 TAILQ_REMOVE(&wp->resize_queue, r, entry)do { if (((r)->entry.tqe_next) != ((void *)0)) (r)->entry
.tqe_next->entry.tqe_prev = (r)->entry.tqe_prev; else (
&wp->resize_queue)->tqh_last = (r)->entry.tqe_prev
; *(r)->entry.tqe_prev = (r)->entry.tqe_next; ; ; } while
(0)
;
982 free(r);
983 }
984
985 RB_REMOVE(window_pane_tree, &all_window_panes, wp)window_pane_tree_RB_REMOVE(&all_window_panes, wp);
986
987 options_free(wp->options);
988 free((void *)wp->cwd);
989 free(wp->shell);
990 cmd_free_argv(wp->argc, wp->argv);
991 colour_palette_free(&wp->palette);
992 free(wp);
993}
994
995static void
996window_pane_read_callback(__unused__attribute__((__unused__)) struct bufferevent *bufev, void *data)
997{
998 struct window_pane *wp = data;
999 struct evbuffer *evb = wp->event->input;
1000 struct window_pane_offset *wpo = &wp->pipe_offset;
1001 size_t size = EVBUFFER_LENGTH(evb)(evb)->off;
1002 char *new_data;
1003 size_t new_size;
1004 struct client *c;
1005
1006 if (wp->pipe_fd != -1) {
1007 new_data = window_pane_get_new_data(wp, wpo, &new_size);
1008 if (new_size > 0) {
1009 bufferevent_write(wp->pipe_event, new_data, new_size);
1010 window_pane_update_used_data(wp, wpo, new_size);
1011 }
1012 }
1013
1014 log_debug("%%%u has %zu bytes", wp->id, size);
1015 TAILQ_FOREACH(c, &clients, entry)for((c) = ((&clients)->tqh_first); (c) != ((void *)0);
(c) = ((c)->entry.tqe_next))
{
1016 if (c->session != NULL((void *)0) && (c->flags & CLIENT_CONTROL0x2000))
1017 control_write_output(c, wp);
1018 }
1019 input_parse_pane(wp);
1020 bufferevent_disable(wp->event, EV_READ0x02);
1021}
1022
1023static void
1024window_pane_error_callback(__unused__attribute__((__unused__)) struct bufferevent *bufev,
1025 __unused__attribute__((__unused__)) short what, void *data)
1026{
1027 struct window_pane *wp = data;
1028
1029 log_debug("%%%u error", wp->id);
1030 wp->flags |= PANE_EXITED0x100;
1031
1032 if (window_pane_destroy_ready(wp))
1033 server_destroy_pane(wp, 1);
1034}
1035
1036void
1037window_pane_set_event(struct window_pane *wp)
1038{
1039 setblocking(wp->fd, 0);
1040
1041 wp->event = bufferevent_new(wp->fd, window_pane_read_callback,
1042 NULL((void *)0), window_pane_error_callback, wp);
1043 if (wp->event == NULL((void *)0))
1044 fatalx("out of memory");
1045 wp->ictx = input_init(wp, wp->event, &wp->palette);
1046
1047 bufferevent_enable(wp->event, EV_READ0x02|EV_WRITE0x04);
1048}
1049
1050void
1051window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
1052{
1053 struct window_mode_entry *wme;
1054 struct window_pane_resize *r;
1055
1056 if (sx == wp->sx && sy == wp->sy)
1057 return;
1058
1059 r = xmalloc(sizeof *r);
1060 r->sx = sx;
1061 r->sy = sy;
1062 r->osx = wp->sx;
1063 r->osy = wp->sy;
1064 TAILQ_INSERT_TAIL (&wp->resize_queue, r, entry)do { (r)->entry.tqe_next = ((void *)0); (r)->entry.tqe_prev
= (&wp->resize_queue)->tqh_last; *(&wp->resize_queue
)->tqh_last = (r); (&wp->resize_queue)->tqh_last
= &(r)->entry.tqe_next; } while (0)
;
1065
1066 wp->sx = sx;
1067 wp->sy = sy;
1068
1069 log_debug("%s: %%%u resize %ux%u", __func__, wp->id, sx, sy);
1070 screen_resize(&wp->base, sx, sy, wp->base.saved_grid == NULL((void *)0));
1071
1072 wme = TAILQ_FIRST(&wp->modes)((&wp->modes)->tqh_first);
1073 if (wme != NULL((void *)0) && wme->mode->resize != NULL((void *)0))
1074 wme->mode->resize(wme, sx, sy);
1075}
1076
1077int
1078window_pane_set_mode(struct window_pane *wp, struct window_pane *swp,
1079 const struct window_mode *mode, struct cmd_find_state *fs,
1080 struct args *args)
1081{
1082 struct window_mode_entry *wme;
1083
1084 if (!TAILQ_EMPTY(&wp->modes)(((&wp->modes)->tqh_first) == ((void *)0)) && TAILQ_FIRST(&wp->modes)((&wp->modes)->tqh_first)->mode == mode)
1085 return (1);
1086
1087 TAILQ_FOREACH(wme, &wp->modes, entry)for((wme) = ((&wp->modes)->tqh_first); (wme) != ((void
*)0); (wme) = ((wme)->entry.tqe_next))
{
1088 if (wme->mode == mode)
1089 break;
1090 }
1091 if (wme != NULL((void *)0)) {
1092 TAILQ_REMOVE(&wp->modes, wme, entry)do { if (((wme)->entry.tqe_next) != ((void *)0)) (wme)->
entry.tqe_next->entry.tqe_prev = (wme)->entry.tqe_prev;
else (&wp->modes)->tqh_last = (wme)->entry.tqe_prev
; *(wme)->entry.tqe_prev = (wme)->entry.tqe_next; ; ; }
while (0)
;
1093 TAILQ_INSERT_HEAD(&wp->modes, wme, entry)do { if (((wme)->entry.tqe_next = (&wp->modes)->
tqh_first) != ((void *)0)) (&wp->modes)->tqh_first->
entry.tqe_prev = &(wme)->entry.tqe_next; else (&wp
->modes)->tqh_last = &(wme)->entry.tqe_next; (&
wp->modes)->tqh_first = (wme); (wme)->entry.tqe_prev
= &(&wp->modes)->tqh_first; } while (0)
;
1094 } else {
1095 wme = xcalloc(1, sizeof *wme);
1096 wme->wp = wp;
1097 wme->swp = swp;
1098 wme->mode = mode;
1099 wme->prefix = 1;
1100 TAILQ_INSERT_HEAD(&wp->modes, wme, entry)do { if (((wme)->entry.tqe_next = (&wp->modes)->
tqh_first) != ((void *)0)) (&wp->modes)->tqh_first->
entry.tqe_prev = &(wme)->entry.tqe_next; else (&wp
->modes)->tqh_last = &(wme)->entry.tqe_next; (&
wp->modes)->tqh_first = (wme); (wme)->entry.tqe_prev
= &(&wp->modes)->tqh_first; } while (0)
;
1101 wme->screen = wme->mode->init(wme, fs, args);
1102 }
1103
1104 wp->screen = wme->screen;
1105 wp->flags |= (PANE_REDRAW0x1|PANE_CHANGED0x80);
1106
1107 server_redraw_window_borders(wp->window);
1108 server_status_window(wp->window);
1109 notify_pane("pane-mode-changed", wp);
1110
1111 return (0);
1112}
1113
1114void
1115window_pane_reset_mode(struct window_pane *wp)
1116{
1117 struct window_mode_entry *wme, *next;
1118
1119 if (TAILQ_EMPTY(&wp->modes)(((&wp->modes)->tqh_first) == ((void *)0)))
9
Taking false branch
1120 return;
1121
1122 wme = TAILQ_FIRST(&wp->modes)((&wp->modes)->tqh_first);
1123 TAILQ_REMOVE(&wp->modes, wme, entry)do { if (((wme)->entry.tqe_next) != ((void *)0)) (wme)->
entry.tqe_next->entry.tqe_prev = (wme)->entry.tqe_prev;
else (&wp->modes)->tqh_last = (wme)->entry.tqe_prev
; *(wme)->entry.tqe_prev = (wme)->entry.tqe_next; ; ; }
while (0)
;
10
Assuming field 'tqe_next' is equal to null
11
Taking false branch
12
Loop condition is false. Exiting loop
1124 wme->mode->free(wme);
1125 free(wme);
13
Memory is released
1126
1127 next = TAILQ_FIRST(&wp->modes)((&wp->modes)->tqh_first);
1128 if (next
13.1
'next' is not equal to NULL
== NULL((void *)0)) {
14
Taking false branch
1129 wp->flags &= ~PANE_UNSEENCHANGES0x2000;
1130 log_debug("%s: no next mode", __func__);
1131 wp->screen = &wp->base;
1132 } else {
1133 log_debug("%s: next mode is %s", __func__, next->mode->name);
15
Use of memory after it is freed
1134 wp->screen = next->screen;
1135 if (next->mode->resize != NULL((void *)0))
1136 next->mode->resize(next, wp->sx, wp->sy);
1137 }
1138 wp->flags |= (PANE_REDRAW0x1|PANE_CHANGED0x80);
1139
1140 server_redraw_window_borders(wp->window);
1141 server_status_window(wp->window);
1142 notify_pane("pane-mode-changed", wp);
1143}
1144
1145void
1146window_pane_reset_mode_all(struct window_pane *wp)
1147{
1148 while (!TAILQ_EMPTY(&wp->modes)(((&wp->modes)->tqh_first) == ((void *)0)))
6
Assuming field 'tqh_first' is not equal to null
7
Loop condition is true. Entering loop body
1149 window_pane_reset_mode(wp);
8
Calling 'window_pane_reset_mode'
1150}
1151
1152static void
1153window_pane_copy_key(struct window_pane *wp, key_code key)
1154{
1155 struct window_pane *loop;
1156
1157 TAILQ_FOREACH(loop, &wp->window->panes, entry)for((loop) = ((&wp->window->panes)->tqh_first); (
loop) != ((void *)0); (loop) = ((loop)->entry.tqe_next))
{
1158 if (loop != wp &&
1159 TAILQ_EMPTY(&loop->modes)(((&loop->modes)->tqh_first) == ((void *)0)) &&
1160 loop->fd != -1 &&
1161 (~loop->flags & PANE_INPUTOFF0x40) &&
1162 window_pane_visible(loop) &&
1163 options_get_number(loop->options, "synchronize-panes"))
1164 input_key_pane(loop, key, NULL((void *)0));
1165 }
1166}
1167
1168int
1169window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
1170 struct winlink *wl, key_code key, struct mouse_event *m)
1171{
1172 struct window_mode_entry *wme;
1173
1174 if (KEYC_IS_MOUSE(key)(((key) & 0x000fffffffffffULL) >= KEYC_MOUSE &&
((key) & 0x000fffffffffffULL) < KEYC_BSPACE)
&& m == NULL((void *)0))
1175 return (-1);
1176
1177 wme = TAILQ_FIRST(&wp->modes)((&wp->modes)->tqh_first);
1178 if (wme != NULL((void *)0)) {
1179 if (wme->mode->key != NULL((void *)0) && c != NULL((void *)0)) {
1180 key &= ~KEYC_MASK_FLAGS0xff000000000000ULL;
1181 wme->mode->key(wme, c, s, wl, key, m);
1182 }
1183 return (0);
1184 }
1185
1186 if (wp->fd == -1 || wp->flags & PANE_INPUTOFF0x40)
1187 return (0);
1188
1189 if (input_key_pane(wp, key, m) != 0)
1190 return (-1);
1191
1192 if (KEYC_IS_MOUSE(key)(((key) & 0x000fffffffffffULL) >= KEYC_MOUSE &&
((key) & 0x000fffffffffffULL) < KEYC_BSPACE)
)
1193 return (0);
1194 if (options_get_number(wp->options, "synchronize-panes"))
1195 window_pane_copy_key(wp, key);
1196 return (0);
1197}
1198
1199int
1200window_pane_visible(struct window_pane *wp)
1201{
1202 if (~wp->window->flags & WINDOW_ZOOMED0x8)
1203 return (1);
1204 return (wp == wp->window->active);
1205}
1206
1207u_int
1208window_pane_search(struct window_pane *wp, const char *term, int regex,
1209 int ignore)
1210{
1211 struct screen *s = &wp->base;
1212 regex_t r;
1213 char *new = NULL((void *)0), *line;
1214 u_int i;
1215 int flags = 0, found;
1216 size_t n;
1217
1218 if (!regex) {
1219 if (ignore)
1220 flags |= FNM_CASEFOLD0x10;
1221 xasprintf(&new, "*%s*", term);
1222 } else {
1223 if (ignore)
1224 flags |= REG_ICASE0002;
1225 if (regcomp(&r, term, flags|REG_EXTENDED0001) != 0)
1226 return (0);
1227 }
1228
1229 for (i = 0; i < screen_size_y(s)((s)->grid->sy); i++) {
1230 line = grid_view_string_cells(s->grid, 0, i, screen_size_x(s)((s)->grid->sx));
1231 for (n = strlen(line); n > 0; n--) {
1232 if (!isspace((u_char)line[n - 1]))
1233 break;
1234 line[n - 1] = '\0';
1235 }
1236 log_debug("%s: %s", __func__, line);
1237 if (!regex)
1238 found = (fnmatch(new, line, flags) == 0);
1239 else
1240 found = (regexec(&r, line, 0, NULL((void *)0), 0) == 0);
1241 free(line);
1242 if (found)
1243 break;
1244 }
1245 if (!regex)
1246 free(new);
1247 else
1248 regfree(&r);
1249
1250 if (i == screen_size_y(s)((s)->grid->sy))
1251 return (0);
1252 return (i + 1);
1253}
1254
1255/* Get MRU pane from a list. */
1256static struct window_pane *
1257window_pane_choose_best(struct window_pane **list, u_int size)
1258{
1259 struct window_pane *next, *best;
1260 u_int i;
1261
1262 if (size == 0)
1263 return (NULL((void *)0));
1264
1265 best = list[0];
1266 for (i = 1; i < size; i++) {
1267 next = list[i];
1268 if (next->active_point > best->active_point)
1269 best = next;
1270 }
1271 return (best);
1272}
1273
1274/*
1275 * Find the pane directly above another. We build a list of those adjacent to
1276 * top edge and then choose the best.
1277 */
1278struct window_pane *
1279window_pane_find_up(struct window_pane *wp)
1280{
1281 struct window *w;
1282 struct window_pane *next, *best, **list;
1283 u_int edge, left, right, end, size;
1284 int status, found;
1285
1286 if (wp == NULL((void *)0))
1287 return (NULL((void *)0));
1288 w = wp->window;
1289 status = options_get_number(w->options, "pane-border-status");
1290
1291 list = NULL((void *)0);
1292 size = 0;
1293
1294 edge = wp->yoff;
1295 if (status == PANE_STATUS_TOP1) {
1296 if (edge == 1)
1297 edge = w->sy + 1;
1298 } else if (status == PANE_STATUS_BOTTOM2) {
1299 if (edge == 0)
1300 edge = w->sy;
1301 } else {
1302 if (edge == 0)
1303 edge = w->sy + 1;
1304 }
1305
1306 left = wp->xoff;
1307 right = wp->xoff + wp->sx;
1308
1309 TAILQ_FOREACH(next, &w->panes, entry)for((next) = ((&w->panes)->tqh_first); (next) != ((
void *)0); (next) = ((next)->entry.tqe_next))
{
1310 if (next == wp)
1311 continue;
1312 if (next->yoff + next->sy + 1 != edge)
1313 continue;
1314 end = next->xoff + next->sx - 1;
1315
1316 found = 0;
1317 if (next->xoff < left && end > right)
1318 found = 1;
1319 else if (next->xoff >= left && next->xoff <= right)
1320 found = 1;
1321 else if (end >= left && end <= right)
1322 found = 1;
1323 if (!found)
1324 continue;
1325 list = xreallocarray(list, size + 1, sizeof *list);
1326 list[size++] = next;
1327 }
1328
1329 best = window_pane_choose_best(list, size);
1330 free(list);
1331 return (best);
1332}
1333
1334/* Find the pane directly below another. */
1335struct window_pane *
1336window_pane_find_down(struct window_pane *wp)
1337{
1338 struct window *w;
1339 struct window_pane *next, *best, **list;
1340 u_int edge, left, right, end, size;
1341 int status, found;
1342
1343 if (wp == NULL((void *)0))
1344 return (NULL((void *)0));
1345 w = wp->window;
1346 status = options_get_number(w->options, "pane-border-status");
1347
1348 list = NULL((void *)0);
1349 size = 0;
1350
1351 edge = wp->yoff + wp->sy + 1;
1352 if (status == PANE_STATUS_TOP1) {
1353 if (edge >= w->sy)
1354 edge = 1;
1355 } else if (status == PANE_STATUS_BOTTOM2) {
1356 if (edge >= w->sy - 1)
1357 edge = 0;
1358 } else {
1359 if (edge >= w->sy)
1360 edge = 0;
1361 }
1362
1363 left = wp->xoff;
1364 right = wp->xoff + wp->sx;
1365
1366 TAILQ_FOREACH(next, &w->panes, entry)for((next) = ((&w->panes)->tqh_first); (next) != ((
void *)0); (next) = ((next)->entry.tqe_next))
{
1367 if (next == wp)
1368 continue;
1369 if (next->yoff != edge)
1370 continue;
1371 end = next->xoff + next->sx - 1;
1372
1373 found = 0;
1374 if (next->xoff < left && end > right)
1375 found = 1;
1376 else if (next->xoff >= left && next->xoff <= right)
1377 found = 1;
1378 else if (end >= left && end <= right)
1379 found = 1;
1380 if (!found)
1381 continue;
1382 list = xreallocarray(list, size + 1, sizeof *list);
1383 list[size++] = next;
1384 }
1385
1386 best = window_pane_choose_best(list, size);
1387 free(list);
1388 return (best);
1389}
1390
1391/* Find the pane directly to the left of another. */
1392struct window_pane *
1393window_pane_find_left(struct window_pane *wp)
1394{
1395 struct window *w;
1396 struct window_pane *next, *best, **list;
1397 u_int edge, top, bottom, end, size;
1398 int found;
1399
1400 if (wp == NULL((void *)0))
1401 return (NULL((void *)0));
1402 w = wp->window;
1403
1404 list = NULL((void *)0);
1405 size = 0;
1406
1407 edge = wp->xoff;
1408 if (edge == 0)
1409 edge = w->sx + 1;
1410
1411 top = wp->yoff;
1412 bottom = wp->yoff + wp->sy;
1413
1414 TAILQ_FOREACH(next, &w->panes, entry)for((next) = ((&w->panes)->tqh_first); (next) != ((
void *)0); (next) = ((next)->entry.tqe_next))
{
1415 if (next == wp)
1416 continue;
1417 if (next->xoff + next->sx + 1 != edge)
1418 continue;
1419 end = next->yoff + next->sy - 1;
1420
1421 found = 0;
1422 if (next->yoff < top && end > bottom)
1423 found = 1;
1424 else if (next->yoff >= top && next->yoff <= bottom)
1425 found = 1;
1426 else if (end >= top && end <= bottom)
1427 found = 1;
1428 if (!found)
1429 continue;
1430 list = xreallocarray(list, size + 1, sizeof *list);
1431 list[size++] = next;
1432 }
1433
1434 best = window_pane_choose_best(list, size);
1435 free(list);
1436 return (best);
1437}
1438
1439/* Find the pane directly to the right of another. */
1440struct window_pane *
1441window_pane_find_right(struct window_pane *wp)
1442{
1443 struct window *w;
1444 struct window_pane *next, *best, **list;
1445 u_int edge, top, bottom, end, size;
1446 int found;
1447
1448 if (wp == NULL((void *)0))
1449 return (NULL((void *)0));
1450 w = wp->window;
1451
1452 list = NULL((void *)0);
1453 size = 0;
1454
1455 edge = wp->xoff + wp->sx + 1;
1456 if (edge >= w->sx)
1457 edge = 0;
1458
1459 top = wp->yoff;
1460 bottom = wp->yoff + wp->sy;
1461
1462 TAILQ_FOREACH(next, &w->panes, entry)for((next) = ((&w->panes)->tqh_first); (next) != ((
void *)0); (next) = ((next)->entry.tqe_next))
{
1463 if (next == wp)
1464 continue;
1465 if (next->xoff != edge)
1466 continue;
1467 end = next->yoff + next->sy - 1;
1468
1469 found = 0;
1470 if (next->yoff < top && end > bottom)
1471 found = 1;
1472 else if (next->yoff >= top && next->yoff <= bottom)
1473 found = 1;
1474 else if (end >= top && end <= bottom)
1475 found = 1;
1476 if (!found)
1477 continue;
1478 list = xreallocarray(list, size + 1, sizeof *list);
1479 list[size++] = next;
1480 }
1481
1482 best = window_pane_choose_best(list, size);
1483 free(list);
1484 return (best);
1485}
1486
1487void
1488window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
1489{
1490 if (wp != NULL((void *)0)) {
1491 window_pane_stack_remove(stack, wp);
1492 TAILQ_INSERT_HEAD(stack, wp, sentry)do { if (((wp)->sentry.tqe_next = (stack)->tqh_first) !=
((void *)0)) (stack)->tqh_first->sentry.tqe_prev = &
(wp)->sentry.tqe_next; else (stack)->tqh_last = &(wp
)->sentry.tqe_next; (stack)->tqh_first = (wp); (wp)->
sentry.tqe_prev = &(stack)->tqh_first; } while (0)
;
1493 wp->flags |= PANE_VISITED0x8;
1494 }
1495}
1496
1497void
1498window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
1499{
1500 if (wp != NULL((void *)0) && (wp->flags & PANE_VISITED0x8)) {
1501 TAILQ_REMOVE(stack, wp, sentry)do { if (((wp)->sentry.tqe_next) != ((void *)0)) (wp)->
sentry.tqe_next->sentry.tqe_prev = (wp)->sentry.tqe_prev
; else (stack)->tqh_last = (wp)->sentry.tqe_prev; *(wp)
->sentry.tqe_prev = (wp)->sentry.tqe_next; ; ; } while (
0)
;
1502 wp->flags &= ~PANE_VISITED0x8;
1503 }
1504}
1505
1506/* Clear alert flags for a winlink */
1507void
1508winlink_clear_flags(struct winlink *wl)
1509{
1510 struct winlink *loop;
1511
1512 wl->window->flags &= ~WINDOW_ALERTFLAGS(0x1|0x2|0x4);
1513 TAILQ_FOREACH(loop, &wl->window->winlinks, wentry)for((loop) = ((&wl->window->winlinks)->tqh_first
); (loop) != ((void *)0); (loop) = ((loop)->wentry.tqe_next
))
{
1514 if ((loop->flags & WINLINK_ALERTFLAGS(0x1|0x2|0x4)) != 0) {
1515 loop->flags &= ~WINLINK_ALERTFLAGS(0x1|0x2|0x4);
1516 server_status_session(loop->session);
1517 }
1518 }
1519}
1520
1521/* Shuffle window indexes up. */
1522int
1523winlink_shuffle_up(struct session *s, struct winlink *wl, int before)
1524{
1525 int idx, last;
1526
1527 if (wl == NULL((void *)0))
1528 return (-1);
1529 if (before)
1530 idx = wl->idx;
1531 else
1532 idx = wl->idx + 1;
1533
1534 /* Find the next free index. */
1535 for (last = idx; last < INT_MAX0x7fffffff; last++) {
1536 if (winlink_find_by_index(&s->windows, last) == NULL((void *)0))
1537 break;
1538 }
1539 if (last == INT_MAX0x7fffffff)
1540 return (-1);
1541
1542 /* Move everything from last - 1 to idx up a bit. */
1543 for (; last > idx; last--) {
1544 wl = winlink_find_by_index(&s->windows, last - 1);
1545 RB_REMOVE(winlinks, &s->windows, wl)winlinks_RB_REMOVE(&s->windows, wl);
1546 wl->idx++;
1547 RB_INSERT(winlinks, &s->windows, wl)winlinks_RB_INSERT(&s->windows, wl);
1548 }
1549
1550 return (idx);
1551}
1552
1553static void
1554window_pane_input_callback(struct client *c, __unused__attribute__((__unused__)) const char *path,
1555 int error, int closed, struct evbuffer *buffer, void *data)
1556{
1557 struct window_pane_input_data *cdata = data;
1558 struct window_pane *wp;
1559 u_char *buf = EVBUFFER_DATA(buffer)(buffer)->buffer;
1560 size_t len = EVBUFFER_LENGTH(buffer)(buffer)->off;
1561
1562 wp = window_pane_find_by_id(cdata->wp);
1563 if (cdata->file != NULL((void *)0) && (wp == NULL((void *)0) || c->flags & CLIENT_DEAD0x200)) {
1564 if (wp == NULL((void *)0)) {
1565 c->retval = 1;
1566 c->flags |= CLIENT_EXIT0x4;
1567 }
1568 file_cancel(cdata->file);
1569 } else if (cdata->file == NULL((void *)0) || closed || error != 0) {
1570 cmdq_continue(cdata->item);
1571 server_client_unref(c);
1572 free(cdata);
1573 } else
1574 input_parse_buffer(wp, buf, len);
1575 evbuffer_drain(buffer, len);
1576}
1577
1578int
1579window_pane_start_input(struct window_pane *wp, struct cmdq_item *item,
1580 char **cause)
1581{
1582 struct client *c = cmdq_get_client(item);
1583 struct window_pane_input_data *cdata;
1584
1585 if (~wp->flags & PANE_EMPTY0x800) {
1586 *cause = xstrdup("pane is not empty");
1587 return (-1);
1588 }
1589 if (c->flags & (CLIENT_DEAD0x200|CLIENT_EXITED0x100))
1590 return (1);
1591 if (c->session != NULL((void *)0))
1592 return (1);
1593
1594 cdata = xmalloc(sizeof *cdata);
1595 cdata->item = item;
1596 cdata->wp = wp->id;
1597 cdata->file = file_read(c, "-", window_pane_input_callback, cdata);
1598 c->references++;
1599
1600 return (0);
1601}
1602
1603void *
1604window_pane_get_new_data(struct window_pane *wp,
1605 struct window_pane_offset *wpo, size_t *size)
1606{
1607 size_t used = wpo->used - wp->base_offset;
1608
1609 *size = EVBUFFER_LENGTH(wp->event->input)(wp->event->input)->off - used;
1610 return (EVBUFFER_DATA(wp->event->input)(wp->event->input)->buffer + used);
1611}
1612
1613void
1614window_pane_update_used_data(struct window_pane *wp,
1615 struct window_pane_offset *wpo, size_t size)
1616{
1617 size_t used = wpo->used - wp->base_offset;
1618
1619 if (size > EVBUFFER_LENGTH(wp->event->input)(wp->event->input)->off - used)
1620 size = EVBUFFER_LENGTH(wp->event->input)(wp->event->input)->off - used;
1621 wpo->used += size;
1622}
1623
1624void
1625window_set_fill_character(struct window *w)
1626{
1627 const char *value;
1628 struct utf8_data *ud;
1629
1630 free(w->fill_character);
1631 w->fill_character = NULL((void *)0);
1632
1633 value = options_get_string(w->options, "fill-character");
1634 if (*value != '\0' && utf8_isvalid(value)) {
1635 ud = utf8_fromcstr(value);
1636 if (ud != NULL((void *)0) && ud[0].width == 1)
1637 w->fill_character = ud;
1638 }
1639}
1640
1641void
1642window_pane_default_cursor(struct window_pane *wp)
1643{
1644 struct screen *s = wp->screen;
1645 int c;
1646
1647 c = options_get_number(wp->options, "cursor-colour");
1648 s->default_ccolour = c;
1649
1650 c = options_get_number(wp->options, "cursor-style");
1651 s->default_mode = 0;
1652 screen_set_cursor_style(c, &s->default_cstyle, &s->default_mode);
1653}