Skip to content

Commit

Permalink
The X/Open Curses standard requires that delwin() delete subwindows b…
Browse files Browse the repository at this point in the history
…efore deleting the parent, and implicitly requires delscreen() to delete windows associated with a SCREEN. We now do that.
  • Loading branch information
Bill-Gray committed Aug 5, 2022
1 parent dedaa02 commit 3b14813
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 8 deletions.
2 changes: 2 additions & 0 deletions curspriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ struct _opaque_screen_t
bool default_colors;
hash_idx_t *pair_hash_tbl;
int pair_hash_tbl_size, pair_hash_tbl_used;
int n_windows;
WINDOW **window_list;
};

#endif /* __CURSES_INTERNALS__ */
5 changes: 4 additions & 1 deletion pdcurses/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,10 @@ void PDC_free_atrtab(void)
free( SP->opaque->pair_hash_tbl);
SP->opaque->pair_hash_tbl = NULL;
SP->opaque->pair_hash_tbl_size = SP->opaque->pair_hash_tbl_used = 0;
free( SP->opaque->pairs);
if( SP->opaque->pairs)
free( SP->opaque->pairs);
if( SP->opaque->window_list)
free( SP->opaque->window_list);
free( SP->opaque);
SP->opaque = NULL;
}
Expand Down
12 changes: 6 additions & 6 deletions pdcurses/initscr.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ WINDOW *initscr(void)
LINES = SP->lines = PDC_get_rows();
COLS = SP->cols = PDC_get_columns();

if( PDC_init_atrtab()) /* set up default colors */
return NULL;

if (LINES < 2 || COLS < 2)
{
fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",
Expand Down Expand Up @@ -268,8 +271,6 @@ WINDOW *initscr(void)
else
curscr->_clear = TRUE;

if( PDC_init_atrtab()) /* set up default colors */
return NULL;

MOUSE_X_POS = MOUSE_Y_POS = -1;
BUTTON_STATUS(1) = BUTTON_RELEASED;
Expand Down Expand Up @@ -370,13 +371,12 @@ void delscreen(SCREEN *sp)

free(SP->c_ungch);
free(SP->c_buffer);
PDC_free_atrtab( );

PDC_slk_free(); /* free the soft label keys, if needed */

delwin(stdscr);
delwin(curscr);
delwin(SP->lastscr);
while( SP->opaque->n_windows)
delwin( SP->opaque->window_list[0]);
PDC_free_atrtab( );
stdscr = (WINDOW *)NULL;
curscr = (WINDOW *)NULL;
SP->lastscr = (WINDOW *)NULL;
Expand Down
4 changes: 4 additions & 0 deletions pdcurses/pad.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ pad
**man-end****************************************************************/

void PDC_add_window_to_list( WINDOW *win);

#include <string.h>

/* save values for pechochar() */
Expand Down Expand Up @@ -104,6 +106,7 @@ WINDOW *newpad(int nlines, int ncols)
win->_smincol = 0;
win->_smaxrow = min(LINES, nlines) - 1;
win->_smaxcol = min(COLS, ncols) - 1;
PDC_add_window_to_list( win);

return win;
}
Expand Down Expand Up @@ -160,6 +163,7 @@ WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx)
win->_smincol = 0;
win->_smaxrow = min(LINES, nlines) - 1;
win->_smaxcol = min(COLS, ncols) - 1;
PDC_add_window_to_list( win);

return win;
}
Expand Down
4 changes: 4 additions & 0 deletions pdcurses/scr_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ int putwin(WINDOW *win, FILE *filep)
}
return OK;
}

void PDC_add_window_to_list( WINDOW *win);

#ifdef _MSC_VER
#pragma warning( disable: 4701) /* suppress spurious warnings */
#endif /* about 'uninitialised' variables */
Expand Down Expand Up @@ -249,6 +252,7 @@ WINDOW *getwin(FILE *filep)
}

touchwin(win);
PDC_add_window_to_list( win);

return win;
}
Expand Down
36 changes: 35 additions & 1 deletion pdcurses/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,18 @@ void PDC_sync(WINDOW *win)
wsyncup(win);
}

#define is_power_of_two( X) (!((X) & ((X) - 1)))

void PDC_add_window_to_list( WINDOW *win)
{
SP->opaque->n_windows++;
if( is_power_of_two( SP->opaque->n_windows))
SP->opaque->window_list = (WINDOW **)realloc( SP->opaque->window_list,
SP->opaque->n_windows * 2 * sizeof( WINDOW *));
assert( SP->opaque->window_list);
SP->opaque->window_list[SP->opaque->n_windows - 1] = win;
}

WINDOW *newwin(int nlines, int ncols, int begy, int begx)
{
WINDOW *win;
Expand All @@ -237,19 +249,34 @@ WINDOW *newwin(int nlines, int ncols, int begy, int begx)
win = PDC_makelines(win);

if (win)
{
werase(win);
PDC_add_window_to_list( win);
}

return win;
}

int delwin(WINDOW *win)
{
PDC_LOG(("delwin() - called\n"));
int i = 0;

assert( win);
if (!win)
return ERR;

assert( SP->opaque->n_windows);
/* recursively delete subwindows, if any */
while( i < SP->opaque->n_windows)
if( SP->opaque->window_list[i]->_parent == win)
{
delwin( SP->opaque->window_list[i]);
i = 0; /* start from beginning of list again */
}
else
i++;

/* subwindows use parents' lines */

if (!(win->_flags & (_SUBWIN|_SUBPAD)))
Expand All @@ -261,7 +288,12 @@ int delwin(WINDOW *win)
if( win->_y)
free(win->_y);
free(win);

i = 0;
while( i < SP->opaque->n_windows && SP->opaque->window_list[i] != win)
i++;
assert( i < SP->opaque->n_windows);
SP->opaque->n_windows--;
SP->opaque->window_list[i] = SP->opaque->window_list[SP->opaque->n_windows];
return OK;
}

Expand Down Expand Up @@ -328,6 +360,7 @@ WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
win->_y[i] = orig->_y[j] + k;

win->_flags |= _SUBWIN;
PDC_add_window_to_list( win);

return win;
}
Expand Down Expand Up @@ -417,6 +450,7 @@ WINDOW *dupwin(WINDOW *win)
new->_parent = win->_parent;
new->_bkgd = win->_bkgd;
new->_flags = win->_flags;
PDC_add_window_to_list( new);

return new;
}
Expand Down

0 comments on commit 3b14813

Please sign in to comment.