1 /**************************************************************************** 2 * Copyright 2018-2020,2021 Thomas E. Dickey * 3 * Copyright 1998-2017,2018 Free Software Foundation, Inc. * 4 * * 5 * Permission is hereby granted, free of charge, to any person obtaining a * 6 * copy of this software and associated documentation files (the * 7 * "Software"), to deal in the Software without restriction, including * 8 * without limitation the rights to use, copy, modify, merge, publish, * 9 * distribute, distribute with modifications, sublicense, and/or sell * 10 * copies of the Software, and to permit persons to whom the Software is * 11 * furnished to do so, subject to the following conditions: * 12 * * 13 * The above copyright notice and this permission notice shall be included * 14 * in all copies or substantial portions of the Software. * 15 * * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 23 * * 24 * Except as contained in this notice, the name(s) of the above copyright * 25 * holders shall not be used in advertising or otherwise to promote the * 26 * sale, use or other dealings in this Software without prior written * 27 * authorization. * 28 ****************************************************************************/ 29 30 /**************************************************************************** 31 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 32 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 33 * and: Thomas E. Dickey 1996-on * 34 * and: Juergen Pfeifer * 35 ****************************************************************************/ 36 37 /* 38 * $Id: curses.priv.h,v 1.646 2021/09/24 16:09:35 tom Exp $ 39 * 40 * curses.priv.h 41 * 42 * Header file for curses library objects which are private to 43 * the library. 44 * 45 */ 46 47 #ifndef CURSES_PRIV_H 48 #define CURSES_PRIV_H 1 49 /* *INDENT-OFF* */ 50 51 #include <ncurses_dll.h> 52 53 #ifdef __cplusplus 54 extern "C" { 55 #endif 56 57 #include <ncurses_cfg.h> 58 59 #if USE_RCS_IDS 60 #define MODULE_ID(id) static const char Ident[] = id; 61 #else 62 #define MODULE_ID(id) /*nothing*/ 63 #endif 64 65 #include <stddef.h> /* for offsetof */ 66 #include <stdlib.h> 67 #include <string.h> 68 #include <sys/types.h> 69 #include <sys/stat.h> 70 71 #if HAVE_UNISTD_H 72 #include <unistd.h> 73 #endif 74 75 #if HAVE_LIMITS_H 76 # include <limits.h> 77 #elif HAVE_SYS_PARAM_H 78 # include <sys/param.h> 79 #endif 80 81 #include <assert.h> 82 #include <stdio.h> 83 84 #include <errno.h> 85 86 #if defined __hpux 87 # ifndef EILSEQ 88 # define EILSEQ 47 89 # endif 90 #endif 91 92 #ifndef PATH_MAX 93 # if defined(_POSIX_PATH_MAX) 94 # define PATH_MAX _POSIX_PATH_MAX 95 # elif defined(MAXPATHLEN) 96 # define PATH_MAX MAXPATHLEN 97 # else 98 # define PATH_MAX 255 /* the Posix minimum path-size */ 99 # endif 100 #endif 101 102 #if DECL_ERRNO 103 extern int errno; 104 #endif 105 106 /* Some Windows related defines */ 107 #undef _NC_WINDOWS 108 #if (defined(_WIN32) || defined(_WIN64)) 109 #define _NC_WINDOWS 110 #else 111 #undef EXP_WIN32_DRIVER 112 #endif 113 114 #undef _NC_MINGW 115 #if (defined(__MINGW32__) || defined(__MINGW64__)) 116 #define _NC_MINGW 117 #endif 118 119 #undef _NC_MSC 120 #ifdef _MSC_VER 121 #define _NC_MSC 122 #endif 123 124 /* Some systems have a broken 'select()', but workable 'poll()'. Use that */ 125 #if HAVE_WORKING_POLL 126 #define USE_FUNC_POLL 1 127 #if HAVE_POLL_H 128 #include <poll.h> 129 #else 130 #include <sys/poll.h> 131 #endif 132 #else 133 #define USE_FUNC_POLL 0 134 #endif 135 136 #if HAVE_INTTYPES_H 137 # include <inttypes.h> 138 #else 139 # if HAVE_STDINT_H 140 # include <stdint.h> 141 # endif 142 #endif 143 144 /* include signal.h before curses.h to work-around defect in glibc 2.1.3 */ 145 #include <signal.h> 146 147 /* Alessandro Rubini's GPM (general-purpose mouse) */ 148 #if HAVE_LIBGPM && HAVE_GPM_H 149 #define USE_GPM_SUPPORT 1 150 #else 151 #define USE_GPM_SUPPORT 0 152 #endif 153 154 /* QNX mouse support */ 155 #if defined(__QNX__) && !defined(__QNXNTO__) 156 #define USE_QNX_MOUSE 1 157 #else 158 #define USE_QNX_MOUSE 0 159 #endif 160 161 /* EMX mouse support */ 162 #ifdef __EMX__ 163 #define USE_EMX_MOUSE 1 164 #else 165 #define USE_EMX_MOUSE 0 166 #endif 167 168 /* kLIBC keyboard/mouse support */ 169 #if defined(__OS2__) && defined(__KLIBC__) 170 #define USE_KLIBC_KBD 1 171 #define USE_KLIBC_MOUSE 1 172 #else 173 #define USE_KLIBC_KBD 0 174 #define USE_KLIBC_MOUSE 0 175 #endif 176 177 #define DEFAULT_MAXCLICK 166 178 #define EV_MAX 8 /* size of mouse circular event queue */ 179 180 /* 181 * If we don't have signals to support it, don't add a sigwinch handler. 182 * In any case, resizing is an extended feature. Use it if we've got it. 183 */ 184 #if !NCURSES_EXT_FUNCS 185 #undef HAVE_SIZECHANGE 186 #define HAVE_SIZECHANGE 0 187 #endif 188 189 #if HAVE_SIZECHANGE && USE_SIGWINCH && defined(SIGWINCH) 190 #define USE_SIZECHANGE 1 191 #else 192 #define USE_SIZECHANGE 0 193 #undef USE_SIGWINCH 194 #define USE_SIGWINCH 0 195 #endif 196 197 /* 198 * When building in the MSYS2 environment, the automatic discovery of 199 * the path separator in configure doesn't work properly. So, if building 200 * for MinGW, we enforce the correct Windows PATH separator 201 */ 202 #if defined(_NC_WINDOWS) 203 # ifdef NCURSES_PATHSEP 204 # undef NCURSES_PATHSEP 205 # endif 206 # define NCURSES_PATHSEP ';' 207 #endif 208 209 /* 210 * Not all platforms have memmove; some have an equivalent bcopy. (Some may 211 * have neither). 212 */ 213 #if USE_OK_BCOPY 214 #define memmove(d,s,n) bcopy(s,d,n) 215 #elif USE_MY_MEMMOVE 216 #define memmove(d,s,n) _nc_memmove(d,s,n) 217 extern NCURSES_EXPORT(void *) _nc_memmove (void *, const void *, size_t); 218 #endif 219 220 /* 221 * If we have va_copy(), use it for assigning va_list's. 222 */ 223 #if defined(HAVE___VA_COPY) 224 #define begin_va_copy(dst,src) __va_copy(dst, src) 225 #define end_va_copy(dst) va_end(dst) 226 #elif defined(va_copy) || defined(HAVE_VA_COPY) 227 #define begin_va_copy(dst,src) va_copy(dst, src) 228 #define end_va_copy(dst) va_end(dst) 229 #else 230 #define begin_va_copy(dst,src) (dst) = (src) 231 #define end_va_copy(dst) /* nothing */ 232 #endif 233 234 /* 235 * Either/both S_ISxxx and/or S_IFxxx are defined in sys/types.h; some systems 236 * lack one or the other. 237 */ 238 #ifndef S_ISDIR 239 #define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR) 240 #endif 241 242 #ifndef S_ISREG 243 #define S_ISREG(mode) ((mode & S_IFMT) == S_IFREG) 244 #endif 245 246 /* 247 * POSIX ignores the "b", which c89 specified. Some very old systems do not 248 * accept it. 249 */ 250 #if USE_FOPEN_BIN_R 251 #define BIN_R "rb" 252 #define BIN_W "wb" 253 #else 254 #define BIN_R "r" 255 #define BIN_W "w" 256 #endif 257 258 /* 259 * Scroll hints are useless when hashmap is used 260 */ 261 #if !USE_SCROLL_HINTS 262 #if !USE_HASHMAP 263 #define USE_SCROLL_HINTS 1 264 #else 265 #define USE_SCROLL_HINTS 0 266 #endif 267 #endif 268 269 #if USE_SCROLL_HINTS 270 #define if_USE_SCROLL_HINTS(stmt) stmt 271 #else 272 #define if_USE_SCROLL_HINTS(stmt) /*nothing*/ 273 #endif 274 275 #include <nc_string.h> 276 277 /* 278 * Options for terminal drivers, etc... 279 */ 280 #ifdef USE_TERM_DRIVER 281 #define NO_TERMINAL "unknown" 282 #define USE_SP_RIPOFF 1 283 #define USE_SP_TERMTYPE 1 284 #define USE_SP_WINDOWLIST 1 285 #else 286 #define NO_TERMINAL 0 287 #endif 288 289 #define VALID_TERM_ENV(term_env, no_terminal) \ 290 (term_env = (NonEmpty(term_env) \ 291 ? term_env \ 292 : no_terminal), \ 293 NonEmpty(term_env)) 294 295 /* 296 * Note: ht/cbt expansion flakes out randomly under Linux 1.1.47, but only 297 * when we're throwing control codes at the screen at high volume. To see 298 * this, re-enable USE_HARD_TABS and run worm for a while. Other systems 299 * probably don't want to define this either due to uncertainties about tab 300 * delays and expansion in raw mode. 301 */ 302 303 #define TRIES struct tries 304 typedef TRIES { 305 TRIES *child; /* ptr to child. NULL if none */ 306 TRIES *sibling; /* ptr to sibling. NULL if none */ 307 unsigned char ch; /* character at this node */ 308 unsigned short value; /* code of string so far. 0 if none. */ 309 #undef TRIES 310 } TRIES; 311 312 /* 313 * Common/troublesome character definitions 314 */ 315 #define StringOf(ch) {ch, 0} 316 317 #define L_BRACE '{' 318 #define R_BRACE '}' 319 #define S_QUOTE '\'' 320 #define D_QUOTE '"' 321 322 #define VT_ACSC "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~" 323 324 /* 325 * Structure for palette tables 326 */ 327 328 #define MAXCOLUMNS 135 329 #define MAXLINES 66 330 #define FIFO_SIZE MAXCOLUMNS+2 /* for nocbreak mode input */ 331 332 #define ACS_LEN 128 333 334 #define WINDOWLIST struct _win_list 335 336 #if USE_WIDEC_SUPPORT 337 #define _nc_bkgd _bkgrnd 338 #else 339 #undef _XOPEN_SOURCE_EXTENDED 340 #undef _XPG5 341 #define _nc_bkgd _bkgd 342 #define wgetbkgrnd(win, wch) ((*wch = win->_bkgd) != 0 ? OK : ERR) 343 #define wbkgrnd wbkgd 344 #endif 345 346 #undef NCURSES_OPAQUE 347 #define NCURSES_INTERNALS 1 348 #define NCURSES_OPAQUE 0 349 350 #include <curses.h> /* we'll use -Ipath directive to get the right one! */ 351 352 #if !(defined(NCURSES_WGETCH_EVENTS) && defined(NEED_KEY_EVENT)) 353 #undef KEY_EVENT /* reduce compiler-warnings with Visual C++ */ 354 #endif 355 356 typedef struct 357 { 358 int red, green, blue; /* what color_content() returns */ 359 int r, g, b; /* params to init_color() */ 360 int init; /* true if we called init_color() */ 361 } 362 color_t; 363 364 typedef union { 365 struct { 366 unsigned char red; 367 unsigned char green; 368 unsigned char blue; 369 } bits; /* bits per color-value in RGB */ 370 unsigned value; 371 } rgb_bits_t; 372 373 /* 374 * If curses.h did not expose the SCREEN-functions, then we do not need the 375 * parameter in the corresponding unextended functions. 376 */ 377 378 #define USE_SP_FUNC_SUPPORT NCURSES_SP_FUNCS 379 #define USE_EXT_SP_FUNC_SUPPORT (NCURSES_SP_FUNCS && NCURSES_EXT_FUNCS) 380 381 #if NCURSES_SP_FUNCS 382 #define SP_PARM sp /* use parameter */ 383 #define NCURSES_SP_ARG SP_PARM 384 #define NCURSES_SP_DCL SCREEN *NCURSES_SP_ARG 385 #define NCURSES_SP_DCL0 NCURSES_SP_DCL 386 #define NCURSES_SP_ARGx NCURSES_SP_ARG, 387 #define NCURSES_SP_DCLx SCREEN *NCURSES_SP_ARGx 388 #else 389 #define SP_PARM SP /* use global variable */ 390 #define NCURSES_SP_ARG 391 #define NCURSES_SP_DCL 392 #define NCURSES_SP_DCL0 void 393 #define NCURSES_SP_ARGx 394 #define NCURSES_SP_DCLx 395 #endif 396 397 #include <nc_panel.h> 398 399 #include <term.priv.h> 400 #include <nc_termios.h> 401 402 #define IsPreScreen(sp) (((sp) != 0) && sp->_prescreen) 403 #define HasTerminal(sp) (((sp) != 0) && (0 != ((sp)->_term))) 404 #define IsValidScreen(sp) (HasTerminal(sp) && !IsPreScreen(sp)) 405 406 #if USE_REENTRANT 407 #define CurTerm _nc_prescreen._cur_term 408 #else 409 #define CurTerm cur_term 410 #endif 411 412 #if NCURSES_SP_FUNCS 413 #define TerminalOf(sp) ((sp) ? ((sp)->_term ? (sp)->_term : CurTerm) : CurTerm) 414 #else 415 #define TerminalOf(sp) CurTerm 416 #endif 417 418 /* 419 * The legacy layout for TERMTYPE uses "short" for all of the numbers. Moving 420 * past that, numeric capabilities can be "int" by using a TERMTYPE2 structure 421 * in TERMINAL, and doing most of the internal work using TERMTYPE2. There are 422 * a few places (mostly to expose the legacy layout) where the distinction 423 * needs attention. 424 */ 425 #if NCURSES_EXT_COLORS && HAVE_INIT_EXTENDED_COLOR 426 #define NCURSES_EXT_NUMBERS 1 427 #define NCURSES_INT2 int 428 #define SIZEOF_INT2 4 429 #define TerminalType(tp) (tp)->type2 430 #else 431 #define NCURSES_EXT_NUMBERS 0 432 #define NCURSES_INT2 short 433 #define SIZEOF_INT2 2 434 #define TerminalType(tp) (tp)->type 435 #endif 436 437 #define SIZEOF_SHORT 2 438 439 #ifdef CUR 440 #undef CUR 441 #define CUR TerminalType(cur_term). 442 #endif 443 444 /* 445 * Reduce dependency on cur_term global by using terminfo data from SCREEN's 446 * pointer to this data. 447 */ 448 #ifdef USE_SP_TERMTYPE 449 #undef CUR 450 #endif 451 452 #define SP_TERMTYPE TerminalType(TerminalOf(sp)). 453 454 #include <term_entry.h> 455 456 #include <nc_tparm.h> 457 458 /* 459 * Simplify ifdef's for the "*_ATTR" macros in case italics are not configured. 460 */ 461 #if defined(A_ITALIC) && defined(exit_italics_mode) 462 #define USE_ITALIC 1 463 #else 464 #define USE_ITALIC 0 465 #undef A_ITALIC 466 #define A_ITALIC 0 467 #endif 468 469 /* 470 * Use these macros internally, to make tracing less verbose. But leave the 471 * option for compiling the tracing into the library. 472 */ 473 #if 1 474 #define ColorPair(n) (NCURSES_BITS(n, 0) & A_COLOR) 475 #define PairNumber(a) (NCURSES_CAST(int,(((unsigned long)(a) & A_COLOR) >> NCURSES_ATTR_SHIFT))) 476 #else 477 #define ColorPair(pair) COLOR_PAIR(pair) 478 #define PairNumber(attr) PAIR_NUMBER(attr) 479 #endif 480 481 #define unColor(n) unColor2(AttrOf(n)) 482 #define unColor2(a) ((a) & ALL_BUT_COLOR) 483 484 /* 485 * Extended-colors stores the color pair in a separate struct-member than the 486 * attributes. But for compatibility, we handle most cases where a program 487 * written for non-extended colors stores the color in the attributes by 488 * checking for a color pair in both places. 489 */ 490 #if NCURSES_EXT_COLORS 491 #define if_EXT_COLORS(stmt) stmt 492 #define SetPair(value,p) SetPair2((value).ext_color, AttrOf(value), p) 493 #define SetPair2(c,a,p) c = (p), \ 494 a = (unColor2(a) | ColorPair(oldColor(c))) 495 #define GetPair(value) GetPair2((value).ext_color, AttrOf(value)) 496 #define GetPair2(c,a) ((c) ? (c) : PairNumber(a)) 497 #define oldColor(p) (((p) > 255) ? 255 : (p)) 498 #define GET_WINDOW_PAIR(w) GetPair2((w)->_color, (w)->_attrs) 499 #define SET_WINDOW_PAIR(w,p) (w)->_color = (p) 500 #define SameAttrOf(a,b) (AttrOf(a) == AttrOf(b) && GetPair(a) == GetPair(b)) 501 502 #define VIDPUTS(sp,attr,pair) do { \ 503 int vid_pair = pair; \ 504 NCURSES_SP_NAME(vid_puts)( \ 505 NCURSES_SP_ARGx attr, \ 506 (NCURSES_PAIRS_T) pair, \ 507 &vid_pair, \ 508 NCURSES_OUTC_FUNC); \ 509 } while (0) 510 511 #else /* !NCURSES_EXT_COLORS */ 512 513 #define if_EXT_COLORS(stmt) /* nothing */ 514 #define SetPair(value,p) RemAttr(value, A_COLOR), \ 515 SetAttr(value, AttrOf(value) | ColorPair(p)) 516 #define GetPair(value) PairNumber(AttrOf(value)) 517 #define GET_WINDOW_PAIR(w) PairNumber(WINDOW_ATTRS(w)) 518 #define SET_WINDOW_PAIR(w,p) WINDOW_ATTRS(w) &= ALL_BUT_COLOR, \ 519 WINDOW_ATTRS(w) |= ColorPair(p) 520 #define SameAttrOf(a,b) (AttrOf(a) == AttrOf(b)) 521 522 #define VIDPUTS(sp,attr,pair) NCURSES_SP_NAME(vidputs)(NCURSES_SP_ARGx attr, NCURSES_OUTC_FUNC) 523 524 #endif /* NCURSES_EXT_COLORS */ 525 526 #define NCURSES_OUTC_FUNC NCURSES_SP_NAME(_nc_outch) 527 #define NCURSES_PUTP2(name,value) NCURSES_SP_NAME(_nc_putp)(NCURSES_SP_ARGx name, value) 528 #define NCURSES_PUTP2_FLUSH(name,value) NCURSES_SP_NAME(_nc_putp_flush)(NCURSES_SP_ARGx name, value) 529 530 #if NCURSES_NO_PADDING 531 #define GetNoPadding(sp) ((sp) ? (sp)->_no_padding : _nc_prescreen._no_padding) 532 #define SetNoPadding(sp) _nc_set_no_padding(sp) 533 extern NCURSES_EXPORT(void) _nc_set_no_padding(SCREEN *); 534 #else 535 #define GetNoPadding(sp) FALSE 536 #define SetNoPadding(sp) /*nothing*/ 537 #endif 538 539 #define WINDOW_ATTRS(w) ((w)->_attrs) 540 541 #define SCREEN_ATTRS(s) (*((s)->_current_attr)) 542 #define GET_SCREEN_PAIR(s) GetPair(SCREEN_ATTRS(s)) 543 #define SET_SCREEN_PAIR(s,p) SetPair(SCREEN_ATTRS(s), p) 544 545 #if USE_REENTRANT || NCURSES_SP_FUNCS 546 NCURSES_EXPORT(int *) _nc_ptr_Lines (SCREEN *); 547 NCURSES_EXPORT(int *) _nc_ptr_Cols (SCREEN *); 548 NCURSES_EXPORT(int *) _nc_ptr_Tabsize (SCREEN *); 549 NCURSES_EXPORT(int *) _nc_ptr_Escdelay (SCREEN *); 550 #endif 551 552 #if USE_REENTRANT 553 554 #define ptrLines(sp) (sp ? &(sp->_LINES) : &(_nc_prescreen._LINES)) 555 #define ptrCols(sp) (sp ? &(sp->_COLS) : &(_nc_prescreen._COLS)) 556 #define ptrTabsize(sp) (sp ? &(sp->_TABSIZE) : &(_nc_prescreen._TABSIZE)) 557 #define ptrEscdelay(sp) (sp ? &(sp->_ESCDELAY) : &(_nc_prescreen._ESCDELAY)) 558 559 #define SET_LINES(value) *_nc_ptr_Lines(SP_PARM) = value 560 #define SET_COLS(value) *_nc_ptr_Cols(SP_PARM) = value 561 #define SET_TABSIZE(value) *_nc_ptr_Tabsize(SP_PARM) = value 562 #define SET_ESCDELAY(value) *_nc_ptr_Escdelay(SP_PARM) = value 563 564 #else 565 566 #define ptrLines(sp) &LINES 567 #define ptrCols(sp) &COLS 568 #define ptrTabsize(sp) &TABSIZE 569 #define ptrEscdelay(sp) &ESCDELAY 570 571 #define SET_LINES(value) LINES = value 572 #define SET_COLS(value) COLS = value 573 #define SET_TABSIZE(value) TABSIZE = value 574 #define SET_ESCDELAY(value) ESCDELAY = value 575 576 #endif 577 578 #define HasHardTabs() (NonEmpty(clear_all_tabs) && NonEmpty(set_tab)) 579 580 #define TR_MUTEX(data) _tracef("%s@%d: me:%08lX COUNT:%2u/%2d/%6d/%2d/%s%9u: " #data, \ 581 __FILE__, __LINE__, \ 582 (unsigned long) (pthread_self()), \ 583 data.__data.__lock, \ 584 data.__data.__count, \ 585 data.__data.__owner, \ 586 data.__data.__kind, \ 587 (data.__data.__nusers > 5) ? " OOPS " : "", \ 588 data.__data.__nusers) 589 #define TR_GLOBAL_MUTEX(name) TR_MUTEX(_nc_globals.mutex_##name) 590 591 #if USE_WEAK_SYMBOLS 592 #if defined(__GNUC__) 593 # if defined __USE_ISOC99 594 # define _cat_pragma(exp) _Pragma(#exp) 595 # define _weak_pragma(exp) _cat_pragma(weak name) 596 # else 597 # define _weak_pragma(exp) 598 # endif 599 # define _declare(name) __extension__ extern __typeof__(name) name 600 # define weak_symbol(name) _weak_pragma(name) _declare(name) __attribute__((weak)) 601 #else 602 # undef USE_WEAK_SYMBOLS 603 # define USE_WEAK_SYMBOLS 0 604 #endif 605 #endif 606 607 #ifdef USE_PTHREADS 608 609 #if USE_REENTRANT 610 #include <pthread.h> 611 extern NCURSES_EXPORT(void) _nc_init_pthreads(void); 612 extern NCURSES_EXPORT(void) _nc_mutex_init(pthread_mutex_t *); 613 extern NCURSES_EXPORT(int) _nc_mutex_lock(pthread_mutex_t *); 614 extern NCURSES_EXPORT(int) _nc_mutex_trylock(pthread_mutex_t *); 615 extern NCURSES_EXPORT(int) _nc_mutex_unlock(pthread_mutex_t *); 616 #define _nc_lock_global(name) _nc_mutex_lock(&_nc_globals.mutex_##name) 617 #define _nc_try_global(name) _nc_mutex_trylock(&_nc_globals.mutex_##name) 618 #define _nc_unlock_global(name) _nc_mutex_unlock(&_nc_globals.mutex_##name) 619 620 #else 621 #error POSIX threads requires --enable-reentrant option 622 #endif 623 624 #ifdef USE_PTHREADS 625 # if USE_WEAK_SYMBOLS 626 weak_symbol(pthread_sigmask); 627 weak_symbol(pthread_kill); 628 weak_symbol(pthread_self); 629 weak_symbol(pthread_equal); 630 weak_symbol(pthread_mutex_init); 631 weak_symbol(pthread_mutex_lock); 632 weak_symbol(pthread_mutex_unlock); 633 weak_symbol(pthread_mutex_trylock); 634 weak_symbol(pthread_mutexattr_settype); 635 weak_symbol(pthread_mutexattr_init); 636 extern NCURSES_EXPORT(int) _nc_sigprocmask(int, const sigset_t *, sigset_t *); 637 # undef sigprocmask 638 # define sigprocmask(a, b, c) _nc_sigprocmask(a, b, c) 639 # define GetThreadID() (((pthread_self)) ? pthread_self() : (pthread_t) getpid()) 640 # else 641 # define GetThreadID() pthread_self() 642 # endif 643 #endif 644 645 #if HAVE_NANOSLEEP 646 #undef HAVE_NANOSLEEP 647 #define HAVE_NANOSLEEP 0 /* nanosleep suspends all threads */ 648 #endif 649 650 #else /* !USE_PTHREADS */ 651 652 #if USE_PTHREADS_EINTR 653 # if USE_WEAK_SYMBOLS 654 #include <pthread.h> 655 weak_symbol(pthread_sigmask); 656 weak_symbol(pthread_kill); 657 weak_symbol(pthread_self); 658 weak_symbol(pthread_equal); 659 extern NCURSES_EXPORT(int) _nc_sigprocmask(int, const sigset_t *, sigset_t *); 660 # undef sigprocmask 661 # define sigprocmask(a, b, c) _nc_sigprocmask(a, b, c) 662 # endif 663 #endif /* USE_PTHREADS_EINTR */ 664 665 #define _nc_init_pthreads() /* nothing */ 666 #define _nc_mutex_init(obj) /* nothing */ 667 668 #define _nc_lock_global(name) /* nothing */ 669 #define _nc_try_global(name) 0 670 #define _nc_unlock_global(name) /* nothing */ 671 672 #endif /* USE_PTHREADS */ 673 674 /* 675 * When using sp-funcs, locks are targeted to SCREEN-level granularity. 676 * So the locking is done in the non-sp-func (which calls the sp-func) rather 677 * than in the sp-func itself. 678 * 679 * Use the _nc_nonsp_XXX functions in the function using "NCURSES_SP_NAME()". 680 * Use the _nc_sp_XXX functions in the function using "#if NCURSES_SP_FUNCS". 681 */ 682 #if NCURSES_SP_FUNCS 683 684 #define _nc_nonsp_lock_global(name) /* nothing */ 685 #define _nc_nonsp_try_global(name) 0 686 #define _nc_nonsp_unlock_global(name) /* nothing */ 687 688 #define _nc_sp_lock_global(name) _nc_lock_global(name) 689 #define _nc_sp_try_global(name) _nc_try_global(name) 690 #define _nc_sp_unlock_global(name) _nc_unlock_global(name) 691 692 #else 693 694 #define _nc_nonsp_lock_global(name) _nc_lock_global(name) 695 #define _nc_nonsp_try_global(name) _nc_try_global(name) 696 #define _nc_nonsp_unlock_global(name) _nc_unlock_global(name) 697 698 #define _nc_sp_lock_global(name) /* nothing */ 699 #define _nc_sp_try_global(name) 0 700 #define _nc_sp_unlock_global(name) /* nothing */ 701 702 #endif 703 704 #if HAVE_GETTIMEOFDAY 705 # define PRECISE_GETTIME 1 706 # define TimeType struct timeval 707 #else 708 # define PRECISE_GETTIME 0 709 # define TimeType time_t 710 #endif 711 712 /* 713 * Definitions for color pairs 714 */ 715 716 #define MAX_OF_TYPE(t) (int)(((unsigned t)(~0))>>1) 717 718 #include <new_pair.h> 719 720 #define isDefaultColor(c) ((c) < 0) 721 #define COLOR_DEFAULT -1 722 723 #if defined(USE_BUILD_CC) || (defined(USE_TERMLIB) && !defined(NEED_NCURSES_CH_T)) 724 725 #undef NCURSES_CH_T /* this is not a termlib feature */ 726 #define NCURSES_CH_T void /* ...but we need a pointer in SCREEN */ 727 728 #endif /* USE_TERMLIB */ 729 730 #ifndef USE_TERMLIB 731 struct ldat 732 { 733 NCURSES_CH_T *text; /* text of the line */ 734 NCURSES_SIZE_T firstchar; /* first changed character in the line */ 735 NCURSES_SIZE_T lastchar; /* last changed character in the line */ 736 NCURSES_SIZE_T oldindex; /* index of the line at last update */ 737 }; 738 #endif /* USE_TERMLIB */ 739 740 typedef enum { 741 M_XTERM = -1 /* use xterm's mouse tracking? */ 742 ,M_NONE = 0 /* no mouse device */ 743 #if USE_GPM_SUPPORT 744 ,M_GPM /* use GPM */ 745 #endif 746 #if USE_SYSMOUSE 747 ,M_SYSMOUSE /* FreeBSD sysmouse on console */ 748 #endif 749 #ifdef USE_TERM_DRIVER 750 ,M_TERM_DRIVER /* Win32 console, etc */ 751 #endif 752 } MouseType; 753 754 typedef enum { 755 MF_X10 = 0 /* conventional 3-byte format */ 756 , MF_SGR1006 /* xterm private mode 1006, SGR-style */ 757 #ifdef EXP_XTERM_1005 758 , MF_XTERM_1005 /* xterm UTF-8 private mode 1005 */ 759 #endif 760 } MouseFormat; 761 762 /* 763 * Structures for scrolling. 764 */ 765 766 typedef struct { 767 unsigned long hashval; 768 int oldcount, newcount; 769 int oldindex, newindex; 770 } HASHMAP; 771 772 /* 773 * Structures for soft labels. 774 */ 775 776 struct _SLK; 777 778 #if !(defined(USE_TERMLIB) || defined(USE_BUILD_CC)) 779 780 typedef struct 781 { 782 char *ent_text; /* text for the label */ 783 char *form_text; /* formatted text (left/center/...) */ 784 int ent_x; /* x coordinate of this field */ 785 char dirty; /* this label has changed */ 786 char visible; /* field is visible */ 787 } slk_ent; 788 789 typedef struct _SLK { 790 bool dirty; /* all labels have changed */ 791 bool hidden; /* soft labels are hidden */ 792 WINDOW *win; 793 slk_ent *ent; 794 short maxlab; /* number of available labels */ 795 short labcnt; /* number of allocated labels */ 796 short maxlen; /* length of labels */ 797 NCURSES_CH_T attr; /* soft label attribute */ 798 } SLK; 799 800 #endif /* USE_TERMLIB */ 801 802 #if USE_GPM_SUPPORT 803 #undef buttons /* term.h defines this, and gpm uses it! */ 804 #include <gpm.h> 805 #if USE_WEAK_SYMBOLS 806 weak_symbol(Gpm_Wgetch); 807 #endif 808 809 #ifdef HAVE_LIBDL 810 /* link dynamically to GPM */ 811 typedef int *TYPE_gpm_fd; 812 typedef int (*TYPE_Gpm_Open) (Gpm_Connect *, int); 813 typedef int (*TYPE_Gpm_Close) (void); 814 typedef int (*TYPE_Gpm_GetEvent) (Gpm_Event *); 815 816 #define my_gpm_fd SP_PARM->_mouse_gpm_fd 817 #define my_Gpm_Open SP_PARM->_mouse_Gpm_Open 818 #define my_Gpm_Close SP_PARM->_mouse_Gpm_Close 819 #define my_Gpm_GetEvent SP_PARM->_mouse_Gpm_GetEvent 820 #else 821 /* link statically to GPM */ 822 #define my_gpm_fd &gpm_fd 823 #define my_Gpm_Open Gpm_Open 824 #define my_Gpm_Close Gpm_Close 825 #define my_Gpm_GetEvent Gpm_GetEvent 826 #endif /* HAVE_LIBDL */ 827 #endif /* USE_GPM_SUPPORT */ 828 829 /* 830 * When converting from terminfo to termcap, check for cases where we can trim 831 * octal escapes down to 2-character form. It is useful for terminfo format 832 * also, but not as important. 833 */ 834 #define MAX_TC_FIXUPS 10 835 #define MIN_TC_FIXUPS 4 836 837 #define isoctal(c) ((c) >= '0' && (c) <= '7') 838 839 /* 840 * The filesystem database normally uses a single-letter for the lower level 841 * of directories. Use a hexadecimal code for filesystems which do not 842 * preserve mixed-case names. 843 */ 844 #if MIXEDCASE_FILENAMES 845 #define LEAF_FMT "%c" 846 #define LEAF_LEN 1 847 #else 848 #define LEAF_FMT "%02x" 849 #define LEAF_LEN 2 850 #endif 851 852 /* 853 * TRACEMSE_FMT is no longer than 80 columns, there are 5 numbers that 854 * could at most have 10 digits, and the mask contains no more than 32 bits 855 * with each bit representing less than 15 characters. Usually the whole 856 * string is less than 80 columns, but this buffer size is an absolute 857 * limit. 858 */ 859 #define TRACEMSE_MAX (80 + (5 * 10) + (32 * 15)) 860 #define TRACEMSE_FMT "id %2d at (%2d, %2d, %2d) state %4lx = {" /* } */ 861 862 #ifdef USE_TERM_DRIVER 863 struct DriverTCB; /* Terminal Control Block forward declaration */ 864 #define INIT_TERM_DRIVER() _nc_globals.term_driver = _nc_get_driver 865 #else 866 #define INIT_TERM_DRIVER() /* nothing */ 867 #endif 868 869 extern NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals; 870 871 /* The limit reserves one byte for a terminating NUL */ 872 #define my_getstr_limit (_nc_globals.getstr_limit - 1) 873 #define _nc_getstr_limit(n) \ 874 (((n) < 0) \ 875 ? my_getstr_limit \ 876 : (((n) > my_getstr_limit) \ 877 ? my_getstr_limit \ 878 : (n))) 879 880 /* 881 * Use screen-specific ripoff data (for softkeys) rather than global. 882 */ 883 #ifdef USE_SP_RIPOFF 884 #define safe_ripoff_sp (sp)->rsp 885 #define safe_ripoff_stack (sp)->rippedoff 886 #else 887 #define safe_ripoff_sp _nc_prescreen.rsp 888 #define safe_ripoff_stack _nc_prescreen.rippedoff 889 #endif 890 891 extern NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen; 892 893 typedef enum { 894 ewInitial = 0, 895 ewRunning, 896 ewSuspend 897 } ENDWIN; 898 899 /* 900 * The SCREEN structure. 901 */ 902 typedef struct screen { 903 int _ifd; /* input file descriptor for screen */ 904 int _ofd; /* output file descriptor for screen */ 905 FILE *_ofp; /* output file ptr for screen */ 906 char *out_buffer; /* output buffer */ 907 size_t out_limit; /* output buffer size */ 908 size_t out_inuse; /* output buffer current use */ 909 bool _filtered; /* filter() was called */ 910 bool _prescreen; /* is in prescreen phase */ 911 bool _use_env; /* LINES & COLS from environment? */ 912 int _checkfd; /* filedesc for typeahead check */ 913 TERMINAL *_term; /* terminal type information */ 914 TTY _saved_tty; /* savetty/resetty information */ 915 NCURSES_SIZE_T _lines; /* screen lines */ 916 NCURSES_SIZE_T _columns; /* screen columns */ 917 918 NCURSES_SIZE_T _lines_avail; /* lines available for stdscr */ 919 NCURSES_SIZE_T _topstolen; /* lines stolen from top */ 920 921 WINDOW *_curscr; /* current screen */ 922 WINDOW *_newscr; /* virtual screen to be updated to */ 923 WINDOW *_stdscr; /* screen's full-window context */ 924 925 #define CurScreen(sp) (sp)->_curscr 926 #define NewScreen(sp) (sp)->_newscr 927 #define StdScreen(sp) (sp)->_stdscr 928 929 TRIES *_keytry; /* "Try" for use with keypad mode */ 930 TRIES *_key_ok; /* Disabled keys via keyok(,FALSE) */ 931 bool _tried; /* keypad mode was initialized */ 932 bool _keypad_on; /* keypad mode is currently on */ 933 934 bool _called_wgetch; /* check for recursion in wgetch() */ 935 int _fifo[FIFO_SIZE]; /* input push-back buffer */ 936 short _fifohead, /* head of fifo queue */ 937 _fifotail, /* tail of fifo queue */ 938 _fifopeek, /* where to peek for next char */ 939 _fifohold; /* set if breakout marked */ 940 941 int _endwin; /* are we out of window mode? */ 942 NCURSES_CH_T *_current_attr; /* holds current attributes set */ 943 int _coloron; /* is color enabled? */ 944 int _color_defs; /* are colors modified */ 945 int _cursor; /* visibility of the cursor */ 946 int _cursrow; /* physical cursor row */ 947 int _curscol; /* physical cursor column */ 948 bool _notty; /* true if we cannot switch non-tty */ 949 int _nl; /* True if NL -> CR/NL is on */ 950 int _raw; /* True if in raw mode */ 951 int _cbreak; /* 1 if in cbreak mode */ 952 /* > 1 if in halfdelay mode */ 953 int _echo; /* True if echo on */ 954 int _use_meta; /* use the meta key? */ 955 struct _SLK *_slk; /* ptr to soft key struct / NULL */ 956 int slk_format; /* selected format for this screen */ 957 /* cursor movement costs; units are 10ths of milliseconds */ 958 int _char_padding; /* cost of character put */ 959 int _cr_cost; /* cost of (carriage_return) */ 960 int _cup_cost; /* cost of (cursor_address) */ 961 int _home_cost; /* cost of (cursor_home) */ 962 int _ll_cost; /* cost of (cursor_to_ll) */ 963 int _cub1_cost; /* cost of (cursor_left) */ 964 int _cuf1_cost; /* cost of (cursor_right) */ 965 int _cud1_cost; /* cost of (cursor_down) */ 966 int _cuu1_cost; /* cost of (cursor_up) */ 967 int _cub_cost; /* cost of (parm_cursor_left) */ 968 int _cuf_cost; /* cost of (parm_cursor_right) */ 969 int _cud_cost; /* cost of (parm_cursor_down) */ 970 int _cuu_cost; /* cost of (parm_cursor_up) */ 971 int _hpa_cost; /* cost of (column_address) */ 972 int _vpa_cost; /* cost of (row_address) */ 973 /* used in tty_update.c, must be chars */ 974 int _ed_cost; /* cost of (clr_eos) */ 975 int _el_cost; /* cost of (clr_eol) */ 976 int _el1_cost; /* cost of (clr_bol) */ 977 int _dch1_cost; /* cost of (delete_character) */ 978 int _ich1_cost; /* cost of (insert_character) */ 979 int _dch_cost; /* cost of (parm_dch) */ 980 int _ich_cost; /* cost of (parm_ich) */ 981 int _ech_cost; /* cost of (erase_chars) */ 982 int _rep_cost; /* cost of (repeat_char) */ 983 int _hpa_ch_cost; /* cost of (column_address) */ 984 int _cup_ch_cost; /* cost of (cursor_address) */ 985 int _cuf_ch_cost; /* cost of (parm_cursor_right) */ 986 int _inline_cost; /* cost of inline-move */ 987 int _smir_cost; /* cost of (enter_insert_mode) */ 988 int _rmir_cost; /* cost of (exit_insert_mode) */ 989 int _ip_cost; /* cost of (insert_padding) */ 990 /* used in lib_mvcur.c */ 991 char * _address_cursor; 992 /* used in tty_update.c */ 993 int _scrolling; /* 1 if terminal's smart enough to */ 994 995 /* used in lib_color.c */ 996 rgb_bits_t _direct_color; /* RGB overrides color-table */ 997 color_t *_color_table; /* screen's color palette */ 998 int _color_count; /* count of colors in palette */ 999 colorpair_t *_color_pairs; /* screen's color pair list */ 1000 int _pair_count; /* same as COLOR_PAIRS */ 1001 int _pair_limit; /* actual limit of color-pairs */ 1002 int _pair_alloc; /* current table-size of color-pairs */ 1003 chtype _ok_attributes; /* valid attributes for terminal */ 1004 chtype _xmc_suppress; /* attributes to suppress if xmc */ 1005 chtype _xmc_triggers; /* attributes to process if xmc */ 1006 chtype * _acs_map; /* the real alternate-charset map */ 1007 bool * _screen_acs_map; 1008 1009 1010 /* used in lib_vidattr.c */ 1011 bool _use_rmso; /* true if we may use 'rmso' */ 1012 bool _use_rmul; /* true if we may use 'rmul' */ 1013 1014 /* 1015 * These data correspond to the state of the idcok() and idlok() 1016 * functions. A caveat is in order here: the XSI and SVr4 1017 * documentation specify that these functions apply to the window which 1018 * is given as an argument. However, ncurses implements this logic 1019 * only for the newscr/curscr update process, _not_ per-window. 1020 */ 1021 bool _nc_sp_idlok; 1022 bool _nc_sp_idcok; 1023 1024 /* 1025 * These are the data that support the mouse interface. 1026 */ 1027 bool _mouse_initialized; 1028 MouseType _mouse_type; 1029 int _maxclick; 1030 bool (*_mouse_event) (SCREEN *); 1031 bool (*_mouse_inline)(SCREEN *); 1032 bool (*_mouse_parse) (SCREEN *, int); 1033 void (*_mouse_resume)(SCREEN *); 1034 void (*_mouse_wrap) (SCREEN *); 1035 int _mouse_fd; /* file-descriptor, if any */ 1036 bool _mouse_active; /* true if initialized */ 1037 mmask_t _mouse_mask; /* set via mousemask() */ 1038 mmask_t _mouse_mask2; /* OR's in press/release bits */ 1039 mmask_t _mouse_bstate; 1040 MouseFormat _mouse_format; /* type of xterm mouse protocol */ 1041 NCURSES_CONST char *_mouse_xtermcap; /* string to enable/disable mouse */ 1042 MEVENT _mouse_events[EV_MAX]; /* hold the last mouse event seen */ 1043 MEVENT *_mouse_eventp; /* next free slot in event queue */ 1044 1045 /* 1046 * These are data that support the proper handling of the panel stack on an 1047 * per screen basis. 1048 */ 1049 struct panelhook _panelHook; 1050 1051 bool _sig_winch; 1052 SCREEN *_next_screen; 1053 1054 /* hashes for old and new lines */ 1055 unsigned long *oldhash, *newhash; 1056 HASHMAP *hashtab; 1057 int hashtab_len; 1058 int *_oldnum_list; 1059 int _oldnum_size; 1060 1061 NCURSES_SP_OUTC _outch; /* output handler if not putc */ 1062 NCURSES_OUTC jump; 1063 1064 ripoff_t rippedoff[N_RIPS]; 1065 ripoff_t *rsp; 1066 1067 int _legacy_coding; /* see use_legacy_coding() */ 1068 1069 #if NCURSES_NO_PADDING 1070 bool _no_padding; /* flag to set if padding disabled */ 1071 #endif 1072 1073 #if USE_HARD_TABS 1074 int _ht_cost; /* cost of (tab) */ 1075 int _cbt_cost; /* cost of (backtab) */ 1076 #endif /* USE_HARD_TABS */ 1077 1078 /* used in lib_vidattr.c */ 1079 #if USE_ITALIC 1080 bool _use_ritm; /* true if we may use 'ritm' */ 1081 #endif 1082 1083 /* used in getch/twait */ 1084 #if USE_KLIBC_KBD 1085 bool _extended_key; /* true if an extended key */ 1086 #endif 1087 1088 /* used in lib_color.c */ 1089 #if NCURSES_EXT_FUNCS 1090 bool _assumed_color; /* use assumed colors */ 1091 bool _default_color; /* use default colors */ 1092 bool _has_sgr_39_49; /* has ECMA default color support */ 1093 int _default_fg; /* assumed default foreground */ 1094 int _default_bg; /* assumed default background */ 1095 int _default_pairs; /* count pairs using default color */ 1096 #endif 1097 1098 /* system-dependent mouse data */ 1099 #if USE_GPM_SUPPORT 1100 bool _mouse_gpm_loaded; 1101 bool _mouse_gpm_found; 1102 #ifdef HAVE_LIBDL 1103 void *_dlopen_gpm; 1104 TYPE_gpm_fd _mouse_gpm_fd; 1105 TYPE_Gpm_Open _mouse_Gpm_Open; 1106 TYPE_Gpm_Close _mouse_Gpm_Close; 1107 TYPE_Gpm_GetEvent _mouse_Gpm_GetEvent; 1108 #endif 1109 Gpm_Connect _mouse_gpm_connect; 1110 #endif /* USE_GPM_SUPPORT */ 1111 1112 #if USE_EMX_MOUSE 1113 int _emxmouse_wfd; 1114 int _emxmouse_thread; 1115 int _emxmouse_activated; 1116 char _emxmouse_buttons[4]; 1117 #endif 1118 1119 #if USE_SYSMOUSE 1120 MEVENT _sysmouse_fifo[FIFO_SIZE]; 1121 int _sysmouse_head; 1122 int _sysmouse_tail; 1123 int _sysmouse_char_width; /* character width */ 1124 int _sysmouse_char_height; /* character height */ 1125 int _sysmouse_old_buttons; 1126 int _sysmouse_new_buttons; 1127 #endif 1128 1129 #if defined(USE_TERM_DRIVER) || defined(EXP_WIN32_DRIVER) 1130 MEVENT _drv_mouse_fifo[FIFO_SIZE]; 1131 int _drv_mouse_head; 1132 int _drv_mouse_tail; 1133 int _drv_mouse_old_buttons; 1134 int _drv_mouse_new_buttons; 1135 #endif 1136 /* 1137 * This supports automatic resizing 1138 */ 1139 #if USE_SIZECHANGE 1140 int (*_resize)(NCURSES_SP_DCLx int y, int x); 1141 int (*_ungetch)(SCREEN *, int); 1142 #endif 1143 1144 #ifdef USE_SP_WINDOWLIST 1145 WINDOWLIST* _windowlist; 1146 #define WindowList(sp) (sp)->_windowlist 1147 #endif 1148 1149 #if USE_REENTRANT 1150 char _ttytype[NAMESIZE]; 1151 int _ESCDELAY; 1152 int _TABSIZE; 1153 int _LINES; 1154 int _COLS; 1155 #endif 1156 1157 #if NCURSES_SP_FUNCS 1158 bool use_tioctl; 1159 #endif 1160 1161 /* 1162 * ncurses/ncursesw are the same up to this point. 1163 */ 1164 #if USE_WIDEC_SUPPORT 1165 /* recent versions of 'screen' have partially-working support for 1166 * UTF-8, but do not permit ACS at the same time (see tty_update.c). 1167 */ 1168 bool _screen_acs_fix; 1169 bool _screen_unicode; 1170 #endif 1171 1172 #if NCURSES_EXT_FUNCS && NCURSES_EXT_COLORS 1173 void *_ordered_pairs; /* index used by alloc_pair() */ 1174 int _pairs_used; /* actual number of color-pairs used */ 1175 int _recent_pair; /* number for most recent free-pair */ 1176 #endif 1177 1178 #ifdef TRACE 1179 char tracechr_buf[40]; 1180 char tracemse_buf[TRACEMSE_MAX]; 1181 #if USE_REENTRANT 1182 long _outchars; 1183 const char *_tputs_trace; 1184 #endif 1185 #endif 1186 #undef SCREEN 1187 } SCREEN; 1188 1189 extern NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain; 1190 extern NCURSES_EXPORT_VAR(SIG_ATOMIC_T) _nc_have_sigwinch; 1191 1192 WINDOWLIST { 1193 WINDOWLIST *next; 1194 SCREEN *screen; /* screen containing the window */ 1195 WINDOW win; /* WINDOW_EXT() needs to account for offset */ 1196 #if NCURSES_WIDECHAR 1197 char addch_work[(MB_LEN_MAX * 9) + 1]; 1198 unsigned addch_used; /* number of bytes in addch_work[] */ 1199 int addch_x; /* x-position for addch_work[] */ 1200 int addch_y; /* y-position for addch_work[] */ 1201 #endif 1202 }; 1203 1204 #define WINDOW_EXT(w,m) (((WINDOWLIST *)((void *)((char *)(w) - offsetof(WINDOWLIST, win))))->m) 1205 1206 #ifdef USE_SP_WINDOWLIST 1207 #define SP_INIT_WINDOWLIST(sp) WindowList(sp) = 0 1208 #else 1209 #define SP_INIT_WINDOWLIST(sp) /* nothing */ 1210 #endif 1211 1212 #define SP_PRE_INIT(sp) \ 1213 sp->_cursrow = -1; \ 1214 sp->_curscol = -1; \ 1215 sp->_nl = TRUE; \ 1216 sp->_raw = FALSE; \ 1217 sp->_cbreak = 0; \ 1218 sp->_echo = TRUE; \ 1219 sp->_fifohead = -1; \ 1220 sp->_endwin = ewSuspend; \ 1221 sp->_cursor = -1; \ 1222 SP_INIT_WINDOWLIST(sp); \ 1223 sp->_outch = NCURSES_OUTC_FUNC; \ 1224 sp->jump = 0 \ 1225 1226 /* usually in <limits.h> */ 1227 #ifndef UCHAR_MAX 1228 #define UCHAR_MAX 255 1229 #endif 1230 1231 /* The terminfo source is assumed to be 7-bit ASCII */ 1232 #define is7bits(c) ((unsigned)(c) < 128) 1233 1234 /* Checks for isprint() should be done on 8-bit characters (non-wide) */ 1235 #define is8bits(c) ((unsigned)(c) <= UCHAR_MAX) 1236 1237 #ifndef min 1238 #define min(a,b) ((a) > (b) ? (b) : (a)) 1239 #endif 1240 1241 #ifndef max 1242 #define max(a,b) ((a) < (b) ? (b) : (a)) 1243 #endif 1244 1245 /* usually in <unistd.h> */ 1246 #ifndef STDIN_FILENO 1247 #define STDIN_FILENO 0 1248 #endif 1249 1250 #ifndef STDOUT_FILENO 1251 #define STDOUT_FILENO 1 1252 #endif 1253 1254 #ifndef STDERR_FILENO 1255 #define STDERR_FILENO 2 1256 #endif 1257 1258 #ifndef EXIT_SUCCESS 1259 #define EXIT_SUCCESS 0 1260 #endif 1261 1262 #ifndef EXIT_FAILURE 1263 #define EXIT_FAILURE 1 1264 #endif 1265 1266 #ifndef R_OK 1267 #define R_OK 4 /* Test for read permission. */ 1268 #endif 1269 #ifndef W_OK 1270 #define W_OK 2 /* Test for write permission. */ 1271 #endif 1272 #ifndef X_OK 1273 #define X_OK 1 /* Test for execute permission. */ 1274 #endif 1275 #ifndef F_OK 1276 #define F_OK 0 /* Test for existence. */ 1277 #endif 1278 1279 #if HAVE_FCNTL_H 1280 #include <fcntl.h> /* may define O_BINARY */ 1281 #endif 1282 1283 #ifndef O_BINARY 1284 #define O_BINARY 0 1285 #endif 1286 1287 #ifdef TRACE 1288 #if USE_REENTRANT 1289 #define COUNT_OUTCHARS(n) _nc_count_outchars(n); 1290 #else 1291 #define COUNT_OUTCHARS(n) _nc_outchars += (n); 1292 #endif 1293 #else 1294 #define COUNT_OUTCHARS(n) /* nothing */ 1295 #endif 1296 1297 #define RESET_OUTCHARS() COUNT_OUTCHARS(-_nc_outchars) 1298 1299 #define UChar(c) ((unsigned char)(c)) 1300 #define UShort(c) ((unsigned short)(c)) 1301 #define ChCharOf(c) ((chtype)(c) & (chtype)A_CHARTEXT) 1302 #define ChAttrOf(c) ((chtype)(c) & (chtype)A_ATTRIBUTES) 1303 1304 #define TR_PUTC(c) TR(TRACE_CHARPUT, ("PUTC %#x", UChar(c))) 1305 1306 #ifndef MB_LEN_MAX 1307 #define MB_LEN_MAX 8 /* should be >= MB_CUR_MAX, but that may be a function */ 1308 #endif 1309 1310 #if USE_WIDEC_SUPPORT /* { */ 1311 #define isEILSEQ(status) (((size_t)status == (size_t)-1) && (errno == EILSEQ)) 1312 1313 #define init_mb(state) memset(&(state), 0, sizeof(state)) 1314 1315 #if NCURSES_EXT_COLORS 1316 #define NulColor , 0 1317 #else 1318 #define NulColor /* nothing */ 1319 #endif 1320 1321 #define NulChar 0,0,0,0 /* FIXME: see CCHARW_MAX */ 1322 #define CharOf(c) ((c).chars[0]) 1323 #define AttrOf(c) ((c).attr) 1324 1325 #define AddAttr(c,a) AttrOf(c) |= ((a) & A_ATTRIBUTES) 1326 #define RemAttr(c,a) AttrOf(c) &= ~((a) & A_ATTRIBUTES) 1327 #define SetAttr(c,a) AttrOf(c) = ((a) & A_ATTRIBUTES) | WidecExt(c) 1328 1329 #define NewChar2(c,a) { a, { c, NulChar } NulColor } 1330 #define NewChar(ch) NewChar2(ChCharOf(ch), ChAttrOf(ch)) 1331 1332 #if CCHARW_MAX == 5 1333 #define CharEq(a,b) (((a).attr == (b).attr) \ 1334 && (a).chars[0] == (b).chars[0] \ 1335 && (a).chars[1] == (b).chars[1] \ 1336 && (a).chars[2] == (b).chars[2] \ 1337 && (a).chars[3] == (b).chars[3] \ 1338 && (a).chars[4] == (b).chars[4] \ 1339 if_EXT_COLORS(&& (a).ext_color == (b).ext_color)) 1340 #elif CCHARW_MAX > 0 1341 #error Inconsistent values for CCHARW_MAX 1342 #else 1343 #define CharEq(a,b) (!memcmp(&(a), &(b), sizeof(a))) 1344 #endif 1345 1346 #define SetChar(ch,c,a) do { \ 1347 NCURSES_CH_T *_cp = &(ch); \ 1348 memset(_cp, 0, sizeof(ch)); \ 1349 _cp->chars[0] = (wchar_t) (c); \ 1350 _cp->attr = (a); \ 1351 if_EXT_COLORS(SetPair(ch, PairNumber(a))); \ 1352 } while (0) 1353 #define CHREF(wch) (&(wch)) 1354 #define CHDEREF(wch) (*(wch)) 1355 #define ARG_CH_T NCURSES_CH_T * 1356 #define CARG_CH_T const NCURSES_CH_T * 1357 #define PUTC_DATA char PUTC_buf[MB_LEN_MAX]; int PUTC_i, PUTC_n; \ 1358 mbstate_t PUT_st; wchar_t PUTC_ch 1359 #define PUTC_INIT init_mb (PUT_st) 1360 #define PUTC(ch) do { if(!isWidecExt(ch)) { \ 1361 if (Charable(ch)) { \ 1362 TR_PUTC(CharOf(ch)); \ 1363 NCURSES_OUTC_FUNC (NCURSES_SP_ARGx CharOf(ch)); \ 1364 COUNT_OUTCHARS(1); \ 1365 } else { \ 1366 for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { \ 1367 PUTC_ch = (ch).chars[PUTC_i]; \ 1368 if (PUTC_ch == L'\0') \ 1369 break; \ 1370 PUTC_INIT; \ 1371 PUTC_n = (int) wcrtomb(PUTC_buf, \ 1372 (ch).chars[PUTC_i], &PUT_st); \ 1373 if (PUTC_n <= 0) { \ 1374 if (PUTC_ch && is8bits(PUTC_ch) && PUTC_i == 0) { \ 1375 TR_PUTC(CharOf(ch)); \ 1376 NCURSES_OUTC_FUNC (NCURSES_SP_ARGx CharOf(ch)); \ 1377 } \ 1378 break; \ 1379 } else { \ 1380 int PUTC_j; \ 1381 for (PUTC_j = 0; PUTC_j < PUTC_n; ++PUTC_j) { \ 1382 TR_PUTC(PUTC_buf[PUTC_j]); \ 1383 NCURSES_OUTC_FUNC (NCURSES_SP_ARGx PUTC_buf[PUTC_j]); \ 1384 } \ 1385 } \ 1386 } \ 1387 COUNT_OUTCHARS(PUTC_i); \ 1388 } } } while (0) 1389 1390 #define BLANK NewChar2(' ', WA_NORMAL) 1391 #define ZEROS NewChar2('\0', WA_NORMAL) 1392 #define ISBLANK(ch) ((ch).chars[0] == L' ' && (ch).chars[1] == L'\0') 1393 1394 /* 1395 * Wide characters cannot be represented in the A_CHARTEXT mask of 1396 * attr_t's but an application might have set a narrow character there. 1397 * But even in that case, it would only be a printable character, or 1398 * zero. Otherwise we can use those bits to tell if a cell is the 1399 * first or extension part of a wide character. 1400 */ 1401 #define WidecExt(ch) (int) (AttrOf(ch) & A_CHARTEXT) 1402 #define isWidecBase(ch) (WidecExt(ch) == 1) 1403 #define isWidecExt(ch) (WidecExt(ch) > 1 && WidecExt(ch) < 32) 1404 #define SetWidecExt(dst, ext) AttrOf(dst) &= ~A_CHARTEXT, \ 1405 AttrOf(dst) |= (attr_t) (ext + 1) 1406 1407 #define if_WIDEC(code) code 1408 #define Charable(ch) (((SP_PARM->_legacy_coding) \ 1409 || (AttrOf(ch) & A_ALTCHARSET) \ 1410 || (!isWidecExt(ch))) && \ 1411 (ch).chars[1] == L'\0' && \ 1412 _nc_is_charable(CharOf(ch))) 1413 1414 #define L(ch) L ## ch 1415 #else /* }{ */ 1416 #define CharOf(c) ChCharOf(c) 1417 #define AttrOf(c) ChAttrOf(c) 1418 #define AddAttr(c,a) c |= (a) 1419 #define RemAttr(c,a) c &= ~((a) & A_ATTRIBUTES) 1420 #define SetAttr(c,a) c = ((c) & ~A_ATTRIBUTES) | (a) 1421 #define NewChar(ch) (ch) 1422 #define NewChar2(c,a) ((c) | (a)) 1423 #define CharEq(a,b) ((a) == (b)) 1424 #define SetChar(ch,c,a) ch = (c) | (a) 1425 #define CHREF(wch) wch 1426 #define CHDEREF(wch) wch 1427 #define ARG_CH_T NCURSES_CH_T 1428 #define CARG_CH_T NCURSES_CH_T 1429 #define PUTC_DATA /* nothing */ 1430 #define PUTC(ch) { \ 1431 TR_PUTC(ch); \ 1432 NCURSES_OUTC_FUNC (NCURSES_SP_ARGx (int) ch); \ 1433 } 1434 1435 #define BLANK (' '|A_NORMAL) 1436 #define ZEROS ('\0'|A_NORMAL) 1437 #define ISBLANK(ch) (CharOf(ch) == ' ') 1438 1439 #define isWidecExt(ch) (0) 1440 #define if_WIDEC(code) /* nothing */ 1441 1442 #define Charable(ch) ((ch) >= ' ' && (ch) <= '~') 1443 #define L(ch) ch 1444 #endif /* } */ 1445 1446 #define AttrOfD(ch) AttrOf(CHDEREF(ch)) 1447 #define CharOfD(ch) CharOf(CHDEREF(ch)) 1448 #define SetChar2(wch,ch) SetChar(wch,ChCharOf(ch),ChAttrOf(ch)) 1449 1450 #define BLANK_ATTR A_NORMAL 1451 #define BLANK_TEXT L(' ') 1452 1453 #define CHANGED -1 1454 1455 #define LEGALYX(w, y, x) \ 1456 ((w) != 0 && \ 1457 ((x) >= 0 && (x) <= (w)->_maxx && \ 1458 (y) >= 0 && (y) <= (w)->_maxy)) 1459 1460 #define CHANGED_CELL(line,col) \ 1461 if (line->firstchar == _NOCHANGE) \ 1462 line->firstchar = line->lastchar = (NCURSES_SIZE_T) (col); \ 1463 else if ((col) < line->firstchar) \ 1464 line->firstchar = (NCURSES_SIZE_T) (col); \ 1465 else if ((col) > line->lastchar) \ 1466 line->lastchar = (NCURSES_SIZE_T) (col) 1467 1468 #define CHANGED_RANGE(line,start,end) \ 1469 if (line->firstchar == _NOCHANGE \ 1470 || line->firstchar > (start)) \ 1471 line->firstchar = (NCURSES_SIZE_T) (start); \ 1472 if (line->lastchar == _NOCHANGE \ 1473 || line->lastchar < (end)) \ 1474 line->lastchar = (NCURSES_SIZE_T) (end) 1475 1476 #define CHANGED_TO_EOL(line,start,end) \ 1477 if (line->firstchar == _NOCHANGE \ 1478 || line->firstchar > (start)) \ 1479 line->firstchar = (NCURSES_SIZE_T) (start); \ 1480 line->lastchar = (NCURSES_SIZE_T) (end) 1481 1482 #define SIZEOF(v) (sizeof(v)/sizeof(v[0])) 1483 1484 #define FreeIfNeeded(p) if ((p) != 0) free(p) 1485 1486 /* FreeAndNull() is not a comma-separated expression because some compilers 1487 * do not accept a mixture of void with values. 1488 */ 1489 #define FreeAndNull(p) do { free(p); p = 0; } while (0) 1490 1491 #include <nc_alloc.h> 1492 #include <nc_access.h> 1493 1494 /* 1495 * Use these for tic/infocmp malloc failures. Generally the ncurses library 1496 * tries to limp along after a failure. 1497 */ 1498 #define TYPE_MALLOC(type, size, name) \ 1499 do { \ 1500 name = typeMalloc(type, size); \ 1501 if (name == 0) \ 1502 _nc_err_abort(MSG_NO_MEMORY); \ 1503 } while (0) 1504 1505 #define TYPE_REALLOC(type, size, name) \ 1506 do { \ 1507 name = typeRealloc(type, size, name); \ 1508 if (name == 0) \ 1509 _nc_err_abort(MSG_NO_MEMORY); \ 1510 } while (0) 1511 1512 /* 1513 * TTY bit definition for converting tabs to spaces. 1514 */ 1515 #ifdef TAB3 1516 # define OFLAGS_TABS TAB3 /* POSIX specifies TAB3 */ 1517 #else 1518 # ifdef XTABS 1519 # define OFLAGS_TABS XTABS /* XTABS is usually the "same" */ 1520 # else 1521 # ifdef OXTABS 1522 # define OFLAGS_TABS OXTABS /* the traditional BSD equivalent */ 1523 # else 1524 # define OFLAGS_TABS 0 1525 # endif 1526 # endif 1527 #endif 1528 1529 #ifdef __TANDEM 1530 #define ROOT_UID 65535 1531 #endif 1532 1533 #ifndef ROOT_UID 1534 #define ROOT_UID 0 1535 #endif 1536 1537 /* 1538 * Standardize/simplify common loops 1539 */ 1540 #define each_screen(p) p = _nc_screen_chain; p != 0; p = (p)->_next_screen 1541 #define each_window(sp,p) p = WindowList(sp); p != 0; p = (p)->next 1542 #define each_ripoff(p) p = safe_ripoff_stack; (p - safe_ripoff_stack) < N_RIPS; ++p 1543 1544 /* 1545 * Prefixes for call/return points of library function traces. We use these to 1546 * instrument the public functions so that the traces can be easily transformed 1547 * into regression scripts. 1548 */ 1549 #define T_CALLED(fmt) "called {" fmt 1550 #define T_CREATE(fmt) "create :" fmt 1551 #define T_RETURN(fmt) "return }" fmt 1552 1553 #define NonNull(s) ((s) != 0 ? s : "<null>") 1554 #define NonEmpty(s) ((s) != 0 && *(s) != '\0') 1555 1556 #ifdef TRACE 1557 1558 #if USE_REENTRANT 1559 #define TPUTS_TRACE(s) _nc_set_tputs_trace(s); 1560 #else 1561 #define TPUTS_TRACE(s) _nc_tputs_trace = s; 1562 #endif 1563 1564 #ifdef HAVE_CONSISTENT_GETENV 1565 #define START_TRACE() \ 1566 if ((_nc_tracing & TRACE_MAXIMUM) == 0) { \ 1567 int t = _nc_getenv_num("NCURSES_TRACE"); \ 1568 if (t >= 0) \ 1569 curses_trace((unsigned) t); \ 1570 } 1571 #else 1572 #define START_TRACE() /* nothing */ 1573 #endif 1574 1575 /* 1576 * Many of the _tracef() calls use static buffers; lock the trace state before 1577 * trying to fill them. 1578 */ 1579 #if USE_REENTRANT 1580 #define USE_TRACEF(mask) _nc_use_tracef(mask) 1581 extern NCURSES_EXPORT(int) _nc_use_tracef (unsigned); 1582 extern NCURSES_EXPORT(void) _nc_locked_tracef (const char *, ...) GCC_PRINTFLIKE(1,2); 1583 #else 1584 #define USE_TRACEF(mask) (_nc_tracing & (mask)) 1585 #define _nc_locked_tracef _tracef 1586 #endif 1587 1588 #define TR(n, a) if (USE_TRACEF(n)) _nc_locked_tracef a 1589 #define T(a) TR(TRACE_CALLS, a) 1590 #define TRACE_RETURN(value,type) return _nc_retrace_##type((type)(value)) 1591 #define TRACE_RETURN1(value,dst) return _nc_retrace_##dst(value) 1592 #define TRACE_RETURN2(value,dst,src) return _nc_retrace_##dst##_##src(value) 1593 #define TRACE_RETURN_SP(value,type) return _nc_retrace_##type(SP_PARM, value) 1594 1595 typedef void VoidFunc(void); 1596 1597 #define TR_FUNC_LEN ((sizeof(void *) + sizeof(void (*)(void))) * 2 + 4) 1598 #define TR_FUNC_BFR(max) char tr_func_data[max][TR_FUNC_LEN] 1599 #define TR_FUNC_ARG(num,func) _nc_fmt_funcptr(&tr_func_data[num][0], (const char *)&(func), sizeof((func))) 1600 1601 #define returnAttr(code) TRACE_RETURN(code,attr_t) 1602 #define returnBits(code) TRACE_RETURN(code,unsigned) 1603 #define returnBool(code) TRACE_RETURN(code,bool) 1604 #define returnCPtr(code) TRACE_RETURN1(code,cptr) 1605 #define returnCVoidPtr(code) TRACE_RETURN1(code,cvoid_ptr) 1606 #define returnChar(code) TRACE_RETURN(code,char) 1607 #define returnChtype(code) TRACE_RETURN(code,chtype) 1608 #define returnCode(code) TRACE_RETURN(code,int) 1609 #define returnIntAttr(code) TRACE_RETURN2(code,int,attr_t) 1610 #define returnMMask(code) TRACE_RETURN_SP(code,mmask_t) 1611 #define returnPtr(code) TRACE_RETURN1(code,ptr) 1612 #define returnSP(code) TRACE_RETURN1(code,sp) 1613 #define returnVoid T((T_RETURN(""))); return 1614 #define returnVoidPtr(code) TRACE_RETURN1(code,void_ptr) 1615 #define returnWin(code) TRACE_RETURN1(code,win) 1616 1617 #define returnDB(rc) do { TR(TRACE_DATABASE,(T_RETURN("code %d"), (rc))); return (rc); } while (0) 1618 1619 extern NCURSES_EXPORT(NCURSES_BOOL) _nc_retrace_bool (int); 1620 extern NCURSES_EXPORT(NCURSES_CONST void *) _nc_retrace_cvoid_ptr (NCURSES_CONST void *); 1621 extern NCURSES_EXPORT(SCREEN *) _nc_retrace_sp (SCREEN *); 1622 extern NCURSES_EXPORT(WINDOW *) _nc_retrace_win (WINDOW *); 1623 extern NCURSES_EXPORT(attr_t) _nc_retrace_attr_t (attr_t); 1624 extern NCURSES_EXPORT(char *) _nc_retrace_ptr (char *); 1625 extern NCURSES_EXPORT(char *) _nc_trace_ttymode(const TTY *tty); 1626 extern NCURSES_EXPORT(char *) _nc_varargs (const char *, va_list); 1627 extern NCURSES_EXPORT(chtype) _nc_retrace_chtype (chtype); 1628 extern NCURSES_EXPORT(const char *) _nc_altcharset_name(attr_t, chtype); 1629 extern NCURSES_EXPORT(const char *) _nc_retrace_cptr (const char *); 1630 extern NCURSES_EXPORT(char) _nc_retrace_char (int); 1631 extern NCURSES_EXPORT(int) _nc_retrace_int (int); 1632 extern NCURSES_EXPORT(int) _nc_retrace_int_attr_t (attr_t); 1633 extern NCURSES_EXPORT(mmask_t) _nc_retrace_mmask_t (SCREEN *, mmask_t); 1634 extern NCURSES_EXPORT(unsigned) _nc_retrace_unsigned (unsigned); 1635 extern NCURSES_EXPORT(void *) _nc_retrace_void_ptr (void *); 1636 extern NCURSES_EXPORT(void) _nc_fifo_dump (SCREEN *); 1637 1638 extern NCURSES_EXPORT(char *) _nc_fmt_funcptr(char *, const char *, size_t); 1639 1640 #if USE_REENTRANT 1641 NCURSES_WRAPPED_VAR(long, _nc_outchars); 1642 NCURSES_WRAPPED_VAR(const char *, _nc_tputs_trace); 1643 #define _nc_outchars NCURSES_PUBLIC_VAR(_nc_outchars()) 1644 #define _nc_tputs_trace NCURSES_PUBLIC_VAR(_nc_tputs_trace()) 1645 extern NCURSES_EXPORT(void) _nc_set_tputs_trace (const char *); 1646 extern NCURSES_EXPORT(void) _nc_count_outchars (long); 1647 #else 1648 extern NCURSES_EXPORT_VAR(const char *) _nc_tputs_trace; 1649 extern NCURSES_EXPORT_VAR(long) _nc_outchars; 1650 #endif 1651 1652 extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing; 1653 1654 extern NCURSES_EXPORT(char *) _nc_tracebits (void); 1655 extern NCURSES_EXPORT(char *) _tracemouse (const MEVENT *); 1656 extern NCURSES_EXPORT(void) _tracedump (const char *, WINDOW *); 1657 1658 #if USE_WIDEC_SUPPORT 1659 extern NCURSES_EXPORT(const char *) _nc_viswbuf2 (int, const wchar_t *); 1660 extern NCURSES_EXPORT(const char *) _nc_viswbufn (const wchar_t *, int); 1661 #endif 1662 1663 extern NCURSES_EXPORT(const char *) _nc_viscbuf2 (int, const NCURSES_CH_T *, int); 1664 extern NCURSES_EXPORT(const char *) _nc_viscbuf (const NCURSES_CH_T *, int); 1665 1666 #else /* !TRACE */ 1667 1668 #define START_TRACE() /* nothing */ 1669 1670 #define T(a) 1671 #define TR(n, a) 1672 #define TPUTS_TRACE(s) 1673 #define TR_FUNC_BFR(max) 1674 1675 #define returnAttr(code) return code 1676 #define returnBits(code) return code 1677 #define returnBool(code) return code 1678 #define returnCPtr(code) return code 1679 #define returnCVoidPtr(code) return code 1680 #define returnChar(code) return ((char) code) 1681 #define returnChtype(code) return code 1682 #define returnCode(code) return code 1683 #define returnIntAttr(code) return code 1684 #define returnMMask(code) return code 1685 #define returnPtr(code) return code 1686 #define returnSP(code) return code 1687 #define returnVoid return 1688 #define returnVoidPtr(code) return code 1689 #define returnWin(code) return code 1690 1691 #define returnDB(code) return code 1692 1693 #endif /* TRACE/!TRACE */ 1694 1695 /* 1696 * Workaround for defective implementation of gcc attribute warn_unused_result 1697 */ 1698 #if defined(__GNUC__) && defined(_FORTIFY_SOURCE) 1699 #define IGNORE_RC(func) errno = (int) func 1700 #else 1701 #define IGNORE_RC(func) (void) func 1702 #endif /* gcc workarounds */ 1703 1704 /* 1705 * Return-codes for tgetent() and friends. 1706 */ 1707 #define TGETENT_YES 1 /* entry is found */ 1708 #define TGETENT_NO 0 /* entry is not found */ 1709 #define TGETENT_ERR -1 /* an error occurred */ 1710 1711 extern NCURSES_EXPORT(const char *) _nc_visbuf2 (int, const char *); 1712 extern NCURSES_EXPORT(const char *) _nc_visbufn (const char *, int); 1713 1714 #define EMPTY_MODULE(name) \ 1715 extern NCURSES_EXPORT(void) name (void); \ 1716 NCURSES_EXPORT(void) name (void) { } 1717 1718 #define ALL_BUT_COLOR ((chtype)~(A_COLOR)) 1719 #define NONBLANK_ATTR (A_BOLD | A_DIM | A_BLINK | A_ITALIC) 1720 #define TPARM_ATTR (A_STANDOUT | A_UNDERLINE | A_REVERSE | A_BLINK | A_DIM | A_BOLD | A_ALTCHARSET | A_INVIS | A_PROTECT) 1721 #define XMC_CONFLICT (A_STANDOUT | A_UNDERLINE | A_REVERSE | A_BLINK | A_DIM | A_BOLD | A_INVIS | A_PROTECT | A_ITALIC) 1722 #define XMC_CHANGES(c) ((c) & SP_PARM->_xmc_suppress) 1723 1724 #define toggle_attr_on(S,at) {\ 1725 if (PairNumber(at) > 0) {\ 1726 (S) = ((S) & ALL_BUT_COLOR) | (attr_t) (at);\ 1727 } else {\ 1728 (S) |= (attr_t) (at);\ 1729 }\ 1730 TR(TRACE_ATTRS, ("new attribute is %s", _traceattr((S))));} 1731 1732 1733 #define toggle_attr_off(S,at) {\ 1734 if (PairNumber(at) > 0) {\ 1735 (S) &= ~(at|A_COLOR);\ 1736 } else {\ 1737 (S) &= ~(at);\ 1738 }\ 1739 TR(TRACE_ATTRS, ("new attribute is %s", _traceattr((S))));} 1740 1741 #define DelCharCost(sp,count) \ 1742 ((parm_dch != 0) \ 1743 ? sp->_dch_cost \ 1744 : ((delete_character != 0) \ 1745 ? (sp->_dch1_cost * count) \ 1746 : INFINITY)) 1747 1748 #define InsCharCost(sp,count) \ 1749 ((parm_ich != 0) \ 1750 ? sp->_ich_cost \ 1751 : ((enter_insert_mode && exit_insert_mode) \ 1752 ? sp->_smir_cost + sp->_rmir_cost + (sp->_ip_cost * count) \ 1753 : ((insert_character != 0) \ 1754 ? ((sp->_ich1_cost + sp->_ip_cost) * count) \ 1755 : INFINITY))) 1756 1757 #if USE_XMC_SUPPORT 1758 #define UpdateAttrs(sp,c) if (!SameAttrOf(SCREEN_ATTRS(sp), c)) { \ 1759 attr_t chg = AttrOf(SCREEN_ATTRS(sp)); \ 1760 VIDPUTS(sp, AttrOf(c), GetPair(c)); \ 1761 if (magic_cookie_glitch > 0 \ 1762 && XMC_CHANGES((chg ^ AttrOf(SCREEN_ATTRS(sp))))) { \ 1763 T(("%s @%d before glitch %d,%d", \ 1764 __FILE__, __LINE__, \ 1765 sp->_cursrow, \ 1766 sp->_curscol)); \ 1767 NCURSES_SP_NAME(_nc_do_xmc_glitch)(NCURSES_SP_ARGx chg); \ 1768 } \ 1769 } 1770 #else 1771 #define UpdateAttrs(sp,c) if (!SameAttrOf(SCREEN_ATTRS(sp), c)) { \ 1772 VIDPUTS(sp, AttrOf(c), GetPair(c)); \ 1773 } 1774 #endif 1775 1776 /* 1777 * Macros to make additional parameter to implement wgetch_events() 1778 */ 1779 #ifdef NCURSES_WGETCH_EVENTS 1780 #define EVENTLIST_0th(param) param 1781 #define EVENTLIST_1st(param) param 1782 #define EVENTLIST_2nd(param) , param 1783 #define TWAIT_MASK (TW_ANY | TW_EVENT) 1784 #else 1785 #define EVENTLIST_0th(param) void 1786 #define EVENTLIST_1st(param) /* nothing */ 1787 #define EVENTLIST_2nd(param) /* nothing */ 1788 #define TWAIT_MASK TW_ANY 1789 #endif 1790 1791 #if NCURSES_EXPANDED && NCURSES_EXT_FUNCS 1792 1793 #undef toggle_attr_on 1794 #define toggle_attr_on(S,at) _nc_toggle_attr_on(&(S), at) 1795 extern NCURSES_EXPORT(void) _nc_toggle_attr_on (attr_t *, attr_t); 1796 1797 #undef toggle_attr_off 1798 #define toggle_attr_off(S,at) _nc_toggle_attr_off(&(S), at) 1799 extern NCURSES_EXPORT(void) _nc_toggle_attr_off (attr_t *, attr_t); 1800 1801 #undef DelCharCost 1802 #define DelCharCost(sp, count) NCURSES_SP_NAME(_nc_DelCharCost)(NCURSES_SP_ARGx count) 1803 1804 #undef InsCharCost 1805 #define InsCharCost(sp, count) NCURSES_SP_NAME(_nc_InsCharCost)(NCURSES_SP_ARGx count) 1806 1807 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_DelCharCost) (NCURSES_SP_DCLx int _c); 1808 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_InsCharCost) (NCURSES_SP_DCLx int _c); 1809 1810 #undef UpdateAttrs 1811 #define UpdateAttrs(sp,c) NCURSES_SP_NAME(_nc_UpdateAttrs)(NCURSES_SP_ARGx CHREF(c)) 1812 1813 #if USE_WIDEC_SUPPORT || defined(NEED_NCURSES_CH_T) 1814 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_UpdateAttrs) (NCURSES_SP_DCLx CARG_CH_T _c); 1815 #else 1816 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_UpdateAttrs) (NCURSES_SP_DCLx chtype c); 1817 #endif 1818 1819 #if NCURSES_SP_FUNCS 1820 extern NCURSES_EXPORT(int) _nc_DelCharCost (int); 1821 extern NCURSES_EXPORT(int) _nc_InsCharCost (int); 1822 extern NCURSES_EXPORT(void) _nc_UpdateAttrs (CARG_CH_T); 1823 #endif /* NCURSES_SP_FUNCS */ 1824 1825 #else 1826 1827 extern NCURSES_EXPORT(void) _nc_expanded (void); 1828 1829 #endif 1830 1831 #if !NCURSES_EXT_FUNCS 1832 #define set_escdelay(value) ESCDELAY = value 1833 #endif 1834 1835 #if !HAVE_GETCWD 1836 #define getcwd(buf,len) getwd(buf) 1837 #endif 1838 1839 #define save_ttytype(termp) \ 1840 if (TerminalType(termp).term_names != 0) { \ 1841 _nc_STRNCPY(ttytype, \ 1842 TerminalType(termp).term_names, \ 1843 NAMESIZE - 1); \ 1844 ttytype[NAMESIZE - 1] = '\0'; \ 1845 } 1846 1847 #if !NCURSES_WCWIDTH_GRAPHICS 1848 extern NCURSES_EXPORT(int) _nc_wacs_width(unsigned); 1849 #else 1850 #define _nc_wacs_width(ch) wcwidth(ch) 1851 #endif 1852 1853 /* charable.c */ 1854 #if USE_WIDEC_SUPPORT 1855 extern NCURSES_EXPORT(bool) _nc_is_charable(wchar_t); 1856 extern NCURSES_EXPORT(int) _nc_to_char(wint_t); 1857 extern NCURSES_EXPORT(wint_t) _nc_to_widechar(int); 1858 #endif 1859 1860 /* comp_captab.c */ 1861 typedef struct { 1862 short nte_name; /* offset of name to hash on */ 1863 int nte_type; /* BOOLEAN, NUMBER or STRING */ 1864 short nte_index; /* index of associated variable in its array */ 1865 short nte_link; /* index in table of next hash, or -1 */ 1866 } name_table_data; 1867 1868 typedef struct 1869 { 1870 short from; 1871 short to; 1872 short source; 1873 } alias_table_data; 1874 1875 /* comp_userdefs.c */ 1876 typedef struct { 1877 short ute_name; /* offset of name to hash on */ 1878 unsigned ute_type; /* mask (BOOLEAN, NUMBER, STRING) */ 1879 unsigned ute_argc; /* number of parameters */ 1880 unsigned ute_args; /* bit-mask for string parameters */ 1881 short ute_index; /* index of associated variable in its array */ 1882 short ute_link; /* index in table of next hash, or -1 */ 1883 } user_table_data; 1884 1885 /* doupdate.c */ 1886 #if USE_XMC_SUPPORT 1887 extern NCURSES_EXPORT(void) _nc_do_xmc_glitch (attr_t); 1888 #endif 1889 1890 /* hardscroll.c */ 1891 #if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG) 1892 extern NCURSES_EXPORT(void) _nc_linedump (void); 1893 #endif 1894 1895 /* lib_acs.c */ 1896 extern NCURSES_EXPORT(void) _nc_init_acs (void); /* corresponds to traditional 'init_acs()' */ 1897 extern NCURSES_EXPORT(int) _nc_msec_cost (const char *const, int); /* used by 'tack' program */ 1898 1899 /* lib_addch.c */ 1900 #if USE_WIDEC_SUPPORT 1901 NCURSES_EXPORT(int) _nc_build_wch(WINDOW *win, ARG_CH_T ch); 1902 #endif 1903 1904 /* lib_addstr.c */ 1905 #if USE_WIDEC_SUPPORT && !(defined(USE_TERMLIB) || defined(USE_BUILD_CC)) 1906 extern NCURSES_EXPORT(int) _nc_wchstrlen(const cchar_t *); 1907 #endif 1908 1909 /* lib_color.c */ 1910 extern NCURSES_EXPORT(int) _nc_init_color(SCREEN *, int, int, int, int); 1911 extern NCURSES_EXPORT(int) _nc_init_pair(SCREEN *, int, int, int); 1912 extern NCURSES_EXPORT(int) _nc_pair_content(SCREEN *, int, int *, int *); 1913 extern NCURSES_EXPORT(bool) _nc_reset_colors(void); 1914 extern NCURSES_EXPORT(void) _nc_reserve_pairs(SCREEN *, int); 1915 extern NCURSES_EXPORT(void) _nc_change_pair(SCREEN *, int); 1916 1917 #define ReservePairs(sp,want) \ 1918 if ((sp->_color_pairs == 0) || (want >= sp->_pair_alloc)) \ 1919 _nc_reserve_pairs(sp, want) 1920 1921 /* lib_getch.c */ 1922 extern NCURSES_EXPORT(int) _nc_wgetch(WINDOW *, int *, int EVENTLIST_2nd(_nc_eventlist *)); 1923 1924 /* lib_insch.c */ 1925 extern NCURSES_EXPORT(int) _nc_insert_ch(SCREEN *, WINDOW *, chtype); 1926 1927 /* lib_mvcur.c */ 1928 #define INFINITY 1000000 /* cost: too high to use */ 1929 1930 extern NCURSES_EXPORT(int) _nc_mvcur(int yold, int xold, int ynew, int xnew); 1931 1932 extern NCURSES_EXPORT(void) _nc_mvcur_init (void); 1933 extern NCURSES_EXPORT(void) _nc_mvcur_resume (void); 1934 extern NCURSES_EXPORT(void) _nc_mvcur_wrap (void); 1935 1936 extern NCURSES_EXPORT(int) _nc_scrolln (int, int, int, int); 1937 1938 extern NCURSES_EXPORT(void) _nc_screen_init (void); 1939 extern NCURSES_EXPORT(void) _nc_screen_resume (void); 1940 extern NCURSES_EXPORT(void) _nc_screen_wrap (void); 1941 1942 /* lib_mouse.c */ 1943 extern NCURSES_EXPORT(bool) _nc_has_mouse (SCREEN *); 1944 1945 /* lib_mvcur.c */ 1946 #define INFINITY 1000000 /* cost: too high to use */ 1947 #define BAUDBYTE 9 /* 9 = 7 bits + 1 parity + 1 stop */ 1948 1949 /* lib_setup.c */ 1950 extern NCURSES_EXPORT(char *) _nc_get_locale(void); 1951 extern NCURSES_EXPORT(int) _nc_unicode_locale(void); 1952 extern NCURSES_EXPORT(int) _nc_locale_breaks_acs(TERMINAL *); 1953 extern NCURSES_EXPORT(int) _nc_setupterm(const char *, int, int *, int); 1954 extern NCURSES_EXPORT(void) _nc_tinfo_cmdch(TERMINAL *, int); 1955 1956 #ifdef USE_PTHREADS 1957 extern NCURSES_EXPORT(SCREEN *) _nc_find_prescr(void); 1958 extern NCURSES_EXPORT(void) _nc_forget_prescr(void); 1959 #else 1960 #define _nc_find_prescr() _nc_prescreen.allocated 1961 #define _nc_forget_prescr() _nc_prescreen.allocated = 0 1962 #endif 1963 1964 /* lib_set_term.c */ 1965 extern NCURSES_EXPORT(int) _nc_ripoffline(int, int(*)(WINDOW*, int)); 1966 1967 /* lib_setup.c */ 1968 #define ExitTerminfo(code) exit_terminfo(code) 1969 1970 #define SETUP_FAIL ERR 1971 1972 #define ret_error(rc, fmt, p, q) if (errret) {\ 1973 *errret = rc;\ 1974 q;\ 1975 returnCode(SETUP_FAIL);\ 1976 } else {\ 1977 fprintf(stderr, fmt, p);\ 1978 q;\ 1979 ExitTerminfo(EXIT_FAILURE);\ 1980 } 1981 1982 #define ret_error1(rc, fmt, p, q) ret_error(rc, "'%s': " fmt, p, q) 1983 1984 #define ret_error0(rc, msg) if (errret) {\ 1985 *errret = rc;\ 1986 returnCode(SETUP_FAIL);\ 1987 } else {\ 1988 fprintf(stderr, msg);\ 1989 ExitTerminfo(EXIT_FAILURE);\ 1990 } 1991 1992 /* lib_tstp.c */ 1993 #if USE_SIGWINCH 1994 extern NCURSES_EXPORT(int) _nc_handle_sigwinch(SCREEN *); 1995 #else 1996 #define _nc_handle_sigwinch(a) /* nothing */ 1997 #endif 1998 1999 /* lib_wacs.c */ 2000 #if USE_WIDEC_SUPPORT 2001 extern NCURSES_EXPORT(void) _nc_init_wacs(void); 2002 #endif 2003 2004 typedef struct { 2005 char *s_head; /* beginning of the string (may be null) */ 2006 char *s_tail; /* end of the string (may be null) */ 2007 size_t s_size; /* current remaining size available */ 2008 size_t s_init; /* total size available */ 2009 } string_desc; 2010 2011 /* strings.c */ 2012 extern NCURSES_EXPORT(string_desc *) _nc_str_init (string_desc *, char *, size_t); 2013 extern NCURSES_EXPORT(string_desc *) _nc_str_null (string_desc *, size_t); 2014 extern NCURSES_EXPORT(string_desc *) _nc_str_copy (string_desc *, string_desc *); 2015 extern NCURSES_EXPORT(bool) _nc_safe_strcat (string_desc *, const char *); 2016 extern NCURSES_EXPORT(bool) _nc_safe_strcpy (string_desc *, const char *); 2017 2018 #if !HAVE_STRSTR 2019 #define strstr _nc_strstr 2020 extern NCURSES_EXPORT(char *) _nc_strstr (const char *, const char *); 2021 #endif 2022 2023 /* safe_sprintf.c */ 2024 extern NCURSES_EXPORT(char *) _nc_printf_string (const char *, va_list); 2025 2026 /* tries.c */ 2027 extern NCURSES_EXPORT(int) _nc_add_to_try (TRIES **, const char *, unsigned); 2028 extern NCURSES_EXPORT(char *) _nc_expand_try (TRIES *, unsigned, int *, size_t); 2029 extern NCURSES_EXPORT(int) _nc_remove_key (TRIES **, unsigned); 2030 extern NCURSES_EXPORT(int) _nc_remove_string (TRIES **, const char *); 2031 2032 /* elsewhere ... */ 2033 extern NCURSES_EXPORT(SCREEN *) _nc_screen_of (WINDOW *); 2034 extern NCURSES_EXPORT(TERMINAL*) _nc_get_cur_term (void); 2035 extern NCURSES_EXPORT(WINDOW *) _nc_makenew (int, int, int, int, int); 2036 extern NCURSES_EXPORT(char *) _nc_trace_buf (int, size_t); 2037 extern NCURSES_EXPORT(char *) _nc_trace_bufcat (int, const char *); 2038 extern NCURSES_EXPORT(char *) _nc_tracechar (SCREEN *, int); 2039 extern NCURSES_EXPORT(char *) _nc_tracemouse (SCREEN *, MEVENT const *); 2040 extern NCURSES_EXPORT(char *) _nc_trace_mmask_t (SCREEN *, mmask_t); 2041 extern NCURSES_EXPORT(int) _nc_access (const char *, int); 2042 extern NCURSES_EXPORT(int) _nc_baudrate (int); 2043 extern NCURSES_EXPORT(int) _nc_freewin (WINDOW *); 2044 extern NCURSES_EXPORT(int) _nc_getenv_num (const char *); 2045 extern NCURSES_EXPORT(int) _nc_keypad (SCREEN *, int); 2046 extern NCURSES_EXPORT(int) _nc_ospeed (int); 2047 extern NCURSES_EXPORT(int) _nc_outch (int); 2048 extern NCURSES_EXPORT(int) _nc_putchar (int); 2049 extern NCURSES_EXPORT(int) _nc_putp(const char *, const char *); 2050 extern NCURSES_EXPORT(int) _nc_putp_flush(const char *, const char *); 2051 extern NCURSES_EXPORT(int) _nc_read_termcap_entry (const char *const, TERMTYPE2 *const); 2052 extern NCURSES_EXPORT(int) _nc_setup_tinfo(const char *, TERMTYPE2 *); 2053 extern NCURSES_EXPORT(int) _nc_setupscreen (int, int, FILE *, int, int); 2054 extern NCURSES_EXPORT(int) _nc_timed_wait (SCREEN *, int, int, int * EVENTLIST_2nd(_nc_eventlist *)); 2055 extern NCURSES_EXPORT(void) _nc_init_termtype (TERMTYPE2 *const); 2056 extern NCURSES_EXPORT(void) _nc_do_color (int, int, int, NCURSES_OUTC); 2057 extern NCURSES_EXPORT(void) _nc_flush (void); 2058 extern NCURSES_EXPORT(void) _nc_free_entry (ENTRY *, TERMTYPE2 *); 2059 extern NCURSES_EXPORT(void) _nc_freeall (void); 2060 extern NCURSES_EXPORT(void) _nc_hash_map (void); 2061 extern NCURSES_EXPORT(void) _nc_init_keytry (SCREEN *); 2062 extern NCURSES_EXPORT(void) _nc_keep_tic_dir (const char *); 2063 extern NCURSES_EXPORT(void) _nc_make_oldhash (int i); 2064 extern NCURSES_EXPORT(void) _nc_scroll_oldhash (int n, int top, int bot); 2065 extern NCURSES_EXPORT(void) _nc_scroll_optimize (void); 2066 extern NCURSES_EXPORT(void) _nc_set_buffer (FILE *, int); 2067 extern NCURSES_EXPORT(void) _nc_setenv_num (const char *, int); 2068 extern NCURSES_EXPORT(void) _nc_signal_handler (int); 2069 extern NCURSES_EXPORT(void) _nc_synchook (WINDOW *); 2070 extern NCURSES_EXPORT(void) _nc_trace_tries (TRIES *); 2071 2072 #if NCURSES_EXT_NUMBERS 2073 extern NCURSES_EXPORT(const TERMTYPE2 *) _nc_fallback2 (const char *); 2074 #else 2075 #define _nc_fallback2(tp) _nc_fallback(tp) 2076 #endif 2077 2078 #if NCURSES_EXT_NUMBERS 2079 extern NCURSES_EXPORT(void) _nc_copy_termtype2 (TERMTYPE2 *, const TERMTYPE2 *); 2080 extern NCURSES_EXPORT(void) _nc_export_termtype2(TERMTYPE *, const TERMTYPE2 *); 2081 #else 2082 #define _nc_copy_termtype2(dst,src) _nc_copy_termtype((dst),(src)) 2083 #define _nc_export_termtype2(dst,src) /* nothing */ 2084 #define _nc_free_termtype2(t) _nc_free_termtype(t) 2085 /* also... */ 2086 #define _nc_read_entry2 _nc_read_entry 2087 #endif 2088 2089 #if NO_LEAKS 2090 extern NCURSES_EXPORT(void) _nc_alloc_entry_leaks(void); 2091 extern NCURSES_EXPORT(void) _nc_captoinfo_leaks(void); 2092 extern NCURSES_EXPORT(void) _nc_codes_leaks(void); 2093 extern NCURSES_EXPORT(void) _nc_comp_captab_leaks(void); 2094 extern NCURSES_EXPORT(void) _nc_comp_error_leaks(void); 2095 extern NCURSES_EXPORT(void) _nc_comp_scan_leaks(void); 2096 extern NCURSES_EXPORT(void) _nc_comp_userdefs_leaks(void); 2097 extern NCURSES_EXPORT(void) _nc_db_iterator_leaks(void); 2098 extern NCURSES_EXPORT(void) _nc_keyname_leaks(void); 2099 extern NCURSES_EXPORT(void) _nc_names_leaks(void); 2100 extern NCURSES_EXPORT(void) _nc_tgetent_leak(TERMINAL *); 2101 extern NCURSES_EXPORT(void) _nc_tgetent_leaks(void); 2102 #endif 2103 2104 #if !(defined(USE_TERMLIB) || defined(USE_BUILD_CC)) 2105 extern NCURSES_EXPORT(NCURSES_CH_T) _nc_render (WINDOW *, NCURSES_CH_T); 2106 extern NCURSES_EXPORT(int) _nc_waddch_nosync (WINDOW *, const NCURSES_CH_T); 2107 extern NCURSES_EXPORT(void) _nc_scroll_window (WINDOW *, int const, int const, int const, NCURSES_CH_T); 2108 #endif 2109 2110 #if USE_WIDEC_SUPPORT 2111 extern NCURSES_EXPORT(int) _nc_insert_wch(WINDOW *, const cchar_t *); 2112 #endif 2113 2114 #if USE_WIDEC_SUPPORT && !(defined(USE_TERMLIB) || defined(USE_BUILD_CC)) 2115 extern NCURSES_EXPORT(size_t) _nc_wcrtomb (char *, wchar_t, mbstate_t *); 2116 #endif 2117 2118 #if USE_SIZECHANGE 2119 extern NCURSES_EXPORT(void) _nc_update_screensize (SCREEN *); 2120 #endif 2121 2122 #if HAVE_RESIZETERM 2123 extern NCURSES_EXPORT(void) _nc_resize_margins (WINDOW *); 2124 #else 2125 #define _nc_resize_margins(wp) /* nothing */ 2126 #endif 2127 2128 #ifdef NCURSES_WGETCH_EVENTS 2129 extern NCURSES_EXPORT(int) _nc_eventlist_timeout(_nc_eventlist *); 2130 #else 2131 #define wgetch_events(win, evl) wgetch(win) 2132 #define wgetnstr_events(win, str, maxlen, evl) wgetnstr(win, str, maxlen) 2133 #endif 2134 2135 /* 2136 * Wide-character macros to hide some platform-differences. 2137 */ 2138 #if USE_WIDEC_SUPPORT 2139 2140 #if defined(_NC_WINDOWS) && !defined(_NC_MSC) && !defined(EXP_WIN32_DRIVER) 2141 /* 2142 * MinGW has wide-character functions, but they do not work correctly. 2143 */ 2144 extern int __MINGW_NOTHROW _nc_wctomb(char *, wchar_t); 2145 #define wctomb(s,wc) _nc_wctomb(s,wc) 2146 #define wcrtomb(s,wc,n) _nc_wctomb(s,wc) 2147 2148 extern int __MINGW_NOTHROW _nc_mbtowc(wchar_t *, const char *, size_t); 2149 #define mbtowc(pwc,s,n) _nc_mbtowc(pwc,s,n) 2150 2151 extern int __MINGW_NOTHROW _nc_mblen(const char *, size_t); 2152 #define mblen(s,n) _nc_mblen(s, n) 2153 2154 #endif /* _NC_WINDOWS && !_NC_MSC */ 2155 2156 #if HAVE_MBTOWC && HAVE_MBLEN 2157 #define reset_mbytes(state) IGNORE_RC(mblen(NULL, (size_t) 0)), IGNORE_RC(mbtowc(NULL, NULL, (size_t) 0)) 2158 #define count_mbytes(buffer,length,state) mblen(buffer,length) 2159 #define check_mbytes(wch,buffer,length,state) \ 2160 (int) mbtowc(&(wch), buffer, length) 2161 #define state_unused 2162 #elif HAVE_MBRTOWC && HAVE_MBRLEN 2163 #define reset_mbytes(state) init_mb(state) 2164 #define count_mbytes(buffer,length,state) mbrlen(buffer,length,&(state)) 2165 #define check_mbytes(wch,buffer,length,state) \ 2166 (int) mbrtowc(&(wch), buffer, length, &(state)) 2167 #else 2168 make an error 2169 #endif 2170 2171 #endif /* USE_WIDEC_SUPPORT */ 2172 2173 /* 2174 * Not everyone has vsscanf(), but we'd like to use it for scanw(). 2175 */ 2176 #if !HAVE_VSSCANF 2177 extern int vsscanf(const char *str, const char *format, va_list __arg); 2178 #endif 2179 2180 /* scroll indices */ 2181 extern NCURSES_EXPORT_VAR(int *) _nc_oldnums; 2182 2183 #define USE_SETBUF_0 0 2184 2185 #define NC_OUTPUT(sp) ((sp != 0 && sp->_ofp != 0) ? sp->_ofp : stdout) 2186 2187 /* 2188 * On systems with a broken linker, define 'SP' as a function to force the 2189 * linker to pull in the data-only module with 'SP'. 2190 */ 2191 #define _nc_alloc_screen_sp() typeCalloc(SCREEN, 1) 2192 2193 #if BROKEN_LINKER 2194 #define SP _nc_screen() 2195 extern NCURSES_EXPORT(SCREEN *) _nc_screen (void); 2196 extern NCURSES_EXPORT(int) _nc_alloc_screen (void); 2197 extern NCURSES_EXPORT(void) _nc_set_screen (SCREEN *); 2198 #define CURRENT_SCREEN _nc_screen() 2199 #else 2200 /* current screen is private data; avoid possible linking conflicts too */ 2201 extern NCURSES_EXPORT_VAR(SCREEN *) SP; 2202 #define CURRENT_SCREEN SP 2203 #define _nc_alloc_screen() ((SP = _nc_alloc_screen_sp()) != 0) 2204 #define _nc_set_screen(sp) SP = sp 2205 #endif 2206 2207 #if NCURSES_SP_FUNCS 2208 #define CURRENT_SCREEN_PRE (IsPreScreen(CURRENT_SCREEN) ? CURRENT_SCREEN : new_prescr()) 2209 #else 2210 #define CURRENT_SCREEN_PRE CURRENT_SCREEN 2211 #endif 2212 2213 /* 2214 * We don't want to use the lines or columns capabilities internally, because 2215 * if the application is running multiple screens under X, it is quite possible 2216 * they could all have type xterm but have different sizes! So... 2217 */ 2218 #define screen_lines(sp) (sp)->_lines 2219 #define screen_columns(sp) (sp)->_columns 2220 2221 extern NCURSES_EXPORT(int) _nc_slk_initialize (WINDOW *, int); 2222 extern NCURSES_EXPORT(int) _nc_format_slks (NCURSES_SP_DCLx int _c); 2223 2224 /* 2225 * Some constants related to SLK's 2226 */ 2227 #define MAX_SKEY_OLD 8 /* count of soft keys */ 2228 #define MAX_SKEY_LEN_OLD 8 /* max length of soft key text */ 2229 #define MAX_SKEY_PC 12 /* This is what most PC's have */ 2230 #define MAX_SKEY_LEN_PC 5 2231 2232 /* Macro to check whether or not we use a standard format */ 2233 #define SLK_STDFMT(fmt) (fmt < 3) 2234 /* Macro to determine height of label window */ 2235 #define SLK_LINES(fmt) (SLK_STDFMT(fmt) ? 1 : ((fmt) - 2)) 2236 2237 #define MAX_SKEY(fmt) (SLK_STDFMT(fmt)? MAX_SKEY_OLD : MAX_SKEY_PC) 2238 #define MAX_SKEY_LEN(fmt) (SLK_STDFMT(fmt)? MAX_SKEY_LEN_OLD : MAX_SKEY_LEN_PC) 2239 2240 /* 2241 * Common error messages 2242 */ 2243 #define MSG_NO_MEMORY "Out of memory" 2244 #define MSG_NO_INPUTS "Premature EOF" 2245 2246 extern NCURSES_EXPORT(int) _nc_set_tty_mode(TTY *); 2247 extern NCURSES_EXPORT(int) _nc_get_tty_mode(TTY *); 2248 2249 /* timed_wait flag definitions */ 2250 #define TW_NONE 0 2251 #define TW_INPUT 1 2252 #define TW_MOUSE 2 2253 #define TW_ANY (TW_INPUT | TW_MOUSE) 2254 #define TW_EVENT 4 2255 2256 #define SetSafeOutcWrapper(outc) \ 2257 SCREEN* sp = CURRENT_SCREEN; \ 2258 struct screen outc_wrapper; \ 2259 if (sp==0) { \ 2260 sp = &outc_wrapper; \ 2261 memset(sp,0,sizeof(struct screen)); \ 2262 sp->_outch = _nc_outc_wrapper; \ 2263 }\ 2264 sp->jump = outc 2265 2266 #ifdef USE_TERM_DRIVER 2267 2268 typedef struct _termInfo 2269 { 2270 bool caninit; 2271 2272 bool hascolor; 2273 bool initcolor; 2274 bool canchange; 2275 2276 int tabsize; 2277 2278 int maxcolors; 2279 int maxpairs; 2280 int nocolorvideo; 2281 2282 int numbuttons; 2283 int numlabels; 2284 int labelwidth; 2285 int labelheight; 2286 2287 const color_t* defaultPalette; 2288 } TerminalInfo; 2289 2290 typedef struct term_driver { 2291 bool isTerminfo; 2292 const char* (*td_name)(struct DriverTCB*); 2293 bool (*td_CanHandle)(struct DriverTCB*, const char*, int*); 2294 void (*td_init)(struct DriverTCB*); 2295 void (*td_release)(struct DriverTCB*); 2296 int (*td_size)(struct DriverTCB*, int* Line, int *Cols); 2297 int (*td_sgmode)(struct DriverTCB*, int setFlag, TTY*); 2298 chtype (*td_conattr)(struct DriverTCB*); 2299 int (*td_hwcur)(struct DriverTCB*, int yold, int xold, int y, int x); 2300 int (*td_mode)(struct DriverTCB*, int progFlag, int defFlag); 2301 bool (*td_rescol)(struct DriverTCB*); 2302 bool (*td_rescolors)(struct DriverTCB*); 2303 void (*td_color)(struct DriverTCB*, int fore, int color, int(*)(SCREEN*, int)); 2304 int (*td_doBeepOrFlash)(struct DriverTCB*, int); 2305 void (*td_initpair)(struct DriverTCB*, int, int, int); 2306 void (*td_initcolor)(struct DriverTCB*, int, int, int, int); 2307 void (*td_docolor)(struct DriverTCB*, int, int, int, int(*)(SCREEN*, int)); 2308 void (*td_initmouse)(struct DriverTCB*); 2309 int (*td_testmouse)(struct DriverTCB*, int EVENTLIST_2nd(_nc_eventlist*)); 2310 void (*td_setfilter)(struct DriverTCB*); 2311 void (*td_hwlabel)(struct DriverTCB*, int, char*); 2312 void (*td_hwlabelOnOff)(struct DriverTCB*, int); 2313 int (*td_update)(struct DriverTCB*); 2314 int (*td_defaultcolors)(struct DriverTCB*, int, int); 2315 int (*td_print)(struct DriverTCB*, char*, int); 2316 int (*td_getsize)(struct DriverTCB*, int*, int*); 2317 int (*td_setsize)(struct DriverTCB*, int, int); 2318 void (*td_initacs)(struct DriverTCB*, chtype*, chtype*); 2319 void (*td_scinit)(SCREEN *); 2320 void (*td_scexit)(SCREEN *); 2321 int (*td_twait)(struct DriverTCB*, int, int, int* EVENTLIST_2nd(_nc_eventlist*)); 2322 int (*td_read)(struct DriverTCB*, int*); 2323 int (*td_nap)(struct DriverTCB*, int); 2324 int (*td_kpad)(struct DriverTCB*, int); 2325 int (*td_kyOk)(struct DriverTCB*, int, int); 2326 bool (*td_kyExist)(struct DriverTCB*, int); 2327 int (*td_cursorSet)(struct DriverTCB*, int); 2328 } TERM_DRIVER; 2329 2330 typedef struct DriverTCB 2331 { 2332 TERMINAL term; /* needs to be the first Element !!! */ 2333 TERM_DRIVER* drv; /* The driver for that Terminal */ 2334 SCREEN* csp; /* The screen that owns that Terminal */ 2335 TerminalInfo info; /* Driver independent core capabilities of the Terminal */ 2336 void* prop; /* Driver dependent property storage to be used by the Driver */ 2337 long magic; 2338 } TERMINAL_CONTROL_BLOCK; 2339 2340 #define NCDRV_MAGIC(id) (0x47110000 | (id&0xffff)) 2341 #define NCDRV_TINFO 0x01 2342 #define NCDRV_WINCONSOLE 0x02 2343 2344 #define TCBOf(sp) ((TERMINAL_CONTROL_BLOCK*)(TerminalOf(sp))) 2345 #define InfoOf(sp) TCBOf(sp)->info 2346 #define CallDriver(sp,method) TCBOf(sp)->drv->method(TCBOf(sp)) 2347 #define CallDriver_1(sp,method,arg1) TCBOf(sp)->drv->method(TCBOf(sp),arg1) 2348 #define CallDriver_2(sp,method,arg1,arg2) TCBOf(sp)->drv->method(TCBOf(sp),arg1,arg2) 2349 #define CallDriver_3(sp,method,arg1,arg2,arg3) TCBOf(sp)->drv->method(TCBOf(sp),arg1,arg2,arg3) 2350 #define CallDriver_4(sp,method,arg1,arg2,arg3,arg4) TCBOf(sp)->drv->method(TCBOf(sp),arg1,arg2,arg3,arg4) 2351 2352 extern NCURSES_EXPORT_VAR(const color_t*) _nc_cga_palette; 2353 extern NCURSES_EXPORT_VAR(const color_t*) _nc_hls_palette; 2354 2355 extern NCURSES_EXPORT(int) _nc_get_driver(TERMINAL_CONTROL_BLOCK*, const char*, int*); 2356 extern NCURSES_EXPORT(void) _nc_get_screensize_ex(SCREEN *, TERMINAL *, int *, int *); 2357 #endif /* USE_TERM_DRIVER */ 2358 2359 /* 2360 * Entrypoints which are actually provided in the terminal driver, which would 2361 * be an sp-name otherwise. 2362 */ 2363 #ifdef USE_TERM_DRIVER 2364 #define TINFO_HAS_KEY _nc_tinfo_has_key 2365 #define TINFO_DOUPDATE _nc_tinfo_doupdate 2366 #define TINFO_MVCUR _nc_tinfo_mvcur 2367 extern NCURSES_EXPORT(int) TINFO_HAS_KEY(SCREEN*, int); 2368 extern NCURSES_EXPORT(int) TINFO_DOUPDATE(SCREEN *); 2369 extern NCURSES_EXPORT(int) TINFO_MVCUR(SCREEN*, int, int, int, int); 2370 #else 2371 #define TINFO_HAS_KEY NCURSES_SP_NAME(has_key) 2372 #define TINFO_DOUPDATE NCURSES_SP_NAME(doupdate) 2373 #define TINFO_MVCUR NCURSES_SP_NAME(_nc_mvcur) 2374 #endif 2375 2376 #if defined(EXP_WIN32_DRIVER) 2377 #include <nc_win32.h> 2378 #endif 2379 2380 /* 2381 * Entrypoints using an extra parameter with the terminal driver. 2382 */ 2383 #ifdef USE_TERM_DRIVER 2384 extern NCURSES_EXPORT(void) _nc_get_screensize(SCREEN *, TERMINAL *, int *, int *); 2385 extern NCURSES_EXPORT(int) _nc_setupterm_ex(TERMINAL **, const char *, int , int *, int); 2386 #define TINFO_GET_SIZE(sp, tp, lp, cp) \ 2387 _nc_get_screensize(sp, tp, lp, cp) 2388 #define TINFO_SET_CURTERM(sp, tp) \ 2389 NCURSES_SP_NAME(set_curterm)(sp, tp) 2390 #define TINFO_SETUP_TERM(tpp, name, fd, err, reuse) \ 2391 _nc_setupterm_ex(tpp, name, fd, err, reuse) 2392 #else /* !USE_TERM_DRIVER */ 2393 extern NCURSES_EXPORT(void) _nc_get_screensize(SCREEN *, int *, int *); 2394 #define TINFO_GET_SIZE(sp, tp, lp, cp) \ 2395 _nc_get_screensize(sp, lp, cp) 2396 #define TINFO_SET_CURTERM(sp, tp) \ 2397 set_curterm(tp) 2398 #define TINFO_SETUP_TERM(tpp, name, fd, err, reuse) \ 2399 _nc_setupterm(name, fd, err, reuse) 2400 #endif /* !USE_TERM_DRIVER */ 2401 2402 #ifdef EXP_WIN32_DRIVER 2403 extern NCURSES_EXPORT_VAR(TERM_DRIVER) _nc_TINFO_DRIVER; 2404 #else 2405 #ifdef USE_TERM_DRIVER 2406 #if defined(USE_WIN32CON_DRIVER) 2407 #include <nc_mingw.h> 2408 extern NCURSES_EXPORT_VAR(TERM_DRIVER) _nc_WIN_DRIVER; 2409 extern NCURSES_EXPORT(int) _nc_mingw_isatty(int fd); 2410 extern NCURSES_EXPORT(int) _nc_mingw_isconsole(int fd); 2411 extern NCURSES_EXPORT(int) _nc_mingw_console_read( 2412 SCREEN *sp, 2413 HANDLE fd, 2414 int *buf); 2415 extern NCURSES_EXPORT(int) _nc_mingw_testmouse( 2416 SCREEN * sp, 2417 HANDLE fd, 2418 int delay EVENTLIST_2nd(_nc_eventlist*)); 2419 #else 2420 #endif 2421 extern NCURSES_EXPORT_VAR(TERM_DRIVER) _nc_TINFO_DRIVER; 2422 #endif /* USE_TERM_DRIVER */ 2423 #endif /* EXP_WIN32_DRIVER */ 2424 2425 #if defined(USE_TERM_DRIVER) && defined(EXP_WIN32_DRIVER) 2426 #define NC_ISATTY(fd) (0 != _nc_console_isatty(fd)) 2427 #elif defined(USE_TERM_DRIVER) && defined(USE_WIN32CON_DRIVER) 2428 #define NC_ISATTY(fd) _nc_mingw_isatty(fd) 2429 #else 2430 #define NC_ISATTY(fd) isatty(fd) 2431 #endif 2432 2433 #ifdef USE_TERM_DRIVER 2434 # define IsTermInfo(sp) ((TCBOf(sp) != 0) && ((TCBOf(sp)->drv->isTerminfo))) 2435 # define HasTInfoTerminal(sp) ((0 != TerminalOf(sp)) && IsTermInfo(sp)) 2436 # if defined(EXP_WIN32_DRIVER) 2437 # define IsTermInfoOnConsole(sp) (IsTermInfo(sp) && _nc_console_test(TerminalOf(sp)->Filedes)) 2438 # elif defined(USE_WIN32CON_DRIVER) 2439 # define IsTermInfoOnConsole(sp) (IsTermInfo(sp) && _nc_mingw_isconsole(TerminalOf(sp)->Filedes)) 2440 # else 2441 # define IsTermInfoOnConsole(sp) FALSE 2442 # endif 2443 #else 2444 # define IsTermInfo(sp) TRUE 2445 # define HasTInfoTerminal(sp) (0 != TerminalOf(sp)) 2446 # if defined(EXP_WIN32_DRIVER) 2447 # define IsTermInfoOnConsole(sp) _nc_console_test(TerminalOf(sp)->Filedes) 2448 # else 2449 # define IsTermInfoOnConsole(sp) FALSE 2450 # endif 2451 #endif 2452 2453 #define IsValidTIScreen(sp) (HasTInfoTerminal(sp)) 2454 2455 /* 2456 * Exported entrypoints beyond the published API 2457 */ 2458 #if NCURSES_SP_FUNCS 2459 extern NCURSES_EXPORT(WINDOW *) _nc_curscr_of(SCREEN*); 2460 extern NCURSES_EXPORT(WINDOW *) _nc_newscr_of(SCREEN*); 2461 extern NCURSES_EXPORT(WINDOW *) _nc_stdscr_of(SCREEN*); 2462 extern NCURSES_EXPORT(int) _nc_outc_wrapper(SCREEN*,int); 2463 2464 #if USE_REENTRANT 2465 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_TABSIZE)(SCREEN*); 2466 extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(longname)(SCREEN*); 2467 #endif 2468 2469 #if NCURSES_EXT_FUNCS 2470 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_set_tabsize)(SCREEN*, int); 2471 #endif 2472 2473 /* 2474 * We put the safe versions of various calls here as they are not published 2475 * part of the API up to now 2476 */ 2477 extern NCURSES_EXPORT(TERMINAL*) NCURSES_SP_NAME(_nc_get_cur_term) (SCREEN *sp); 2478 extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(_nc_makenew) (SCREEN*, int, int, int, int, int); 2479 extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(_nc_reset_colors)(SCREEN*); 2480 extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(_nc_printf_string)(SCREEN*, const char *, va_list); 2481 extern NCURSES_EXPORT(chtype) NCURSES_SP_NAME(_nc_acs_char)(SCREEN*,int); 2482 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_get_tty_mode)(SCREEN*,TTY*); 2483 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_mcprint)(SCREEN*,char*, int); 2484 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_msec_cost)(SCREEN*, const char *, int); 2485 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_mvcur)(SCREEN*, int, int, int, int); 2486 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_outch)(SCREEN*, int); 2487 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_putchar)(SCREEN*, int); 2488 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_putp)(SCREEN*, const char *, const char*); 2489 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_putp_flush)(SCREEN*, const char *, const char *); 2490 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_ripoffline)(SCREEN*, int, int (*)(WINDOW *,int)); 2491 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_scrolln)(SCREEN*, int, int, int, int); 2492 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_set_tty_mode)(SCREEN*, TTY*); 2493 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_setupscreen)(SCREEN**, int, int, FILE *, int, int); 2494 extern NCURSES_EXPORT(int) NCURSES_SP_NAME(_nc_tgetent)(SCREEN*,char*,const char *); 2495 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_do_color)(SCREEN*, int, int, int, NCURSES_SP_OUTC); 2496 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_do_xmc_glitch)(SCREEN*, attr_t); 2497 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_flush)(SCREEN*); 2498 extern GCC_NORETURN NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_free_and_exit)(SCREEN*, int); 2499 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_freeall)(SCREEN*); 2500 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_hash_map)(SCREEN*); 2501 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_init_acs)(SCREEN*); 2502 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_make_oldhash)(SCREEN*, int i); 2503 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_mvcur_init)(SCREEN*); 2504 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_mvcur_resume)(SCREEN*); 2505 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_mvcur_wrap)(SCREEN*); 2506 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_screen_init)(SCREEN*); 2507 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_screen_resume)(SCREEN*); 2508 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_screen_wrap)(SCREEN*); 2509 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_scroll_oldhash)(SCREEN*, int n, int top, int bot); 2510 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_scroll_optimize)(SCREEN*); 2511 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_set_buffer)(SCREEN*, FILE *, int); 2512 2513 extern NCURSES_EXPORT(void) _nc_cookie_init(SCREEN *sp); 2514 2515 #if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG) 2516 extern NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_linedump)(SCREEN*); 2517 #endif 2518 2519 #if USE_WIDEC_SUPPORT 2520 extern NCURSES_EXPORT(wchar_t *) NCURSES_SP_NAME(_nc_wunctrl)(SCREEN*, cchar_t *); 2521 #endif 2522 2523 #endif /* NCURSES_SP_FUNCS */ 2524 2525 #if NCURSES_SP_FUNCS 2526 2527 #define safe_keyname NCURSES_SP_NAME(keyname) 2528 #define safe_unctrl NCURSES_SP_NAME(unctrl) 2529 #define safe_ungetch NCURSES_SP_NAME(ungetch) 2530 2531 #else 2532 2533 #define safe_keyname _nc_keyname 2534 #define safe_unctrl _nc_unctrl 2535 #define safe_ungetch _nc_ungetch 2536 2537 extern NCURSES_EXPORT(NCURSES_CONST char *) _nc_keyname (SCREEN *, int); 2538 extern NCURSES_EXPORT(int) _nc_ungetch (SCREEN *, int); 2539 extern NCURSES_EXPORT(NCURSES_CONST char *) _nc_unctrl (SCREEN *, chtype); 2540 2541 #endif 2542 2543 #ifdef EXP_XTERM_1005 2544 NCURSES_EXPORT(int) _nc_conv_to_utf8(unsigned char *, unsigned, unsigned); 2545 NCURSES_EXPORT(int) _nc_conv_to_utf32(unsigned *, const char *, unsigned); 2546 #endif 2547 2548 #ifdef __cplusplus 2549 } 2550 #endif 2551 2552 /* *INDENT-ON* */ 2553 2554 #endif /* CURSES_PRIV_H */ 2555