]> ncurses.scripts.mit.edu Git - ncurses.git/blob - ncurses/curses.priv.h
ncurses 5.3
[ncurses.git] / ncurses / curses.priv.h
1 /****************************************************************************
2  * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28
29 /****************************************************************************
30  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
31  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32  *     and: Thomas E. Dickey 1996-2002                                      *
33  ****************************************************************************/
34
35
36 /*
37  * $Id: curses.priv.h,v 1.228 2002/10/12 15:49:10 tom Exp $
38  *
39  *      curses.priv.h
40  *
41  *      Header file for curses library objects which are private to
42  *      the library.
43  *
44  */
45
46 #ifndef CURSES_PRIV_H
47 #define CURSES_PRIV_H 1
48
49 #include <ncurses_dll.h>
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 #include <ncurses_cfg.h>
56
57 #if USE_RCS_IDS
58 #define MODULE_ID(id) static const char Ident[] = id;
59 #else
60 #define MODULE_ID(id) /*nothing*/
61 #endif
62
63 #include <stdlib.h>
64 #include <string.h>
65 #include <sys/types.h>
66
67 #if HAVE_UNISTD_H
68 #include <unistd.h>
69 #endif
70
71 #if HAVE_SYS_BSDTYPES_H
72 #include <sys/bsdtypes.h>       /* needed for ISC */
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 #ifndef PATH_MAX
82 # if defined(_POSIX_PATH_MAX)
83 #  define PATH_MAX _POSIX_PATH_MAX
84 # elif defined(MAXPATHLEN)
85 #  define PATH_MAX MAXPATHLEN
86 # else
87 #  define PATH_MAX 255  /* the Posix minimum path-size */
88 # endif
89 #endif
90
91 #include <assert.h>
92 #include <stdio.h>
93
94 #include <errno.h>
95
96 #if DECL_ERRNO
97 extern int errno;
98 #endif
99
100 #include <nc_panel.h>
101
102 /* Some systems have a broken 'select()', but workable 'poll()'.  Use that */
103 #if HAVE_WORKING_POLL
104 #define USE_FUNC_POLL 1
105 #if HAVE_POLL_H
106 #include <poll.h>
107 #else
108 #include <sys/poll.h>
109 #endif
110 #else
111 #define USE_FUNC_POLL 0
112 #endif
113
114 /* include signal.h before curses.h to work-around defect in glibc 2.1.3 */
115 #include <signal.h>
116
117 /* Alessandro Rubini's GPM (general-purpose mouse) */
118 #if HAVE_LIBGPM && HAVE_GPM_H
119 #define USE_GPM_SUPPORT 1
120 #else
121 #define USE_GPM_SUPPORT 0
122 #endif
123
124 /* QNX mouse support */
125 #if defined(__QNX__) && !defined(__QNXNTO__)
126 #define USE_QNX_MOUSE 1
127 #else
128 #define USE_QNX_MOUSE 0
129 #endif
130
131 /* EMX mouse support */
132 #ifdef __EMX__
133 #define USE_EMX_MOUSE
134 #endif
135
136 #define DEFAULT_MAXCLICK 166
137 #define EV_MAX          8       /* size of mouse circular event queue */
138
139 /*
140  * If we don't have signals to support it, don't add a sigwinch handler.
141  * In any case, resizing is an extended feature.  Use it if we've got it.
142  */
143 #if !NCURSES_EXT_FUNCS
144 #undef HAVE_SIZECHANGE
145 #define HAVE_SIZECHANGE 0
146 #endif
147
148 #if HAVE_SIZECHANGE && defined(SIGWINCH)
149 #define USE_SIZECHANGE 1
150 #else
151 #define USE_SIZECHANGE 0
152 #undef USE_SIGWINCH
153 #define USE_SIGWINCH 0
154 #endif
155
156 /*
157  * If desired, one can configure this, disabling environment variables that
158  * point to custom terminfo/termcap locations.
159  */
160 #ifdef USE_ROOT_ENVIRON
161 #define use_terminfo_vars() 1
162 #else
163 #define use_terminfo_vars() _nc_env_access()
164 extern NCURSES_EXPORT(int) _nc_env_access (void);
165 #endif
166
167 /*
168  * Not all platforms have memmove; some have an equivalent bcopy.  (Some may
169  * have neither).
170  */
171 #if USE_OK_BCOPY
172 #define memmove(d,s,n) bcopy(s,d,n)
173 #elif USE_MY_MEMMOVE
174 #define memmove(d,s,n) _nc_memmove(d,s,n)
175 extern NCURSES_EXPORT(void *) _nc_memmove (void *, const void *, size_t);
176 #endif
177
178 /*
179  * Scroll hints are useless when hashmap is used
180  */
181 #if !USE_SCROLL_HINTS
182 #if !USE_HASHMAP
183 #define USE_SCROLL_HINTS 1
184 #else
185 #define USE_SCROLL_HINTS 0
186 #endif
187 #endif
188
189 #if USE_SCROLL_HINTS
190 #define if_USE_SCROLL_HINTS(stmt) stmt
191 #else
192 #define if_USE_SCROLL_HINTS(stmt) /*nothing*/
193 #endif
194
195 /*
196  * Note:  ht/cbt expansion flakes out randomly under Linux 1.1.47, but only
197  * when we're throwing control codes at the screen at high volume.  To see
198  * this, re-enable USE_HARD_TABS and run worm for a while.  Other systems
199  * probably don't want to define this either due to uncertainties about tab
200  * delays and expansion in raw mode.
201  */
202
203 struct tries {
204         struct tries    *child;     /* ptr to child.  NULL if none          */
205         struct tries    *sibling;   /* ptr to sibling.  NULL if none        */
206         unsigned char    ch;        /* character at this node               */
207         unsigned short   value;     /* code of string so far.  0 if none.   */
208 };
209
210 /*
211  * Definitions for color pairs
212  */
213 #define C_SHIFT 8               /* we need more bits than there are colors */
214 #define C_MASK  ((1 << C_SHIFT) - 1)
215
216 #define PAIR_OF(fg, bg) ((((fg) & C_MASK) << C_SHIFT) | ((bg) & C_MASK))
217
218 /*
219  * Common/troublesome character definitions
220  */
221 #define L_BRACE '{'
222 #define R_BRACE '}'
223 #define S_QUOTE '\''
224 #define D_QUOTE '"'
225
226 #define VT_ACSC "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~"
227
228 /*
229  * Structure for palette tables
230  */
231
232 typedef struct
233 {
234     short red, green, blue;     /* what color_content() returns */
235     short r, g, b;              /* params to init_color() */
236     int init;                   /* true if we called init_color() */
237 }
238 color_t;
239
240 #define MAXCOLUMNS    135
241 #define MAXLINES      66
242 #define FIFO_SIZE     MAXCOLUMNS+2  /* for nocbreak mode input */
243
244 #define ACS_LEN       128
245
246 #define WINDOWLIST struct _win_list
247
248 #if USE_WIDEC_SUPPORT
249 #define _nc_bkgd    _bkgrnd
250 #else
251 #undef _XOPEN_SOURCE_EXTENDED
252 #define _nc_bkgd    _bkgd
253 #define wgetbkgrnd(win, wch)    *wch = win->_bkgd
254 #define wbkgrnd     wbkgd
255 #endif
256
257 #include <curses.h>     /* we'll use -Ipath directive to get the right one! */
258 #include <term.h>
259
260 struct ldat
261 {
262         NCURSES_CH_T    *text;          /* text of the line */
263         NCURSES_SIZE_T  firstchar;      /* first changed character in the line */
264         NCURSES_SIZE_T  lastchar;       /* last changed character in the line */
265         NCURSES_SIZE_T  oldindex;       /* index of the line at last update */
266 };
267
268 /*
269  * Structure for soft labels.
270  */
271
272 typedef struct
273 {
274         char *text;             /* text for the label */
275         char *form_text;        /* formatted text (left/center/...) */
276         int x;                  /* x coordinate of this field */
277         char dirty;             /* this label has changed */
278         char visible;           /* field is visible */
279 } slk_ent;
280
281 typedef struct {
282         char dirty;             /* all labels have changed */
283         char hidden;            /* soft labels are hidden */
284         WINDOW *win;
285         slk_ent *ent;
286         char*  buffer;           /* buffer for labels */
287         short  maxlab;           /* number of available labels */
288         short  labcnt;           /* number of allocated labels */
289         short  maxlen;           /* length of labels */
290         chtype attr;             /* soft label attribute */
291 } SLK;
292
293 typedef struct {
294         unsigned long hashval;
295         int oldcount, newcount;
296         int oldindex, newindex;
297 } HASHMAP;
298
299 typedef struct {
300         int     line;           /* lines to take, < 0 => from bottom*/
301         int     (*hook)(WINDOW *, int); /* callback for user        */
302         WINDOW *w;              /* maybe we need this for cleanup   */
303 } ripoff_t;
304
305 struct screen {
306         int             _ifd;           /* input file ptr for screen        */
307         FILE            *_ofp;          /* output file ptr for screen       */
308         char            *_setbuf;       /* buffered I/O for output          */
309         int             _buffered;      /* setvbuf uses _setbuf data        */
310         int             _checkfd;       /* filedesc for typeahead check     */
311         struct term     *_term;         /* terminal type information        */
312         short           _lines;         /* screen lines                     */
313         short           _columns;       /* screen columns                   */
314
315         short           _lines_avail;   /* lines available for stdscr       */
316         short           _topstolen;     /* lines stolen from top            */
317         ripoff_t        _rippedoff[5];  /* list of lines stolen             */
318         int             _rip_count;     /* ...and total lines stolen        */
319
320         WINDOW          *_curscr;       /* current screen                   */
321         WINDOW          *_newscr;       /* virtual screen to be updated to  */
322         WINDOW          *_stdscr;       /* screen's full-window context     */
323
324         struct tries    *_keytry;       /* "Try" for use with keypad mode   */
325         struct tries    *_key_ok;       /* Disabled keys via keyok(,FALSE)  */
326         bool            _tried;         /* keypad mode was initialized      */
327         bool            _keypad_on;     /* keypad mode is currently on      */
328
329         int             _fifo[FIFO_SIZE];       /* input push-back buffer   */
330         short           _fifohead,      /* head of fifo queue               */
331                         _fifotail,      /* tail of fifo queue               */
332                         _fifopeek,      /* where to peek for next char      */
333                         _fifohold;      /* set if breakout marked           */
334
335         int             _endwin;        /* are we out of window mode?       */
336         attr_t          _current_attr;  /* terminal attribute current set   */
337         int             _coloron;       /* is color enabled?                */
338         int             _color_defs;    /* are colors modified              */
339         int             _cursor;        /* visibility of the cursor         */
340         int             _cursrow;       /* physical cursor row              */
341         int             _curscol;       /* physical cursor column           */
342         int             _nl;            /* True if NL -> CR/NL is on        */
343         int             _raw;           /* True if in raw mode              */
344         int             _cbreak;        /* 1 if in cbreak mode              */
345                                         /* > 1 if in halfdelay mode         */
346         int             _echo;          /* True if echo on                  */
347         int             _use_meta;      /* use the meta key?                */
348         SLK             *_slk;          /* ptr to soft key struct / NULL    */
349         int             slk_format;     /* selected format for this screen  */
350         /* cursor movement costs; units are 10ths of milliseconds */
351 #if NCURSES_NO_PADDING
352         int             _no_padding;    /* flag to set if padding disabled  */
353 #endif
354         int             _char_padding;  /* cost of character put            */
355         int             _cr_cost;       /* cost of (carriage_return)        */
356         int             _cup_cost;      /* cost of (cursor_address)         */
357         int             _home_cost;     /* cost of (cursor_home)            */
358         int             _ll_cost;       /* cost of (cursor_to_ll)           */
359 #if USE_HARD_TABS
360         int             _ht_cost;       /* cost of (tab)                    */
361         int             _cbt_cost;      /* cost of (backtab)                */
362 #endif /* USE_HARD_TABS */
363         int             _cub1_cost;     /* cost of (cursor_left)            */
364         int             _cuf1_cost;     /* cost of (cursor_right)           */
365         int             _cud1_cost;     /* cost of (cursor_down)            */
366         int             _cuu1_cost;     /* cost of (cursor_up)              */
367         int             _cub_cost;      /* cost of (parm_cursor_left)       */
368         int             _cuf_cost;      /* cost of (parm_cursor_right)      */
369         int             _cud_cost;      /* cost of (parm_cursor_down)       */
370         int             _cuu_cost;      /* cost of (parm_cursor_up)         */
371         int             _hpa_cost;      /* cost of (column_address)         */
372         int             _vpa_cost;      /* cost of (row_address)            */
373         /* used in tty_update.c, must be chars */
374         int             _ed_cost;       /* cost of (clr_eos)                */
375         int             _el_cost;       /* cost of (clr_eol)                */
376         int             _el1_cost;      /* cost of (clr_bol)                */
377         int             _dch1_cost;     /* cost of (delete_character)       */
378         int             _ich1_cost;     /* cost of (insert_character)       */
379         int             _dch_cost;      /* cost of (parm_dch)               */
380         int             _ich_cost;      /* cost of (parm_ich)               */
381         int             _ech_cost;      /* cost of (erase_chars)            */
382         int             _rep_cost;      /* cost of (repeat_char)            */
383         int             _hpa_ch_cost;   /* cost of (column_address)         */
384         int             _cup_ch_cost;   /* cost of (cursor_address)         */
385         int             _cuf_ch_cost;   /* cost of (parm_cursor_right)      */
386         int             _inline_cost;   /* cost of inline-move              */
387         int             _smir_cost;     /* cost of (enter_insert_mode)      */
388         int             _rmir_cost;     /* cost of (exit_insert_mode)       */
389         int             _ip_cost;       /* cost of (insert_padding)         */
390         /* used in lib_mvcur.c */
391         char *          _address_cursor;
392         /* used in tty_update.c */
393         int             _scrolling;     /* 1 if terminal's smart enough to  */
394
395         /* used in lib_color.c */
396         color_t         *_color_table;  /* screen's color palette            */
397         int             _color_count;   /* count of colors in palette        */
398         unsigned short  *_color_pairs;  /* screen's color pair list          */
399         int             _pair_count;    /* count of color pairs              */
400 #if NCURSES_EXT_FUNCS
401         bool            _default_color; /* use default colors                */
402         bool            _has_sgr_39_49; /* has ECMA default color support    */
403         int             _default_fg;    /* assumed default foreground        */
404         int             _default_bg;    /* assumed default background        */
405 #endif
406         chtype          _xmc_suppress;  /* attributes to suppress if xmc     */
407         chtype          _xmc_triggers;  /* attributes to process if xmc      */
408         chtype          _acs_map[ACS_LEN];
409
410         /* used in lib_vidattr.c */
411         bool            _use_rmso;      /* true if we may use 'rmso'         */
412         bool            _use_rmul;      /* true if we may use 'rmul'         */
413
414         /*
415          * These data correspond to the state of the idcok() and idlok()
416          * functions.  A caveat is in order here:  the XSI and SVr4
417          * documentation specify that these functions apply to the window which
418          * is given as an argument.  However, ncurses implements this logic
419          * only for the newscr/curscr update process, _not_ per-window.
420          */
421         bool            _nc_sp_idlok;
422         bool            _nc_sp_idcok;
423 #define _nc_idlok SP->_nc_sp_idlok
424 #define _nc_idcok SP->_nc_sp_idcok
425
426         /*
427          * These are the data that support the mouse interface.
428          */
429         int             _maxclick;
430         bool            (*_mouse_event) (SCREEN *);
431         bool            (*_mouse_inline)(SCREEN *);
432         bool            (*_mouse_parse) (int);
433         void            (*_mouse_resume)(SCREEN *);
434         void            (*_mouse_wrap)  (SCREEN *);
435         int             _mouse_fd;      /* file-descriptor, if any */
436
437         /*
438          * This supports automatic resizing
439          */
440 #if USE_SIZECHANGE
441         int             (*_resize)(int,int);
442 #endif
443
444         /*
445          * These are data that support the proper handling of the panel stack on an
446          * per screen basis.
447          */
448         struct panelhook _panelHook;
449         /*
450          * Linked-list of all windows, to support '_nc_resizeall()' and
451          * '_nc_freeall()'
452          */
453         WINDOWLIST      *_nc_sp_windows;
454 #define _nc_windows SP->_nc_sp_windows
455
456         bool            _sig_winch;
457         SCREEN          *_next_screen;
458
459         /* hashes for old and new lines */
460         unsigned long   *oldhash, *newhash;
461         HASHMAP         *hashtab;
462         int             hashtab_len;
463
464         bool            _cleanup;       /* cleanup after int/quit signal */
465         int             (*_outch)(int); /* output handler if not putc */
466 };
467
468 extern NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain;
469
470 #if NCURSES_NOMACROS
471 #include <nomacros.h>
472 #endif
473
474 /*
475  * The margins are used in resizeterm() to retain the original layout after
476  * resizing.
477  */
478         WINDOWLIST {
479         WINDOWLIST *next;
480 #if HAVE_RESIZETERM
481         int     l_margin;
482         int     r_margin;
483         int     t_margin;
484         int     b_margin;
485 #endif
486         WINDOW  win;
487 };
488
489 /* The terminfo source is assumed to be 7-bit ASCII */
490 #define is7bits(c)      ((unsigned)(c) < 128)
491
492 #ifndef min
493 #define min(a,b)        ((a) > (b)  ?  (b)  :  (a))
494 #endif
495
496 #ifndef max
497 #define max(a,b)        ((a) < (b)  ?  (b)  :  (a))
498 #endif
499
500 /* usually in <unistd.h> */
501 #ifndef STDIN_FILENO
502 #define STDIN_FILENO 0
503 #endif
504
505 #ifndef STDOUT_FILENO
506 #define STDOUT_FILENO 1
507 #endif
508
509 #ifndef STDERR_FILENO
510 #define STDERR_FILENO 2
511 #endif
512
513 #ifndef EXIT_SUCCESS
514 #define EXIT_SUCCESS 0
515 #endif
516
517 #ifndef EXIT_FAILURE
518 #define EXIT_FAILURE 1
519 #endif
520
521 #ifndef R_OK
522 #define R_OK    4               /* Test for read permission.  */
523 #endif
524 #ifndef W_OK
525 #define W_OK    2               /* Test for write permission.  */
526 #endif
527 #ifndef X_OK
528 #define X_OK    1               /* Test for execute permission.  */
529 #endif
530 #ifndef F_OK
531 #define F_OK    0               /* Test for existence.  */
532 #endif
533
534 #if HAVE_FCNTL_H
535 #include <fcntl.h>              /* may define O_BINARY  */
536 #endif
537
538 #ifndef O_BINARY
539 #define O_BINARY 0
540 #endif
541
542 #define UChar(c)        ((unsigned char)(c))
543 #define ChCharOf(c)     ((c) & (chtype)A_CHARTEXT)
544 #define ChAttrOf(c)     ((c) & (chtype)A_ATTRIBUTES)
545
546 #if USE_WIDEC_SUPPORT /* { */
547 #define CharOf(c)       ((c).chars[0])
548 #define AttrOf(c)       ((c).attr)
549 #define AddAttr(c,a)    (c).attr |= a
550 #define RemAttr(c,a)    (c).attr &= ~(a)
551 #define SetAttr(c,a)    (c).attr = a
552 #define NewChar(ch)     { ChAttrOf(ch), { ChCharOf(ch) } }
553 #define NewChar2(c,a)   { a, { c } }
554 #define CharEq(a,b)     (!memcmp(&a, &b, sizeof(a)))
555 #define SetChar(ch,c,a) do {                                                        \
556                             NCURSES_CH_T *_cp = &ch;                                \
557                             memset(_cp,0,sizeof(ch)); _cp->chars[0] = c; _cp->attr = a; \
558                         } while (0)
559 #define CHREF(wch)      (&wch)
560 #define CHDEREF(wch)    (*wch)
561 #define ARG_CH_T        NCURSES_CH_T *
562 #define CARG_CH_T       const NCURSES_CH_T *
563 #define PUTC_DATA       char PUTC_buf[MB_LEN_MAX]; int PUTC_i, PUTC_n; \
564                         mbstate_t PUT_st; wchar_t PUTC_ch
565 #define PUTC(ch,b)      do { if(!isnac(ch)) {                                       \
566                             memset (&PUT_st, '\0', sizeof (PUT_st));                \
567                             PUTC_i = 0;                                             \
568                             do {                                                    \
569                                 PUTC_ch = PUTC_i < CCHARW_MAX ?                     \
570                                             (ch).chars[PUTC_i] : L'\0';             \
571                                 PUTC_n = wcrtomb(PUTC_buf,                          \
572                                                  (ch).chars[PUTC_i], &PUT_st);      \
573                                 if (PUTC_ch == L'\0')                               \
574                                     --PUTC_n;                                       \
575                                 if (PUTC_n <= 0)                                    \
576                                     break;                                          \
577                                 fwrite(PUTC_buf, (unsigned) PUTC_n, 1, b);          \
578                                 ++PUTC_i;                                           \
579                             } while (PUTC_ch != L'\0');                             \
580                         } } while (0)
581
582 #define BLANK           { WA_NORMAL, ' ' }
583 #define ISBLANK(ch)     ((ch).chars[0] == L' ' && (ch).chars[1] == L'\0')
584
585 #define WA_NAC          1
586 #define isnac(ch)       (AttrOf(ch) & WA_NAC)
587 #define if_WIDEC(code)  code
588 #define Charable(ch)    (!isnac(ch) &&                                  \
589                          (ch).chars[1] == L'\0' &&                      \
590                          (wctob(CharOf(ch)) == (char)CharOf(ch)))
591
592 #define L(ch)           L ## ch
593 #else /* }{ */
594 #define CharOf(c)       ChCharOf(c)
595 #define AttrOf(c)       ChAttrOf(c)
596 #define AddAttr(c,a)    c |= a
597 #define RemAttr(c,a)    c &= ~(a & A_ATTRIBUTES)
598 #define SetAttr(c,a)    c = (c & ~A_ATTRIBUTES) | a
599 #define NewChar(ch)     (ch)
600 #define NewChar2(c,a)   (c | a)
601 #define CharEq(a,b)     (a == b)
602 #define SetChar(ch,c,a) ch = c | a
603 #define CHREF(wch)      wch
604 #define CHDEREF(wch)    wch
605 #define ARG_CH_T        NCURSES_CH_T
606 #define CARG_CH_T       NCURSES_CH_T
607 #define PUTC_DATA       int data = 0
608 #define PUTC(a,b)       do { data = CharOf(ch); putc(data,b); } while (0)
609
610 #define BLANK           (' '|A_NORMAL)
611 #define ISBLANK(ch)     (CharOf(ch) == ' ')
612
613 #define isnac(ch)       (0)
614 #define if_WIDEC(code) /* nothing */
615
616 #define L(ch)           ch
617 #endif /* } */
618
619 #define AttrOfD(ch)     AttrOf(CHDEREF(ch))
620 #define CharOfD(ch)     CharOf(CHDEREF(ch))
621 #define SetChar2(wch,ch)    SetChar(wch,ChCharOf(ch),ChAttrOf(ch))
622
623 #define BLANK_ATTR      A_NORMAL
624 #define BLANK_TEXT      L(' ')
625
626 #define CHANGED     -1
627
628 #define CHANGED_CELL(line,col) \
629         if (line->firstchar == _NOCHANGE) \
630                 line->firstchar = line->lastchar = col; \
631         else if ((col) < line->firstchar) \
632                 line->firstchar = col; \
633         else if ((col) > line->lastchar) \
634                 line->lastchar = col
635
636 #define CHANGED_RANGE(line,start,end) \
637         if (line->firstchar == _NOCHANGE \
638          || line->firstchar > (start)) \
639                 line->firstchar = start; \
640         if (line->lastchar == _NOCHANGE \
641          || line->lastchar < (end)) \
642                 line->lastchar = end
643
644 #define CHANGED_TO_EOL(line,start,end) \
645         if (line->firstchar == _NOCHANGE \
646          || line->firstchar > (start)) \
647                 line->firstchar = start; \
648         line->lastchar = end
649
650 #define SIZEOF(v) (sizeof(v)/sizeof(v[0]))
651
652 #define FreeIfNeeded(p)  if ((p) != 0) free(p)
653
654 /* FreeAndNull() is not a comma-separated expression because some compilers
655  * do not accept a mixture of void with values.
656  */
657 #define FreeAndNull(p)   free(p); p = 0
658
659 #include <nc_alloc.h>
660
661 /*
662  * Prefixes for call/return points of library function traces.  We use these to
663  * instrument the public functions so that the traces can be easily transformed
664  * into regression scripts.
665  */
666 #define T_CALLED(fmt) "called {" fmt
667 #define T_CREATE(fmt) "create :" fmt
668 #define T_RETURN(fmt) "return }" fmt
669
670 #ifdef TRACE
671
672 #define START_TRACE() \
673         if ((_nc_tracing & TRACE_MAXIMUM) == 0) { \
674             int t = _nc_getenv_num("NCURSES_TRACE"); \
675             if (t >= 0) \
676                 trace((unsigned) t); \
677         }
678
679 #define TR(n, a)        if (_nc_tracing & (n)) _tracef a
680 #define T(a)            TR(TRACE_CALLS, a)
681 #define TPUTS_TRACE(s)  _nc_tputs_trace = s;
682 #define TRACE_RETURN(value,type) return _nc_retrace_##type(value)
683
684 #define returnAttr(code) TRACE_RETURN(code,attr_t)
685 #define returnChar(code) TRACE_RETURN(code,chtype)
686 #define returnBool(code) TRACE_RETURN(code,bool)
687 #define returnBits(code) TRACE_RETURN(code,unsigned)
688 #define returnCode(code) TRACE_RETURN(code,int)
689 #define returnPtr(code)  TRACE_RETURN(code,ptr)
690 #define returnSP(code)   TRACE_RETURN(code,sp)
691 #define returnVoid       T((T_RETURN(""))); return
692 #define returnWin(code)  TRACE_RETURN(code,win)
693
694 extern NCURSES_EXPORT(NCURSES_BOOL)     _nc_retrace_bool (NCURSES_BOOL);
695 extern NCURSES_EXPORT(SCREEN *)         _nc_retrace_sp (SCREEN *);
696 extern NCURSES_EXPORT(WINDOW *)         _nc_retrace_win (WINDOW *);
697 extern NCURSES_EXPORT(attr_t)           _nc_retrace_attr_t (attr_t);
698 extern NCURSES_EXPORT(char *)           _nc_retrace_ptr (char *);
699 extern NCURSES_EXPORT(char *)           _nc_trace_ttymode(TTY *tty);
700 extern NCURSES_EXPORT(char *)           _nc_varargs (const char *, va_list);
701 extern NCURSES_EXPORT(chtype)           _nc_retrace_chtype (chtype);
702 extern NCURSES_EXPORT(const char *)     _nc_altcharset_name(attr_t, chtype);
703 extern NCURSES_EXPORT(int)              _nc_retrace_int (int);
704 extern NCURSES_EXPORT(unsigned)         _nc_retrace_unsigned (unsigned);
705 extern NCURSES_EXPORT(void)             _nc_fifo_dump (void);
706 extern NCURSES_EXPORT_VAR(const char *) _nc_tputs_trace;
707 extern NCURSES_EXPORT_VAR(long)         _nc_outchars;
708 extern NCURSES_EXPORT_VAR(unsigned)     _nc_tracing;
709
710 #if USE_WIDEC_SUPPORT
711 extern NCURSES_EXPORT(const char *) _nc_viswbuf2 (int, const wchar_t *);
712 extern NCURSES_EXPORT(const char *) _nc_viswbufn (const wchar_t *, int);
713 extern NCURSES_EXPORT(const char *) _nc_viscbuf2 (int, const cchar_t *, int);
714 extern NCURSES_EXPORT(const char *) _nc_viscbuf (const cchar_t *, int);
715 #endif
716
717 #else /* !TRACE */
718
719 #define START_TRACE() /* nothing */
720
721 #define T(a)
722 #define TR(n, a)
723 #define TPUTS_TRACE(s)
724
725 #define returnAttr(code) return code
726 #define returnBits(code) return code
727 #define returnBool(code) return code
728 #define returnChar(code) return code
729 #define returnCode(code) return code
730 #define returnPtr(code)  return code
731 #define returnSP(code)   return code
732 #define returnVoid       return
733 #define returnWin(code)  return code
734
735 #endif /* TRACE/!TRACE */
736
737 extern NCURSES_EXPORT(const char *) _nc_visbuf2 (int, const char *);
738 extern NCURSES_EXPORT(const char *) _nc_visbufn (const char *, int);
739
740 #define empty_module(name) \
741 extern  NCURSES_EXPORT(void) name (void); \
742         NCURSES_EXPORT(void) name (void) { }
743
744 #define ALL_BUT_COLOR ((chtype)~(A_COLOR))
745 #define IGNORE_COLOR_OFF FALSE
746 #define NONBLANK_ATTR (A_BOLD|A_DIM|A_BLINK)
747 #define XMC_CHANGES(c) ((c) & SP->_xmc_suppress)
748
749 #define toggle_attr_on(S,at) {\
750    if (PAIR_NUMBER(at) > 0)\
751       (S) = ((S) & ALL_BUT_COLOR) | (at);\
752    else\
753       (S) |= (at);\
754    TR(TRACE_ATTRS, ("new attribute is %s", _traceattr((S))));}
755
756
757 #define toggle_attr_off(S,at) {\
758    if (IGNORE_COLOR_OFF == TRUE) {\
759       if (PAIR_NUMBER(at) == 0xff) /* turn off color */\
760          (S) &= ~(at);\
761       else /* leave color alone */\
762          (S) &= ~((at)&ALL_BUT_COLOR);\
763    } else {\
764       if (PAIR_NUMBER(at) > 0x00) /* turn off color */\
765          (S) &= ~(at|A_COLOR);\
766       else /* leave color alone */\
767          (S) &= ~(at);\
768    }\
769    TR(TRACE_ATTRS, ("new attribute is %s", _traceattr((S))));}
770
771 #define DelCharCost(count) \
772                 ((parm_dch != 0) \
773                 ? SP->_dch_cost \
774                 : ((delete_character != 0) \
775                         ? (SP->_dch1_cost * count) \
776                         : INFINITY))
777
778 #define InsCharCost(count) \
779                 ((parm_ich != 0) \
780                 ? SP->_ich_cost \
781                 : ((enter_insert_mode && exit_insert_mode) \
782                   ? SP->_smir_cost + SP->_rmir_cost + (SP->_ip_cost * count) \
783                   : ((insert_character != 0) \
784                     ? (SP->_ich1_cost * count) \
785                     : INFINITY)))
786
787 #if USE_XMC_SUPPORT
788 #define UpdateAttrs(a)  if (SP->_current_attr != (a)) { \
789                                 attr_t chg = SP->_current_attr; \
790                                 vidattr((a)); \
791                                 if (magic_cookie_glitch > 0 \
792                                  && XMC_CHANGES((chg ^ SP->_current_attr))) { \
793                                         T(("%s @%d before glitch %d,%d", \
794                                                 __FILE__, __LINE__, \
795                                                 SP->_cursrow, \
796                                                 SP->_curscol)); \
797                                         _nc_do_xmc_glitch(chg); \
798                                 } \
799                         }
800 #else
801 #define UpdateAttrs(a)  if (SP->_current_attr != (a)) \
802                                 vidattr((a));
803 #endif
804
805 /*
806  * Macros to make additional parameter to implement wgetch_events()
807  */
808 #ifdef NCURSES_WGETCH_EVENTS
809 #define EVENTLIST_0th(param) param
810 #define EVENTLIST_1st(param) param
811 #define EVENTLIST_2nd(param) , param
812 #else
813 #define EVENTLIST_0th(param) void
814 #define EVENTLIST_1st(param) /* nothing */
815 #define EVENTLIST_2nd(param) /* nothing */
816 #endif
817
818 #if NCURSES_EXPANDED && NCURSES_EXT_FUNCS
819
820 #undef  toggle_attr_on
821 #define toggle_attr_on(S,at) _nc_toggle_attr_on(&(S), at)
822 extern NCURSES_EXPORT(void) _nc_toggle_attr_on (attr_t *, attr_t);
823
824 #undef  toggle_attr_off
825 #define toggle_attr_off(S,at) _nc_toggle_attr_off(&(S), at)
826 extern NCURSES_EXPORT(void) _nc_toggle_attr_off (attr_t *, attr_t);
827
828 #undef  DelCharCost
829 #define DelCharCost(count) _nc_DelCharCost(count)
830 extern NCURSES_EXPORT(int) _nc_DelCharCost (int);
831
832 #undef  InsCharCost
833 #define InsCharCost(count) _nc_InsCharCost(count)
834 extern NCURSES_EXPORT(int) _nc_InsCharCost (int);
835
836 #undef  UpdateAttrs
837 #define UpdateAttrs(c) _nc_UpdateAttrs(c)
838 extern NCURSES_EXPORT(void) _nc_UpdateAttrs (chtype);
839
840 #else
841
842 extern NCURSES_EXPORT(void) _nc_expanded (void);
843
844 #endif
845
846 #if !HAVE_GETCWD
847 #define getcwd(buf,len) getwd(buf)
848 #endif
849
850 /* doupdate.c */
851 #if USE_XMC_SUPPORT
852 extern NCURSES_EXPORT(void) _nc_do_xmc_glitch (attr_t);
853 #endif
854
855 /* hardscroll.c */
856 #if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG)
857 extern NCURSES_EXPORT(void) _nc_linedump (void);
858 #endif
859
860 /* lib_acs.c */
861 extern NCURSES_EXPORT(void) _nc_init_acs (void);        /* corresponds to traditional 'init_acs()' */
862 extern NCURSES_EXPORT(int) _nc_msec_cost (const char *const, int);  /* used by 'tack' program */
863
864 /* lib_addstr.c */
865 #if USE_WIDEC_SUPPORT
866 extern NCURSES_EXPORT(int) _nc_wchstrlen(const cchar_t *);
867 #endif
868
869 /* lib_color.c */
870 extern NCURSES_EXPORT(bool) _nc_reset_colors(void);
871
872 /* lib_getch.c */
873 extern NCURSES_EXPORT(int) _nc_wgetch(WINDOW *, unsigned long *, int EVENTLIST_2nd(_nc_eventlist *));
874
875 /* lib_mvcur.c */
876 #define INFINITY        1000000 /* cost: too high to use */
877
878 extern NCURSES_EXPORT(void) _nc_mvcur_init (void);
879 extern NCURSES_EXPORT(void) _nc_mvcur_resume (void);
880 extern NCURSES_EXPORT(void) _nc_mvcur_wrap (void);
881
882 extern NCURSES_EXPORT(int) _nc_scrolln (int, int, int, int);
883
884 extern NCURSES_EXPORT(void) _nc_screen_init (void);
885 extern NCURSES_EXPORT(void) _nc_screen_resume (void);
886 extern NCURSES_EXPORT(void) _nc_screen_wrap (void);
887
888 /* lib_mouse.c */
889 extern NCURSES_EXPORT(int) _nc_has_mouse (void);
890
891 /* lib_mvcur.c */
892 #define INFINITY        1000000 /* cost: too high to use */
893
894 /* lib_wacs.c */
895 #if USE_WIDEC_SUPPORT
896 extern NCURSES_EXPORT(void) _nc_init_wacs(void);
897 #endif
898
899 typedef struct {
900     char *s_head;
901     char *s_tail;
902     size_t s_size;
903 } string_desc;
904
905 /* strings.c */
906 extern NCURSES_EXPORT(string_desc *) _nc_str_init (string_desc *, char *, size_t);
907 extern NCURSES_EXPORT(string_desc *) _nc_str_null (string_desc *, size_t);
908 extern NCURSES_EXPORT(string_desc *) _nc_str_copy (string_desc *, string_desc *);
909 extern NCURSES_EXPORT(bool) _nc_safe_strcat (string_desc *, const char *);
910 extern NCURSES_EXPORT(bool) _nc_safe_strcpy (string_desc *, const char *);
911
912 extern NCURSES_EXPORT(void) _nc_mvcur_init (void);
913 extern NCURSES_EXPORT(void) _nc_mvcur_resume (void);
914 extern NCURSES_EXPORT(void) _nc_mvcur_wrap (void);
915
916 extern NCURSES_EXPORT(int) _nc_scrolln (int, int, int, int);
917
918 extern NCURSES_EXPORT(void) _nc_screen_init (void);
919 extern NCURSES_EXPORT(void) _nc_screen_resume (void);
920 extern NCURSES_EXPORT(void) _nc_screen_wrap (void);
921
922 #if !HAVE_STRSTR
923 #define strstr _nc_strstr
924 extern NCURSES_EXPORT(char *) _nc_strstr (const char *, const char *);
925 #endif
926
927 /* safe_sprintf.c */
928 extern NCURSES_EXPORT(char *) _nc_printf_string (const char *, va_list);
929
930 /* tries.c */
931 extern NCURSES_EXPORT(void) _nc_add_to_try (struct tries **, const char *, unsigned short);
932 extern NCURSES_EXPORT(char *) _nc_expand_try (struct tries *, unsigned short, int *, size_t);
933 extern NCURSES_EXPORT(int) _nc_remove_key (struct tries **, unsigned short);
934 extern NCURSES_EXPORT(int) _nc_remove_string (struct tries **, char *);
935
936 /* elsewhere ... */
937 extern NCURSES_EXPORT(WINDOW *) _nc_makenew (int, int, int, int, int);
938 extern NCURSES_EXPORT(char *) _nc_home_terminfo (void);
939 extern NCURSES_EXPORT(char *) _nc_trace_buf (int, size_t);
940 extern NCURSES_EXPORT(NCURSES_CH_T) _nc_render (WINDOW *, NCURSES_CH_T);
941 extern NCURSES_EXPORT(int)  _nc_access (const char *, int);
942 extern NCURSES_EXPORT(int) _nc_baudrate (int);
943 extern NCURSES_EXPORT(int) _nc_freewin (WINDOW *);
944 extern NCURSES_EXPORT(int) _nc_getenv_num (const char *);
945 extern NCURSES_EXPORT(int) _nc_keypad (bool);
946 extern NCURSES_EXPORT(int) _nc_ospeed (int);
947 extern NCURSES_EXPORT(int) _nc_outch (int);
948 extern NCURSES_EXPORT(int) _nc_setupscreen (short, short const, FILE *);
949 extern NCURSES_EXPORT(int) _nc_timed_wait(int, int, int * EVENTLIST_2nd(_nc_eventlist *));
950 extern NCURSES_EXPORT(int) _nc_waddch_nosync (WINDOW *, const NCURSES_CH_T);
951 extern NCURSES_EXPORT(void) _nc_do_color (int, int, bool, int (*)(int));
952 extern NCURSES_EXPORT(void) _nc_flush (void);
953 extern NCURSES_EXPORT(void) _nc_freeall (void);
954 extern NCURSES_EXPORT(void) _nc_hash_map (void);
955 extern NCURSES_EXPORT(void) _nc_init_keytry (void);
956 extern NCURSES_EXPORT(void) _nc_keep_tic_dir (const char *);
957 extern NCURSES_EXPORT(void) _nc_make_oldhash (int i);
958 extern NCURSES_EXPORT(void) _nc_outstr (const char *str);
959 extern NCURSES_EXPORT(void) _nc_scroll_oldhash (int n, int top, int bot);
960 extern NCURSES_EXPORT(void) _nc_scroll_optimize (void);
961 extern NCURSES_EXPORT(void) _nc_scroll_window (WINDOW *, int const, short const, short const, NCURSES_CH_T);
962 extern NCURSES_EXPORT(void) _nc_set_buffer (FILE *, bool);
963 extern NCURSES_EXPORT(void) _nc_signal_handler (bool);
964 extern NCURSES_EXPORT(void) _nc_synchook (WINDOW *);
965 extern NCURSES_EXPORT(void) _nc_trace_tries (struct tries *);
966
967 #if USE_SIZECHANGE
968 extern NCURSES_EXPORT(void) _nc_update_screensize (void);
969 #endif
970
971 #if HAVE_RESIZETERM
972 extern NCURSES_EXPORT(void) _nc_resize_margins (WINDOW *);
973 #else
974 #define _nc_resize_margins(wp) /* nothing */
975 #endif
976
977 #ifdef NCURSES_WGETCH_EVENTS
978 extern NCURSES_EXPORT(int) _nc_eventlist_timeout(_nc_eventlist *);
979 #else
980 #define wgetch_events(win, evl) wgetch(win)
981 #define wgetnstr_events(win, str, maxlen, evl) wgetnstr(win, str, maxlen)
982 #endif
983
984 /*
985  * Not everyone has vsscanf(), but we'd like to use it for scanw().
986  */
987 #if !HAVE_VSSCANF
988 extern int vsscanf(const char *str, const char *format, va_list __arg);
989 #endif
990
991 /* scroll indices */
992 extern NCURSES_EXPORT_VAR(int *) _nc_oldnums;
993
994 #define USE_SETBUF_0 0
995
996 #define NC_BUFFERED(flag) \
997         if ((SP->_buffered != 0) != flag) \
998                 _nc_set_buffer(SP->_ofp, flag)
999
1000 #define NC_OUTPUT ((SP != 0) ? SP->_ofp : stdout)
1001
1002 /*
1003  * On systems with a broken linker, define 'SP' as a function to force the
1004  * linker to pull in the data-only module with 'SP'.
1005  */
1006 #if BROKEN_LINKER
1007 #define SP _nc_screen()
1008 extern NCURSES_EXPORT(SCREEN *) _nc_screen (void);
1009 extern NCURSES_EXPORT(int) _nc_alloc_screen (void);
1010 extern NCURSES_EXPORT(void) _nc_set_screen (SCREEN *);
1011 #else
1012 /* current screen is private data; avoid possible linking conflicts too */
1013 extern NCURSES_EXPORT_VAR(SCREEN *) SP;
1014 #define _nc_alloc_screen() ((SP = typeCalloc(SCREEN, 1)) != 0)
1015 #define _nc_set_screen(sp) SP = sp
1016 #endif
1017
1018 /*
1019  * We don't want to use the lines or columns capabilities internally, because
1020  * if the application is running multiple screens under X, it's quite possible
1021  * they could all have type xterm but have different sizes!  So...
1022  */
1023 #define screen_lines    SP->_lines
1024 #define screen_columns  SP->_columns
1025
1026 extern NCURSES_EXPORT_VAR(int) _nc_slk_format;  /* != 0 if slk_init() called */
1027 extern NCURSES_EXPORT(int) _nc_slk_initialize (WINDOW *, int);
1028
1029 /*
1030  * Some constants related to SLK's
1031  */
1032 #define MAX_SKEY_OLD       8    /* count of soft keys */
1033 #define MAX_SKEY_LEN_OLD   8    /* max length of soft key text */
1034 #define MAX_SKEY_PC       12    /* This is what most PC's have */
1035 #define MAX_SKEY_LEN_PC    5
1036
1037 /* Macro to check whether or not we use a standard format */
1038 #define SLK_STDFMT(fmt) (fmt < 3)
1039 /* Macro to determine height of label window */
1040 #define SLK_LINES(fmt)  (SLK_STDFMT(fmt) ? 1 : ((fmt) - 2))
1041
1042 #define MAX_SKEY(fmt)     (SLK_STDFMT(fmt)? MAX_SKEY_OLD : MAX_SKEY_PC)
1043 #define MAX_SKEY_LEN(fmt) (SLK_STDFMT(fmt)? MAX_SKEY_LEN_OLD : MAX_SKEY_LEN_PC)
1044
1045 extern NCURSES_EXPORT(int) _nc_ripoffline (int line, int (*init)(WINDOW *,int));
1046
1047 /*
1048  * Common error messages
1049  */
1050 #define MSG_NO_MEMORY "Out of memory"
1051 #define MSG_NO_INPUTS "Premature EOF"
1052
1053 #ifdef __cplusplus
1054 }
1055 #endif
1056
1057 #endif /* CURSES_PRIV_H */