Back to index

tetex-bin  3.0
lib_newwin.c
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Copyright (c) 1998-2002,2004 Free Software Foundation, Inc.              *
00003  *                                                                          *
00004  * Permission is hereby granted, free of charge, to any person obtaining a  *
00005  * copy of this software and associated documentation files (the            *
00006  * "Software"), to deal in the Software without restriction, including      *
00007  * without limitation the rights to use, copy, modify, merge, publish,      *
00008  * distribute, distribute with modifications, sublicense, and/or sell       *
00009  * copies of the Software, and to permit persons to whom the Software is    *
00010  * furnished to do so, subject to the following conditions:                 *
00011  *                                                                          *
00012  * The above copyright notice and this permission notice shall be included  *
00013  * in all copies or substantial portions of the Software.                   *
00014  *                                                                          *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00018  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00020  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00021  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00022  *                                                                          *
00023  * Except as contained in this notice, the name(s) of the above copyright   *
00024  * holders shall not be used in advertising or otherwise to promote the     *
00025  * sale, use or other dealings in this Software without prior written       *
00026  * authorization.                                                           *
00027  ****************************************************************************/
00028 
00029 /****************************************************************************
00030  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
00031  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
00032  ****************************************************************************/
00033 
00034 /*
00035 **     lib_newwin.c
00036 **
00037 **     The routines newwin(), subwin() and their dependent
00038 **
00039 */
00040 
00041 #include <curses.priv.h>
00042 
00043 MODULE_ID("$Id: lib_newwin.c,v 1.35 2004/04/10 23:42:00 tom Exp $")
00044 
00045 static WINDOW *
00046 remove_window_from_screen(WINDOW *win)
00047 {
00048     SCREEN **scan = &_nc_screen_chain;
00049 
00050     while (*scan) {
00051        SCREEN *sp = *scan;
00052        if (sp->_curscr == win) {
00053            sp->_curscr = 0;
00054            if (win == curscr)
00055               curscr = 0;
00056        } else if (sp->_stdscr == win) {
00057            sp->_stdscr = 0;
00058            if (win == stdscr)
00059               stdscr = 0;
00060        } else if (sp->_newscr == win) {
00061            sp->_newscr = 0;
00062            if (win == newscr)
00063               newscr = 0;
00064        } else {
00065            scan = &(*scan)->_next_screen;
00066            continue;
00067        }
00068        break;
00069     }
00070 
00071     return 0;
00072 }
00073 
00074 NCURSES_EXPORT(int)
00075 _nc_freewin(WINDOW *win)
00076 {
00077     WINDOWLIST *p, *q;
00078     int i;
00079     int result = ERR;
00080 
00081     if (win != 0) {
00082        for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) {
00083            if (&(p->win) == win) {
00084               remove_window_from_screen(win);
00085               if (q == 0)
00086                   _nc_windows = p->next;
00087               else
00088                   q->next = p->next;
00089 
00090               if (!(win->_flags & _SUBWIN)) {
00091                   for (i = 0; i <= win->_maxy; i++)
00092                      FreeIfNeeded(win->_line[i].text);
00093               }
00094               free(win->_line);
00095               free(p);
00096 
00097               result = OK;
00098               T(("...deleted win=%p", win));
00099               break;
00100            }
00101        }
00102     }
00103     return result;
00104 }
00105 
00106 NCURSES_EXPORT(WINDOW *)
00107 newwin(int num_lines, int num_columns, int begy, int begx)
00108 {
00109     WINDOW *win;
00110     NCURSES_CH_T *ptr;
00111     int i;
00112 
00113     T((T_CALLED("newwin(%d,%d,%d,%d)"), num_lines, num_columns, begy, begx));
00114 
00115     if (begy < 0 || begx < 0 || num_lines < 0 || num_columns < 0)
00116        returnWin(0);
00117 
00118     if (num_lines == 0)
00119        num_lines = SP->_lines_avail - begy;
00120     if (num_columns == 0)
00121        num_columns = screen_columns - begx;
00122 
00123     if ((win = _nc_makenew(num_lines, num_columns, begy, begx, 0)) == 0)
00124        returnWin(0);
00125 
00126     for (i = 0; i < num_lines; i++) {
00127        win->_line[i].text = typeCalloc(NCURSES_CH_T, (unsigned) num_columns);
00128        if (win->_line[i].text == 0) {
00129            (void) _nc_freewin(win);
00130            returnWin(0);
00131        }
00132        for (ptr = win->_line[i].text;
00133             ptr < win->_line[i].text + num_columns;
00134             ptr++)
00135            SetChar(*ptr, BLANK_TEXT, BLANK_ATTR);
00136     }
00137 
00138     returnWin(win);
00139 }
00140 
00141 NCURSES_EXPORT(WINDOW *)
00142 derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
00143 {
00144     WINDOW *win;
00145     int i;
00146     int flags = _SUBWIN;
00147 
00148     T((T_CALLED("derwin(%p,%d,%d,%d,%d)"), orig, num_lines, num_columns,
00149        begy, begx));
00150 
00151     /*
00152      * make sure window fits inside the original one
00153      */
00154     if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0 || num_columns < 0)
00155        returnWin(0);
00156     if (begy + num_lines > orig->_maxy + 1
00157        || begx + num_columns > orig->_maxx + 1)
00158        returnWin(0);
00159 
00160     if (num_lines == 0)
00161        num_lines = orig->_maxy + 1 - begy;
00162 
00163     if (num_columns == 0)
00164        num_columns = orig->_maxx + 1 - begx;
00165 
00166     if (orig->_flags & _ISPAD)
00167        flags |= _ISPAD;
00168 
00169     if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
00170                         orig->_begx + begx, flags)) == 0)
00171        returnWin(0);
00172 
00173     win->_pary = begy;
00174     win->_parx = begx;
00175     win->_attrs = orig->_attrs;
00176     win->_nc_bkgd = orig->_nc_bkgd;
00177 
00178     for (i = 0; i < num_lines; i++)
00179        win->_line[i].text = &orig->_line[begy++].text[begx];
00180 
00181     win->_parent = orig;
00182 
00183     returnWin(win);
00184 }
00185 
00186 NCURSES_EXPORT(WINDOW *)
00187 subwin(WINDOW *w, int l, int c, int y, int x)
00188 {
00189     T((T_CALLED("subwin(%p, %d, %d, %d, %d)"), w, l, c, y, x));
00190     T(("parent has begy = %d, begx = %d", w->_begy, w->_begx));
00191 
00192     returnWin(derwin(w, l, c, y - w->_begy, x - w->_begx));
00193 }
00194 
00195 static bool
00196 dimension_limit(int value)
00197 {
00198     NCURSES_SIZE_T test = value;
00199     return (test == value && value > 0);
00200 }
00201 
00202 NCURSES_EXPORT(WINDOW *)
00203 _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags)
00204 {
00205     int i;
00206     WINDOWLIST *wp;
00207     WINDOW *win;
00208     bool is_pad = (flags & _ISPAD);
00209 
00210     T(("_nc_makenew(%d,%d,%d,%d)", num_lines, num_columns, begy, begx));
00211 
00212     if (!dimension_limit(num_lines) || !dimension_limit(num_columns))
00213        return 0;
00214 
00215     if ((wp = typeCalloc(WINDOWLIST, 1)) == 0)
00216        return 0;
00217 
00218     win = &(wp->win);
00219 
00220     if ((win->_line = typeCalloc(struct ldat, ((unsigned) num_lines))) == 0) {
00221        free(win);
00222        return 0;
00223     }
00224 
00225     win->_curx = 0;
00226     win->_cury = 0;
00227     win->_maxy = num_lines - 1;
00228     win->_maxx = num_columns - 1;
00229     win->_begy = begy;
00230     win->_begx = begx;
00231     win->_yoffset = SP->_topstolen;
00232 
00233     win->_flags = flags;
00234     win->_attrs = A_NORMAL;
00235     SetChar(win->_nc_bkgd, BLANK_TEXT, BLANK_ATTR);
00236 
00237     win->_clear = is_pad ? FALSE : (num_lines == screen_lines
00238                                 && num_columns == screen_columns);
00239     win->_idlok = FALSE;
00240     win->_idcok = TRUE;
00241     win->_scroll = FALSE;
00242     win->_leaveok = FALSE;
00243     win->_use_keypad = FALSE;
00244     win->_delay = -1;
00245     win->_immed = FALSE;
00246     win->_sync = 0;
00247     win->_parx = -1;
00248     win->_pary = -1;
00249     win->_parent = 0;
00250 
00251     win->_regtop = 0;
00252     win->_regbottom = num_lines - 1;
00253 
00254     win->_pad._pad_y = -1;
00255     win->_pad._pad_x = -1;
00256     win->_pad._pad_top = -1;
00257     win->_pad._pad_bottom = -1;
00258     win->_pad._pad_left = -1;
00259     win->_pad._pad_right = -1;
00260 
00261     for (i = 0; i < num_lines; i++) {
00262        /*
00263         * This used to do
00264         *
00265         * win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE;
00266         *
00267         * which marks the whole window unchanged.  That's how
00268         * SVr1 curses did it, but SVr4 curses marks the whole new
00269         * window changed.
00270         *
00271         * With the old SVr1-like code, say you have stdscr full of
00272         * characters, then create a new window with newwin(),
00273         * then do a printw(win, "foo        ");, the trailing spaces are
00274         * completely ignored by the following refreshes.  So, you
00275         * get "foojunkjunk" on the screen instead of "foo        " as
00276         * you actually intended.
00277         *
00278         * SVr4 doesn't do this.  Instead the spaces are actually written.
00279         * So that's how we want ncurses to behave.
00280         */
00281        win->_line[i].firstchar = 0;
00282        win->_line[i].lastchar = num_columns - 1;
00283 
00284        if_USE_SCROLL_HINTS(win->_line[i].oldindex = i);
00285     }
00286 
00287     if (!is_pad && (begx + num_columns == screen_columns)) {
00288        win->_flags |= _ENDLINE;
00289 
00290        if (begx == 0 && num_lines == screen_lines && begy == 0)
00291            win->_flags |= _FULLWIN;
00292 
00293        if (begy + num_lines == screen_lines)
00294            win->_flags |= _SCROLLWIN;
00295     }
00296 
00297     wp->next = _nc_windows;
00298     _nc_windows = wp;
00299 
00300     T((T_CREATE("window %p"), win));
00301 
00302     return (win);
00303 }