1 /* $NetBSD: newwin.c,v 1.46 2008/04/14 20:33:15 jdc Exp $ */
4 * Copyright (c) 1981, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)newwin.c 8.3 (Berkeley) 7/27/94";
37 __RCSID("$NetBSD: newwin.c,v 1.46 2008/04/14 20:33:15 jdc Exp $");
44 #include "curses_private.h"
47 static WINDOW
*__makenew(SCREEN
*screen
, int nlines
, int ncols
, int by
,
48 int bx
, int sub
, int ispad
);
49 static WINDOW
*__subwin(WINDOW
*orig
, int nlines
, int ncols
, int by
, int bx
,
54 * Create a new window in the same manner as subwin but (by, bx)
55 * are relative to the origin of window orig instead of absolute.
58 derwin(WINDOW
*orig
, int nlines
, int ncols
, int by
, int bx
)
61 return __subwin(orig
, nlines
, ncols
, orig
->begy
+ by
, orig
->begx
+ bx
,
67 * Create a new pad in the same manner as subwin but (by, bx)
68 * are relative to the origin of window orig instead of absolute.
71 subpad(WINDOW
*orig
, int nlines
, int ncols
, int by
, int bx
)
74 return __subwin(orig
, nlines
, ncols
, orig
->begy
+ by
, orig
->begx
+ bx
,
80 * Create a copy of the given window.
87 if ((new_one
= __newwin(_cursesi_screen
, win
->maxy
, win
->maxx
,
88 win
->begy
, win
->begx
, FALSE
)) == NULL
)
91 overwrite(win
, new_one
);
97 * Allocate space for and set up defaults for a new window.
100 newwin(int nlines
, int ncols
, int by
, int bx
)
102 return __newwin(_cursesi_screen
, nlines
, ncols
, by
, bx
, FALSE
);
107 * Allocate space for and set up defaults for a new pad.
110 newpad(int nlines
, int ncols
)
112 if (nlines
< 1 || ncols
< 1)
114 return __newwin(_cursesi_screen
, nlines
, ncols
, 0, 0, TRUE
);
118 __newwin(SCREEN
*screen
, int nlines
, int ncols
, int by
, int bx
, int ispad
)
126 if (by
< 0 || bx
< 0)
129 maxy
= nlines
> 0 ? nlines
: LINES
- by
+ nlines
;
130 maxx
= ncols
> 0 ? ncols
: COLS
- bx
+ ncols
;
132 if ((win
= __makenew(screen
, maxy
, maxx
, by
, bx
, 0, ispad
)) == NULL
)
137 win
->battr
= __default_color
;
147 __CTRACE(__CTRACE_WINDOW
, "newwin: win->ch_off = %d\n", win
->ch_off
);
150 for (i
= 0; i
< maxy
; i
++) {
153 lp
->flags
= __ISDIRTY
;
156 for (sp
= lp
->line
, j
= 0; j
< maxx
; j
++, sp
++) {
161 sp
->ch
= ( wchar_t )btowc(( int ) win
->bch
);
164 #endif /* HAVE_WCHAR */
166 lp
->hash
= __hash((char *)(void *)lp
->line
,
167 (size_t) (ncols
* __LDATASIZE
));
173 subwin(WINDOW
*orig
, int nlines
, int ncols
, int by
, int bx
)
176 return __subwin(orig
, nlines
, ncols
, by
, bx
, FALSE
);
180 __subwin(WINDOW
*orig
, int nlines
, int ncols
, int by
, int bx
, int ispad
)
188 __CTRACE(__CTRACE_WINDOW
, "subwin: (%p, %d, %d, %d, %d, %d)\n",
189 orig
, nlines
, ncols
, by
, bx
, ispad
);
191 if (orig
== NULL
|| orig
->orig
!= NULL
)
194 /* Make sure window fits inside the original one. */
195 maxy
= nlines
> 0 ? nlines
: orig
->maxy
+ orig
->begy
- by
+ nlines
;
196 maxx
= ncols
> 0 ? ncols
: orig
->maxx
+ orig
->begx
- bx
+ ncols
;
197 if (by
< orig
->begy
|| bx
< orig
->begx
198 || by
+ maxy
> orig
->maxy
+ orig
->begy
199 || bx
+ maxx
> orig
->maxx
+ orig
->begx
)
201 if ((win
= __makenew(_cursesi_screen
, maxy
, maxx
,
202 by
, bx
, 1, ispad
)) == NULL
)
204 win
->bch
= orig
->bch
;
205 win
->battr
= orig
->battr
;
208 win
->nextp
= orig
->nextp
;
212 /* Initialize flags here so that refresh can also use __set_subwin. */
213 for (lp
= win
->lspace
, i
= 0; i
< win
->maxy
; i
++, lp
++)
215 __set_subwin(orig
, win
);
219 * This code is shared with mvwin().
222 __set_subwin(WINDOW
*orig
, WINDOW
*win
)
230 #endif /* HAVE_WCHAR */
232 win
->ch_off
= win
->begx
- orig
->begx
;
233 /* Point line pointers to line space. */
234 for (lp
= win
->lspace
, i
= 0; i
< win
->maxy
; i
++, lp
++) {
236 olp
= orig
->alines
[i
+ win
->begy
- orig
->begy
];
238 lp
->sentinel
= SENTINEL_VALUE
;
240 lp
->line
= &olp
->line
[win
->ch_off
];
241 lp
->firstchp
= &olp
->firstch
;
242 lp
->lastchp
= &olp
->lastch
;
244 lp
->hash
= __hash((char *)(void *)lp
->line
,
245 (size_t) (win
->maxx
* __LDATASIZE
));
247 for ( cp
= lp
->line
, j
= 0; j
< win
->maxx
; j
++, cp
++ ) {
248 lp
->hash
= __hash_more( &cp
->ch
,
249 sizeof( wchar_t ), lp
->hash
);
250 lp
->hash
= __hash_more( &cp
->attr
,
251 sizeof( wchar_t ), lp
->hash
);
255 lp
->hash
= __hash_more( &np
->ch
,
256 sizeof( wchar_t ), lp
->hash
);
261 #endif /* HAVE_WCHAR */
265 __CTRACE(__CTRACE_WINDOW
, "__set_subwin: win->ch_off = %d\n",
271 * Set up a window buffer and returns a pointer to it.
274 __makenew(SCREEN
*screen
, int nlines
, int ncols
, int by
, int bx
, int sub
,
279 struct __winlist
*wlp
, *wlp2
;
284 __CTRACE(__CTRACE_WINDOW
, "makenew: (%d, %d, %d, %d)\n",
285 nlines
, ncols
, by
, bx
);
287 if (nlines
<= 0 || ncols
<= 0)
290 if ((win
= malloc(sizeof(WINDOW
))) == NULL
)
293 __CTRACE(__CTRACE_WINDOW
, "makenew: win = %p\n", win
);
296 /* Set up line pointer array and line space. */
297 if ((win
->alines
= malloc(nlines
* sizeof(__LINE
*))) == NULL
) {
301 if ((win
->lspace
= malloc(nlines
* sizeof(__LINE
))) == NULL
) {
306 /* Don't allocate window and line space if it's a subwindow */
311 * Allocate window space in one chunk.
314 malloc(ncols
* nlines
* sizeof(__LDATA
))) == NULL
) {
321 * Append window to window list.
323 if ((wlp
= malloc(sizeof(struct __winlist
))) == NULL
) {
332 if (screen
->winlistp
== NULL
)
333 screen
->winlistp
= wlp
;
335 wlp2
= screen
->winlistp
;
336 while (wlp2
->nextp
!= NULL
)
341 * Point line pointers to line space, and lines themselves into
344 for (lp
= win
->lspace
, i
= 0; i
< nlines
; i
++, lp
++) {
346 lp
->line
= &win
->wspace
[i
* ncols
];
348 lp
->sentinel
= SENTINEL_VALUE
;
350 lp
->firstchp
= &lp
->firstch
;
351 lp
->lastchp
= &lp
->lastch
;
362 __CTRACE(__CTRACE_WINDOW
, "makenew: ncols = %d\n", ncols
);
364 win
->screen
= screen
;
365 win
->cury
= win
->curx
= 0;
373 win
->flags
= (__IDLINE
| __IDCHAR
);
378 SET_BGWCOL( *win
, 1 );
379 #endif /* HAVE_WCHAR */
381 win
->scr_b
= win
->maxy
- 1;
383 win
->flags
|= __ISPAD
;
393 __CTRACE(__CTRACE_WINDOW
, "makenew: win->wattr = %08x\n", win
->wattr
);
394 __CTRACE(__CTRACE_WINDOW
, "makenew: win->flags = %#.4x\n", win
->flags
);
395 __CTRACE(__CTRACE_WINDOW
, "makenew: win->maxy = %d\n", win
->maxy
);
396 __CTRACE(__CTRACE_WINDOW
, "makenew: win->maxx = %d\n", win
->maxx
);
397 __CTRACE(__CTRACE_WINDOW
, "makenew: win->begy = %d\n", win
->begy
);
398 __CTRACE(__CTRACE_WINDOW
, "makenew: win->begx = %d\n", win
->begx
);
399 __CTRACE(__CTRACE_WINDOW
, "makenew: win->scr_t = %d\n", win
->scr_t
);
400 __CTRACE(__CTRACE_WINDOW
, "makenew: win->scr_b = %d\n", win
->scr_b
);
406 __swflags(WINDOW
*win
)
408 win
->flags
&= ~(__ENDLINE
| __FULLWIN
| __SCROLLWIN
| __LEAVEOK
);
409 if (win
->begx
+ win
->maxx
== COLS
&& !(win
->flags
& __ISPAD
)) {
410 win
->flags
|= __ENDLINE
;
411 if (win
->begx
== 0 && win
->maxy
== LINES
&& win
->begy
== 0)
412 win
->flags
|= __FULLWIN
;
413 if (win
->begy
+ win
->maxy
== LINES
)
414 win
->flags
|= __SCROLLWIN
;