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)
298 int j = begy - orig->_begy;
299 int k = begx - orig->_begx;
301 PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n",
302 nlines, ncols, begy, begx));
304 /* make sure window fits inside the original one */
306 if (!orig || (begy < orig->_begy) || (begx < orig->_begx) ||
307 (begy + nlines) > (orig->_begy + orig->_maxy) ||
308 (begx + ncols) > (orig->_begx + orig->_maxx))
309 return (WINDOW *)NULL;
312 nlines = orig->_maxy - 1 - j;
314 ncols = orig->_maxx - 1 - k;
316 if ( !(win = PDC_makenew(nlines, ncols, begy, begx)) )
317 return (WINDOW *)NULL;
319 /* initialize window variables */
321 win->_attrs = orig->_attrs;
322 win->_bkgd = orig->_bkgd;
323 win->_leaveit = orig->_leaveit;
324 win->_scroll = orig->_scroll;
325 win->_nodelay = orig->_nodelay;
326 win->_use_keypad = orig->_use_keypad;
327 win->_immed = orig->_immed;
328 win->_sync = orig->_sync;
333 for (i = 0; i < nlines; i++, j++)
334 win->_y[i] = orig->_y[j] + k;
336 win->_flags |= _SUBWIN;
341 WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
343 return subwin(orig, nlines, ncols, begy + orig->_begy, begx + orig->_begx);
346 int mvderwin(WINDOW *win, int pary, int parx)
351 if (!win || !(win->_parent))
354 mypar = win->_parent;
356 if (pary < 0 || parx < 0 || (pary + win->_maxy) > mypar->_maxy ||
357 (parx + win->_maxx) > mypar->_maxx)
362 for (i = 0; i < win->_maxy; i++)
363 win->_y[i] = (mypar->_y[j++]) + parx;
371 WINDOW *dupwin(WINDOW *win)
375 int nlines, ncols, begy, begx, i;
378 return (WINDOW *)NULL;
385 if ( !(new = PDC_makenew(nlines, ncols, begy, begx))
386 || !(new = PDC_makelines(new)) )
387 return (WINDOW *)NULL;
389 /* copy the contents of win into new */
391 for (i = 0; i < nlines; i++)
393 for (ptr = new->_y[i], ptr1 = win->_y[i];
394 ptr < new->_y[i] + ncols; ptr++, ptr1++)
397 new->_firstch[i] = 0;
398 new->_lastch[i] = ncols - 1;
401 new->_curx = win->_curx;
402 new->_cury = win->_cury;
403 new->_maxy = win->_maxy;
404 new->_maxx = win->_maxx;
405 new->_begy = win->_begy;
406 new->_begx = win->_begx;
407 new->_flags = win->_flags;
408 new->_attrs = win->_attrs;
409 new->_clear = win->_clear;
410 new->_leaveit = win->_leaveit;
411 new->_scroll = win->_scroll;
412 new->_nodelay = win->_nodelay;
413 new->_use_keypad = win->_use_keypad;
414 new->_tmarg = win->_tmarg;
415 new->_bmarg = win->_bmarg;
416 new->_parx = win->_parx;
417 new->_pary = win->_pary;
418 new->_parent = win->_parent;
419 new->_bkgd = win->_bkgd;
420 new->_flags = win->_flags;
425 WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
428 int i, save_cury, save_curx, new_begy, new_begx;
430 PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
434 return (WINDOW *)NULL;
436 if (win->_flags & _SUBPAD)
438 if ( !(new = subpad(win->_parent, nlines, ncols,
439 win->_begy, win->_begx)) )
440 return (WINDOW *)NULL;
442 else if (win->_flags & _SUBWIN)
444 if ( !(new = subwin(win->_parent, nlines, ncols,
445 win->_begy, win->_begx)) )
446 return (WINDOW *)NULL;
450 if (win == SP->slk_winptr)
452 new_begy = SP->lines - SP->slklines;
457 new_begy = win->_begy;
458 new_begx = win->_begx;
461 if ( !(new = PDC_makenew(nlines, ncols, new_begy, new_begx)) )
462 return (WINDOW *)NULL;
465 save_curx = min(win->_curx, new->_maxx);
466 save_cury = min(win->_cury, new->_maxy);
468 if (!(win->_flags & (_SUBPAD|_SUBWIN)))
470 if ( !(new = PDC_makelines(new)) )
471 return (WINDOW *)NULL;
475 copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1,
476 min(win->_maxx, new->_maxx) - 1, FALSE);
478 for (i = 0; i < win->_maxy && win->_y[i]; i++)
483 new->_flags = win->_flags;
484 new->_attrs = win->_attrs;
485 new->_clear = win->_clear;
486 new->_leaveit = win->_leaveit;
487 new->_scroll = win->_scroll;
488 new->_nodelay = win->_nodelay;
489 new->_use_keypad = win->_use_keypad;
490 new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg;
491 new->_bmarg = (win->_bmarg == win->_maxy - 1) ?
492 new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1));
493 new->_parent = win->_parent;
494 new->_immed = win->_immed;
495 new->_sync = win->_sync;
496 new->_bkgd = win->_bkgd;
498 new->_curx = save_curx;
499 new->_cury = save_cury;
511 int wresize(WINDOW *win, int nlines, int ncols)
513 return (resize_window(win, nlines, ncols) ? OK : ERR);
516 void wsyncup(WINDOW *win)
520 PDC_LOG(("wsyncup() - called\n"));
522 for (tmp = win; tmp; tmp = tmp->_parent)
526 int syncok(WINDOW *win, bool bf)
528 PDC_LOG(("syncok() - called\n"));
538 void wcursyncup(WINDOW *win)
542 PDC_LOG(("wcursyncup() - called\n"));
544 for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent)
545 wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx);
548 void wsyncdown(WINDOW *win)
552 PDC_LOG(("wsyncdown() - called\n"));
554 for (tmp = win; tmp; tmp = tmp->_parent)
556 if (is_wintouched(tmp))