Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 1 | /**************************************************************************** |
| 2 | * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * |
| 3 | * * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a * |
| 5 | * copy of this software and associated documentation files (the * |
| 6 | * "Software"), to deal in the Software without restriction, including * |
| 7 | * without limitation the rights to use, copy, modify, merge, publish, * |
| 8 | * distribute, distribute with modifications, sublicense, and/or sell * |
| 9 | * copies of the Software, and to permit persons to whom the Software is * |
| 10 | * furnished to do so, subject to the following conditions: * |
| 11 | * * |
| 12 | * The above copyright notice and this permission notice shall be included * |
| 13 | * in all copies or substantial portions of the Software. * |
| 14 | * * |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * |
| 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * |
| 18 | * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * |
| 19 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * |
| 20 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * |
| 21 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * |
| 22 | * * |
| 23 | * Except as contained in this notice, the name(s) of the above copyright * |
| 24 | * holders shall not be used in advertising or otherwise to promote the * |
| 25 | * sale, use or other dealings in this Software without prior written * |
| 26 | * authorization. * |
| 27 | ****************************************************************************/ |
| 28 | |
| 29 | /**************************************************************************** |
| 30 | * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * |
| 31 | * and: Eric S. Raymond <esr@snark.thyrsus.com> * |
| 32 | ****************************************************************************/ |
| 33 | |
| 34 | /* |
| 35 | ** lib_window.c |
| 36 | ** |
| 37 | ** |
| 38 | */ |
| 39 | |
| 40 | #include <curses.priv.h> |
| 41 | |
| 42 | MODULE_ID("$Id: lib_window.c,v 1.25 2008/06/07 14:12:56 tom Exp $") |
| 43 | |
| 44 | NCURSES_EXPORT(void) |
| 45 | _nc_synchook(WINDOW *win) |
| 46 | /* hook to be called after each window change */ |
| 47 | { |
| 48 | if (win->_immed) |
| 49 | wrefresh(win); |
| 50 | if (win->_sync) |
| 51 | wsyncup(win); |
| 52 | } |
| 53 | |
| 54 | NCURSES_EXPORT(int) |
| 55 | mvderwin(WINDOW *win, int y, int x) |
| 56 | /* move a derived window */ |
| 57 | { |
| 58 | WINDOW *orig; |
| 59 | int i; |
| 60 | |
| 61 | T((T_CALLED("mvderwin(%p,%d,%d)"), win, y, x)); |
| 62 | |
| 63 | if (win && (orig = win->_parent)) { |
| 64 | if (win->_parx == x && win->_pary == y) |
| 65 | returnCode(OK); |
| 66 | if (x < 0 || y < 0) |
| 67 | returnCode(ERR); |
| 68 | if ((x + getmaxx(win) > getmaxx(orig)) || |
| 69 | (y + getmaxy(win) > getmaxy(orig))) |
| 70 | returnCode(ERR); |
| 71 | } else |
| 72 | returnCode(ERR); |
| 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 | returnCode(OK); |
| 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)"), 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)"), 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)"), 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)"), 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 | size_t linesize; |
| 183 | int i; |
| 184 | |
| 185 | T((T_CALLED("dupwin(%p)"), win)); |
| 186 | |
| 187 | if (win != 0) { |
| 188 | |
| 189 | _nc_lock_global(curses); |
| 190 | if (win->_flags & _ISPAD) { |
| 191 | nwin = newpad(win->_maxy + 1, |
| 192 | win->_maxx + 1); |
| 193 | } else { |
| 194 | nwin = newwin(win->_maxy + 1, |
| 195 | win->_maxx + 1, |
| 196 | win->_begy, |
| 197 | win->_begx); |
| 198 | } |
| 199 | |
| 200 | if (nwin != 0) { |
| 201 | |
| 202 | nwin->_curx = win->_curx; |
| 203 | nwin->_cury = win->_cury; |
| 204 | nwin->_maxy = win->_maxy; |
| 205 | nwin->_maxx = win->_maxx; |
| 206 | nwin->_begy = win->_begy; |
| 207 | nwin->_begx = win->_begx; |
| 208 | nwin->_yoffset = win->_yoffset; |
| 209 | |
| 210 | nwin->_flags = win->_flags & ~_SUBWIN; |
| 211 | /* Due to the use of newwin(), the clone is not a subwindow. |
| 212 | * The text is really copied into the clone. |
| 213 | */ |
| 214 | |
| 215 | WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); |
| 216 | nwin->_nc_bkgd = win->_nc_bkgd; |
| 217 | |
| 218 | nwin->_notimeout = win->_notimeout; |
| 219 | nwin->_clear = win->_clear; |
| 220 | nwin->_leaveok = win->_leaveok; |
| 221 | nwin->_scroll = win->_scroll; |
| 222 | nwin->_idlok = win->_idlok; |
| 223 | nwin->_idcok = win->_idcok; |
| 224 | nwin->_immed = win->_immed; |
| 225 | nwin->_sync = win->_sync; |
| 226 | nwin->_use_keypad = win->_use_keypad; |
| 227 | nwin->_delay = win->_delay; |
| 228 | |
| 229 | nwin->_parx = 0; |
| 230 | nwin->_pary = 0; |
| 231 | nwin->_parent = (WINDOW *) 0; |
| 232 | /* See above: the clone isn't a subwindow! */ |
| 233 | |
| 234 | nwin->_regtop = win->_regtop; |
| 235 | nwin->_regbottom = win->_regbottom; |
| 236 | |
| 237 | if (win->_flags & _ISPAD) |
| 238 | nwin->_pad = win->_pad; |
| 239 | |
| 240 | linesize = (win->_maxx + 1) * sizeof(NCURSES_CH_T); |
| 241 | for (i = 0; i <= nwin->_maxy; i++) { |
| 242 | memcpy(nwin->_line[i].text, win->_line[i].text, linesize); |
| 243 | nwin->_line[i].firstchar = win->_line[i].firstchar; |
| 244 | nwin->_line[i].lastchar = win->_line[i].lastchar; |
| 245 | } |
| 246 | } |
| 247 | _nc_unlock_global(curses); |
| 248 | } |
| 249 | returnWin(nwin); |
| 250 | } |