1bacd15cpeter/****************************************************************************
201cf73abapt * Copyright 2018-2019,2020 Thomas E. Dickey                                *
301cf73abapt * Copyright 1998-2017,2018 Free Software Foundation, Inc.                  *
4bacd15cpeter *                                                                          *
5bacd15cpeter * Permission is hereby granted, free of charge, to any person obtaining a  *
6bacd15cpeter * copy of this software and associated documentation files (the            *
7bacd15cpeter * "Software"), to deal in the Software without restriction, including      *
8bacd15cpeter * without limitation the rights to use, copy, modify, merge, publish,      *
9bacd15cpeter * distribute, distribute with modifications, sublicense, and/or sell       *
10bacd15cpeter * copies of the Software, and to permit persons to whom the Software is    *
11bacd15cpeter * furnished to do so, subject to the following conditions:                 *
12bacd15cpeter *                                                                          *
13bacd15cpeter * The above copyright notice and this permission notice shall be included  *
14bacd15cpeter * in all copies or substantial portions of the Software.                   *
15bacd15cpeter *                                                                          *
16bacd15cpeter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17bacd15cpeter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18bacd15cpeter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19bacd15cpeter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20bacd15cpeter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21bacd15cpeter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22bacd15cpeter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23bacd15cpeter *                                                                          *
24bacd15cpeter * Except as contained in this notice, the name(s) of the above copyright   *
25bacd15cpeter * holders shall not be used in advertising or otherwise to promote the     *
26bacd15cpeter * sale, use or other dealings in this Software without prior written       *
27bacd15cpeter * authorization.                                                           *
28bacd15cpeter ****************************************************************************/
29bacd15cpeter
30bacd15cpeter/****************************************************************************
31bacd15cpeter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
32bacd15cpeter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
33de9cbefrafan *     and: Thomas E. Dickey                        1996-on                 *
341034bfcdelphij *     and: Juergen Pfeifer                                                 *
35bacd15cpeter ****************************************************************************/
36bacd15cpeter
37bacd15cpeter/*
3801cf73abapt * $Id: curses.priv.h,v 1.628 2020/02/02 23:34:34 tom Exp $
39bacd15cpeter *
40bacd15cpeter *	curses.priv.h
41bacd15cpeter *
42bacd15cpeter *	Header file for curses library objects which are private to
43bacd15cpeter *	the library.
44bacd15cpeter *
45bacd15cpeter */
46bacd15cpeter
47bacd15cpeter#ifndef CURSES_PRIV_H
48bacd15cpeter#define CURSES_PRIV_H 1
491034bfcdelphij/* *INDENT-OFF* */
50bacd15cpeter
51b7ada7fpeter#include <ncurses_dll.h>
52b7ada7fpeter
53bacd15cpeter#ifdef __cplusplus
54bacd15cpeterextern "C" {
55bacd15cpeter#endif
56bacd15cpeter
57bacd15cpeter#include <ncurses_cfg.h>
58bacd15cpeter
59bacd15cpeter#if USE_RCS_IDS
60bacd15cpeter#define MODULE_ID(id) static const char Ident[] = id;
61bacd15cpeter#else
62bacd15cpeter#define MODULE_ID(id) /*nothing*/
63bacd15cpeter#endif
64bacd15cpeter
651034bfcdelphij#include <stddef.h>		/* for offsetof */
66bacd15cpeter#include <stdlib.h>
67bacd15cpeter#include <string.h>
68bacd15cpeter#include <sys/types.h>
697dbeededelphij#include <sys/stat.h>
70bacd15cpeter
71bacd15cpeter#if HAVE_UNISTD_H
72bacd15cpeter#include <unistd.h>
73bacd15cpeter#endif
74bacd15cpeter
75f52ca6ebapt#if HAVE_SYS_BSDTYPES_H && !(defined(_WIN32) || defined(_WIN64))
76bacd15cpeter#include <sys/bsdtypes.h>	/* needed for ISC */
77bacd15cpeter#endif
78bacd15cpeter
79bacd15cpeter#if HAVE_LIMITS_H
80bacd15cpeter# include <limits.h>
81bacd15cpeter#elif HAVE_SYS_PARAM_H
82bacd15cpeter# include <sys/param.h>
83bacd15cpeter#endif
84bacd15cpeter
85de9cbefrafan#include <assert.h>
86de9cbefrafan#include <stdio.h>
87de9cbefrafan
88de9cbefrafan#include <errno.h>
89de9cbefrafan
907dbeededelphij#if defined __hpux
917dbeededelphij#  ifndef EILSEQ
927dbeededelphij#    define EILSEQ 47
937dbeededelphij#  endif
947dbeededelphij#endif
957dbeededelphij
96bacd15cpeter#ifndef PATH_MAX
97bacd15cpeter# if defined(_POSIX_PATH_MAX)
98bacd15cpeter#  define PATH_MAX _POSIX_PATH_MAX
99bacd15cpeter# elif defined(MAXPATHLEN)
100bacd15cpeter#  define PATH_MAX MAXPATHLEN
101bacd15cpeter# else
102bacd15cpeter#  define PATH_MAX 255	/* the Posix minimum path-size */
103bacd15cpeter# endif
104bacd15cpeter#endif
105bacd15cpeter
106bacd15cpeter#if DECL_ERRNO
107bacd15cpeterextern int errno;
108bacd15cpeter#endif
109bacd15cpeter
110bacd15cpeter/* Some systems have a broken 'select()', but workable 'poll()'.  Use that */
111cc6a5ccpeter#if HAVE_WORKING_POLL
112bacd15cpeter#define USE_FUNC_POLL 1
113a81407apeter#if HAVE_POLL_H
114cc6a5ccpeter#include <poll.h>
115cc6a5ccpeter#else
116cc6a5ccpeter#include <sys/poll.h>
117cc6a5ccpeter#endif
118bacd15cpeter#else
119bacd15cpeter#define USE_FUNC_POLL 0
120bacd15cpeter#endif
121bacd15cpeter
1227dbeededelphij#if HAVE_INTTYPES_H
1237dbeededelphij# include <inttypes.h>
1247dbeededelphij#else
1257dbeededelphij# if HAVE_STDINT_H
1267dbeededelphij#  include <stdint.h>
1277dbeededelphij# endif
1287dbeededelphij#endif
1297dbeededelphij
1309a7523dpeter/* include signal.h before curses.h to work-around defect in glibc 2.1.3 */
1319a7523dpeter#include <signal.h>
1329a7523dpeter
133bacd15cpeter/* Alessandro Rubini's GPM (general-purpose mouse) */
134bacd15cpeter#if HAVE_LIBGPM && HAVE_GPM_H
135bacd15cpeter#define USE_GPM_SUPPORT 1
136bacd15cpeter#else
137bacd15cpeter#define USE_GPM_SUPPORT 0
138bacd15cpeter#endif
139bacd15cpeter
140bacd15cpeter/* QNX mouse support */
141bacd15cpeter#if defined(__QNX__) && !defined(__QNXNTO__)
142bacd15cpeter#define USE_QNX_MOUSE 1
143bacd15cpeter#else
144bacd15cpeter#define USE_QNX_MOUSE 0
145bacd15cpeter#endif
146bacd15cpeter
147bacd15cpeter/* EMX mouse support */
148bacd15cpeter#ifdef __EMX__
149de9cbefrafan#define USE_EMX_MOUSE 1
150de9cbefrafan#else
151de9cbefrafan#define USE_EMX_MOUSE 0
152bacd15cpeter#endif
153bacd15cpeter
1547dbeededelphij/* kLIBC keyboard/mouse support */
1557dbeededelphij#if defined(__OS2__) && defined(__KLIBC__)
1567dbeededelphij#define USE_KLIBC_KBD   1
1577dbeededelphij#define USE_KLIBC_MOUSE 1
1587dbeededelphij#else
1597dbeededelphij#define USE_KLIBC_KBD   0
1607dbeededelphij#define USE_KLIBC_MOUSE 0
1617dbeededelphij#endif
1627dbeededelphij
163bacd15cpeter#define DEFAULT_MAXCLICK 166
164bacd15cpeter#define EV_MAX		8	/* size of mouse circular event queue */
165bacd15cpeter
166bacd15cpeter/*
167bacd15cpeter * If we don't have signals to support it, don't add a sigwinch handler.
168bacd15cpeter * In any case, resizing is an extended feature.  Use it if we've got it.
169bacd15cpeter */
170a81407apeter#if !NCURSES_EXT_FUNCS
171bacd15cpeter#undef HAVE_SIZECHANGE
172de9cbefrafan#define HAVE_SIZECHANGE 0
173bacd15cpeter#endif
174bacd15cpeter
175d078158rafan#if HAVE_SIZECHANGE && USE_SIGWINCH && defined(SIGWINCH)
176bacd15cpeter#define USE_SIZECHANGE 1
177bacd15cpeter#else
178de9cbefrafan#define USE_SIZECHANGE 0
179bacd15cpeter#undef USE_SIGWINCH
180de9cbefrafan#define USE_SIGWINCH 0
181bacd15cpeter#endif
182bacd15cpeter
183bacd15cpeter/*
184f52ca6ebapt * When building in the MSYS2 environment, the automatic discovery of
185f52ca6ebapt * the path separator in configure doesn't work properly. So, if building
186f52ca6ebapt * for MinGW, we enforce the correct Windows PATH separator
187f52ca6ebapt */
188f52ca6ebapt#ifdef _WIN32
189f52ca6ebapt#  ifdef NCURSES_PATHSEP
190f52ca6ebapt#    undef NCURSES_PATHSEP
191f52ca6ebapt#  endif
192f52ca6ebapt#  define NCURSES_PATHSEP ';'
193f52ca6ebapt#endif
194f52ca6ebapt
195f52ca6ebapt/*
196a81407apeter * If desired, one can configure this, disabling environment variables that
197a81407apeter * point to custom terminfo/termcap locations.
198a81407apeter */
199a81407apeter#ifdef USE_ROOT_ENVIRON
200a81407apeter#define use_terminfo_vars() 1
201a81407apeter#else
202a81407apeter#define use_terminfo_vars() _nc_env_access()
203b7ada7fpeterextern NCURSES_EXPORT(int) _nc_env_access (void);
204a81407apeter#endif
205a81407apeter
206a81407apeter/*
207bacd15cpeter * Not all platforms have memmove; some have an equivalent bcopy.  (Some may
208bacd15cpeter * have neither).
209bacd15cpeter */
210bacd15cpeter#if USE_OK_BCOPY
211bacd15cpeter#define memmove(d,s,n) bcopy(s,d,n)
212bacd15cpeter#elif USE_MY_MEMMOVE
213bacd15cpeter#define memmove(d,s,n) _nc_memmove(d,s,n)
214b7ada7fpeterextern NCURSES_EXPORT(void *) _nc_memmove (void *, const void *, size_t);
215bacd15cpeter#endif
216bacd15cpeter
217bacd15cpeter/*
2181034bfcdelphij * If we have va_copy(), use it for assigning va_list's.
2191034bfcdelphij */
2201034bfcdelphij#if defined(HAVE___VA_COPY)
2211034bfcdelphij#define begin_va_copy(dst,src)	__va_copy(dst, src)
2221034bfcdelphij#define end_va_copy(dst)	va_end(dst)
2231034bfcdelphij#elif defined(va_copy) || defined(HAVE_VA_COPY)
2241034bfcdelphij#define begin_va_copy(dst,src)	va_copy(dst, src)
2251034bfcdelphij#define end_va_copy(dst)	va_end(dst)
2261034bfcdelphij#else
2271034bfcdelphij#define begin_va_copy(dst,src) (dst) = (src)
2281034bfcdelphij#define end_va_copy(dst)	/* nothing */
2291034bfcdelphij#endif
2301034bfcdelphij
2311034bfcdelphij/*
2327dbeededelphij * Either/both S_ISxxx and/or S_IFxxx are defined in sys/types.h; some systems
2337dbeededelphij * lack one or the other.
2347dbeededelphij */
2357dbeededelphij#ifndef S_ISDIR
2367dbeededelphij#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
2377dbeededelphij#endif
2387dbeededelphij
2397dbeededelphij#ifndef S_ISREG
2407dbeededelphij#define S_ISREG(mode) ((mode & S_IFMT) == S_IFREG)
2417dbeededelphij#endif
2427dbeededelphij
2437dbeededelphij/*
244f52ca6ebapt * POSIX ignores the "b", which c89 specified.  Some very old systems do not
245f52ca6ebapt * accept it.
246f52ca6ebapt */
247f52ca6ebapt#if USE_FOPEN_BIN_R
248f52ca6ebapt#define BIN_R	"rb"
249f52ca6ebapt#define BIN_W	"wb"
250f52ca6ebapt#else
251f52ca6ebapt#define BIN_R	"r"
252f52ca6ebapt#define BIN_W	"w"
253f52ca6ebapt#endif
254f52ca6ebapt
255f52ca6ebapt/*
256bacd15cpeter * Scroll hints are useless when hashmap is used
257bacd15cpeter */
258bacd15cpeter#if !USE_SCROLL_HINTS
259bacd15cpeter#if !USE_HASHMAP
260bacd15cpeter#define USE_SCROLL_HINTS 1
261bacd15cpeter#else
262bacd15cpeter#define USE_SCROLL_HINTS 0
263bacd15cpeter#endif
264bacd15cpeter#endif
265bacd15cpeter
266bacd15cpeter#if USE_SCROLL_HINTS
267bacd15cpeter#define if_USE_SCROLL_HINTS(stmt) stmt
268bacd15cpeter#else
269bacd15cpeter#define if_USE_SCROLL_HINTS(stmt) /*nothing*/
270bacd15cpeter#endif
271bacd15cpeter
2727dbeededelphij#include <nc_string.h>
2737dbeededelphij
274bacd15cpeter/*
2751034bfcdelphij * Options for terminal drivers, etc...
2761034bfcdelphij */
2771034bfcdelphij#ifdef USE_TERM_DRIVER
2781034bfcdelphij#define USE_SP_RIPOFF     1
2791034bfcdelphij#define USE_SP_TERMTYPE   1
2801034bfcdelphij#define USE_SP_WINDOWLIST 1
2811034bfcdelphij#endif
2821034bfcdelphij
2831034bfcdelphij/*
284bacd15cpeter * Note:  ht/cbt expansion flakes out randomly under Linux 1.1.47, but only
285bacd15cpeter * when we're throwing control codes at the screen at high volume.  To see
286bacd15cpeter * this, re-enable USE_HARD_TABS and run worm for a while.  Other systems
287bacd15cpeter * probably don't want to define this either due to uncertainties about tab
288bacd15cpeter * delays and expansion in raw mode.
289bacd15cpeter */
290bacd15cpeter
2919f9e55frafan#define TRIES struct tries
2929f9e55frafantypedef TRIES {
2939f9e55frafan	TRIES    *child;            /* ptr to child.  NULL if none          */
2949f9e55frafan	TRIES    *sibling;          /* ptr to sibling.  NULL if none        */
295bacd15cpeter	unsigned char    ch;        /* character at this node               */
296bacd15cpeter	unsigned short   value;     /* code of string so far.  0 if none.   */
2979f9e55frafan#undef TRIES
2989f9e55frafan} TRIES;
299bacd15cpeter
300bacd15cpeter/*
301bacd15cpeter * Common/troublesome character definitions
302bacd15cpeter */
3039f9e55frafan#define StringOf(ch) {ch, 0}
3049f9e55frafan
305bacd15cpeter#define L_BRACE '{'
306bacd15cpeter#define R_BRACE '}'
307bacd15cpeter#define S_QUOTE '\''
3089a7523dpeter#define D_QUOTE '"'
309bacd15cpeter
310bbc1d3eache#define VT_ACSC "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~"
311bbc1d3eache
312bacd15cpeter/*
313bacd15cpeter * Structure for palette tables
314bacd15cpeter */
315bacd15cpeter
316bacd15cpeter#define MAXCOLUMNS    135
317bacd15cpeter#define MAXLINES      66
318bacd15cpeter#define FIFO_SIZE     MAXCOLUMNS+2  /* for nocbreak mode input */
319bacd15cpeter
320bacd15cpeter#define ACS_LEN       128
321bacd15cpeter
322bacd15cpeter#define WINDOWLIST struct _win_list
323bacd15cpeter
3249a7523dpeter#if USE_WIDEC_SUPPORT
3259a7523dpeter#define _nc_bkgd    _bkgrnd
3269a7523dpeter#else
3279a7523dpeter#undef _XOPEN_SOURCE_EXTENDED
3281034bfcdelphij#undef _XPG5
3299a7523dpeter#define _nc_bkgd    _bkgd
330f52ca6ebapt#define wgetbkgrnd(win, wch)	((*wch = win->_bkgd) != 0 ? OK : ERR)
3319a7523dpeter#define wbkgrnd	    wbkgd
3329a7523dpeter#endif
3339a7523dpeter
3349f9e55frafan#undef NCURSES_OPAQUE
3359f9e55frafan#define NCURSES_INTERNALS 1
3369f9e55frafan#define NCURSES_OPAQUE 0
3379f9e55frafan
338bacd15cpeter#include <curses.h>	/* we'll use -Ipath directive to get the right one! */
3391034bfcdelphij
3407dbeededelphijtypedef struct
3417dbeededelphij{
342f52ca6ebapt    int red, green, blue;	/* what color_content() returns */
343f52ca6ebapt    int r, g, b;		/* params to init_color() */
3447dbeededelphij    int init;			/* true if we called init_color() */
3457dbeededelphij}
3467dbeededelphijcolor_t;
3477dbeededelphij
348f52ca6ebapttypedef union {
349f52ca6ebapt    struct {
350f52ca6ebapt	unsigned char red;
351f52ca6ebapt	unsigned char green;
352f52ca6ebapt	unsigned char blue;
353f52ca6ebapt    } bits;			/* bits per color-value in RGB */
354f52ca6ebapt    unsigned value;
355f52ca6ebapt} rgb_bits_t;
356f52ca6ebapt
3571034bfcdelphij/*
3581034bfcdelphij * If curses.h did not expose the SCREEN-functions, then we do not need the
3591034bfcdelphij * parameter in the corresponding unextended functions.
3601034bfcdelphij */
3611034bfcdelphij
3621034bfcdelphij#define USE_SP_FUNC_SUPPORT     NCURSES_SP_FUNCS
3631034bfcdelphij#define USE_EXT_SP_FUNC_SUPPORT (NCURSES_SP_FUNCS && NCURSES_EXT_FUNCS)
3641034bfcdelphij
3651034bfcdelphij#if NCURSES_SP_FUNCS
3661034bfcdelphij#define SP_PARM         sp	/* use parameter */
3671034bfcdelphij#define NCURSES_SP_ARG          SP_PARM
3681034bfcdelphij#define NCURSES_SP_DCL  SCREEN *NCURSES_SP_ARG
3691034bfcdelphij#define NCURSES_SP_DCL0 NCURSES_SP_DCL
3701034bfcdelphij#define NCURSES_SP_ARGx         NCURSES_SP_ARG,
3711034bfcdelphij#define NCURSES_SP_DCLx SCREEN *NCURSES_SP_ARGx
3721034bfcdelphij#else
3731034bfcdelphij#define SP_PARM         SP	/* use global variable */
3741034bfcdelphij#define NCURSES_SP_ARG
3751034bfcdelphij#define NCURSES_SP_DCL
3761034bfcdelphij#define NCURSES_SP_DCL0 void
3771034bfcdelphij#define NCURSES_SP_ARGx
3781034bfcdelphij#define NCURSES_SP_DCLx
3791034bfcdelphij#endif
3801034bfcdelphij
3811034bfcdelphij#include <nc_panel.h>
3821034bfcdelphij
383f52ca6ebapt#include <term.h>
384f52ca6ebapt#include <nc_termios.h>
385f52ca6ebapt
3861034bfcdelphij#define IsPreScreen(sp)      (((sp) != 0) && sp->_prescreen)
3871034bfcdelphij#define HasTerminal(sp)      (((sp) != 0) && (0 != ((sp)->_term)))
3881034bfcdelphij#define IsValidScreen(sp)    (HasTerminal(sp) && !IsPreScreen(sp))
3891034bfcdelphij
3907dbeededelphij#if USE_REENTRANT
3911034bfcdelphij#define CurTerm              _nc_prescreen._cur_term
3921034bfcdelphij#else
3931034bfcdelphij#define CurTerm              cur_term
3941034bfcdelphij#endif
3951034bfcdelphij
3961034bfcdelphij#if NCURSES_SP_FUNCS
3971034bfcdelphij#define TerminalOf(sp)       ((sp) ? ((sp)->_term ? (sp)->_term : CurTerm) : CurTerm)
3981034bfcdelphij#else
3991034bfcdelphij#define TerminalOf(sp)       CurTerm
4001034bfcdelphij#endif
4011034bfcdelphij
402f52ca6ebapt/*
403f52ca6ebapt * The legacy layout for TERMTYPE uses "short" for all of the numbers.  Moving
404f52ca6ebapt * past that, numeric capabilities can be "int" by using a TERMTYPE2 structure
405f52ca6ebapt * in TERMINAL, and doing most of the internal work using TERMTYPE2.  There are
406f52ca6ebapt * a few places (mostly to expose the legacy layout) where the distinction
407f52ca6ebapt * needs attention.
408f52ca6ebapt */
409f52ca6ebapt#if NCURSES_EXT_COLORS && HAVE_INIT_EXTENDED_COLOR
410f52ca6ebapt#define NCURSES_EXT_NUMBERS  1
411f52ca6ebapt#define NCURSES_INT2         int
412f52ca6ebapt#define SIZEOF_INT2          4
413f52ca6ebapt#define TerminalType(tp)     (tp)->type2
414f52ca6ebapt#else
415f52ca6ebapt#define NCURSES_EXT_NUMBERS  0
416f52ca6ebapt#define NCURSES_INT2         short
417f52ca6ebapt#define SIZEOF_INT2          2
418f52ca6ebapt#define TerminalType(tp)     (tp)->type
419f52ca6ebapt#endif
420f52ca6ebapt
421f52ca6ebapt#define SIZEOF_SHORT         2
422f52ca6ebapt
423f52ca6ebapt#ifdef CUR
424f52ca6ebapt#undef CUR
425f52ca6ebapt#define CUR TerminalType(cur_term).
426f52ca6ebapt#endif
4271034bfcdelphij
4281034bfcdelphij/*
4291034bfcdelphij * Reduce dependency on cur_term global by using terminfo data from SCREEN's
4301034bfcdelphij * pointer to this data.
4311034bfcdelphij */
4321034bfcdelphij#ifdef USE_SP_TERMTYPE
4331034bfcdelphij#undef CUR
4341034bfcdelphij#endif
4351034bfcdelphij
436f52ca6ebapt#define SP_TERMTYPE TerminalType(TerminalOf(sp)).
4371034bfcdelphij
438de9cbefrafan#include <term_entry.h>
4391034bfcdelphij
440de9cbefrafan#include <nc_tparm.h>
441de9cbefrafan
4421034bfcdelphij/*
4437dbeededelphij * Simplify ifdef's for the "*_ATTR" macros in case italics are not configured.
4447dbeededelphij */
445f52ca6ebapt#if defined(A_ITALIC) && defined(exit_italics_mode)
4467dbeededelphij#define USE_ITALIC 1
4477dbeededelphij#else
4487dbeededelphij#define USE_ITALIC 0
449f52ca6ebapt#undef  A_ITALIC
4507dbeededelphij#define A_ITALIC 0
4517dbeededelphij#endif
4527dbeededelphij
4537dbeededelphij/*
4541034bfcdelphij * Use these macros internally, to make tracing less verbose.  But leave the
4551034bfcdelphij * option for compiling the tracing into the library.
4561034bfcdelphij */
4571034bfcdelphij#if 1
458f52ca6ebapt#define ColorPair(n)		(NCURSES_BITS(n, 0) & A_COLOR)
4591034bfcdelphij#define PairNumber(a)		(NCURSES_CAST(int,(((unsigned long)(a) & A_COLOR) >> NCURSES_ATTR_SHIFT)))
4601034bfcdelphij#else
4611034bfcdelphij#define ColorPair(pair)		COLOR_PAIR(pair)
4621034bfcdelphij#define PairNumber(attr)	PAIR_NUMBER(attr)
4631034bfcdelphij#endif
4641034bfcdelphij
4651034bfcdelphij#define unColor(n)		unColor2(AttrOf(n))
4661034bfcdelphij#define unColor2(a)		((a) & ALL_BUT_COLOR)
4671034bfcdelphij
4681034bfcdelphij/*
4691034bfcdelphij * Extended-colors stores the color pair in a separate struct-member than the
4701034bfcdelphij * attributes.  But for compatibility, we handle most cases where a program
4711034bfcdelphij * written for non-extended colors stores the color in the attributes by
4721034bfcdelphij * checking for a color pair in both places.
4731034bfcdelphij */
4741034bfcdelphij#if NCURSES_EXT_COLORS
475de9cbefrafan#define if_EXT_COLORS(stmt)	stmt
4761034bfcdelphij#define SetPair(value,p)	SetPair2((value).ext_color, AttrOf(value), p)
4771034bfcdelphij#define SetPair2(c,a,p)		c = (p), \
478f52ca6ebapt				a = (unColor2(a) | ColorPair(oldColor(c)))
4791034bfcdelphij#define GetPair(value)		GetPair2((value).ext_color, AttrOf(value))
4801034bfcdelphij#define GetPair2(c,a)		((c) ? (c) : PairNumber(a))
4811034bfcdelphij#define oldColor(p)		(((p) > 255) ? 255 : (p))
4821034bfcdelphij#define GET_WINDOW_PAIR(w)	GetPair2((w)->_color, (w)->_attrs)
483de9cbefrafan#define SET_WINDOW_PAIR(w,p)	(w)->_color = (p)
484de9cbefrafan#define SameAttrOf(a,b)		(AttrOf(a) == AttrOf(b) && GetPair(a) == GetPair(b))
4851034bfcdelphij
486f52ca6ebapt#define VIDPUTS(sp,attr,pair)	do { \
487f52ca6ebapt				    int vid_pair = pair; \
488f52ca6ebapt				    NCURSES_SP_NAME(vid_puts)( \
489f52ca6ebapt					NCURSES_SP_ARGx attr, \
490f52ca6ebapt					(NCURSES_PAIRS_T) pair, \
491f52ca6ebapt					&vid_pair, \
492f52ca6ebapt					NCURSES_OUTC_FUNC); \
493f52ca6ebapt				} while (0)
4941034bfcdelphij
4951034bfcdelphij#else /* !NCURSES_EXT_COLORS */
4961034bfcdelphij
497de9cbefrafan#define if_EXT_COLORS(stmt)	/* nothing */
498de9cbefrafan#define SetPair(value,p)	RemAttr(value, A_COLOR), \
499f52ca6ebapt				SetAttr(value, AttrOf(value) | ColorPair(p))
5001034bfcdelphij#define GetPair(value)		PairNumber(AttrOf(value))
5011034bfcdelphij#define GET_WINDOW_PAIR(w)	PairNumber(WINDOW_ATTRS(w))
502de9cbefrafan#define SET_WINDOW_PAIR(w,p)	WINDOW_ATTRS(w) &= ALL_BUT_COLOR, \
503f52ca6ebapt				WINDOW_ATTRS(w) |= ColorPair(p)
504de9cbefrafan#define SameAttrOf(a,b)		(AttrOf(a) == AttrOf(b))
5051034bfcdelphij
506f52ca6ebapt#define VIDPUTS(sp,attr,pair)	NCURSES_SP_NAME(vidputs)(NCURSES_SP_ARGx attr, NCURSES_OUTC_FUNC)
507de9cbefrafan
5081034bfcdelphij#endif /* NCURSES_EXT_COLORS */
5091034bfcdelphij
5107dbeededelphij#define NCURSES_OUTC_FUNC       NCURSES_SP_NAME(_nc_outch)
5117dbeededelphij#define NCURSES_PUTP2(name,value)    NCURSES_SP_NAME(_nc_putp)(NCURSES_SP_ARGx name, value)
5127dbeededelphij#define NCURSES_PUTP2_FLUSH(name,value)    NCURSES_SP_NAME(_nc_putp_flush)(NCURSES_SP_ARGx name, value)
5137dbeededelphij
514d078158rafan#if NCURSES_NO_PADDING
515d078158rafan#define GetNoPadding(sp)	((sp) ? (sp)->_no_padding : _nc_prescreen._no_padding)
516d078158rafan#define SetNoPadding(sp)	_nc_set_no_padding(sp)
5171034bfcdelphijextern NCURSES_EXPORT(void)     _nc_set_no_padding(SCREEN *);
518d078158rafan#else
519d078158rafan#define GetNoPadding(sp)	FALSE
520d078158rafan#define SetNoPadding(sp)	/*nothing*/
521d078158rafan#endif
522d078158rafan
523de9cbefrafan#define WINDOW_ATTRS(w)		((w)->_attrs)
524de9cbefrafan
525de9cbefrafan#define SCREEN_ATTRS(s)		(*((s)->_current_attr))
526de9cbefrafan#define GET_SCREEN_PAIR(s)	GetPair(SCREEN_ATTRS(s))
527de9cbefrafan#define SET_SCREEN_PAIR(s,p)	SetPair(SCREEN_ATTRS(s), p)
528bacd15cpeter
5291034bfcdelphij#if USE_REENTRANT || NCURSES_SP_FUNCS
5301034bfcdelphijNCURSES_EXPORT(int *)        _nc_ptr_Lines (SCREEN *);
5311034bfcdelphijNCURSES_EXPORT(int *)        _nc_ptr_Cols (SCREEN *);
5321034bfcdelphijNCURSES_EXPORT(int *)        _nc_ptr_Tabsize (SCREEN *);
5331034bfcdelphijNCURSES_EXPORT(int *)        _nc_ptr_Escdelay (SCREEN *);
5341034bfcdelphij#endif
5351034bfcdelphij
5369f9e55frafan#if USE_REENTRANT
5371034bfcdelphij
5381034bfcdelphij#define ptrLines(sp)         (sp ? &(sp->_LINES) : &(_nc_prescreen._LINES))
5391034bfcdelphij#define ptrCols(sp)          (sp ? &(sp->_COLS) : &(_nc_prescreen._COLS))
5401034bfcdelphij#define ptrTabsize(sp)       (sp ? &(sp->_TABSIZE) : &(_nc_prescreen._TABSIZE))
5411034bfcdelphij#define ptrEscdelay(sp)      (sp ? &(sp->_ESCDELAY) : &(_nc_prescreen._ESCDELAY))
5421034bfcdelphij
5431034bfcdelphij#define SET_LINES(value)     *_nc_ptr_Lines(SP_PARM) = value
5441034bfcdelphij#define SET_COLS(value)      *_nc_ptr_Cols(SP_PARM) = value
5451034bfcdelphij#define SET_TABSIZE(value)   *_nc_ptr_Tabsize(SP_PARM) = value
5461034bfcdelphij#define SET_ESCDELAY(value)  *_nc_ptr_Escdelay(SP_PARM) = value
5471034bfcdelphij
5489f9e55frafan#else
5491034bfcdelphij
5501034bfcdelphij#define ptrLines(sp)         &LINES
5511034bfcdelphij#define ptrCols(sp)          &COLS
5521034bfcdelphij#define ptrTabsize(sp)       &TABSIZE
5531034bfcdelphij#define ptrEscdelay(sp)      &ESCDELAY
5541034bfcdelphij
5551034bfcdelphij#define SET_LINES(value)     LINES = value
5561034bfcdelphij#define SET_COLS(value)      COLS = value
5571034bfcdelphij#define SET_TABSIZE(value)   TABSIZE = value
5581034bfcdelphij#define SET_ESCDELAY(value)  ESCDELAY = value
5591034bfcdelphij
5609f9e55frafan#endif
5619f9e55frafan
562f52ca6ebapt#define HasHardTabs()	(NonEmpty(clear_all_tabs) && NonEmpty(set_tab))
563f52ca6ebapt
5649f9e55frafan#define TR_MUTEX(data) _tracef("%s@%d: me:%08lX COUNT:%2u/%2d/%6d/%2d/%s%9u: " #data, \
5659f9e55frafan	    __FILE__, __LINE__, \
5669f9e55frafan	    (unsigned long) (pthread_self()), \
5679f9e55frafan	    data.__data.__lock, \
5689f9e55frafan	    data.__data.__count, \
5699f9e55frafan	    data.__data.__owner, \
5709f9e55frafan	    data.__data.__kind, \
5719f9e55frafan	    (data.__data.__nusers > 5) ? " OOPS " : "", \
5729f9e55frafan	    data.__data.__nusers)
5739f9e55frafan#define TR_GLOBAL_MUTEX(name) TR_MUTEX(_nc_globals.mutex_##name)
5749f9e55frafan
5751034bfcdelphij#if USE_WEAK_SYMBOLS
5761034bfcdelphij#if defined(__GNUC__)
5771034bfcdelphij#  if defined __USE_ISOC99
5781034bfcdelphij#    define _cat_pragma(exp)	_Pragma(#exp)
5791034bfcdelphij#    define _weak_pragma(exp)	_cat_pragma(weak name)
5801034bfcdelphij#  else
5811034bfcdelphij#    define _weak_pragma(exp)
5821034bfcdelphij#  endif
5831034bfcdelphij#  define _declare(name)	__extension__ extern __typeof__(name) name
5841034bfcdelphij#  define weak_symbol(name)	_weak_pragma(name) _declare(name) __attribute__((weak))
5857dbeededelphij#else
5867dbeededelphij#  undef USE_WEAK_SYMBOLS
5877dbeededelphij#  define USE_WEAK_SYMBOLS 0
5881034bfcdelphij#endif
5891034bfcdelphij#endif
5901034bfcdelphij
5919f9e55frafan#ifdef USE_PTHREADS
592d036c70rafan
5939f9e55frafan#if USE_REENTRANT
5949f9e55frafan#include <pthread.h>
595d078158rafanextern NCURSES_EXPORT(void) _nc_init_pthreads(void);
596d036c70rafanextern NCURSES_EXPORT(void) _nc_mutex_init(pthread_mutex_t *);
59732c0e5frafanextern NCURSES_EXPORT(int) _nc_mutex_lock(pthread_mutex_t *);
59832c0e5frafanextern NCURSES_EXPORT(int) _nc_mutex_trylock(pthread_mutex_t *);
59932c0e5frafanextern NCURSES_EXPORT(int) _nc_mutex_unlock(pthread_mutex_t *);
60032c0e5frafan#define _nc_lock_global(name)	_nc_mutex_lock(&_nc_globals.mutex_##name)
60132c0e5frafan#define _nc_try_global(name)    _nc_mutex_trylock(&_nc_globals.mutex_##name)
60232c0e5frafan#define _nc_unlock_global(name)	_nc_mutex_unlock(&_nc_globals.mutex_##name)
6039f9e55frafan
6049f9e55frafan#else
6059f9e55frafan#error POSIX threads requires --enable-reentrant option
6069f9e55frafan#endif
607d036c70rafan
608d078158rafan#ifdef USE_PTHREADS
609d078158rafan#  if USE_WEAK_SYMBOLS
610d078158rafanweak_symbol(pthread_sigmask);
6111034bfcdelphijweak_symbol(pthread_kill);
612d078158rafanweak_symbol(pthread_self);
613d078158rafanweak_symbol(pthread_equal);
614d078158rafanweak_symbol(pthread_mutex_init);
615d078158rafanweak_symbol(pthread_mutex_lock);
616d078158rafanweak_symbol(pthread_mutex_unlock);
617d078158rafanweak_symbol(pthread_mutex_trylock);
618d078158rafanweak_symbol(pthread_mutexattr_settype);
619d078158rafanweak_symbol(pthread_mutexattr_init);
620d078158rafanextern NCURSES_EXPORT(int) _nc_sigprocmask(int, const sigset_t *, sigset_t *);
621d078158rafan#    undef  sigprocmask
622f52ca6ebapt#    define sigprocmask(a, b, c) _nc_sigprocmask(a, b, c)
623f52ca6ebapt#    define GetThreadID() (((pthread_self)) ? pthread_self() : (pthread_t) getpid())
624f52ca6ebapt#  else
625f52ca6ebapt#    define GetThreadID() pthread_self()
626d078158rafan#  endif
627d078158rafan#endif
628d078158rafan
629d036c70rafan#if HAVE_NANOSLEEP
630d036c70rafan#undef HAVE_NANOSLEEP
631d036c70rafan#define HAVE_NANOSLEEP 0	/* nanosleep suspends all threads */
632d036c70rafan#endif
633d036c70rafan
634d036c70rafan#else /* !USE_PTHREADS */
635d036c70rafan
6361034bfcdelphij#if USE_PTHREADS_EINTR
6371034bfcdelphij#  if USE_WEAK_SYMBOLS
6381034bfcdelphij#include <pthread.h>
6391034bfcdelphijweak_symbol(pthread_sigmask);
6401034bfcdelphijweak_symbol(pthread_kill);
6411034bfcdelphijweak_symbol(pthread_self);
6421034bfcdelphijweak_symbol(pthread_equal);
6431034bfcdelphijextern NCURSES_EXPORT(int) _nc_sigprocmask(int, const sigset_t *, sigset_t *);
6441034bfcdelphij#    undef  sigprocmask
645f52ca6ebapt#    define sigprocmask(a, b, c) _nc_sigprocmask(a, b, c)
6461034bfcdelphij#  endif
6471034bfcdelphij#endif /* USE_PTHREADS_EINTR */
6481034bfcdelphij
649d078158rafan#define _nc_init_pthreads()	/* nothing */
650d036c70rafan#define _nc_mutex_init(obj)	/* nothing */
651d036c70rafan
6529f9e55frafan#define _nc_lock_global(name)	/* nothing */
6539f9e55frafan#define _nc_try_global(name)    0
6549f9e55frafan#define _nc_unlock_global(name)	/* nothing */
6559f9e55frafan
656d036c70rafan#endif /* USE_PTHREADS */
6579f9e55frafan
6581034bfcdelphij/*
6591034bfcdelphij * When using sp-funcs, locks are targeted to SCREEN-level granularity.
6601034bfcdelphij * So the locking is done in the non-sp-func (which calls the sp-func) rather
6611034bfcdelphij * than in the sp-func itself.
6621034bfcdelphij *
6631034bfcdelphij * Use the _nc_nonsp_XXX functions in the function using "NCURSES_SP_NAME()".
6641034bfcdelphij * Use the _nc_sp_XXX functions in the function using "#if NCURSES_SP_FUNCS".
6651034bfcdelphij */
6661034bfcdelphij#if NCURSES_SP_FUNCS
6671034bfcdelphij
6681034bfcdelphij#define _nc_nonsp_lock_global(name)	/* nothing */
6691034bfcdelphij#define _nc_nonsp_try_global(name)    0
6701034bfcdelphij#define _nc_nonsp_unlock_global(name)	/* nothing */
6711034bfcdelphij
6721034bfcdelphij#define _nc_sp_lock_global(name)	_nc_lock_global(name)
6731034bfcdelphij#define _nc_sp_try_global(name)         _nc_try_global(name)
6741034bfcdelphij#define _nc_sp_unlock_global(name)	_nc_unlock_global(name)
6751034bfcdelphij
6761034bfcdelphij#else
6771034bfcdelphij
6781034bfcdelphij#define _nc_nonsp_lock_global(name)	_nc_lock_global(name)
6791034bfcdelphij#define _nc_nonsp_try_global(name)      _nc_try_global(name)
6801034bfcdelphij#define _nc_nonsp_unlock_global(name)	_nc_unlock_global(name)
6811034bfcdelphij
6821034bfcdelphij#define _nc_sp_lock_global(name)	/* nothing */
6831034bfcdelphij#define _nc_sp_try_global(name)    0
6841034bfcdelphij#define _nc_sp_unlock_global(name)	/* nothing */
6851034bfcdelphij
6861034bfcdelphij#endif
6871034bfcdelphij
688d036c70rafan#if HAVE_GETTIMEOFDAY
689d036c70rafan# define PRECISE_GETTIME 1
690d036c70rafan# define TimeType struct timeval
691d036c70rafan#else
692d036c70rafan# define PRECISE_GETTIME 0
693d036c70rafan# define TimeType time_t
694d036c70rafan#endif
6959f9e55frafan
696de9cbefrafan/*
697de9cbefrafan * Definitions for color pairs
698de9cbefrafan */
699de9cbefrafan
700f52ca6ebapt#define MAX_OF_TYPE(t)   (int)(((unsigned t)(~0))>>1)
701f52ca6ebapt
702f52ca6ebapt#include <new_pair.h>
703f52ca6ebapt
704f52ca6ebapt#define isDefaultColor(c)	((c) < 0)
705f52ca6ebapt#define COLOR_DEFAULT		-1
706de9cbefrafan
7071034bfcdelphij#if defined(USE_BUILD_CC) || (defined(USE_TERMLIB) && !defined(NEED_NCURSES_CH_T))
708de9cbefrafan
709de9cbefrafan#undef NCURSES_CH_T		/* this is not a termlib feature */
710de9cbefrafan#define NCURSES_CH_T void	/* ...but we need a pointer in SCREEN */
711de9cbefrafan
712de9cbefrafan#endif	/* USE_TERMLIB */
713de9cbefrafan
714de9cbefrafan#ifndef USE_TERMLIB
7159a7523dpeterstruct ldat
7169a7523dpeter{
717de9cbefrafan	NCURSES_CH_T	*text;		/* text of the line */
718de9cbefrafan	NCURSES_SIZE_T	firstchar;	/* first changed character in the line */
719de9cbefrafan	NCURSES_SIZE_T	lastchar;	/* last changed character in the line */
720de9cbefrafan	NCURSES_SIZE_T	oldindex;	/* index of the line at last update */
7219a7523dpeter};
722de9cbefrafan#endif	/* USE_TERMLIB */
723de9cbefrafan
724de9cbefrafantypedef enum {
725de9cbefrafan	M_XTERM	= -1		/* use xterm's mouse tracking? */
726de9cbefrafan	,M_NONE = 0		/* no mouse device */
727de9cbefrafan#if USE_GPM_SUPPORT
728de9cbefrafan	,M_GPM			/* use GPM */
729de9cbefrafan#endif
730de9cbefrafan#if USE_SYSMOUSE
731de9cbefrafan	,M_SYSMOUSE		/* FreeBSD sysmouse on console */
732de9cbefrafan#endif
7331034bfcdelphij#ifdef USE_TERM_DRIVER
7341034bfcdelphij	,M_TERM_DRIVER		/* Win32 console, etc */
7351034bfcdelphij#endif
736de9cbefrafan} MouseType;
7379a7523dpeter
738f52ca6ebapttypedef enum {
739f52ca6ebapt    	MF_X10 = 0		/* conventional 3-byte format */
740f52ca6ebapt	, MF_SGR1006		/* xterm private mode 1006, SGR-style */
741f52ca6ebapt#ifdef EXP_XTERM_1005
742f52ca6ebapt	, MF_XTERM_1005		/* xterm UTF-8 private mode 1005 */
743f52ca6ebapt#endif
744f52ca6ebapt} MouseFormat;
745f52ca6ebapt
746bacd15cpeter/*
747de9cbefrafan * Structures for scrolling.
748bacd15cpeter */
749bacd15cpeter
750de9cbefrafantypedef struct {
751de9cbefrafan	unsigned long hashval;
752de9cbefrafan	int oldcount, newcount;
753de9cbefrafan	int oldindex, newindex;
754de9cbefrafan} HASHMAP;
755de9cbefrafan
756de9cbefrafan/*
757de9cbefrafan * Structures for soft labels.
758de9cbefrafan */
759de9cbefrafan
760de9cbefrafanstruct _SLK;
761de9cbefrafan
7621034bfcdelphij#if !(defined(USE_TERMLIB) || defined(USE_BUILD_CC))
763de9cbefrafan
764bacd15cpetertypedef struct
765bacd15cpeter{
766de9cbefrafan	char *ent_text;		/* text for the label */
767de9cbefrafan	char *form_text;	/* formatted text (left/center/...) */
768de9cbefrafan	int ent_x;		/* x coordinate of this field */
769de9cbefrafan	char dirty;		/* this label has changed */
770de9cbefrafan	char visible;		/* field is visible */
771bacd15cpeter} slk_ent;
772bacd15cpeter
773de9cbefrafantypedef struct _SLK {
7741034bfcdelphij	bool    dirty;		/* all labels have changed */
7751034bfcdelphij	bool    hidden;		/* soft labels are hidden */
7761034bfcdelphij	WINDOW  *win;
777bacd15cpeter	slk_ent *ent;
7781034bfcdelphij	short   maxlab;		/* number of available labels */
7791034bfcdelphij	short   labcnt;		/* number of allocated labels */
7801034bfcdelphij	short   maxlen;		/* length of labels */
781de9cbefrafan	NCURSES_CH_T attr;	/* soft label attribute */
782bacd15cpeter} SLK;
783bacd15cpeter
784de9cbefrafan#endif	/* USE_TERMLIB */
785de9cbefrafan
786de9cbefrafantypedef	struct {
78732c0e5frafan	WINDOW *win;		/* the window used in the hook      */
788de9cbefrafan	int	line;		/* lines to take, < 0 => from bottom*/
789de9cbefrafan	int	(*hook)(WINDOW *, int); /* callback for user	    */
790de9cbefrafan} ripoff_t;
791de9cbefrafan
792de9cbefrafan#if USE_GPM_SUPPORT
793de9cbefrafan#undef buttons			/* term.h defines this, and gpm uses it! */
794de9cbefrafan#include <gpm.h>
7957dbeededelphij#if USE_WEAK_SYMBOLS
7967dbeededelphijweak_symbol(Gpm_Wgetch);
7977dbeededelphij#endif
798de9cbefrafan
799de9cbefrafan#ifdef HAVE_LIBDL
800de9cbefrafan/* link dynamically to GPM */
801de9cbefrafantypedef int *TYPE_gpm_fd;
802de9cbefrafantypedef int (*TYPE_Gpm_Open) (Gpm_Connect *, int);
803de9cbefrafantypedef int (*TYPE_Gpm_Close) (void);
804de9cbefrafantypedef int (*TYPE_Gpm_GetEvent) (Gpm_Event *);
805de9cbefrafan
8061034bfcdelphij#define my_gpm_fd       SP_PARM->_mouse_gpm_fd
8071034bfcdelphij#define my_Gpm_Open     SP_PARM->_mouse_Gpm_Open
8081034bfcdelphij#define my_Gpm_Close    SP_PARM->_mouse_Gpm_Close
8091034bfcdelphij#define my_Gpm_GetEvent SP_PARM->_mouse_Gpm_GetEvent
810de9cbefrafan#else
811de9cbefrafan/* link statically to GPM */
812de9cbefrafan#define my_gpm_fd       &gpm_fd
813de9cbefrafan#define my_Gpm_Open     Gpm_Open
814de9cbefrafan#define my_Gpm_Close    Gpm_Close
815de9cbefrafan#define my_Gpm_GetEvent Gpm_GetEvent
816de9cbefrafan#endif /* HAVE_LIBDL */
817de9cbefrafan#endif /* USE_GPM_SUPPORT */
818de9cbefrafan
8199f9e55frafantypedef struct {
8209f9e55frafan    long sequence;
8219f9e55frafan    bool last_used;
8229f9e55frafan    char *fix_sgr0;		/* this holds the filtered sgr0 string */
8239f9e55frafan    char *last_bufp;		/* help with fix_sgr0 leak */
8249f9e55frafan    TERMINAL *last_term;
8259f9e55frafan} TGETENT_CACHE;
8269f9e55frafan
8279f9e55frafan#define TGETENT_MAX 4
8289f9e55frafan
8299f9e55frafan/*
830f52ca6ebapt * When converting from terminfo to termcap, check for cases where we can trim
831f52ca6ebapt * octal escapes down to 2-character form.  It is useful for terminfo format
832f52ca6ebapt * also, but not as important.
833f52ca6ebapt */
834f52ca6ebapt#define MAX_TC_FIXUPS	10
835f52ca6ebapt#define MIN_TC_FIXUPS	4
836f52ca6ebapt
837f52ca6ebapt#define isoctal(c) ((c) >= '0' && (c) <= '7')
838f52ca6ebapt
839f52ca6ebapt/*
8409f9e55frafan * State of tparm().
8419f9e55frafan */
8429f9e55frafan#define STACKSIZE 20
8439f9e55frafan
8449f9e55frafantypedef struct {
8459f9e55frafan	union {
8469f9e55frafan		int	num;
8479f9e55frafan		char	*str;
8489f9e55frafan	} data;
8499f9e55frafan	bool num_type;
8509f9e55frafan} STACK_FRAME;
8519f9e55frafan
8529f9e55frafan#define NUM_VARS 26
8539f9e55frafan
8549f9e55frafantypedef struct {
8559f9e55frafan	const char	*tparam_base;
8569f9e55frafan
8579f9e55frafan	STACK_FRAME	stack[STACKSIZE];
8589f9e55frafan	int		stack_ptr;
8599f9e55frafan
8609f9e55frafan	char		*out_buff;
8619f9e55frafan	size_t		out_size;
8629f9e55frafan	size_t		out_used;
8639f9e55frafan
8649f9e55frafan	char		*fmt_buff;
8659f9e55frafan	size_t		fmt_size;
8669f9e55frafan
8679f9e55frafan	int		dynamic_var[NUM_VARS];
8689f9e55frafan	int		static_vars[NUM_VARS];
869f52ca6ebapt#ifdef TRACE
870f52ca6ebapt	const char	*tname;
871f52ca6ebapt#endif
8729f9e55frafan} TPARM_STATE;
8739f9e55frafan
8749f9e55frafantypedef struct {
8759f9e55frafan    char *text;
8769f9e55frafan    size_t size;
8779f9e55frafan} TRACEBUF;
8789f9e55frafan
8799f9e55frafan/*
8809f9e55frafan * The filesystem database normally uses a single-letter for the lower level
8819f9e55frafan * of directories.  Use a hexadecimal code for filesystems which do not
8829f9e55frafan * preserve mixed-case names.
8839f9e55frafan */
8849f9e55frafan#if MIXEDCASE_FILENAMES
8859f9e55frafan#define LEAF_FMT "%c"
8861034bfcdelphij#define LEAF_LEN 1
8879f9e55frafan#else
8889f9e55frafan#define LEAF_FMT "%02x"
8891034bfcdelphij#define LEAF_LEN 2
8909f9e55frafan#endif
8919f9e55frafan
8929f9e55frafan/*
8939f9e55frafan * TRACEMSE_FMT is no longer than 80 columns, there are 5 numbers that
8949f9e55frafan * could at most have 10 digits, and the mask contains no more than 32 bits
8959f9e55frafan * with each bit representing less than 15 characters.  Usually the whole
8969f9e55frafan * string is less than 80 columns, but this buffer size is an absolute
8979f9e55frafan * limit.
8989f9e55frafan */
8999f9e55frafan#define TRACEMSE_MAX	(80 + (5 * 10) + (32 * 15))
9009f9e55frafan#define TRACEMSE_FMT	"id %2d  at (%2d, %2d, %2d) state %4lx = {" /* } */
9019f9e55frafan
9021034bfcdelphij#ifdef USE_TERM_DRIVER
9031034bfcdelphijstruct DriverTCB; /* Terminal Control Block forward declaration */
9041034bfcdelphij#define INIT_TERM_DRIVER()	_nc_globals.term_driver = _nc_get_driver
9051034bfcdelphij#else
9061034bfcdelphij#define INIT_TERM_DRIVER()	/* nothing */
9071034bfcdelphij#endif
9081034bfcdelphij
9097dbeededelphijtypedef struct {
9107dbeededelphij    const char *name;
9117dbeededelphij    char *value;
9127dbeededelphij} ITERATOR_VARS;
9137dbeededelphij
9149f9e55frafan/*
9159f9e55frafan * Global data which is not specific to a screen.
9169f9e55frafan */
9179f9e55frafantypedef struct {
9187dbeededelphij	SIG_ATOMIC_T	have_sigtstp;
9199f9e55frafan	SIG_ATOMIC_T	have_sigwinch;
9209f9e55frafan	SIG_ATOMIC_T	cleanup_nested;
9219f9e55frafan
9229f9e55frafan	bool		init_signals;
9239f9e55frafan	bool		init_screen;
9249f9e55frafan
9257dbeededelphij	char		*comp_sourcename;
9269f9e55frafan	char		*comp_termtype;
9279f9e55frafan
9289f9e55frafan	bool		have_tic_directory;
9299f9e55frafan	bool		keep_tic_directory;
9309f9e55frafan	const char	*tic_directory;
9319f9e55frafan
9329f9e55frafan	char		*dbi_list;
9339f9e55frafan	int		dbi_size;
9349f9e55frafan
9359f9e55frafan	char		*first_name;
9369f9e55frafan	char		**keyname_table;
9377dbeededelphij	int		init_keyname;
9389f9e55frafan
93932c0e5frafan	int		slk_format;
94032c0e5frafan
941f52ca6ebapt	int		getstr_limit;	/* getstr_limit based on POSIX LINE_MAX */
942f52ca6ebapt
9439f9e55frafan	char		*safeprint_buf;
9449f9e55frafan	size_t		safeprint_used;
9459f9e55frafan
9469f9e55frafan	TGETENT_CACHE	tgetent_cache[TGETENT_MAX];
9479f9e55frafan	int		tgetent_index;
9489f9e55frafan	long		tgetent_sequence;
9499f9e55frafan
9507dbeededelphij	char		*dbd_blob;	/* string-heap for dbd_list[] */
9517dbeededelphij	char		**dbd_list;	/* distinct places to look for data */
9527dbeededelphij	int		dbd_size;	/* length of dbd_list[] */
9537dbeededelphij	time_t		dbd_time;	/* cache last updated */
9547dbeededelphij	ITERATOR_VARS	dbd_vars[dbdLAST];
9557dbeededelphij
956f52ca6ebapt#ifdef USE_TERM_DRIVER
957f52ca6ebapt	int		(*term_driver)(struct DriverTCB*, const char*, int*);
958f52ca6ebapt#endif
959f52ca6ebapt
9601034bfcdelphij#ifndef USE_SP_WINDOWLIST
961d036c70rafan	WINDOWLIST	*_nc_windowlist;
9621034bfcdelphij#define WindowList(sp)	_nc_globals._nc_windowlist
9631034bfcdelphij#endif
964d036c70rafan
9659f9e55frafan#if USE_HOME_TERMINFO
9669f9e55frafan	char		*home_terminfo;
9679f9e55frafan#endif
9689f9e55frafan
9699f9e55frafan#if !USE_SAFE_SPRINTF
9709f9e55frafan	int		safeprint_cols;
9719f9e55frafan	int		safeprint_rows;
9729f9e55frafan#endif
9739f9e55frafan
974f52ca6ebapt#ifdef USE_PTHREADS
975f52ca6ebapt	pthread_mutex_t	mutex_curses;
976f52ca6ebapt	pthread_mutex_t	mutex_prescreen;
977f52ca6ebapt	pthread_mutex_t	mutex_screen;
978f52ca6ebapt	pthread_mutex_t	mutex_update;
979f52ca6ebapt	pthread_mutex_t	mutex_tst_tracef;
980f52ca6ebapt	pthread_mutex_t	mutex_tracef;
981f52ca6ebapt	int		nested_tracef;
982f52ca6ebapt	int		use_pthreads;
983f52ca6ebapt#define _nc_use_pthreads	_nc_globals.use_pthreads
984f52ca6ebapt#if USE_PTHREADS_EINTR
985f52ca6ebapt	pthread_t	read_thread;		/* The reading thread */
986f52ca6ebapt#endif
987f52ca6ebapt#endif
988f52ca6ebapt#if USE_WIDEC_SUPPORT
989f52ca6ebapt	char		key_name[MB_LEN_MAX + 1];
9901034bfcdelphij#endif
9911034bfcdelphij
9929f9e55frafan#ifdef TRACE
993f52ca6ebapt	bool		trace_opened;
9949f9e55frafan	char		trace_fname[PATH_MAX];
9959f9e55frafan	int		trace_level;
9969f9e55frafan	FILE		*trace_fp;
997f52ca6ebapt	int		trace_fd;
9989f9e55frafan
9999f9e55frafan	char		*tracearg_buf;
10009f9e55frafan	size_t		tracearg_used;
10019f9e55frafan
10029f9e55frafan	TRACEBUF	*tracebuf_ptr;
10039f9e55frafan	size_t		tracebuf_used;
10049f9e55frafan
10059f9e55frafan	char		tracechr_buf[40];
10069f9e55frafan
10079f9e55frafan	char		*tracedmp_buf;
10089f9e55frafan	size_t		tracedmp_used;
10099f9e55frafan
10109f9e55frafan	unsigned char	*tracetry_buf;
10119f9e55frafan	size_t		tracetry_used;
10129f9e55frafan
10139f9e55frafan	char		traceatr_color_buf[2][80];
10149f9e55frafan	int		traceatr_color_sel;
10159f9e55frafan	int		traceatr_color_last;
10161034bfcdelphij#if !defined(USE_PTHREADS) && USE_REENTRANT
10171034bfcdelphij	int		nested_tracef;
10181034bfcdelphij#endif
10199f9e55frafan#endif	/* TRACE */
10209f9e55frafan
1021f52ca6ebapt#if NO_LEAKS
1022f52ca6ebapt	bool		leak_checking;
10231034bfcdelphij#endif
10249f9e55frafan} NCURSES_GLOBALS;
10259f9e55frafan
10269f9e55frafanextern NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals;
10279f9e55frafan
10289f9e55frafan#define N_RIPS 5
10299f9e55frafan
1030f52ca6ebapt/* The limit reserves one byte for a terminating NUL */
1031f52ca6ebapt#define my_getstr_limit	(_nc_globals.getstr_limit - 1)
1032f52ca6ebapt#define _nc_getstr_limit(n) \
1033f52ca6ebapt	(((n) < 0) \
1034f52ca6ebapt	 ? my_getstr_limit \
1035f52ca6ebapt	 : (((n) > my_getstr_limit) \
1036f52ca6ebapt	    ? my_getstr_limit \
1037f52ca6ebapt	    : (n)))
1038f52ca6ebapt
1039f52ca6ebapt#ifdef USE_PTHREADS
1040f52ca6ebapttypedef struct _prescreen_list {
1041f52ca6ebapt	struct _prescreen_list *next;
1042f52ca6ebapt	pthread_t id;
1043f52ca6ebapt	struct screen *sp;
1044f52ca6ebapt} PRESCREEN_LIST;
1045f52ca6ebapt#endif
1046f52ca6ebapt
10479f9e55frafan/*
1048d036c70rafan * Global data which can be swept up into a SCREEN when one is created.
10499f9e55frafan * It may be modified before the next SCREEN is created.
10509f9e55frafan */
10519f9e55frafantypedef struct {
1052f52ca6ebapt#ifdef USE_PTHREADS
1053f52ca6ebapt	PRESCREEN_LIST *allocated;
1054f52ca6ebapt#else
1055f52ca6ebapt	struct screen * allocated;
1056f52ca6ebapt#endif
10579f9e55frafan	bool		use_env;
10589f9e55frafan	bool		filter_mode;
10599f9e55frafan	attr_t		previous_attr;
1060f52ca6ebapt	TPARM_STATE	tparm_state;
1061f52ca6ebapt	TTY		*saved_tty;	/* savetty/resetty information	    */
1062f52ca6ebapt	bool		use_tioctl;
1063f52ca6ebapt	NCURSES_SP_OUTC	_outch;		/* output handler if not putc */
10641034bfcdelphij#ifndef USE_SP_RIPOFF
10659f9e55frafan	ripoff_t	rippedoff[N_RIPS];
10669f9e55frafan	ripoff_t	*rsp;
10671034bfcdelphij#endif
1068d078158rafan#if NCURSES_NO_PADDING
1069d078158rafan	bool		_no_padding;	/* flag to set if padding disabled  */
1070d078158rafan#endif
10719f9e55frafan#if BROKEN_LINKER || USE_REENTRANT
10729f9e55frafan	chtype		*real_acs_map;
10739f9e55frafan	int		_LINES;
10749f9e55frafan	int		_COLS;
10751034bfcdelphij	int		_TABSIZE;
10761034bfcdelphij	int		_ESCDELAY;
1077d078158rafan	TERMINAL	*_cur_term;
1078f52ca6ebapt#endif
10799f9e55frafan#ifdef TRACE
1080f52ca6ebapt#if BROKEN_LINKER || USE_REENTRANT
10819f9e55frafan	long		_outchars;
10829f9e55frafan	const char	*_tputs_trace;
10839f9e55frafan#endif
10849f9e55frafan#endif
10859f9e55frafan} NCURSES_PRESCREEN;
10869f9e55frafan
10871034bfcdelphij/*
10881034bfcdelphij * Use screen-specific ripoff data (for softkeys) rather than global.
10891034bfcdelphij */
10901034bfcdelphij#ifdef USE_SP_RIPOFF
10911034bfcdelphij#define safe_ripoff_sp     (sp)->rsp
10921034bfcdelphij#define safe_ripoff_stack  (sp)->rippedoff
10931034bfcdelphij#else
10941034bfcdelphij#define safe_ripoff_sp	   _nc_prescreen.rsp
10951034bfcdelphij#define safe_ripoff_stack  _nc_prescreen.rippedoff
10961034bfcdelphij#endif
109732c0e5frafan
10989f9e55frafanextern NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen;
10999f9e55frafan
1100f52ca6ebapttypedef enum {
1101f52ca6ebapt    ewInitial = 0,
1102f52ca6ebapt    ewRunning,
1103f52ca6ebapt    ewSuspend
1104f52ca6ebapt} ENDWIN;
1105f52ca6ebapt
1106de9cbefrafan/*
1107de9cbefrafan * The SCREEN structure.
1108de9cbefrafan */
11099a7523dpeter
1110bacd15cpeterstruct screen {
11117dbeededelphij	int		_ifd;		/* input file descriptor for screen */
11127dbeededelphij	int		_ofd;		/* output file descriptor for screen */
1113de9cbefrafan	FILE		*_ofp;		/* output file ptr for screen	    */
11147dbeededelphij	char		*out_buffer;	/* output buffer		    */
11157dbeededelphij	size_t		out_limit;	/* output buffer size		    */
11167dbeededelphij	size_t		out_inuse;	/* output buffer current use	    */
1117de9cbefrafan	bool		_filtered;	/* filter() was called		    */
11181034bfcdelphij	bool		_prescreen;	/* is in prescreen phase	    */
11191034bfcdelphij	bool		_use_env;	/* LINES & COLS from environment?   */
1120de9cbefrafan	int		_checkfd;	/* filedesc for typeahead check	    */
1121de9cbefrafan	TERMINAL	*_term;		/* terminal type information	    */
11229f9e55frafan	TTY		_saved_tty;	/* savetty/resetty information	    */
11239f9e55frafan	NCURSES_SIZE_T	_lines;		/* screen lines			    */
11249f9e55frafan	NCURSES_SIZE_T	_columns;	/* screen columns		    */
1125de9cbefrafan
11269f9e55frafan	NCURSES_SIZE_T	_lines_avail;	/* lines available for stdscr	    */
11279f9e55frafan	NCURSES_SIZE_T	_topstolen;	/* lines stolen from top	    */
1128de9cbefrafan
1129de9cbefrafan	WINDOW		*_curscr;	/* current screen		    */
1130de9cbefrafan	WINDOW		*_newscr;	/* virtual screen to be updated to  */
1131de9cbefrafan	WINDOW		*_stdscr;	/* screen's full-window context	    */
1132de9cbefrafan
11331034bfcdelphij#define CurScreen(sp)  (sp)->_curscr
11341034bfcdelphij#define NewScreen(sp)  (sp)->_newscr
11351034bfcdelphij#define StdScreen(sp)  (sp)->_stdscr
11361034bfcdelphij
11379f9e55frafan	TRIES		*_keytry;	/* "Try" for use with keypad mode   */
11389f9e55frafan	TRIES		*_key_ok;	/* Disabled keys via keyok(,FALSE)  */
1139de9cbefrafan	bool		_tried;		/* keypad mode was initialized	    */
1140de9cbefrafan	bool		_keypad_on;	/* keypad mode is currently on	    */
1141de9cbefrafan
1142de9cbefrafan	bool		_called_wgetch;	/* check for recursion in wgetch()  */
1143de9cbefrafan	int		_fifo[FIFO_SIZE];	/* input push-back buffer   */
1144de9cbefrafan	short		_fifohead,	/* head of fifo queue		    */
1145de9cbefrafan			_fifotail,	/* tail of fifo queue		    */
1146de9cbefrafan			_fifopeek,	/* where to peek for next char	    */
1147de9cbefrafan			_fifohold;	/* set if breakout marked	    */
1148de9cbefrafan
1149de9cbefrafan	int		_endwin;	/* are we out of window mode?	    */
1150de9cbefrafan	NCURSES_CH_T	*_current_attr; /* holds current attributes set	    */
1151de9cbefrafan	int		_coloron;	/* is color enabled?		    */
1152de9cbefrafan	int		_color_defs;	/* are colors modified		    */
1153de9cbefrafan	int		_cursor;	/* visibility of the cursor	    */
1154de9cbefrafan	int		_cursrow;	/* physical cursor row		    */
1155de9cbefrafan	int		_curscol;	/* physical cursor column	    */
1156de9cbefrafan	bool		_notty;		/* true if we cannot switch non-tty */
1157de9cbefrafan	int		_nl;		/* True if NL -> CR/NL is on	    */
1158de9cbefrafan	int		_raw;		/* True if in raw mode		    */
1159de9cbefrafan	int		_cbreak;	/* 1 if in cbreak mode		    */
1160de9cbefrafan					/* > 1 if in halfdelay mode	    */
1161de9cbefrafan	int		_echo;		/* True if echo on		    */
1162de9cbefrafan	int		_use_meta;	/* use the meta key?		    */
1163de9cbefrafan	struct _SLK	*_slk;		/* ptr to soft key struct / NULL    */
1164de9cbefrafan	int		slk_format;	/* selected format for this screen  */
1165bacd15cpeter	/* cursor movement costs; units are 10ths of milliseconds */
1166de9cbefrafan	int		_char_padding;	/* cost of character put	    */
1167de9cbefrafan	int		_cr_cost;	/* cost of (carriage_return)	    */
1168de9cbefrafan	int		_cup_cost;	/* cost of (cursor_address)	    */
1169de9cbefrafan	int		_home_cost;	/* cost of (cursor_home)	    */
1170de9cbefrafan	int		_ll_cost;	/* cost of (cursor_to_ll)	    */
1171de9cbefrafan	int		_cub1_cost;	/* cost of (cursor_left)	    */
1172de9cbefrafan	int		_cuf1_cost;	/* cost of (cursor_right)	    */
1173de9cbefrafan	int		_cud1_cost;	/* cost of (cursor_down)	    */
1174de9cbefrafan	int		_cuu1_cost;	/* cost of (cursor_up)		    */
1175de9cbefrafan	int		_cub_cost;	/* cost of (parm_cursor_left)	    */
1176de9cbefrafan	int		_cuf_cost;	/* cost of (parm_cursor_right)	    */
1177de9cbefrafan	int		_cud_cost;	/* cost of (parm_cursor_down)	    */
1178de9cbefrafan	int		_cuu_cost;	/* cost of (parm_cursor_up)	    */
1179de9cbefrafan	int		_hpa_cost;	/* cost of (column_address)	    */
1180de9cbefrafan	int		_vpa_cost;	/* cost of (row_address)	    */
1181cc6a5ccpeter	/* used in tty_update.c, must be chars */
1182de9cbefrafan	int		_ed_cost;	/* cost of (clr_eos)		    */
1183de9cbefrafan	int		_el_cost;	/* cost of (clr_eol)		    */
1184de9cbefrafan	int		_el1_cost;	/* cost of (clr_bol)		    */
1185de9cbefrafan	int		_dch1_cost;	/* cost of (delete_character)	    */
1186de9cbefrafan	int		_ich1_cost;	/* cost of (insert_character)	    */
1187de9cbefrafan	int		_dch_cost;	/* cost of (parm_dch)		    */
1188de9cbefrafan	int		_ich_cost;	/* cost of (parm_ich)		    */
1189de9cbefrafan	int		_ech_cost;	/* cost of (erase_chars)	    */
1190de9cbefrafan	int		_rep_cost;	/* cost of (repeat_char)	    */
1191de9cbefrafan	int		_hpa_ch_cost;	/* cost of (column_address)	    */
1192de9cbefrafan	int		_cup_ch_cost;	/* cost of (cursor_address)	    */
1193de9cbefrafan	int		_cuf_ch_cost;	/* cost of (parm_cursor_right)	    */
1194de9cbefrafan	int		_inline_cost;	/* cost of inline-move		    */
1195de9cbefrafan	int		_smir_cost;	/* cost of (enter_insert_mode)	    */
1196de9cbefrafan	int		_rmir_cost;	/* cost of (exit_insert_mode)	    */
1197de9cbefrafan	int		_ip_cost;	/* cost of (insert_padding)	    */
1198bacd15cpeter	/* used in lib_mvcur.c */
1199de9cbefrafan	char *		_address_cursor;
1200a81407apeter	/* used in tty_update.c */
1201de9cbefrafan	int		_scrolling;	/* 1 if terminal's smart enough to  */
1202bacd15cpeter
1203bacd15cpeter	/* used in lib_color.c */
1204f52ca6ebapt	rgb_bits_t	_direct_color;	/* RGB overrides color-table	     */
1205de9cbefrafan	color_t		*_color_table;	/* screen's color palette	     */
1206de9cbefrafan	int		_color_count;	/* count of colors in palette	     */
1207de9cbefrafan	colorpair_t	*_color_pairs;	/* screen's color pair list	     */
1208f52ca6ebapt	int		_pair_count;	/* same as COLOR_PAIRS               */
12091034bfcdelphij	int		_pair_limit;	/* actual limit of color-pairs       */
1210f52ca6ebapt	int		_pair_alloc;	/* current table-size of color-pairs */
1211de9cbefrafan	chtype		_ok_attributes; /* valid attributes for terminal     */
1212de9cbefrafan	chtype		_xmc_suppress;	/* attributes to suppress if xmc     */
1213de9cbefrafan	chtype		_xmc_triggers;	/* attributes to process if xmc	     */
1214de9cbefrafan	chtype *	_acs_map;	/* the real alternate-charset map    */
1215de9cbefrafan	bool *		_screen_acs_map;
1216de9cbefrafan
1217bacd15cpeter
1218bacd15cpeter	/* used in lib_vidattr.c */
1219de9cbefrafan	bool		_use_rmso;	/* true if we may use 'rmso'	     */
1220de9cbefrafan	bool		_use_rmul;	/* true if we may use 'rmul'	     */
1221bacd15cpeter
1222bacd15cpeter	/*
1223bacd15cpeter	 * These data correspond to the state of the idcok() and idlok()
1224bacd15cpeter	 * functions.  A caveat is in order here:  the XSI and SVr4
1225bacd15cpeter	 * documentation specify that these functions apply to the window which
1226bacd15cpeter	 * is given as an argument.  However, ncurses implements this logic
1227bacd15cpeter	 * only for the newscr/curscr update process, _not_ per-window.
1228bacd15cpeter	 */
1229de9cbefrafan	bool		_nc_sp_idlok;
1230de9cbefrafan	bool		_nc_sp_idcok;
1231bacd15cpeter
1232bacd15cpeter	/*
1233bacd15cpeter	 * These are the data that support the mouse interface.
1234bacd15cpeter	 */
1235de9cbefrafan	bool		_mouse_initialized;
1236de9cbefrafan	MouseType	_mouse_type;
1237de9cbefrafan	int		_maxclick;
1238de9cbefrafan	bool		(*_mouse_event) (SCREEN *);
1239de9cbefrafan	bool		(*_mouse_inline)(SCREEN *);
1240d078158rafan	bool		(*_mouse_parse) (SCREEN *, int);
1241de9cbefrafan	void		(*_mouse_resume)(SCREEN *);
1242de9cbefrafan	void		(*_mouse_wrap)	(SCREEN *);
1243de9cbefrafan	int		_mouse_fd;	/* file-descriptor, if any */
1244de9cbefrafan	bool		_mouse_active;	/* true if initialized */
12457dbeededelphij	mmask_t		_mouse_mask;	/* set via mousemask() */
12467dbeededelphij	mmask_t		_mouse_mask2;	/* OR's in press/release bits */
12477dbeededelphij	mmask_t		_mouse_bstate;
1248f52ca6ebapt	MouseFormat	_mouse_format;	/* type of xterm mouse protocol */
1249de9cbefrafan	NCURSES_CONST char *_mouse_xtermcap; /* string to enable/disable mouse */
1250de9cbefrafan	MEVENT		_mouse_events[EV_MAX];	/* hold the last mouse event seen */
1251de9cbefrafan	MEVENT		*_mouse_eventp;	/* next free slot in event queue */
1252de9cbefrafan
1253f52ca6ebapt	/*
1254f52ca6ebapt	 * These are data that support the proper handling of the panel stack on an
1255f52ca6ebapt	 * per screen basis.
1256f52ca6ebapt	 */
1257f52ca6ebapt	struct panelhook _panelHook;
1258f52ca6ebapt
1259f52ca6ebapt	bool		_sig_winch;
1260f52ca6ebapt	SCREEN		*_next_screen;
1261f52ca6ebapt
1262f52ca6ebapt	/* hashes for old and new lines */
1263f52ca6ebapt	unsigned long	*oldhash, *newhash;
1264f52ca6ebapt	HASHMAP		*hashtab;
1265f52ca6ebapt	int		hashtab_len;
1266f52ca6ebapt	int		*_oldnum_list;
1267f52ca6ebapt	int		_oldnum_size;
1268f52ca6ebapt
1269f52ca6ebapt	NCURSES_SP_OUTC	_outch;		/* output handler if not putc */
1270f52ca6ebapt	NCURSES_OUTC	jump;
1271f52ca6ebapt
1272f52ca6ebapt	ripoff_t	rippedoff[N_RIPS];
1273f52ca6ebapt	ripoff_t	*rsp;
1274f52ca6ebapt
1275f52ca6ebapt	int		_legacy_coding;	/* see use_legacy_coding() */
1276f52ca6ebapt
1277f52ca6ebapt#if NCURSES_NO_PADDING
1278f52ca6ebapt	bool		_no_padding;	/* flag to set if padding disabled  */
1279f52ca6ebapt#endif
1280f52ca6ebapt
1281f52ca6ebapt#if USE_HARD_TABS
1282f52ca6ebapt	int		_ht_cost;	/* cost of (tab)		    */
1283f52ca6ebapt	int		_cbt_cost;	/* cost of (backtab)		    */
1284f52ca6ebapt#endif /* USE_HARD_TABS */
1285f52ca6ebapt
1286f52ca6ebapt	/* used in lib_vidattr.c */
1287f52ca6ebapt#if USE_ITALIC
1288f52ca6ebapt	bool		_use_ritm;	/* true if we may use 'ritm'	     */
1289f52ca6ebapt#endif
1290f52ca6ebapt
1291f52ca6ebapt	/* used in getch/twait */
1292f52ca6ebapt#if USE_KLIBC_KBD
1293f52ca6ebapt	bool		_extended_key;	/* true if an extended key	     */
1294f52ca6ebapt#endif
1295f52ca6ebapt
1296f52ca6ebapt	/* used in lib_color.c */
1297f52ca6ebapt#if NCURSES_EXT_FUNCS
1298f52ca6ebapt	bool		_assumed_color; /* use assumed colors		     */
1299f52ca6ebapt	bool		_default_color; /* use default colors		     */
1300f52ca6ebapt	bool		_has_sgr_39_49; /* has ECMA default color support    */
1301f52ca6ebapt	int		_default_fg;	/* assumed default foreground	     */
1302f52ca6ebapt	int		_default_bg;	/* assumed default background	     */
1303f52ca6ebapt	int		_default_pairs;	/* count pairs using default color   */
1304f52ca6ebapt#endif
1305f52ca6ebapt
1306f52ca6ebapt	/* system-dependent mouse data */
1307de9cbefrafan#if USE_GPM_SUPPORT
1308de9cbefrafan	bool		_mouse_gpm_loaded;
1309de9cbefrafan	bool		_mouse_gpm_found;
1310de9cbefrafan#ifdef HAVE_LIBDL
1311d078158rafan	void		*_dlopen_gpm;
1312de9cbefrafan	TYPE_gpm_fd	_mouse_gpm_fd;
1313de9cbefrafan	TYPE_Gpm_Open	_mouse_Gpm_Open;
1314de9cbefrafan	TYPE_Gpm_Close	_mouse_Gpm_Close;
1315de9cbefrafan	TYPE_Gpm_GetEvent _mouse_Gpm_GetEvent;
1316de9cbefrafan#endif
1317de9cbefrafan	Gpm_Connect	_mouse_gpm_connect;
1318de9cbefrafan#endif /* USE_GPM_SUPPORT */
1319de9cbefrafan
1320de9cbefrafan#if USE_EMX_MOUSE
1321de9cbefrafan	int		_emxmouse_wfd;
1322de9cbefrafan	int		_emxmouse_thread;
1323de9cbefrafan	int		_emxmouse_activated;
1324de9cbefrafan	char		_emxmouse_buttons[4];
1325de9cbefrafan#endif
1326de9cbefrafan
1327de9cbefrafan#if USE_SYSMOUSE
1328de9cbefrafan	MEVENT		_sysmouse_fifo[FIFO_SIZE];
1329de9cbefrafan	int		_sysmouse_head;
1330de9cbefrafan	int		_sysmouse_tail;
1331de9cbefrafan	int		_sysmouse_char_width;	/* character width */
1332de9cbefrafan	int		_sysmouse_char_height;	/* character height */
1333de9cbefrafan	int		_sysmouse_old_buttons;
1334de9cbefrafan	int		_sysmouse_new_buttons;
1335de9cbefrafan#endif
1336bacd15cpeter
13371034bfcdelphij#ifdef USE_TERM_DRIVER
13381034bfcdelphij	MEVENT		_drv_mouse_fifo[FIFO_SIZE];
13391034bfcdelphij	int		_drv_mouse_head;
13401034bfcdelphij	int		_drv_mouse_tail;
13411034bfcdelphij	int		_drv_mouse_old_buttons;
13421034bfcdelphij	int		_drv_mouse_new_buttons;
13431034bfcdelphij#endif
1344bacd15cpeter	/*
1345bacd15cpeter	 * This supports automatic resizing
1346bacd15cpeter	 */
1347bacd15cpeter#if USE_SIZECHANGE
13481034bfcdelphij	int		(*_resize)(NCURSES_SP_DCLx int y, int x);
13497dbeededelphij	int		(*_ungetch)(SCREEN *, int);
1350bacd15cpeter#endif
1351bacd15cpeter
1352f52ca6ebapt#ifdef USE_SP_WINDOWLIST
1353f52ca6ebapt	WINDOWLIST*	_windowlist;
1354f52ca6ebapt#define WindowList(sp)  (sp)->_windowlist
1355f52ca6ebapt#endif
1356bacd15cpeter
13579f9e55frafan#if USE_REENTRANT
13589f9e55frafan	char		_ttytype[NAMESIZE];
13599f9e55frafan	int		_ESCDELAY;
13609f9e55frafan	int		_TABSIZE;
13619f9e55frafan	int		_LINES;
13629f9e55frafan	int		_COLS;
13639f9e55frafan#endif
1364d078158rafan
1365f52ca6ebapt#if NCURSES_SP_FUNCS
1366f52ca6ebapt	bool		use_tioctl;
13671034bfcdelphij#endif
13681034bfcdelphij
1369de9cbefrafan	/*
1370de9cbefrafan	 * ncurses/ncursesw are the same up to this point.
1371de9cbefrafan	 */
1372de9cbefrafan#if USE_WIDEC_SUPPORT
1373de9cbefrafan	/* recent versions of 'screen' have partially-working support for
1374de9cbefrafan	 * UTF-8, but do not permit ACS at the same time (see tty_update.c).
1375de9cbefrafan	 */
1376de9cbefrafan	bool		_screen_acs_fix;
13777dbeededelphij	bool		_screen_unicode;
1378bacd15cpeter#endif
13797dbeededelphij
1380f52ca6ebapt#if NCURSES_EXT_FUNCS && NCURSES_EXT_COLORS
1381f52ca6ebapt	void		*_ordered_pairs; /* index used by alloc_pair()	     */
1382f52ca6ebapt	int		_pairs_used;	/* actual number of color-pairs used */
1383f52ca6ebapt	int		_recent_pair;	/* number for most recent free-pair  */
1384f52ca6ebapt#endif
1385f52ca6ebapt
1386f52ca6ebapt#ifdef TRACE
1387f52ca6ebapt	char		tracechr_buf[40];
1388f52ca6ebapt	char		tracemse_buf[TRACEMSE_MAX];
1389f52ca6ebapt#if USE_REENTRANT
1390f52ca6ebapt	long		_outchars;
1391f52ca6ebapt	const char	*_tputs_trace;
1392f52ca6ebapt#endif
1393f52ca6ebapt#endif
1394de9cbefrafan};
1395de9cbefrafan
1396de9cbefrafanextern NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain;
13979f9e55frafanextern NCURSES_EXPORT_VAR(SIG_ATOMIC_T) _nc_have_sigwinch;
1398bacd15cpeter
1399bacd15cpeter	WINDOWLIST {
1400bacd15cpeter	WINDOWLIST *next;
1401d078158rafan	SCREEN *screen;		/* screen containing the window */
14021034bfcdelphij	WINDOW	win;		/* WINDOW_EXT() needs to account for offset */
14037dbeededelphij#if NCURSES_WIDECHAR
1404de9cbefrafan	char addch_work[(MB_LEN_MAX * 9) + 1];
1405de9cbefrafan	unsigned addch_used;	/* number of bytes in addch_work[] */
1406de9cbefrafan	int addch_x;		/* x-position for addch_work[] */
1407de9cbefrafan	int addch_y;		/* y-position for addch_work[] */
14089a7523dpeter#endif
1409bacd15cpeter};
1410bacd15cpeter
14111034bfcdelphij#define WINDOW_EXT(w,m) (((WINDOWLIST *)((void *)((char *)(w) - offsetof(WINDOWLIST, win))))->m)
14121034bfcdelphij
1413f52ca6ebapt#ifdef USE_SP_WINDOWLIST
1414f52ca6ebapt#define SP_INIT_WINDOWLIST(sp)	WindowList(sp) = 0
1415f52ca6ebapt#else
1416f52ca6ebapt#define SP_INIT_WINDOWLIST(sp)	/* nothing */
1417f52ca6ebapt#endif
1418f52ca6ebapt
14191034bfcdelphij#define SP_PRE_INIT(sp)                         \
14201034bfcdelphij    sp->_cursrow = -1;                          \
14211034bfcdelphij    sp->_curscol = -1;                          \
14221034bfcdelphij    sp->_nl = TRUE;                             \
14231034bfcdelphij    sp->_raw = FALSE;                           \
14241034bfcdelphij    sp->_cbreak = 0;                            \
14251034bfcdelphij    sp->_echo = TRUE;                           \
14261034bfcdelphij    sp->_fifohead = -1;                         \
1427f52ca6ebapt    sp->_endwin = ewSuspend;                    \
14281034bfcdelphij    sp->_cursor = -1;                           \
1429f52ca6ebapt    SP_INIT_WINDOWLIST(sp);                     \
14307dbeededelphij    sp->_outch = NCURSES_OUTC_FUNC;             \
14311034bfcdelphij    sp->jump = 0                                \
1432de9cbefrafan
1433de9cbefrafan/* usually in <limits.h> */
1434de9cbefrafan#ifndef UCHAR_MAX
1435de9cbefrafan#define UCHAR_MAX 255
1436de9cbefrafan#endif
1437bacd15cpeter
1438bacd15cpeter/* The terminfo source is assumed to be 7-bit ASCII */
1439bacd15cpeter#define is7bits(c)	((unsigned)(c) < 128)
1440bacd15cpeter
1441de9cbefrafan/* Checks for isprint() should be done on 8-bit characters (non-wide) */
1442de9cbefrafan#define is8bits(c)	((unsigned)(c) <= UCHAR_MAX)
1443de9cbefrafan
1444bacd15cpeter#ifndef min
1445bacd15cpeter#define min(a,b)	((a) > (b)  ?  (b)  :  (a))
1446bacd15cpeter#endif
1447bacd15cpeter
1448bacd15cpeter#ifndef max
1449bacd15cpeter#define max(a,b)	((a) < (b)  ?  (b)  :  (a))
1450bacd15cpeter#endif
1451bacd15cpeter
1452bacd15cpeter/* usually in <unistd.h> */
1453bacd15cpeter#ifndef STDIN_FILENO
1454bacd15cpeter#define STDIN_FILENO 0
1455bacd15cpeter#endif
1456bacd15cpeter
1457bacd15cpeter#ifndef STDOUT_FILENO
1458bacd15cpeter#define STDOUT_FILENO 1
1459bacd15cpeter#endif
1460bacd15cpeter
1461bacd15cpeter#ifndef STDERR_FILENO
1462bacd15cpeter#define STDERR_FILENO 2
1463bacd15cpeter#endif
1464bacd15cpeter
1465bacd15cpeter#ifndef EXIT_SUCCESS
1466bacd15cpeter#define EXIT_SUCCESS 0
1467bacd15cpeter#endif
1468bacd15cpeter
1469bacd15cpeter#ifndef EXIT_FAILURE
1470bacd15cpeter#define EXIT_FAILURE 1
1471bacd15cpeter#endif
1472bacd15cpeter
1473bacd15cpeter#ifndef R_OK
1474bacd15cpeter#define	R_OK	4		/* Test for read permission.  */
1475bacd15cpeter#endif
1476bacd15cpeter#ifndef W_OK
1477bacd15cpeter#define	W_OK	2		/* Test for write permission.  */
1478bacd15cpeter#endif
1479bacd15cpeter#ifndef X_OK
1480bacd15cpeter#define	X_OK	1		/* Test for execute permission.  */
1481bacd15cpeter#endif
1482bacd15cpeter#ifndef F_OK
1483bacd15cpeter#define	F_OK	0		/* Test for existence.  */
1484bacd15cpeter#endif
1485bacd15cpeter
1486cc6a5ccpeter#if HAVE_FCNTL_H
1487cc6a5ccpeter#include <fcntl.h>		/* may define O_BINARY	*/
1488cc6a5ccpeter#endif
1489cc6a5ccpeter
1490cc6a5ccpeter#ifndef O_BINARY
1491cc6a5ccpeter#define O_BINARY 0
1492cc6a5ccpeter#endif
1493cc6a5ccpeter
1494de9cbefrafan#ifdef TRACE
14959f9e55frafan#if USE_REENTRANT
14969f9e55frafan#define COUNT_OUTCHARS(n) _nc_count_outchars(n);
14979f9e55frafan#else
14989f9e55frafan#define COUNT_OUTCHARS(n) _nc_outchars += (n);
14999f9e55frafan#endif
1500de9cbefrafan#else
15019f9e55frafan#define COUNT_OUTCHARS(n) /* nothing */
1502de9cbefrafan#endif
1503de9cbefrafan
15049f9e55frafan#define RESET_OUTCHARS() COUNT_OUTCHARS(-_nc_outchars)
15059f9e55frafan
15069a7523dpeter#define UChar(c)	((unsigned char)(c))
15071034bfcdelphij#define UShort(c)	((unsigned short)(c))
15087dbeededelphij#define ChCharOf(c)	((chtype)(c) & (chtype)A_CHARTEXT)
15097dbeededelphij#define ChAttrOf(c)	((chtype)(c) & (chtype)A_ATTRIBUTES)
1510de9cbefrafan
1511f52ca6ebapt#define TR_PUTC(c)	TR(TRACE_CHARPUT, ("PUTC %#x", UChar(c)))
1512f52ca6ebapt
1513de9cbefrafan#ifndef MB_LEN_MAX
1514de9cbefrafan#define MB_LEN_MAX 8 /* should be >= MB_CUR_MAX, but that may be a function */
1515de9cbefrafan#endif
15169a7523dpeter
15179a7523dpeter#if USE_WIDEC_SUPPORT /* { */
15189f9e55frafan#define isEILSEQ(status) (((size_t)status == (size_t)-1) && (errno == EILSEQ))
1519de9cbefrafan
1520de9cbefrafan#define init_mb(state)	memset(&state, 0, sizeof(state))
1521de9cbefrafan
1522de9cbefrafan#if NCURSES_EXT_COLORS
1523de9cbefrafan#define NulColor	, 0
1524de9cbefrafan#else
1525de9cbefrafan#define NulColor	/* nothing */
1526de9cbefrafan#endif
1527de9cbefrafan
1528de9cbefrafan#define NulChar		0,0,0,0	/* FIXME: see CCHARW_MAX */
15299a7523dpeter#define CharOf(c)	((c).chars[0])
15309a7523dpeter#define AttrOf(c)	((c).attr)
15319f9e55frafan
15329f9e55frafan#define AddAttr(c,a)	AttrOf(c) |=  ((a) & A_ATTRIBUTES)
1533de9cbefrafan#define RemAttr(c,a)	AttrOf(c) &= ~((a) & A_ATTRIBUTES)
15349f9e55frafan#define SetAttr(c,a)	AttrOf(c) =   ((a) & A_ATTRIBUTES) | WidecExt(c)
15359f9e55frafan
1536de9cbefrafan#define NewChar2(c,a)	{ a, { c, NulChar } NulColor }
1537de9cbefrafan#define NewChar(ch)	NewChar2(ChCharOf(ch), ChAttrOf(ch))
15389f9e55frafan
15399f9e55frafan#if CCHARW_MAX == 5
15409f9e55frafan#define CharEq(a,b)	(((a).attr == (b).attr) \
15419f9e55frafan		       && (a).chars[0] == (b).chars[0] \
15429f9e55frafan		       && (a).chars[1] == (b).chars[1] \
15439f9e55frafan		       && (a).chars[2] == (b).chars[2] \
15449f9e55frafan		       && (a).chars[3] == (b).chars[3] \
15459f9e55frafan		       && (a).chars[4] == (b).chars[4] \
15469f9e55frafan			if_EXT_COLORS(&& (a).ext_color == (b).ext_color))
1547f52ca6ebapt#elif CCHARW_MAX > 0
1548f52ca6ebapt#error Inconsistent values for CCHARW_MAX
15499f9e55frafan#else
1550de9cbefrafan#define CharEq(a,b)	(!memcmp(&(a), &(b), sizeof(a)))
15519f9e55frafan#endif
15529f9e55frafan
1553de9cbefrafan#define SetChar(ch,c,a) do {							    \
15549a7523dpeter			    NCURSES_CH_T *_cp = &ch;				    \
1555de9cbefrafan			    memset(_cp, 0, sizeof(ch));				    \
15561034bfcdelphij			    _cp->chars[0] = (wchar_t) (c);			    \
1557de9cbefrafan			    _cp->attr = (a);					    \
15581034bfcdelphij			    if_EXT_COLORS(SetPair(ch, PairNumber(a)));		    \
15599a7523dpeter			} while (0)
15609a7523dpeter#define CHREF(wch)	(&wch)
15619a7523dpeter#define CHDEREF(wch)	(*wch)
15629a7523dpeter#define ARG_CH_T	NCURSES_CH_T *
15639a7523dpeter#define CARG_CH_T	const NCURSES_CH_T *
15649a7523dpeter#define PUTC_DATA	char PUTC_buf[MB_LEN_MAX]; int PUTC_i, PUTC_n; \
15659a7523dpeter			mbstate_t PUT_st; wchar_t PUTC_ch
1566de9cbefrafan#define PUTC_INIT	init_mb (PUT_st)
15677dbeededelphij#define PUTC(ch)	do { if(!isWidecExt(ch)) {				    \
1568de9cbefrafan			if (Charable(ch)) {					    \
1569f52ca6ebapt			    TR_PUTC(CharOf(ch));				    \
1570f52ca6ebapt			    NCURSES_OUTC_FUNC (NCURSES_SP_ARGx CharOf(ch));	    \
15719f9e55frafan			    COUNT_OUTCHARS(1);					    \
1572de9cbefrafan			} else {						    \
1573de9cbefrafan			    for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) {	    \
1574de9cbefrafan				PUTC_ch = (ch).chars[PUTC_i];			    \
1575de9cbefrafan				if (PUTC_ch == L'\0')				    \
1576de9cbefrafan				    break;					    \
1577f52ca6ebapt				PUTC_INIT;					    \
15781034bfcdelphij				PUTC_n = (int) wcrtomb(PUTC_buf,		    \
15791034bfcdelphij						       (ch).chars[PUTC_i], &PUT_st); \
1580de9cbefrafan				if (PUTC_n <= 0) {				    \
1581f52ca6ebapt				    if (PUTC_ch && is8bits(PUTC_ch) && PUTC_i == 0) { \
1582f52ca6ebapt					TR_PUTC(CharOf(ch));			    \
15837dbeededelphij					NCURSES_OUTC_FUNC (NCURSES_SP_ARGx CharOf(ch)); \
1584f52ca6ebapt				    }						    \
15859a7523dpeter				    break;					    \
15867dbeededelphij				} else {					    \
15877dbeededelphij				    int PUTC_j;					    \
15887dbeededelphij				    for (PUTC_j = 0; PUTC_j < PUTC_n; ++PUTC_j) {   \
1589f52ca6ebapt					TR_PUTC(PUTC_buf[PUTC_j]);		    \
15907dbeededelphij					NCURSES_OUTC_FUNC (NCURSES_SP_ARGx PUTC_buf[PUTC_j]); \
15917dbeededelphij				    }						    \
1592de9cbefrafan				}						    \
1593de9cbefrafan			    }							    \
15949f9e55frafan			    COUNT_OUTCHARS(PUTC_i);				    \
1595de9cbefrafan			} } } while (0)
15969a7523dpeter
15979f9e55frafan#define BLANK		NewChar2(' ', WA_NORMAL)
15989f9e55frafan#define ZEROS		NewChar2('\0', WA_NORMAL)
15999a7523dpeter#define ISBLANK(ch)	((ch).chars[0] == L' ' && (ch).chars[1] == L'\0')
16009a7523dpeter
1601de9cbefrafan	/*
1602de9cbefrafan	 * Wide characters cannot be represented in the A_CHARTEXT mask of
1603de9cbefrafan	 * attr_t's but an application might have set a narrow character there.
1604de9cbefrafan	 * But even in that case, it would only be a printable character, or
1605de9cbefrafan	 * zero.  Otherwise we can use those bits to tell if a cell is the
1606de9cbefrafan	 * first or extension part of a wide character.
1607de9cbefrafan	 */
16081034bfcdelphij#define WidecExt(ch)	(int) (AttrOf(ch) & A_CHARTEXT)
1609de9cbefrafan#define isWidecBase(ch)	(WidecExt(ch) == 1)
1610de9cbefrafan#define isWidecExt(ch)	(WidecExt(ch) > 1 && WidecExt(ch) < 32)
1611de9cbefrafan#define SetWidecExt(dst, ext)	AttrOf(dst) &= ~A_CHARTEXT,		\
16121034bfcdelphij				AttrOf(dst) |= (attr_t) (ext + 1)
1613de9cbefrafan
16149a7523dpeter#define if_WIDEC(code)  code
1615f52ca6ebapt#define Charable(ch)	(((SP_PARM->_legacy_coding)			\
1616de9cbefrafan			 || (AttrOf(ch) & A_ALTCHARSET)			\
1617f52ca6ebapt			 || (!isWidecExt(ch))) &&			\
1618de9cbefrafan			     (ch).chars[1] == L'\0' &&			\
1619f52ca6ebapt			     _nc_is_charable(CharOf(ch)))
16209a7523dpeter
16219a7523dpeter#define L(ch)		L ## ch
16229a7523dpeter#else /* }{ */
16239a7523dpeter#define CharOf(c)	ChCharOf(c)
16249a7523dpeter#define AttrOf(c)	ChAttrOf(c)
1625de9cbefrafan#define AddAttr(c,a)	c |= (a)
1626de9cbefrafan#define RemAttr(c,a)	c &= ~((a) & A_ATTRIBUTES)
1627de9cbefrafan#define SetAttr(c,a)	c = ((c) & ~A_ATTRIBUTES) | (a)
16289a7523dpeter#define NewChar(ch)	(ch)
1629de9cbefrafan#define NewChar2(c,a)	((c) | (a))
1630de9cbefrafan#define CharEq(a,b)	((a) == (b))
1631de9cbefrafan#define SetChar(ch,c,a)	ch = (c) | (a)
16329a7523dpeter#define CHREF(wch)	wch
16339a7523dpeter#define CHDEREF(wch)	wch
16349a7523dpeter#define ARG_CH_T	NCURSES_CH_T
16359a7523dpeter#define CARG_CH_T	NCURSES_CH_T
16367dbeededelphij#define PUTC_DATA	/* nothing */
1637f52ca6ebapt#define PUTC(ch)	{ \
1638f52ca6ebapt			    TR_PUTC(ch); \
1639f52ca6ebapt			    NCURSES_OUTC_FUNC (NCURSES_SP_ARGx (int) ch); \
1640f52ca6ebapt			}
16419a7523dpeter
16429a7523dpeter#define BLANK		(' '|A_NORMAL)
1643de9cbefrafan#define ZEROS		('\0'|A_NORMAL)
16449a7523dpeter#define ISBLANK(ch)	(CharOf(ch) == ' ')
16459a7523dpeter
1646de9cbefrafan#define isWidecExt(ch)	(0)
16479a7523dpeter#define if_WIDEC(code) /* nothing */
16489a7523dpeter
1649f52ca6ebapt#define Charable(ch)	((ch) >= ' ' && (ch) <= '~')
16509a7523dpeter#define L(ch)		ch
16519a7523dpeter#endif /* } */
16529a7523dpeter
16539a7523dpeter#define AttrOfD(ch)	AttrOf(CHDEREF(ch))
16549a7523dpeter#define CharOfD(ch)	CharOf(CHDEREF(ch))
16559a7523dpeter#define SetChar2(wch,ch)    SetChar(wch,ChCharOf(ch),ChAttrOf(ch))
16569a7523dpeter
16579a7523dpeter#define BLANK_ATTR	A_NORMAL
16589a7523dpeter#define BLANK_TEXT	L(' ')
1659bacd15cpeter
1660bacd15cpeter#define CHANGED     -1
1661bacd15cpeter
1662de9cbefrafan#define LEGALYX(w, y, x) \
1663de9cbefrafan	      ((w) != 0 && \
1664de9cbefrafan		((x) >= 0 && (x) <= (w)->_maxx && \
1665de9cbefrafan		 (y) >= 0 && (y) <= (w)->_maxy))
1666de9cbefrafan
1667bacd15cpeter#define CHANGED_CELL(line,col) \
1668bacd15cpeter	if (line->firstchar == _NOCHANGE) \
16697dbeededelphij		line->firstchar = line->lastchar = (NCURSES_SIZE_T) (col); \
1670bacd15cpeter	else if ((col) < line->firstchar) \
16717dbeededelphij		line->firstchar = (NCURSES_SIZE_T) (col); \
1672bacd15cpeter	else if ((col) > line->lastchar) \
16737dbeededelphij		line->lastchar = (NCURSES_SIZE_T) (col)
1674bacd15cpeter
1675bacd15cpeter#define CHANGED_RANGE(line,start,end) \
1676bacd15cpeter	if (line->firstchar == _NOCHANGE \
1677bacd15cpeter	 || line->firstchar > (start)) \
16787dbeededelphij		line->firstchar = (NCURSES_SIZE_T) (start); \
1679bacd15cpeter	if (line->lastchar == _NOCHANGE \
1680bacd15cpeter	 || line->lastchar < (end)) \
16817dbeededelphij		line->lastchar = (NCURSES_SIZE_T) (end)
1682bacd15cpeter
1683bacd15cpeter#define CHANGED_TO_EOL(line,start,end) \
1684bacd15cpeter	if (line->firstchar == _NOCHANGE \
1685bacd15cpeter	 || line->firstchar > (start)) \
16867dbeededelphij		line->firstchar = (NCURSES_SIZE_T) (start); \
16877dbeededelphij	line->lastchar = (NCURSES_SIZE_T) (end)
1688bacd15cpeter
1689bacd15cpeter#define SIZEOF(v) (sizeof(v)/sizeof(v[0]))
1690cc6a5ccpeter
1691cc6a5ccpeter#define FreeIfNeeded(p)  if ((p) != 0) free(p)
1692cc6a5ccpeter
1693cc6a5ccpeter/* FreeAndNull() is not a comma-separated expression because some compilers
1694cc6a5ccpeter * do not accept a mixture of void with values.
1695cc6a5ccpeter */
1696f52ca6ebapt#define FreeAndNull(p)   do { free(p); p = 0; } while (0)
1697bacd15cpeter
1698bacd15cpeter#include <nc_alloc.h>
1699bacd15cpeter
1700bacd15cpeter/*
17017dbeededelphij * Use these for tic/infocmp malloc failures.  Generally the ncurses library
17027dbeededelphij * tries to limp along after a failure.
17037dbeededelphij */
17047dbeededelphij#define TYPE_MALLOC(type, size, name) \
1705f52ca6ebapt	do { \
1706f52ca6ebapt	    name = typeMalloc(type, size); \
1707f52ca6ebapt	    if (name == 0) \
1708f52ca6ebapt		_nc_err_abort(MSG_NO_MEMORY); \
1709f52ca6ebapt	} while (0)
17107dbeededelphij
17117dbeededelphij#define TYPE_REALLOC(type, size, name) \
1712f52ca6ebapt	do { \
1713f52ca6ebapt	    name = typeRealloc(type, size, name); \
1714f52ca6ebapt	    if (name == 0) \
1715f52ca6ebapt		_nc_err_abort(MSG_NO_MEMORY); \
1716f52ca6ebapt	} while (0)
17177dbeededelphij
17187dbeededelphij/*
1719de9cbefrafan * TTY bit definition for converting tabs to spaces.
1720de9cbefrafan */
1721de9cbefrafan#ifdef TAB3
1722de9cbefrafan# define OFLAGS_TABS TAB3	/* POSIX specifies TAB3 */
1723de9cbefrafan#else
1724de9cbefrafan# ifdef XTABS
1725de9cbefrafan#  define OFLAGS_TABS XTABS	/* XTABS is usually the "same" */
1726de9cbefrafan# else
1727de9cbefrafan#  ifdef OXTABS
1728de9cbefrafan#   define OFLAGS_TABS OXTABS	/* the traditional BSD equivalent */
1729de9cbefrafan#  else
1730de9cbefrafan#   define OFLAGS_TABS 0
1731de9cbefrafan#  endif
1732de9cbefrafan# endif
1733de9cbefrafan#endif
1734de9cbefrafan
1735f52ca6ebapt#ifdef __TANDEM
1736f52ca6ebapt#define ROOT_UID 65535
1737f52ca6ebapt#endif
1738f52ca6ebapt
1739f52ca6ebapt#ifndef ROOT_UID
1740f52ca6ebapt#define ROOT_UID 0
1741f52ca6ebapt#endif
1742f52ca6ebapt
1743de9cbefrafan/*
1744d036c70rafan * Standardize/simplify common loops
1745d036c70rafan */
1746d036c70rafan#define each_screen(p) p = _nc_screen_chain; p != 0; p = (p)->_next_screen
17471034bfcdelphij#define each_window(sp,p) p = WindowList(sp); p != 0; p = (p)->next
17481034bfcdelphij#define each_ripoff(p) p = safe_ripoff_stack; (p - safe_ripoff_stack) < N_RIPS; ++p
1749d036c70rafan
1750d036c70rafan/*
1751bacd15cpeter * Prefixes for call/return points of library function traces.  We use these to
1752bacd15cpeter * instrument the public functions so that the traces can be easily transformed
1753bacd15cpeter * into regression scripts.
1754bacd15cpeter */
17559a7523dpeter#define T_CALLED(fmt) "called {" fmt
17569a7523dpeter#define T_CREATE(fmt) "create :" fmt
17579a7523dpeter#define T_RETURN(fmt) "return }" fmt
1758bacd15cpeter
1759f52ca6ebapt#define NonNull(s)              ((s) != 0 ? s : "<null>")
1760f52ca6ebapt#define NonEmpty(s)             ((s) != 0 && *(s) != '\0')
1761f52ca6ebapt
1762bacd15cpeter#ifdef TRACE
1763de9cbefrafan
17649f9e55frafan#if USE_REENTRANT
17659f9e55frafan#define TPUTS_TRACE(s)	_nc_set_tputs_trace(s);
17669f9e55frafan#else
17679f9e55frafan#define TPUTS_TRACE(s)	_nc_tputs_trace = s;
17689f9e55frafan#endif
17699f9e55frafan
1770f52ca6ebapt#ifdef HAVE_CONSISTENT_GETENV
1771de9cbefrafan#define START_TRACE() \
1772de9cbefrafan	if ((_nc_tracing & TRACE_MAXIMUM) == 0) { \
1773de9cbefrafan	    int t = _nc_getenv_num("NCURSES_TRACE"); \
1774de9cbefrafan	    if (t >= 0) \
1775f52ca6ebapt		curses_trace((unsigned) t); \
1776de9cbefrafan	}
1777f52ca6ebapt#else
1778f52ca6ebapt#define START_TRACE() /* nothing */
1779f52ca6ebapt#endif
1780de9cbefrafan
17819f9e55frafan/*
17829f9e55frafan * Many of the _tracef() calls use static buffers; lock the trace state before
17839f9e55frafan * trying to fill them.
17849f9e55frafan */
17859f9e55frafan#if USE_REENTRANT
17869f9e55frafan#define USE_TRACEF(mask) _nc_use_tracef(mask)
17879f9e55frafanextern NCURSES_EXPORT(int)	_nc_use_tracef (unsigned);
17889f9e55frafanextern NCURSES_EXPORT(void)	_nc_locked_tracef (const char *, ...) GCC_PRINTFLIKE(1,2);
17899f9e55frafan#else
17909f9e55frafan#define USE_TRACEF(mask) (_nc_tracing & (mask))
17919f9e55frafan#define _nc_locked_tracef _tracef
17929f9e55frafan#endif
17939f9e55frafan
17949f9e55frafan#define TR(n, a)	if (USE_TRACEF(n)) _nc_locked_tracef a
1795bacd15cpeter#define T(a)		TR(TRACE_CALLS, a)
1796f52ca6ebapt#define TRACE_RETURN(value,type)     return _nc_retrace_##type((type)(value))
1797f52ca6ebapt#define TRACE_RETURN1(value,dst)     return _nc_retrace_##dst(value)
17981034bfcdelphij#define TRACE_RETURN2(value,dst,src) return _nc_retrace_##dst##_##src(value)
17991034bfcdelphij#define TRACE_RETURN_SP(value,type)  return _nc_retrace_##type(SP_PARM, value)
18001034bfcdelphij
1801f52ca6ebapttypedef void VoidFunc(void);
1802f52ca6ebapt
1803f52ca6ebapt#define TR_FUNC_LEN		((sizeof(void *) + sizeof(void (*)(void))) * 2 + 4)
1804f52ca6ebapt#define TR_FUNC_BFR(max)	char tr_func_data[max][TR_FUNC_LEN]
1805f52ca6ebapt#define TR_FUNC_ARG(num,func)	_nc_fmt_funcptr(&tr_func_data[num][0], (const char *)&(func), sizeof((func)))
1806de9cbefrafan
1807de9cbefrafan#define returnAttr(code)	TRACE_RETURN(code,attr_t)
1808de9cbefrafan#define returnBits(code)	TRACE_RETURN(code,unsigned)
1809de9cbefrafan#define returnBool(code)	TRACE_RETURN(code,bool)
1810f52ca6ebapt#define returnCPtr(code)	TRACE_RETURN1(code,cptr)
1811f52ca6ebapt#define returnCVoidPtr(code)	TRACE_RETURN1(code,cvoid_ptr)
18121034bfcdelphij#define returnChar(code)	TRACE_RETURN(code,char)
18131034bfcdelphij#define returnChtype(code)	TRACE_RETURN(code,chtype)
1814de9cbefrafan#define returnCode(code)	TRACE_RETURN(code,int)
18151034bfcdelphij#define returnIntAttr(code)	TRACE_RETURN2(code,int,attr_t)
18161034bfcdelphij#define returnMMask(code)	TRACE_RETURN_SP(code,mmask_t)
1817f52ca6ebapt#define returnPtr(code)		TRACE_RETURN1(code,ptr)
1818f52ca6ebapt#define returnSP(code)		TRACE_RETURN1(code,sp)
1819de9cbefrafan#define returnVoid		T((T_RETURN(""))); return
1820f52ca6ebapt#define returnVoidPtr(code)	TRACE_RETURN1(code,void_ptr)
1821f52ca6ebapt#define returnWin(code)		TRACE_RETURN1(code,win)
1822f52ca6ebapt
1823f52ca6ebapt#define returnDB(rc)		do { TR(TRACE_DATABASE,(T_RETURN("code %d"), (rc))); return (rc); } while (0)
1824de9cbefrafan
18257dbeededelphijextern NCURSES_EXPORT(NCURSES_BOOL)     _nc_retrace_bool (int);
1826de9cbefrafanextern NCURSES_EXPORT(NCURSES_CONST void *) _nc_retrace_cvoid_ptr (NCURSES_CONST void *);
1827de9cbefrafanextern NCURSES_EXPORT(SCREEN *)         _nc_retrace_sp (SCREEN *);
1828de9cbefrafanextern NCURSES_EXPORT(WINDOW *)         _nc_retrace_win (WINDOW *);
1829de9cbefrafanextern NCURSES_EXPORT(attr_t)           _nc_retrace_attr_t (attr_t);
1830de9cbefrafanextern NCURSES_EXPORT(char *)           _nc_retrace_ptr (char *);
1831de9cbefrafanextern NCURSES_EXPORT(char *)           _nc_trace_ttymode(TTY *tty);
1832de9cbefrafanextern NCURSES_EXPORT(char *)           _nc_varargs (const char *, va_list);
1833de9cbefrafanextern NCURSES_EXPORT(chtype)           _nc_retrace_chtype (chtype);
1834de9cbefrafanextern NCURSES_EXPORT(const char *)     _nc_altcharset_name(attr_t, chtype);
1835de9cbefrafanextern NCURSES_EXPORT(const char *)     _nc_retrace_cptr (const char *);
18367dbeededelphijextern NCURSES_EXPORT(char)             _nc_retrace_char (int);
1837de9cbefrafanextern NCURSES_EXPORT(int)              _nc_retrace_int (int);
18381034bfcdelphijextern NCURSES_EXPORT(int)              _nc_retrace_int_attr_t (attr_t);
18391034bfcdelphijextern NCURSES_EXPORT(mmask_t)          _nc_retrace_mmask_t (SCREEN *, mmask_t);
1840de9cbefrafanextern NCURSES_EXPORT(unsigned)         _nc_retrace_unsigned (unsigned);
1841de9cbefrafanextern NCURSES_EXPORT(void *)           _nc_retrace_void_ptr (void *);
1842d036c70rafanextern NCURSES_EXPORT(void)             _nc_fifo_dump (SCREEN *);
18439f9e55frafan
1844f52ca6ebaptextern NCURSES_EXPORT(char *)           _nc_fmt_funcptr(char *, const char *, size_t);
1845f52ca6ebapt
18469f9e55frafan#if USE_REENTRANT
18479f9e55frafanNCURSES_WRAPPED_VAR(long, _nc_outchars);
18489f9e55frafanNCURSES_WRAPPED_VAR(const char *, _nc_tputs_trace);
18499f9e55frafan#define _nc_outchars       NCURSES_PUBLIC_VAR(_nc_outchars())
18509f9e55frafan#define _nc_tputs_trace    NCURSES_PUBLIC_VAR(_nc_tputs_trace())
18519f9e55frafanextern NCURSES_EXPORT(void)		_nc_set_tputs_trace (const char *);
18529f9e55frafanextern NCURSES_EXPORT(void)		_nc_count_outchars (long);
18539f9e55frafan#else
18549a7523dpeterextern NCURSES_EXPORT_VAR(const char *) _nc_tputs_trace;
1855de9cbefrafanextern NCURSES_EXPORT_VAR(long)         _nc_outchars;
18569f9e55frafan#endif
18579f9e55frafan
1858de9cbefrafanextern NCURSES_EXPORT_VAR(unsigned)     _nc_tracing;
1859de9cbefrafan
1860f52ca6ebaptextern NCURSES_EXPORT(char *) _nc_tracebits (void);
1861f52ca6ebaptextern NCURSES_EXPORT(char *) _tracemouse (const MEVENT *);
1862f52ca6ebaptextern NCURSES_EXPORT(void) _tracedump (const char *, WINDOW *);
1863f52ca6ebapt
18649a7523dpeter#if USE_WIDEC_SUPPORT
18659a7523dpeterextern NCURSES_EXPORT(const char *) _nc_viswbuf2 (int, const wchar_t *);
1866de9cbefrafanextern NCURSES_EXPORT(const char *) _nc_viswbufn (const wchar_t *, int);
18679a7523dpeter#endif
1868de9cbefrafan
1869de9cbefrafanextern NCURSES_EXPORT(const char *) _nc_viscbuf2 (int, const NCURSES_CH_T *, int);
1870de9cbefrafanextern NCURSES_EXPORT(const char *) _nc_viscbuf (const NCURSES_CH_T *, int);
1871de9cbefrafan
1872de9cbefrafan#else /* !TRACE */
1873