1 /* $OpenBSD: lib_window.c,v 1.4 2023/10/17 09:52:09 nicm Exp $ */ 2 3 /**************************************************************************** 4 * Copyright 2020,2021 Thomas E. Dickey * 5 * Copyright 1998-2010,2016 Free Software Foundation, Inc. * 6 * * 7 * Permission is hereby granted, free of charge, to any person obtaining a * 8 * copy of this software and associated documentation files (the * 9 * "Software"), to deal in the Software without restriction, including * 10 * without limitation the rights to use, copy, modify, merge, publish, * 11 * distribute, distribute with modifications, sublicense, and/or sell * 12 * copies of the Software, and to permit persons to whom the Software is * 13 * furnished to do so, subject to the following conditions: * 14 * * 15 * The above copyright notice and this permission notice shall be included * 16 * in all copies or substantial portions of the Software. * 17 * * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 21 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 24 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 25 * * 26 * Except as contained in this notice, the name(s) of the above copyright * 27 * holders shall not be used in advertising or otherwise to promote the * 28 * sale, use or other dealings in this Software without prior written * 29 * authorization. * 30 ****************************************************************************/ 31 32 /**************************************************************************** 33 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 34 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 35 ****************************************************************************/ 36 37 /* 38 ** lib_window.c 39 ** 40 ** 41 */ 42 43 #include <curses.priv.h> 44 45 MODULE_ID("$Id: lib_window.c,v 1.4 2023/10/17 09:52:09 nicm Exp $") 46 47 NCURSES_EXPORT(void) 48 _nc_synchook(WINDOW *win) 49 /* hook to be called after each window change */ 50 { 51 if (win->_immed) 52 wrefresh(win); 53 if (win->_sync) 54 wsyncup(win); 55 } 56 57 NCURSES_EXPORT(int) 58 mvderwin(WINDOW *win, int y, int x) 59 /* move a derived window */ 60 { 61 WINDOW *orig; 62 int rc = ERR; 63 64 T((T_CALLED("mvderwin(%p,%d,%d)"), (void *) win, y, x)); 65 66 if (win != 0 67 && (orig = win->_parent) != 0 68 && (x >= 0 && y >= 0) 69 && (x + getmaxx(win) <= getmaxx(orig)) 70 && (y + getmaxy(win) <= getmaxy(orig))) { 71 int i; 72 73 wsyncup(win); 74 win->_parx = x; 75 win->_pary = y; 76 for (i = 0; i < getmaxy(win); i++) 77 win->_line[i].text = &(orig->_line[y++].text[x]); 78 rc = OK; 79 } 80 returnCode(rc); 81 } 82 83 NCURSES_EXPORT(int) 84 syncok(WINDOW *win, bool bf) 85 /* enable/disable automatic wsyncup() on each change to window */ 86 { 87 T((T_CALLED("syncok(%p,%d)"), (void *) win, bf)); 88 89 if (win) { 90 win->_sync = bf; 91 returnCode(OK); 92 } else 93 returnCode(ERR); 94 } 95 96 NCURSES_EXPORT(void) 97 wsyncup(WINDOW *win) 98 /* mark changed every cell in win's ancestors that is changed in win */ 99 /* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 100 { 101 WINDOW *wp; 102 103 T((T_CALLED("wsyncup(%p)"), (void *) win)); 104 if (win && win->_parent) { 105 for (wp = win; wp->_parent; wp = wp->_parent) { 106 int y; 107 WINDOW *pp = wp->_parent; 108 109 assert((wp->_pary <= pp->_maxy) && 110 ((wp->_pary + wp->_maxy) <= pp->_maxy)); 111 112 for (y = 0; y <= wp->_maxy; y++) { 113 int left = wp->_line[y].firstchar; 114 if (left >= 0) { /* line is touched */ 115 struct ldat *line = &(pp->_line[wp->_pary + y]); 116 /* left & right character in parent window coordinates */ 117 int right = wp->_line[y].lastchar + wp->_parx; 118 left += wp->_parx; 119 120 CHANGED_RANGE(line, left, right); 121 } 122 } 123 } 124 } 125 returnVoid; 126 } 127 128 NCURSES_EXPORT(void) 129 wsyncdown(WINDOW *win) 130 /* mark changed every cell in win that is changed in any of its ancestors */ 131 /* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 132 { 133 T((T_CALLED("wsyncdown(%p)"), (void *) win)); 134 135 if (win != NULL && win->_parent != NULL) { 136 WINDOW *pp = win->_parent; 137 int y; 138 139 /* This recursion guarantees, that the changes are propagated down- 140 wards from the root to our direct parent. */ 141 wsyncdown(pp); 142 143 /* and now we only have to propagate the changes from our direct 144 parent, if there are any. */ 145 assert((win->_pary <= pp->_maxy) && 146 ((win->_pary + win->_maxy) <= pp->_maxy)); 147 148 for (y = 0; y <= win->_maxy; y++) { 149 if (pp->_line[win->_pary + y].firstchar >= 0) { /* parent changed */ 150 struct ldat *line = &(win->_line[y]); 151 /* left and right character in child coordinates */ 152 int left = pp->_line[win->_pary + y].firstchar - win->_parx; 153 int right = pp->_line[win->_pary + y].lastchar - win->_parx; 154 /* The change may be outside the child's range */ 155 if (left < 0) 156 left = 0; 157 if (right > win->_maxx) 158 right = win->_maxx; 159 CHANGED_RANGE(line, left, right); 160 } 161 } 162 } 163 returnVoid; 164 } 165 166 NCURSES_EXPORT(void) 167 wcursyncup(WINDOW *win) 168 /* sync the cursor in all derived windows to its value in the base window */ 169 { 170 WINDOW *wp; 171 172 T((T_CALLED("wcursyncup(%p)"), (void *) win)); 173 for (wp = win; wp && wp->_parent; wp = wp->_parent) { 174 wmove(wp->_parent, wp->_pary + wp->_cury, wp->_parx + wp->_curx); 175 } 176 returnVoid; 177 } 178 179 NCURSES_EXPORT(WINDOW *) 180 dupwin(WINDOW *win) 181 /* make an exact duplicate of the given window */ 182 { 183 WINDOW *nwin = 0; 184 185 T((T_CALLED("dupwin(%p)"), (void *) win)); 186 187 if (win != 0) { 188 #if NCURSES_SP_FUNCS 189 SCREEN *sp = _nc_screen_of(win); 190 #endif 191 _nc_lock_global(curses); 192 if (IS_PAD(win)) { 193 nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx 194 win->_maxy + 1, 195 win->_maxx + 1); 196 } else { 197 nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 198 win->_maxy + 1, 199 win->_maxx + 1, 200 win->_begy, 201 win->_begx); 202 } 203 204 if (nwin != 0) { 205 int i; 206 size_t linesize; 207 208 nwin->_curx = win->_curx; 209 nwin->_cury = win->_cury; 210 nwin->_maxy = win->_maxy; 211 nwin->_maxx = win->_maxx; 212 nwin->_begy = win->_begy; 213 nwin->_begx = win->_begx; 214 nwin->_yoffset = win->_yoffset; 215 216 nwin->_flags = win->_flags & ~_SUBWIN; 217 /* Due to the use of newwin(), the clone is not a subwindow. 218 * The text is really copied into the clone. 219 */ 220 221 WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); 222 nwin->_nc_bkgd = win->_nc_bkgd; 223 224 nwin->_notimeout = win->_notimeout; 225 nwin->_clear = win->_clear; 226 nwin->_leaveok = win->_leaveok; 227 nwin->_scroll = win->_scroll; 228 nwin->_idlok = win->_idlok; 229 nwin->_idcok = win->_idcok; 230 nwin->_immed = win->_immed; 231 nwin->_sync = win->_sync; 232 nwin->_use_keypad = win->_use_keypad; 233 nwin->_delay = win->_delay; 234 235 nwin->_parx = 0; 236 nwin->_pary = 0; 237 nwin->_parent = (WINDOW *) 0; 238 /* See above: the clone isn't a subwindow! */ 239 240 nwin->_regtop = win->_regtop; 241 nwin->_regbottom = win->_regbottom; 242 243 if (IS_PAD(win)) 244 nwin->_pad = win->_pad; 245 246 linesize = (unsigned) (win->_maxx + 1) * sizeof(NCURSES_CH_T); 247 for (i = 0; i <= nwin->_maxy; i++) { 248 memcpy(nwin->_line[i].text, win->_line[i].text, linesize); 249 nwin->_line[i].firstchar = win->_line[i].firstchar; 250 nwin->_line[i].lastchar = win->_line[i].lastchar; 251 } 252 } 253 _nc_unlock_global(curses); 254 } 255 returnWin(nwin); 256 } 257