1158910Srwatson/**************************************************************************** 2158910Srwatson * Copyright 2020 Thomas E. Dickey * 3158910Srwatson * Copyright 1998-2010,2016 Free Software Foundation, Inc. * 4158910Srwatson * * 5158910Srwatson * Permission is hereby granted, free of charge, to any person obtaining a * 6158910Srwatson * copy of this software and associated documentation files (the * 7158910Srwatson * "Software"), to deal in the Software without restriction, including * 8158910Srwatson * without limitation the rights to use, copy, modify, merge, publish, * 9158910Srwatson * distribute, distribute with modifications, sublicense, and/or sell * 10158910Srwatson * copies of the Software, and to permit persons to whom the Software is * 11158910Srwatson * furnished to do so, subject to the following conditions: * 12158910Srwatson * * 13158910Srwatson * The above copyright notice and this permission notice shall be included * 14158910Srwatson * in all copies or substantial portions of the Software. * 15158910Srwatson * * 16158910Srwatson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 17158910Srwatson * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 18158910Srwatson * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 19158910Srwatson * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 20158910Srwatson * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 21158910Srwatson * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 22158910Srwatson * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 23158910Srwatson * * 24158910Srwatson * Except as contained in this notice, the name(s) of the above copyright * 25158910Srwatson * holders shall not be used in advertising or otherwise to promote the * 26158910Srwatson * sale, use or other dealings in this Software without prior written * 27158910Srwatson * authorization. * 28158910Srwatson ****************************************************************************/ 29158910Srwatson 30158910Srwatson/**************************************************************************** 31168854Spjd * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 32204294Sbrucec * and: Eric S. Raymond <esr@snark.thyrsus.com> * 33158910Srwatson ****************************************************************************/ 34158910Srwatson 35158910Srwatson/* 36158910Srwatson** lib_window.c 37204294Sbrucec** 38216379Spjd** 39158910Srwatson*/ 40204294Sbrucec 41158910Srwatson#include <curses.priv.h> 42168855Sdes 43158910SrwatsonMODULE_ID("$Id: lib_window.c,v 1.31 2020/02/02 23:34:34 tom Exp $") 44158910Srwatson 45158910SrwatsonNCURSES_EXPORT(void) 46158910Srwatson_nc_synchook(WINDOW *win) 47158910Srwatson/* hook to be called after each window change */ 48158910Srwatson{ 49182903Smaxim if (win->_immed) 50158910Srwatson wrefresh(win); 51158910Srwatson if (win->_sync) 52158910Srwatson wsyncup(win); 53158910Srwatson} 54204294Sbrucec 55204294SbrucecNCURSES_EXPORT(int) 56204294Sbrucecmvderwin(WINDOW *win, int y, int x) 57204294Sbrucec/* move a derived window */ 58204294Sbrucec{ 59204294Sbrucec WINDOW *orig; 60158910Srwatson int rc = ERR; 61158910Srwatson 62168854Spjd T((T_CALLED("mvderwin(%p,%d,%d)"), (void *) win, y, x)); 63158910Srwatson 64158910Srwatson if (win != 0 65158910Srwatson && (orig = win->_parent) != 0 66204294Sbrucec && (x >= 0 && y >= 0) 67204294Sbrucec && (x + getmaxx(win) <= getmaxx(orig)) 68204294Sbrucec && (y + getmaxy(win) <= getmaxy(orig))) { 69204294Sbrucec int i; 70204294Sbrucec 71158910Srwatson wsyncup(win); 72158910Srwatson win->_parx = x; 73204294Sbrucec win->_pary = y; 74204294Sbrucec for (i = 0; i < getmaxy(win); i++) 75204294Sbrucec win->_line[i].text = &(orig->_line[y++].text[x]); 76204294Sbrucec rc = OK; 77255451Semaste } 78204294Sbrucec returnCode(rc); 79204294Sbrucec} 80255451Semaste 81255451SemasteNCURSES_EXPORT(int) 82255451Semastesyncok(WINDOW *win, bool bf) 83255451Semaste/* enable/disable automatic wsyncup() on each change to window */ 84158910Srwatson{ 85204294Sbrucec T((T_CALLED("syncok(%p,%d)"), (void *) win, bf)); 86204294Sbrucec 87204294Sbrucec if (win) { 88204294Sbrucec win->_sync = bf; 89204294Sbrucec returnCode(OK); 90204294Sbrucec } else 91204294Sbrucec returnCode(ERR); 92204294Sbrucec} 93204294Sbrucec 94204294SbrucecNCURSES_EXPORT(void) 95204294Sbrucecwsyncup(WINDOW *win) 96255451Semaste/* mark changed every cell in win's ancestors that is changed in win */ 97204294Sbrucec/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 98204294Sbrucec{ 99204294Sbrucec WINDOW *wp; 100204294Sbrucec 101158910Srwatson T((T_CALLED("wsyncup(%p)"), (void *) win)); 102204294Sbrucec if (win && win->_parent) { 103204294Sbrucec for (wp = win; wp->_parent; wp = wp->_parent) { 104158910Srwatson int y; 105158910Srwatson WINDOW *pp = wp->_parent; 106158910Srwatson 107204294Sbrucec assert((wp->_pary <= pp->_maxy) && 108158910Srwatson ((wp->_pary + wp->_maxy) <= pp->_maxy)); 109158910Srwatson 110158910Srwatson for (y = 0; y <= wp->_maxy; y++) { 111204294Sbrucec int left = wp->_line[y].firstchar; 112158910Srwatson if (left >= 0) { /* line is touched */ 113158910Srwatson struct ldat *line = &(pp->_line[wp->_pary + y]); 114158910Srwatson /* left & right character in parent window coordinates */ 115158910Srwatson int right = wp->_line[y].lastchar + wp->_parx; 116158910Srwatson left += wp->_parx; 117204294Sbrucec 118158910Srwatson CHANGED_RANGE(line, left, right); 119204294Sbrucec } 120204294Sbrucec } 121204294Sbrucec } 122204294Sbrucec } 123204294Sbrucec returnVoid; 124204294Sbrucec} 125204294Sbrucec 126204294SbrucecNCURSES_EXPORT(void) 127158910Srwatsonwsyncdown(WINDOW *win) 128158910Srwatson/* mark changed every cell in win that is changed in any of its ancestors */ 129158910Srwatson/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 130158910Srwatson{ 131158910Srwatson T((T_CALLED("wsyncdown(%p)"), (void *) win)); 132204294Sbrucec 133204294Sbrucec if (win && win->_parent) { 134204294Sbrucec WINDOW *pp = win->_parent; 135204294Sbrucec int y; 136158910Srwatson 137158910Srwatson /* This recursion guarantees, that the changes are propagated down- 138204294Sbrucec wards from the root to our direct parent. */ 139158910Srwatson wsyncdown(pp); 140158910Srwatson 141158910Srwatson /* and now we only have to propagate the changes from our direct 142158910Srwatson parent, if there are any. */ 143158910Srwatson assert((win->_pary <= pp->_maxy) && 144204294Sbrucec ((win->_pary + win->_maxy) <= pp->_maxy)); 145204294Sbrucec 146204294Sbrucec for (y = 0; y <= win->_maxy; y++) { 147158910Srwatson if (pp->_line[win->_pary + y].firstchar >= 0) { /* parent changed */ 148158910Srwatson struct ldat *line = &(win->_line[y]); 149204294Sbrucec /* left and right character in child coordinates */ 150204294Sbrucec int left = pp->_line[win->_pary + y].firstchar - win->_parx; 151158910Srwatson int right = pp->_line[win->_pary + y].lastchar - win->_parx; 152204294Sbrucec /* The change may be outside the child's range */ 153158910Srwatson if (left < 0) 154158910Srwatson left = 0; 155204294Sbrucec if (right > win->_maxx) 156204294Sbrucec right = win->_maxx; 157204294Sbrucec CHANGED_RANGE(line, left, right); 158158910Srwatson } 159158910Srwatson } 160204294Sbrucec } 161204294Sbrucec returnVoid; 162158910Srwatson} 163204294Sbrucec 164204294SbrucecNCURSES_EXPORT(void) 165158910Srwatsonwcursyncup(WINDOW *win) 166204294Sbrucec/* sync the cursor in all derived windows to its value in the base window */ 167204294Sbrucec{ 168158910Srwatson WINDOW *wp; 169158910Srwatson 170204294Sbrucec T((T_CALLED("wcursyncup(%p)"), (void *) win)); 171204294Sbrucec for (wp = win; wp && wp->_parent; wp = wp->_parent) { 172158910Srwatson wmove(wp->_parent, wp->_pary + wp->_cury, wp->_parx + wp->_curx); 173204294Sbrucec } 174204294Sbrucec returnVoid; 175158910Srwatson} 176204294Sbrucec 177204294SbrucecNCURSES_EXPORT(WINDOW *) 178204294Sbrucecdupwin(WINDOW *win) 179204294Sbrucec/* make an exact duplicate of the given window */ 180204294Sbrucec{ 181204294Sbrucec WINDOW *nwin = 0; 182204294Sbrucec 183204294Sbrucec T((T_CALLED("dupwin(%p)"), (void *) win)); 184204294Sbrucec 185158910Srwatson if (win != 0) { 186158910Srwatson#if NCURSES_SP_FUNCS 187158910Srwatson SCREEN *sp = _nc_screen_of(win); 188158910Srwatson#endif 189158910Srwatson _nc_lock_global(curses); 190204294Sbrucec if (win->_flags & _ISPAD) { 191204294Sbrucec nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx 192158910Srwatson win->_maxy + 1, 193204294Sbrucec win->_maxx + 1); 194204294Sbrucec } else { 195204294Sbrucec nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx 196204294Sbrucec win->_maxy + 1, 197204294Sbrucec win->_maxx + 1, 198204294Sbrucec win->_begy, 199204294Sbrucec win->_begx); 200204294Sbrucec } 201204294Sbrucec 202204294Sbrucec if (nwin != 0) { 203204294Sbrucec int i; 204204294Sbrucec size_t linesize; 205204294Sbrucec 206204294Sbrucec nwin->_curx = win->_curx; 207204294Sbrucec nwin->_cury = win->_cury; 208204294Sbrucec nwin->_maxy = win->_maxy; 209204294Sbrucec nwin->_maxx = win->_maxx; 210204294Sbrucec nwin->_begy = win->_begy; 211204294Sbrucec nwin->_begx = win->_begx; 212204294Sbrucec nwin->_yoffset = win->_yoffset; 213204294Sbrucec 214204294Sbrucec nwin->_flags = win->_flags & ~_SUBWIN; 215204294Sbrucec /* Due to the use of newwin(), the clone is not a subwindow. 216204294Sbrucec * The text is really copied into the clone. 217204294Sbrucec */ 218158910Srwatson 219158910Srwatson WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); 220204294Sbrucec nwin->_nc_bkgd = win->_nc_bkgd; 221204294Sbrucec 222204294Sbrucec nwin->_notimeout = win->_notimeout; 223204294Sbrucec nwin->_clear = win->_clear; 224204294Sbrucec nwin->_leaveok = win->_leaveok; 225204294Sbrucec nwin->_scroll = win->_scroll; 226158910Srwatson nwin->_idlok = win->_idlok; 227204294Sbrucec nwin->_idcok = win->_idcok; 228204294Sbrucec nwin->_immed = win->_immed; 229204294Sbrucec nwin->_sync = win->_sync; 230204294Sbrucec nwin->_use_keypad = win->_use_keypad; 231158910Srwatson nwin->_delay = win->_delay; 232158910Srwatson 233158910Srwatson nwin->_parx = 0; 234204294Sbrucec nwin->_pary = 0; 235158910Srwatson nwin->_parent = (WINDOW *) 0; 236158910Srwatson /* See above: the clone isn't a subwindow! */ 237204294Sbrucec 238158910Srwatson nwin->_regtop = win->_regtop; 239204294Sbrucec nwin->_regbottom = win->_regbottom; 240204294Sbrucec 241204294Sbrucec if (win->_flags & _ISPAD) 242158910Srwatson nwin->_pad = win->_pad; 243158910Srwatson 244158910Srwatson linesize = (unsigned) (win->_maxx + 1) * sizeof(NCURSES_CH_T); 245158910Srwatson for (i = 0; i <= nwin->_maxy; i++) { 246158910Srwatson memcpy(nwin->_line[i].text, win->_line[i].text, linesize); 247158910Srwatson nwin->_line[i].firstchar = win->_line[i].firstchar; 248158910Srwatson nwin->_line[i].lastchar = win->_line[i].lastchar; 249204294Sbrucec } 250204294Sbrucec } 251158910Srwatson _nc_unlock_global(curses); 252204294Sbrucec } 253158910Srwatson returnWin(nwin); 254158910Srwatson} 255158910Srwatson