]> ncurses.scripts.mit.edu Git - ncurses.git/blob - ncurses/lib_window.c
ncurses 4.1
[ncurses.git] / ncurses / lib_window.c
1
2 /***************************************************************************
3 *                            COPYRIGHT NOTICE                              *
4 ****************************************************************************
5 *                ncurses is copyright (C) 1992-1995                        *
6 *                          Zeyd M. Ben-Halim                               *
7 *                          zmbenhal@netcom.com                             *
8 *                          Eric S. Raymond                                 *
9 *                          esr@snark.thyrsus.com                           *
10 *                                                                          *
11 *        Permission is hereby granted to reproduce and distribute ncurses  *
12 *        by any means and for any fee, whether alone or as part of a       *
13 *        larger distribution, in source or in binary form, PROVIDED        *
14 *        this notice is included with any such distribution, and is not    *
15 *        removed from any of its header files. Mention of ncurses in any   *
16 *        applications linked with it is highly appreciated.                *
17 *                                                                          *
18 *        ncurses comes AS IS with no warranty, implied or expressed.       *
19 *                                                                          *
20 ***************************************************************************/
21
22 /*
23 **      lib_window.c
24 **
25 **
26 */
27
28 #include <curses.priv.h>
29
30 MODULE_ID("$Id: lib_window.c,v 1.8 1997/02/02 01:14:43 tom Exp $")
31
32 void _nc_synchook(WINDOW *win)
33 /* hook to be called after each window change */
34 {
35         if (win->_immed) wrefresh(win);
36         if (win->_sync) wsyncup(win);
37 }
38
39 int mvderwin(WINDOW *win, int y, int x)
40 /* move a derived window */
41 {
42    WINDOW *orig = win->_parent;
43    int i;
44
45    T((T_CALLED("mvderwin(%p,%d,%d)"), win, y, x));
46
47    if (orig)
48    {
49       if (win->_parx==x && win->_pary==y)
50         returnCode(OK);
51       if (x<0 || y<0)
52         returnCode(ERR);
53       if ( (x+getmaxx(win) > getmaxx(orig)) ||
54            (y+getmaxy(win) > getmaxy(orig)) )
55         returnCode(ERR);
56    }
57    else
58       returnCode(ERR);
59    wsyncup(win);
60    win->_parx = x;
61    win->_pary = y;
62    for(i=0;i<getmaxy(win);i++)
63      win->_line[i].text = &(orig->_line[y++].text[x]);
64    returnCode(OK);
65 }
66
67 int syncok(WINDOW *win, bool bf)
68 /* enable/disable automatic wsyncup() on each change to window */
69 {
70         T((T_CALLED("syncok(%p,%d)"), win, bf));
71
72         if (win) {
73                 win->_sync = bf;
74                 returnCode(OK);
75         } else
76                 returnCode(ERR);
77 }
78
79 void wsyncup(WINDOW *win)
80 /* mark changed every cell in win's ancestors that is changed in win */
81 /* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...)      */
82 {
83   WINDOW        *wp;
84
85   if (win && win->_parent)
86     for (wp = win; wp->_parent; wp = wp->_parent)
87       {
88         int y;
89         WINDOW *pp = wp->_parent;
90
91         assert((wp->_pary <= pp->_maxy) &&
92                ((wp->_pary+wp->_maxy) <= pp->_maxy));
93
94         for (y = 0; y <= wp->_maxy; y++)
95           {
96             int left = wp->_line[y].firstchar;
97             if (left >= 0) /* line is touched */
98               {
99                 /* left & right character in parent window coordinates */
100                 int right = wp->_line[y].lastchar + wp->_parx;
101                 left += wp->_parx;
102
103                 if (pp->_line[wp->_pary + y].firstchar == _NOCHANGE)
104                   {
105                     pp->_line[wp->_pary + y].firstchar = left;
106                     pp->_line[wp->_pary + y].lastchar  = right;
107                   }
108                 else
109                   {
110                     if (left < pp->_line[wp->_pary + y].firstchar)
111                       pp->_line[wp->_pary + y].firstchar = left;
112                     if (pp->_line[wp->_pary + y].lastchar < right)
113                       pp->_line[wp->_pary + y].lastchar = right;
114                   }
115               }
116           }
117       }
118 }
119
120 void wsyncdown(WINDOW *win)
121 /* mark changed every cell in win that is changed in any of its ancestors */
122 /* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...)           */
123 {
124   if (win && win->_parent)
125     {
126       WINDOW *pp = win->_parent;
127       int y;
128
129       /* This recursion guarantees, that the changes are propagated down-
130          wards from the root to our direct parent. */
131       wsyncdown(pp);
132
133       /* and now we only have to propagate the changes from our direct
134          parent, if there are any. */
135       assert((win->_pary <= pp->_maxy) &&
136              ((win->_pary + win->_maxy) <= pp->_maxy));
137
138       for (y = 0; y <= win->_maxy; y++)
139         {
140           if (pp->_line[win->_pary + y].firstchar >= 0) /* parent changed */
141             {
142               /* left and right character in child coordinates */
143               int left  = pp->_line[win->_pary + y].firstchar - win->_parx;
144               int right = pp->_line[win->_pary + y].lastchar  - win->_parx;
145               /* The change maybe outside the childs range */
146               if (left<0)
147                 left = 0;
148               if (right > win->_maxx)
149                 right = win->_maxx;
150               if (win->_line[y].firstchar == _NOCHANGE)
151                 {
152                   win->_line[y].firstchar = left;
153                   win->_line[y].lastchar  = right;
154                 }
155               else
156                 {
157                   if (left < win->_line[y].firstchar)
158                     win->_line[y].firstchar = left;
159                   if (win->_line[y].lastchar < right)
160                     win->_line[y].lastchar = right;
161                 }
162             }
163         }
164     }
165 }
166
167 void wcursyncup(WINDOW *win)
168 /* sync the cursor in all derived windows to its value in the base window */
169 {
170    WINDOW *wp;
171    for( wp = win; wp && wp->_parent; wp = wp->_parent ) {
172       wmove( wp->_parent, wp->_pary + wp->_cury, wp->_parx + wp->_curx );
173    }
174 }
175
176 WINDOW *dupwin(WINDOW *win)
177 /* make an exact duplicate of the given window */
178 {
179 WINDOW *nwin;
180 size_t linesize;
181 int i;
182
183         T((T_CALLED("dupwin(%p)"), win));
184
185         if ((nwin = newwin(win->_maxy + 1, win->_maxx + 1, win->_begy, win->_begx)) == NULL)
186                 returnWin(0);
187
188         nwin->_curx        = win->_curx;
189         nwin->_cury        = win->_cury;
190         nwin->_maxy        = win->_maxy;
191         nwin->_maxx        = win->_maxx;
192         nwin->_begy        = win->_begy;
193         nwin->_begx        = win->_begx;
194         nwin->_yoffset     = win->_yoffset;
195
196         nwin->_flags       = win->_flags;
197         nwin->_attrs       = win->_attrs;
198         nwin->_bkgd        = win->_bkgd;
199
200         nwin->_clear       = win->_clear;
201         nwin->_scroll      = win->_scroll;
202         nwin->_leaveok     = win->_leaveok;
203         nwin->_use_keypad  = win->_use_keypad;
204         nwin->_delay       = win->_delay;
205         nwin->_immed       = win->_immed;
206         nwin->_sync        = win->_sync;
207         nwin->_parx        = win->_parx;
208         nwin->_pary        = win->_pary;
209         nwin->_parent      = win->_parent;
210
211         nwin->_regtop      = win->_regtop;
212         nwin->_regbottom   = win->_regbottom;
213
214         linesize = (win->_maxx + 1) * sizeof(chtype);
215         for (i = 0; i <= nwin->_maxy; i++) {
216                 memcpy(nwin->_line[i].text, win->_line[i].text, linesize);
217                 nwin->_line[i].firstchar  = win->_line[i].firstchar;
218                 nwin->_line[i].lastchar = win->_line[i].lastchar;
219         }
220
221         returnWin(nwin);
222 }