ncurses 5.1
[ncurses.git] / panel / panel.priv.h
1 /* $Id: panel.priv.h,v 1.13 2000/01/15 20:39:53 juergen Exp $ */
2
3 #ifndef _PANEL_PRIV_H
4 #define _PANEL_PRIV_H
5
6 #if HAVE_CONFIG_H
7 #  include <ncurses_cfg.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <assert.h>
13
14 #if HAVE_LIBDMALLOC
15 #  include <dmalloc.h>    /* Gray Watson's library */
16 #endif
17
18 #if HAVE_LIBDBMALLOC
19 #  include <dbmalloc.h>   /* Conor Cahill's library */
20 #endif
21
22 #include <nc_panel.h>
23 #include "panel.h"
24
25 #if ( CC_HAS_INLINE_FUNCS && !defined(TRACE) )
26 #  define INLINE inline
27 #else
28 #  define INLINE
29 #endif
30
31 #ifdef USE_RCS_IDS
32 #  define MODULE_ID(id) static const char Ident[] = id;
33 #else
34 #  define MODULE_ID(id) /*nothing*/
35 #endif
36
37
38 #ifdef TRACE
39    extern const char *_nc_my_visbuf(const void *);
40 #  ifdef TRACE_TXT
41 #    define USER_PTR(ptr) _nc_visbuf((const char *)ptr)
42 #  else
43 #    define USER_PTR(ptr) _nc_my_visbuf((const char *)ptr)
44 #  endif
45
46    extern void _nc_dPanel(const char*, const PANEL*);
47    extern void _nc_dStack(const char*, int, const PANEL*);
48    extern void _nc_Wnoutrefresh(const PANEL*);
49    extern void _nc_Touchpan(const PANEL*);
50    extern void _nc_Touchline(const PANEL*, int, int);
51
52 #  define dBug(x) _tracef x
53 #  define dPanel(text,pan) _nc_dPanel(text,pan)
54 #  define dStack(fmt,num,pan) _nc_dStack(fmt,num,pan)
55 #  define Wnoutrefresh(pan) _nc_Wnoutrefresh(pan)
56 #  define Touchpan(pan) _nc_Touchpan(pan)
57 #  define Touchline(pan,start,count) _nc_Touchline(pan,start,count)
58 #else /* !TRACE */
59 #  define dBug(x)
60 #  define dPanel(text,pan)
61 #  define dStack(fmt,num,pan)
62 #  define Wnoutrefresh(pan) wnoutrefresh((pan)->win)
63 #  define Touchpan(pan) touchwin((pan)->win)
64 #  define Touchline(pan,start,count) touchline((pan)->win,start,count)
65 #endif
66
67 #define _nc_stdscr_pseudo_panel _nc_panelhook()->stdscr_pseudo_panel
68 #define _nc_top_panel _nc_panelhook()->top_panel
69 #define _nc_bottom_panel _nc_panelhook()->bottom_panel
70
71 #define EMPTY_STACK() (_nc_top_panel==_nc_bottom_panel)
72 #define Is_Bottom(p)  (((p)!=(PANEL*)0) && !EMPTY_STACK() && (_nc_bottom_panel->above==(p))) 
73 #define Is_Top(p) (((p)!=(PANEL*)0) && !EMPTY_STACK() && (_nc_top_panel==(p)))
74 #define Is_Pseudo(p) ((p) && ((p)==_nc_bottom_panel))
75
76 /* borrowed from curses.priv.h */
77 #define CHANGED_RANGE(line,start,end) \
78         if (line->firstchar == _NOCHANGE \
79          || line->firstchar > (start)) \
80                 line->firstchar = start; \
81         if (line->lastchar == _NOCHANGE \
82          || line->lastchar < (end)) \
83                 line->lastchar = end
84
85 /*+-------------------------------------------------------------------------
86         IS_LINKED(pan) - check to see if panel is in the stack
87 --------------------------------------------------------------------------*/
88 /* This works! The only case where it would fail is, when the list has
89    only one element. But this could only be the pseudo panel at the bottom */
90 #define IS_LINKED(p) (((p)->above || (p)->below ||((p)==_nc_bottom_panel)) ? TRUE : FALSE)
91
92 #define PSTARTX(pan) ((pan)->win->_begx)
93 #define PENDX(pan)   ((pan)->win->_begx + getmaxx((pan)->win) - 1)
94 #define PSTARTY(pan) ((pan)->win->_begy)
95 #define PENDY(pan)   ((pan)->win->_begy + getmaxy((pan)->win) - 1)
96
97 /*+-------------------------------------------------------------------------
98         PANELS_OVERLAPPED(pan1,pan2) - check panel overlapped
99 ---------------------------------------------------------------------------*/
100 #define PANELS_OVERLAPPED(pan1,pan2) \
101 (( !(pan1) || !(pan2) || \
102        PSTARTY(pan1) > PENDY(pan2) || PENDY(pan1) < PSTARTY(pan2) ||\
103        PSTARTX(pan1) > PENDX(pan2) || PENDX(pan1) < PSTARTX(pan2) ) \
104      ? FALSE : TRUE)
105
106
107 /*+-------------------------------------------------------------------------
108         Compute the intersection rectangle of two overlapping rectangles
109 ---------------------------------------------------------------------------*/
110 #define COMPUTE_INTERSECTION(pan1,pan2,ix1,ix2,iy1,iy2)\
111    ix1 = (PSTARTX(pan1) < PSTARTX(pan2)) ? PSTARTX(pan2) : PSTARTX(pan1);\
112    ix2 = (PENDX(pan1)   < PENDX(pan2))   ? PENDX(pan1)   : PENDX(pan2);\
113    iy1 = (PSTARTY(pan1) < PSTARTY(pan2)) ? PSTARTY(pan2) : PSTARTY(pan1);\
114    iy2 = (PENDY(pan1)   < PENDY(pan2))   ? PENDY(pan1)   : PENDY(pan2);\
115    assert((ix1<=ix2) && (iy1<=iy2));\
116
117
118 /*+-------------------------------------------------------------------------
119         Walk through the panel stack starting at the given location and
120         check for intersections; overlapping panels are "touched", so they
121         are incrementally overwriting cells that should be hidden. 
122         If the "touch" flag is set, the panel gets touched before it is
123         updated. 
124 ---------------------------------------------------------------------------*/
125 #define PANEL_UPDATE(pan,panstart,touch)\
126 {  PANEL* pan2 = ((panstart) ? (panstart) : _nc_bottom_panel);\
127    if (touch)\
128       Touchpan(pan);\
129    while(pan2) {\
130       if ((pan2 != pan) && PANELS_OVERLAPPED(pan,pan2)) {\
131         int y,ix1,ix2,iy1,iy2;\
132         COMPUTE_INTERSECTION(pan,pan2,ix1,ix2,iy1,iy2);\
133         for(y = iy1; y <= iy2; y++) {\
134           if (is_linetouched(pan->win,y - PSTARTY(pan))) {\
135             struct ldat* line = &(pan2->win->_line[y - PSTARTY(pan2)]);\
136             CHANGED_RANGE(line,ix1-PSTARTX(pan2),ix2-PSTARTX(pan2));\
137           }\
138         }\
139       }\
140       pan2 = pan2->above;\
141    }\
142 }
143
144 /*+-------------------------------------------------------------------------
145         Remove panel from stack.
146 ---------------------------------------------------------------------------*/
147 #define PANEL_UNLINK(pan,err) \
148 {  err = ERR;\
149    if (pan) {\
150      if (IS_LINKED(pan)) {\
151        if ((pan)->below)\
152          (pan)->below->above = (pan)->above;\
153        if ((pan)->above)\
154          (pan)->above->below = (pan)->below;\
155        if ((pan) == _nc_bottom_panel) \
156          _nc_bottom_panel = (pan)->above;\
157        if ((pan) == _nc_top_panel) \
158          _nc_top_panel = (pan)->below;\
159        err = OK;\
160      }\
161      (pan)->above = (pan)->below = (PANEL*)0;\
162    }\
163 }
164
165 #define HIDE_PANEL(pan,err,err_if_unlinked)\
166   if (IS_LINKED(pan)) {\
167     PANEL_UPDATE(pan,(PANEL*)0,TRUE);\
168     PANEL_UNLINK(pan,err);\
169   } \
170   else {\
171     if (err_if_unlinked)\
172       err = ERR;\
173   }
174
175 #endif /* _PANEL_PRIV_H */