1 /* Public Domain Curses */
5 RCSID("$Id: window.c,v 1.62 2008/07/13 16:08:18 wmcbrine Exp $")
7 /*man-start**************************************************************
12 WINDOW *newwin(int nlines, int ncols, int begy, int begx);
13 WINDOW *derwin(WINDOW* orig, int nlines, int ncols,
15 WINDOW *subwin(WINDOW* orig, int nlines, int ncols,
17 WINDOW *dupwin(WINDOW *win);
18 int delwin(WINDOW *win);
19 int mvwin(WINDOW *win, int y, int x);
20 int mvderwin(WINDOW *win, int pary, int parx);
21 int syncok(WINDOW *win, bool bf);
22 void wsyncup(WINDOW *win);
23 void wcursyncup(WINDOW *win);
24 void wsyncdown(WINDOW *win);
26 WINDOW *resize_window(WINDOW *win, int nlines, int ncols);
27 int wresize(WINDOW *win, int nlines, int ncols);
28 WINDOW *PDC_makelines(WINDOW *win);
29 WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx);
30 void PDC_sync(WINDOW *win);
33 newwin() creates a new window with the given number of lines,
34 nlines and columns, ncols. The upper left corner of the window
35 is at line begy, column begx. If nlines is zero, it defaults to
36 LINES - begy; ncols to COLS - begx. Create a new full-screen
37 window by calling newwin(0, 0, 0, 0).
39 delwin() deletes the named window, freeing all associated
40 memory. In the case of overlapping windows, subwindows should be
41 deleted before the main window.
43 mvwin() moves the window so that the upper left-hand corner is
44 at position (y,x). If the move would cause the window to be off
45 the screen, it is an error and the window is not moved. Moving
46 subwindows is allowed.
48 subwin() creates a new subwindow within a window. The
49 dimensions of the subwindow are nlines lines and ncols columns.
50 The subwindow is at position (begy, begx) on the screen. This
51 position is relative to the screen, and not to the window orig.
52 Changes made to either window will affect both. When using this
53 routine, you will often need to call touchwin() before calling
56 derwin() is the same as subwin(), except that begy and begx are
57 relative to the origin of the window orig rather than the
58 screen. There is no difference between subwindows and derived
61 mvderwin() moves a derived window (or subwindow) inside its
62 parent window. The screen-relative parameters of the window are
63 not changed. This routine is used to display different parts of
64 the parent window at the same physical position on the screen.
66 dupwin() creates an exact duplicate of the window win.
68 wsyncup() causes a touchwin() of all of the window's parents.
70 If wsyncok() is called with a second argument of TRUE, this
71 causes a wsyncup() to be called every time the window is
74 wcursyncup() causes the current cursor position of all of a
75 window's ancestors to reflect the current cursor position of the
78 wsyncdown() causes a touchwin() of the current window if any of
79 its parent's windows have been touched.
81 resize_window() allows the user to resize an existing window. It
82 returns the pointer to the new window, or NULL on failure.
84 wresize() is an ncurses-compatible wrapper for resize_window().
85 Note that, unlike ncurses, it will NOT process any subwindows of
86 the window. (However, you still can call it _on_ subwindows.) It
89 PDC_makenew() allocates all data for a new WINDOW * except the
90 actual lines themselves. If it's unable to allocate memory for
91 the window structure, it will free all allocated memory and
92 return a NULL pointer.
94 PDC_makelines() allocates the memory for the lines.
96 PDC_sync() handles wrefresh() and wsyncup() calls when a window
100 newwin(), subwin(), derwin() and dupwin() return a pointer
101 to the new window, or NULL on failure. delwin(), mvwin(),
102 mvderwin() and syncok() return OK or ERR. wsyncup(),
103 wcursyncup() and wsyncdown() return nothing.
106 It is an error to call resize_window() before calling initscr().
107 Also, an error will be generated if we fail to create a newly
108 sized replacement window for curscr, or stdscr. This could
109 happen when increasing the window size. NOTE: If this happens,
110 the previously successfully allocated windows are left alone;
111 i.e., the resize is NOT cancelled for those windows.
113 Portability X/Open BSD SYS V
131 **man-end****************************************************************/
135 WINDOW
*PDC_makenew(int nlines
, int ncols
, int begy
, int begx
)
139 PDC_LOG(("PDC_makenew() - called: lines %d cols %d begy %d begx %d\n",
140 nlines
, ncols
, begy
, begx
));
142 /* allocate the window structure itself */
144 if ((win
= calloc(1, sizeof(WINDOW
))) == (WINDOW
*)NULL
)
147 /* allocate the line pointer array */
149 if ((win
->_y
= malloc(nlines
* sizeof(chtype
*))) == NULL
)
152 return (WINDOW
*)NULL
;
155 /* allocate the minchng and maxchng arrays */
157 if ((win
->_firstch
= malloc(nlines
* sizeof(int))) == NULL
)
161 return (WINDOW
*)NULL
;
164 if ((win
->_lastch
= malloc(nlines
* sizeof(int))) == NULL
)
169 return (WINDOW
*)NULL
;
172 /* initialize window variables */
174 win
->_maxy
= nlines
; /* real max screen size */
175 win
->_maxx
= ncols
; /* real max screen size */
178 win
->_bkgd
= ' '; /* wrs 4/10/93 -- initialize background to blank */
179 win
->_clear
= (bool) ((nlines
== LINES
) && (ncols
== COLS
));
180 win
->_bmarg
= nlines
- 1;
181 win
->_parx
= win
->_pary
= -1;
183 /* init to say window all changed */
190 WINDOW
*PDC_makelines(WINDOW
*win
)
192 int i
, j
, nlines
, ncols
;
194 PDC_LOG(("PDC_makelines() - called: lines %d cols %d\n", nlines
, ncols
));
197 return (WINDOW
*)NULL
;
202 for (i
= 0; i
< nlines
; i
++)
204 if ((win
->_y
[i
] = malloc(ncols
* sizeof(chtype
))) == NULL
)
206 /* if error, free all the data */
208 for (j
= 0; j
< i
; j
++)
216 return (WINDOW
*)NULL
;
223 void PDC_sync(WINDOW
*win
)
225 PDC_LOG(("PDC_sync() - called:\n"));
233 WINDOW
*newwin(int nlines
, int ncols
, int begy
, int begx
)
237 PDC_LOG(("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n",
238 nlines
, ncols
, begy
, begx
));
241 nlines
= LINES
- begy
;
245 if ( (begy
+ nlines
> SP
->lines
|| begx
+ ncols
> SP
->cols
)
246 || !(win
= PDC_makenew(nlines
, ncols
, begy
, begx
))
247 || !(win
= PDC_makelines(win
)) )
248 return (WINDOW
*)NULL
;
255 int delwin(WINDOW
*win
)
259 PDC_LOG(("delwin() - called\n"));
264 /* subwindows use parents' lines */
266 if (!(win
->_flags
& (_SUBWIN
|_SUBPAD
)))
267 for (i
= 0; i
< win
->_maxy
&& win
->_y
[i
]; i
++)
279 int mvwin(WINDOW
*win
, int y
, int x
)
281 PDC_LOG(("mvwin() - called\n"));
283 if (!win
|| (y
+ win
->_maxy
> LINES
|| y
< 0)
284 || (x
+ win
->_maxx
> COLS
|| x
< 0))
294 WINDOW
*subwin(WINDOW
*orig
, int nlines
, int ncols
, int begy
, int begx
)
299 PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n",
300 nlines
, ncols
, begy
, begx
));
302 /* make sure window fits inside the original one */
304 if (!orig
|| (begy
< orig
->_begy
) || (begx
< orig
->_begx
) ||
305 (begy
+ nlines
) > (orig
->_begy
+ orig
->_maxy
) ||
306 (begx
+ ncols
) > (orig
->_begx
+ orig
->_maxx
))
307 return (WINDOW
*)NULL
;
309 j
= begy
- orig
->_begy
;
310 k
= begx
- orig
->_begx
;
313 nlines
= orig
->_maxy
- 1 - j
;
315 ncols
= orig
->_maxx
- 1 - k
;
317 if ( !(win
= PDC_makenew(nlines
, ncols
, begy
, begx
)) )
318 return (WINDOW
*)NULL
;
320 /* initialize window variables */
322 win
->_attrs
= orig
->_attrs
;
323 win
->_bkgd
= orig
->_bkgd
;
324 win
->_leaveit
= orig
->_leaveit
;
325 win
->_scroll
= orig
->_scroll
;
326 win
->_nodelay
= orig
->_nodelay
;
327 win
->_use_keypad
= orig
->_use_keypad
;
328 win
->_immed
= orig
->_immed
;
329 win
->_sync
= orig
->_sync
;
334 for (i
= 0; i
< nlines
; i
++, j
++)
335 win
->_y
[i
] = orig
->_y
[j
] + k
;
337 win
->_flags
|= _SUBWIN
;
342 WINDOW
*derwin(WINDOW
*orig
, int nlines
, int ncols
, int begy
, int begx
)
344 return subwin(orig
, nlines
, ncols
, begy
+ orig
->_begy
, begx
+ orig
->_begx
);
347 int mvderwin(WINDOW
*win
, int pary
, int parx
)
352 if (!win
|| !(win
->_parent
))
355 mypar
= win
->_parent
;
357 if (pary
< 0 || parx
< 0 || (pary
+ win
->_maxy
) > mypar
->_maxy
||
358 (parx
+ win
->_maxx
) > mypar
->_maxx
)
363 for (i
= 0; i
< win
->_maxy
; i
++)
364 win
->_y
[i
] = (mypar
->_y
[j
++]) + parx
;
372 WINDOW
*dupwin(WINDOW
*win
)
376 int nlines
, ncols
, begy
, begx
, i
;
379 return (WINDOW
*)NULL
;
386 if ( !(new = PDC_makenew(nlines
, ncols
, begy
, begx
))
387 || !(new = PDC_makelines(new)) )
388 return (WINDOW
*)NULL
;
390 /* copy the contents of win into new */
392 for (i
= 0; i
< nlines
; i
++)
394 for (ptr
= new->_y
[i
], ptr1
= win
->_y
[i
];
395 ptr
< new->_y
[i
] + ncols
; ptr
++, ptr1
++)
398 new->_firstch
[i
] = 0;
399 new->_lastch
[i
] = ncols
- 1;
402 new->_curx
= win
->_curx
;
403 new->_cury
= win
->_cury
;
404 new->_maxy
= win
->_maxy
;
405 new->_maxx
= win
->_maxx
;
406 new->_begy
= win
->_begy
;
407 new->_begx
= win
->_begx
;
408 new->_flags
= win
->_flags
;
409 new->_attrs
= win
->_attrs
;
410 new->_clear
= win
->_clear
;
411 new->_leaveit
= win
->_leaveit
;
412 new->_scroll
= win
->_scroll
;
413 new->_nodelay
= win
->_nodelay
;
414 new->_use_keypad
= win
->_use_keypad
;
415 new->_tmarg
= win
->_tmarg
;
416 new->_bmarg
= win
->_bmarg
;
417 new->_parx
= win
->_parx
;
418 new->_pary
= win
->_pary
;
419 new->_parent
= win
->_parent
;
420 new->_bkgd
= win
->_bkgd
;
421 new->_flags
= win
->_flags
;
426 WINDOW
*resize_window(WINDOW
*win
, int nlines
, int ncols
)
429 int i
, save_cury
, save_curx
, new_begy
, new_begx
;
431 PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
435 return (WINDOW
*)NULL
;
437 if (win
->_flags
& _SUBPAD
)
439 if ( !(new = subpad(win
->_parent
, nlines
, ncols
,
440 win
->_begy
, win
->_begx
)) )
441 return (WINDOW
*)NULL
;
443 else if (win
->_flags
& _SUBWIN
)
445 if ( !(new = subwin(win
->_parent
, nlines
, ncols
,
446 win
->_begy
, win
->_begx
)) )
447 return (WINDOW
*)NULL
;
451 if (win
== SP
->slk_winptr
)
453 new_begy
= SP
->lines
- SP
->slklines
;
458 new_begy
= win
->_begy
;
459 new_begx
= win
->_begx
;
462 if ( !(new = PDC_makenew(nlines
, ncols
, new_begy
, new_begx
)) )
463 return (WINDOW
*)NULL
;
466 save_curx
= min(win
->_curx
, new->_maxx
);
467 save_cury
= min(win
->_cury
, new->_maxy
);
469 if (!(win
->_flags
& (_SUBPAD
|_SUBWIN
)))
471 if ( !(new = PDC_makelines(new)) )
472 return (WINDOW
*)NULL
;
476 copywin(win
, new, 0, 0, 0, 0, min(win
->_maxy
, new->_maxy
) - 1,
477 min(win
->_maxx
, new->_maxx
) - 1, FALSE
);
479 for (i
= 0; i
< win
->_maxy
&& win
->_y
[i
]; i
++)
484 new->_flags
= win
->_flags
;
485 new->_attrs
= win
->_attrs
;
486 new->_clear
= win
->_clear
;
487 new->_leaveit
= win
->_leaveit
;
488 new->_scroll
= win
->_scroll
;
489 new->_nodelay
= win
->_nodelay
;
490 new->_use_keypad
= win
->_use_keypad
;
491 new->_tmarg
= (win
->_tmarg
> new->_maxy
- 1) ? 0 : win
->_tmarg
;
492 new->_bmarg
= (win
->_bmarg
== win
->_maxy
- 1) ?
493 new->_maxy
- 1 : min(win
->_bmarg
, (new->_maxy
- 1));
494 new->_parent
= win
->_parent
;
495 new->_immed
= win
->_immed
;
496 new->_sync
= win
->_sync
;
497 new->_bkgd
= win
->_bkgd
;
499 new->_curx
= save_curx
;
500 new->_cury
= save_cury
;
512 int wresize(WINDOW
*win
, int nlines
, int ncols
)
514 return (resize_window(win
, nlines
, ncols
) ? OK
: ERR
);
517 void wsyncup(WINDOW
*win
)
521 PDC_LOG(("wsyncup() - called\n"));
523 for (tmp
= win
; tmp
; tmp
= tmp
->_parent
)
527 int syncok(WINDOW
*win
, bool bf
)
529 PDC_LOG(("syncok() - called\n"));
539 void wcursyncup(WINDOW
*win
)
543 PDC_LOG(("wcursyncup() - called\n"));
545 for (tmp
= win
; tmp
&& tmp
->_parent
; tmp
= tmp
->_parent
)
546 wmove(tmp
->_parent
, tmp
->_pary
+ tmp
->_cury
, tmp
->_parx
+ tmp
->_curx
);
549 void wsyncdown(WINDOW
*win
)
553 PDC_LOG(("wsyncdown() - called\n"));
555 for (tmp
= win
; tmp
; tmp
= tmp
->_parent
)
557 if (is_wintouched(tmp
))