1 /**************************************************************************** 2 * Copyright 2020 Thomas E. Dickey * 3 * Copyright 1998-2010,2016 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 ****************************************************************************/ 34 35 /* 36 ** lib_window.c 37 ** 38 ** 39 */ 40 41 #include <curses.priv.h> 42 43 MODULE_ID("$Id: lib_window.c,v 1.31 2020/02/02 23:34:34 tom Exp $") 44 45 NCURSES_EXPORT(void) 46 _nc_synchook(WINDOW *win) 47 /* hook to be called after each window change */ 48 { 49 if (win->_immed) 50 wrefresh(win); 51 if (win->_sync) 52 wsyncup(win); 53 } 54 55 NCURSES_EXPORT(int) 56 mvderwin(WINDOW *win, int y, int x) 57 /* move a derived window */ 58 { 59 WINDOW *orig; 60 int rc = ERR; 61 62 T((T_CALLED("mvderwin(%p,%d,%d)"), (void *) win, y, x)); 63 64 if (win != 0 65 && (orig = win->_parent) != 0 66 && (x >= 0 && y >= 0) 67 && (x + getmaxx(win) <= getmaxx(orig)) 68 && (y + getmaxy(win) <= getmaxy(orig))) { 69 int i; 70 71 wsyncup(win); 72 win->_parx = x; 73 win->_pary = y; 74 for (i = 0; i < getmaxy(win); i++) 75 win->_line[i].text = &(orig->_line[y++].text[x]); 76 rc = OK; 77 } 78 returnCode(rc); 79 } 80 81 NCURSES_EXPORT(int) 82 syncok(WINDOW *win, bool bf) 83 /* enable/disable automatic wsyncup() on each change to window */ 84 { 85 T((T_CALLED("syncok(%p,%d)"), (void *) win, bf)); 86 87 if (win) { 88 win->_sync = bf; 89 returnCode(OK); 90 } else 91 returnCode(ERR); 92 } 93 94 NCURSES_EXPORT(void) 95 wsyncup(WINDOW *win) 96 /* mark changed every cell in win's ancestors that is changed in win */ 97 /* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 98 { 99 WINDOW *wp; 100 101 T((T_CALLED("wsyncup(%p)"), (void *) win)); 102 if (win && win->_parent) { 103 for (wp = win; wp->_parent; wp = wp->_parent) { 104 int y; 105 WINDOW *pp = wp->_parent; 106 107 assert((wp->_pary <= pp->_maxy) && 108 ((wp->_pary + wp->_maxy) <= pp->_maxy)); 109 110 for (y = 0; y <= wp->_maxy; y++) { 111 int left = wp->_line[y].firstchar; 112 if (left >= 0) { /* line is touched */ 113 struct ldat *line = &(pp->_line[wp->_pary + y]); 114 /* left & right character in parent window coordinates */ 115 int right = wp->_line[y].lastchar + wp->_parx; 116 left += wp->_parx; 117 118 CHANGED_RANGE(line, left, right); 119 } 120 } 121 } 122 } 123 returnVoid; 124 } 125 126 NCURSES_EXPORT(void) 127 wsyncdown(WINDOW *win) 128 /* mark changed every cell in win that is changed in any of its ancestors */ 129 /* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 130 { 131 T((T_CALLED("wsyncdown(%p)"), (void *) win)); 132 133 if (win && win->_parent) { 134 WINDOW *pp = win->_parent; 135 int y; 136 137 /* This recursion guarantees, that the changes are propagated down- 138 wards from the root to our direct parent. */ 139 wsyncdown(pp); 140 141 /* and now we only have to propagate the changes from our direct 142 parent, if there are any. */ 143 assert((win->_pary <= pp->_maxy) && 144 ((win->_pary + win->_maxy) <= pp->_maxy)); 145 146 for (y = 0; y <= win->_maxy; y++) { 147 if (pp->_line[win->_pary + y].firstchar >= 0) { /* parent changed */ 148 struct ldat *line = &(win->_line[y]); 149 /* left and right character in child coordinates */ 150 int left = pp->_line[win->_pary + y].firstchar - win->_parx; 151 int right = pp->_line[win->_pary + y].lastchar - win->_parx; 152 /* The change may be outside the child's range */ 153 if (left < 0) 154 left = 0; 155 if (right > win->_maxx) 156 right = win->_maxx; 157 CHANGED_RANGE(line, left, right); 158 } 159 } 160 } 161 returnVoid; 162 } 163 164 NCURSES_EXPORT(void) 165 wcursyncup(WINDOW *win) 166 /* sync the cursor in all derived windows to its value in the base window */ 167 { 168 WINDOW *wp; 169 170 T((T_CALLED("wcursyncup(%p)"), (void *) win)); 171 for (wp = win; wp && wp->_parent; wp = wp->_parent) { 172 wmove(wp->_parent, wp->_pary + wp->_cury, wp->_parx + wp->_curx); 173 } 174 returnVoid; 175 } 176 177 NCURSES_EXPORT(WINDOW *) 178 dupwin(WINDOW *win) 179 /* make an exact duplicate of the given window */ 180 { 181 WINDOW *nwin = 0; 182 183 T((T_CALLED("dupwin(%p)"), (void *) win)); 184 185 if (win != 0) { 186 #if NCURSES_SP_FUNCS 187 SCREEN *sp = _nc_screen_of(win); 188 #endif 189 _nc_lock_global(curses); 190 if (win->_flags & _ISPAD) { 191 nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx 192 win->_maxy + 1, 193 win->_maxx + 1); 194 } else { 195 nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 196 win->_maxy + 1, 197 win->_maxx + 1, 198 win->_begy, 199 win->_begx); 200 } 201 202 if (nwin != 0) { 203 int i; 204 size_t linesize; 205 206 nwin->_curx = win->_curx; 207 nwin->_cury = win->_cury; 208 nwin->_maxy = win->_maxy; 209 nwin->_maxx = win->_maxx; 210 nwin->_begy = win->_begy; 211 nwin->_begx = win->_begx; 212 nwin->_yoffset = win->_yoffset; 213 214 nwin->_flags = win->_flags & ~_SUBWIN; 215 /* Due to the use of newwin(), the clone is not a subwindow. 216 * The text is really copied into the clone. 217 */ 218 219 WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); 220 nwin->_nc_bkgd = win->_nc_bkgd; 221 222 nwin->_notimeout = win->_notimeout; 223 nwin->_clear = win->_clear; 224 nwin->_leaveok = win->_leaveok; 225 nwin->_scroll = win->_scroll; 226 nwin->_idlok = win->_idlok; 227 nwin->_idcok = win->_idcok; 228 nwin->_immed = win->_immed; 229 nwin->_sync = win->_sync; 230 nwin->_use_keypad = win->_use_keypad; 231 nwin->_delay = win->_delay; 232 233 nwin->_parx = 0; 234 nwin->_pary = 0; 235 nwin->_parent = (WINDOW *) 0; 236 /* See above: the clone isn't a subwindow! */ 237 238 nwin->_regtop = win->_regtop; 239 nwin->_regbottom = win->_regbottom; 240 241 if (win->_flags & _ISPAD) 242 nwin->_pad = win->_pad; 243 244 linesize = (unsigned) (win->_maxx + 1) * sizeof(NCURSES_CH_T); 245 for (i = 0; i <= nwin->_maxy; i++) { 246 memcpy(nwin->_line[i].text, win->_line[i].text, linesize); 247 nwin->_line[i].firstchar = win->_line[i].firstchar; 248 nwin->_line[i].lastchar = win->_line[i].lastchar; 249 } 250 } 251 _nc_unlock_global(curses); 252 } 253 returnWin(nwin); 254 } 255