150276Speter/**************************************************************************** 2178866Srafan * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 3050276Speter * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 3150276Speter * and: Eric S. Raymond <esr@snark.thyrsus.com> * 3250276Speter ****************************************************************************/ 3350276Speter 3450276Speter/* 3550276Speter** lib_window.c 3650276Speter** 3750276Speter** 3850276Speter*/ 3950276Speter 4050276Speter#include <curses.priv.h> 4150276Speter 42184989SrafanMODULE_ID("$Id: lib_window.c,v 1.25 2008/06/07 14:12:56 tom Exp $") 4350276Speter 4476726SpeterNCURSES_EXPORT(void) 4576726Speter_nc_synchook(WINDOW *win) 4650276Speter/* hook to be called after each window change */ 4750276Speter{ 4876726Speter if (win->_immed) 4976726Speter wrefresh(win); 5076726Speter if (win->_sync) 5176726Speter wsyncup(win); 5250276Speter} 5350276Speter 5476726SpeterNCURSES_EXPORT(int) 5576726Spetermvderwin(WINDOW *win, int y, int x) 5650276Speter/* move a derived window */ 5750276Speter{ 5876726Speter WINDOW *orig; 5976726Speter int i; 6050276Speter 6176726Speter T((T_CALLED("mvderwin(%p,%d,%d)"), win, y, x)); 6250276Speter 6376726Speter if (win && (orig = win->_parent)) { 6476726Speter if (win->_parx == x && win->_pary == y) 6576726Speter returnCode(OK); 6676726Speter if (x < 0 || y < 0) 6776726Speter returnCode(ERR); 6876726Speter if ((x + getmaxx(win) > getmaxx(orig)) || 6976726Speter (y + getmaxy(win) > getmaxy(orig))) 7076726Speter returnCode(ERR); 7176726Speter } else 7250276Speter returnCode(ERR); 7376726Speter wsyncup(win); 7476726Speter win->_parx = x; 7576726Speter win->_pary = y; 7676726Speter for (i = 0; i < getmaxy(win); i++) 7776726Speter win->_line[i].text = &(orig->_line[y++].text[x]); 7876726Speter returnCode(OK); 7950276Speter} 8050276Speter 8176726SpeterNCURSES_EXPORT(int) 8276726Spetersyncok(WINDOW *win, bool bf) 8350276Speter/* enable/disable automatic wsyncup() on each change to window */ 8450276Speter{ 8576726Speter T((T_CALLED("syncok(%p,%d)"), win, bf)); 8650276Speter 8776726Speter if (win) { 8876726Speter win->_sync = bf; 8976726Speter returnCode(OK); 9076726Speter } else 9176726Speter returnCode(ERR); 9250276Speter} 9350276Speter 9476726SpeterNCURSES_EXPORT(void) 9576726Speterwsyncup(WINDOW *win) 9650276Speter/* mark changed every cell in win's ancestors that is changed in win */ 9750276Speter/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 9850276Speter{ 9976726Speter WINDOW *wp; 10050276Speter 10197049Speter T((T_CALLED("wsyncup(%p)"), win)); 10297049Speter if (win && win->_parent) { 10376726Speter for (wp = win; wp->_parent; wp = wp->_parent) { 10476726Speter int y; 10576726Speter WINDOW *pp = wp->_parent; 10650276Speter 10776726Speter assert((wp->_pary <= pp->_maxy) && 10876726Speter ((wp->_pary + wp->_maxy) <= pp->_maxy)); 10950276Speter 11076726Speter for (y = 0; y <= wp->_maxy; y++) { 11176726Speter int left = wp->_line[y].firstchar; 11276726Speter if (left >= 0) { /* line is touched */ 11376726Speter struct ldat *line = &(pp->_line[wp->_pary + y]); 11476726Speter /* left & right character in parent window coordinates */ 11576726Speter int right = wp->_line[y].lastchar + wp->_parx; 11676726Speter left += wp->_parx; 11750276Speter 11876726Speter CHANGED_RANGE(line, left, right); 11976726Speter } 12076726Speter } 12176726Speter } 12297049Speter } 12397049Speter returnVoid; 12450276Speter} 12550276Speter 12676726SpeterNCURSES_EXPORT(void) 12776726Speterwsyncdown(WINDOW *win) 12850276Speter/* mark changed every cell in win that is changed in any of its ancestors */ 12950276Speter/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ 13050276Speter{ 13197049Speter T((T_CALLED("wsyncdown(%p)"), win)); 13297049Speter 13376726Speter if (win && win->_parent) { 13476726Speter WINDOW *pp = win->_parent; 13576726Speter int y; 13650276Speter 13776726Speter /* This recursion guarantees, that the changes are propagated down- 13876726Speter wards from the root to our direct parent. */ 13976726Speter wsyncdown(pp); 14050276Speter 14176726Speter /* and now we only have to propagate the changes from our direct 14276726Speter parent, if there are any. */ 14376726Speter assert((win->_pary <= pp->_maxy) && 14476726Speter ((win->_pary + win->_maxy) <= pp->_maxy)); 14550276Speter 14676726Speter for (y = 0; y <= win->_maxy; y++) { 14776726Speter if (pp->_line[win->_pary + y].firstchar >= 0) { /* parent changed */ 14876726Speter struct ldat *line = &(win->_line[y]); 14976726Speter /* left and right character in child coordinates */ 15076726Speter int left = pp->_line[win->_pary + y].firstchar - win->_parx; 15176726Speter int right = pp->_line[win->_pary + y].lastchar - win->_parx; 152174993Srafan /* The change may be outside the child's range */ 15376726Speter if (left < 0) 15476726Speter left = 0; 15576726Speter if (right > win->_maxx) 15676726Speter right = win->_maxx; 15776726Speter CHANGED_RANGE(line, left, right); 15850276Speter } 15950276Speter } 16050276Speter } 16197049Speter returnVoid; 16250276Speter} 16350276Speter 16476726SpeterNCURSES_EXPORT(void) 16576726Speterwcursyncup(WINDOW *win) 16650276Speter/* sync the cursor in all derived windows to its value in the base window */ 16750276Speter{ 16876726Speter WINDOW *wp; 16997049Speter 17097049Speter T((T_CALLED("wcursyncup(%p)"), win)); 17176726Speter for (wp = win; wp && wp->_parent; wp = wp->_parent) { 17276726Speter wmove(wp->_parent, wp->_pary + wp->_cury, wp->_parx + wp->_curx); 17376726Speter } 17497049Speter returnVoid; 17550276Speter} 17650276Speter 17776726SpeterNCURSES_EXPORT(WINDOW *) 17876726Speterdupwin(WINDOW *win) 17950276Speter/* make an exact duplicate of the given window */ 18050276Speter{ 181166124Srafan WINDOW *nwin = 0; 18276726Speter size_t linesize; 18376726Speter int i; 18450276Speter 18576726Speter T((T_CALLED("dupwin(%p)"), win)); 18650276Speter 187166124Srafan if (win != 0) { 18850276Speter 189184989Srafan _nc_lock_global(curses); 190166124Srafan if (win->_flags & _ISPAD) { 191166124Srafan nwin = newpad(win->_maxy + 1, 192166124Srafan win->_maxx + 1); 193166124Srafan } else { 194166124Srafan nwin = newwin(win->_maxy + 1, 195166124Srafan win->_maxx + 1, 196166124Srafan win->_begy, 197166124Srafan win->_begx); 198166124Srafan } 19950276Speter 200166124Srafan if (nwin != 0) { 20150276Speter 202166124Srafan nwin->_curx = win->_curx; 203166124Srafan nwin->_cury = win->_cury; 204166124Srafan nwin->_maxy = win->_maxy; 205166124Srafan nwin->_maxx = win->_maxx; 206166124Srafan nwin->_begy = win->_begy; 207166124Srafan nwin->_begx = win->_begx; 208166124Srafan nwin->_yoffset = win->_yoffset; 20950276Speter 210166124Srafan nwin->_flags = win->_flags & ~_SUBWIN; 211166124Srafan /* Due to the use of newwin(), the clone is not a subwindow. 212166124Srafan * The text is really copied into the clone. 213166124Srafan */ 21450276Speter 215166124Srafan WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); 216166124Srafan nwin->_nc_bkgd = win->_nc_bkgd; 21750276Speter 218166124Srafan nwin->_notimeout = win->_notimeout; 219166124Srafan nwin->_clear = win->_clear; 220166124Srafan nwin->_leaveok = win->_leaveok; 221166124Srafan nwin->_scroll = win->_scroll; 222166124Srafan nwin->_idlok = win->_idlok; 223166124Srafan nwin->_idcok = win->_idcok; 224166124Srafan nwin->_immed = win->_immed; 225166124Srafan nwin->_sync = win->_sync; 226166124Srafan nwin->_use_keypad = win->_use_keypad; 227166124Srafan nwin->_delay = win->_delay; 22850276Speter 229166124Srafan nwin->_parx = 0; 230166124Srafan nwin->_pary = 0; 231166124Srafan nwin->_parent = (WINDOW *) 0; 232166124Srafan /* See above: the clone isn't a subwindow! */ 233166124Srafan 234166124Srafan nwin->_regtop = win->_regtop; 235166124Srafan nwin->_regbottom = win->_regbottom; 236166124Srafan 237166124Srafan if (win->_flags & _ISPAD) 238166124Srafan nwin->_pad = win->_pad; 239166124Srafan 240166124Srafan linesize = (win->_maxx + 1) * sizeof(NCURSES_CH_T); 241166124Srafan for (i = 0; i <= nwin->_maxy; i++) { 242166124Srafan memcpy(nwin->_line[i].text, win->_line[i].text, linesize); 243166124Srafan nwin->_line[i].firstchar = win->_line[i].firstchar; 244166124Srafan nwin->_line[i].lastchar = win->_line[i].lastchar; 245166124Srafan } 246166124Srafan } 247184989Srafan _nc_unlock_global(curses); 24876726Speter } 24976726Speter returnWin(nwin); 25050276Speter} 251