[net.bugs] CURSES sub-windows bugs - correction to Mike Laman article

idallen@watmath.UUCP (08/21/84)

> From: laman@sdcsvax.UUCP (Mike Laman)
> First of all let me point out that when sub windows are
> created, the window's text is SEPARATE from original window.

This is not true with the 4.2bsd curses dated June/July 1983.
Sub windows are merely edge vectors into their parent windows.
A change in either is reflected in both, since they are the same.

> As I mentioned earlier, the real killer is that EACH routine would be
> responsible for adding the information to each associated window.
> I suggest the correct solution be to have sub windows SHARE the window text
> with the information in the WINDOW header telling what part of the lines it
> "owns".

4.2 curses already does share window text.  The line-change flags are
not shared, and are not updated correctly by any of the erase or
clearing functions.

> As for the problem at hand, I guess you'll have to be happy with
> "overwrite()" (and "overlay()"), until you get a System V.2 to use.

I would be surprised if even V.2 got sub-windows right.  The fix to
making clear and erase affect all related window change flags is easy. 
CLEAR already calls ERASE.  Make ERASE and CLRTOBOT call CLRTOEOL for all
appropriate lines.  Make CLRTOEOL set change flags in all affected windows.

Here's a simple sub-windows test program.  See if V.2 passes the test.

/* Test curses to see if deleting a line in a parent window is
 * correctly represented in a sub-window.
 * Test curses to see if clearing part of a sub-window is correctly
 * represented in the parent window.
 * idallen@watmath.UUCP  Ian! D. Allen   University of Waterloo
 */
#include <curses.h>

WINDOW *win;
int bell = 007;
int i;

main()
{
    initscr();
    win = subwin( stdscr, 0, 0, 0, 0 );

    for( i=0; i<LINES; i++ )
    	mvwprintw( stdscr, i, 0, "This is Line %d\n", i );
    wrefresh( stdscr );

    /* Delete line ten.  All the lines thereafter move up one line.
     */
    sleep(5); write( 2, &bell, 1 );
    move( 10, 0 );
    deleteln();
    wrefresh( stdscr );

    /* See what the sub-window thinks the screen should look like.
     * If the sub-window bug is here, line ten will reappear as a blank
     * line and all the other lines will move back to where they were.
     */
    sleep(3); write( 2, &bell, 1 );
    touchwin( win );
    wrefresh( win );

    /* Recreate the parent-window version of the window.
     */
    sleep(3); write( 2, &bell, 1 );
    touchwin( stdscr );
    wrefresh( stdscr );

    /* Recreate the sub-window version of the window.
     */
    sleep(3); write( 2, &bell, 1 );
    touchwin( win );
    wrefresh( win );

    /* Now, clear part of the parent window and refresh the sub-window.
     * Because clearing doesn't use addch(), the change flags aren't
     * set for the sub-window and nothing happens.
     */
    sleep(3); write( 2, &bell, 1 );
    move( 5, 0 );
    clrtobot();
    wrefresh( win );	/* if you have the bug, nothing happens here */

    sleep(3); write( 2, &bell, 1 );
    wrefresh( stdscr );	/* now, the screen clears correctly */

    sleep(5);
    endwin();
}
-- 
        -IAN!  (Ian! D. Allen)      University of Waterloo

laman@sdcsvax.UUCP (Mike Laman) (09/23/84)

In article <8713@watmath.UUCP> idallen@watmath.UUCP writes:
>> From: laman@sdcsvax.UUCP (Mike Laman)
>> First of all let me point out that when sub windows are
>> created, the window's text is SEPARATE from original window.
>
>This is not true with the 4.2bsd curses dated June/July 1983.
>Sub windows are merely edge vectors into their parent windows.
>A change in either is reflected in both, since they are the same.

He is correct.  I am embarrassed as to how I could have fooled myself.  Sigh.

>> As I mentioned earlier, the real killer is that EACH routine would be
>> responsible for adding the information to each associated window.
>> I suggest the correct solution be to have sub windows SHARE the window text
>> with the information in the WINDOW header telling what part of the lines it
>> "owns".
>
>4.2 curses already does share window text.  The line-change flags are
>not shared, and are not updated correctly by any of the erase or
>clearing functions.
>
>> As for the problem at hand, I guess you'll have to be happy with
>> "overwrite()" (and "overlay()"), until you get a System V.2 to use.
>
>I would be surprised if even V.2 got sub-windows right.  The fix to
>making clear and erase affect all related window change flags is easy. 
>CLEAR already calls ERASE.  Make ERASE and CLRTOBOT call CLRTOEOL for all
>appropriate lines.  Make CLRTOEOL set change flags in all affected windows.
>	:
>	:
>	:
>        -IAN!  (Ian! D. Allen)      University of Waterloo

5.2 didn't get sub windows right either.  There are two problems with them:
Three routines shuffle pointer that are unique to EACH window, so the shuffling
doesn't have the right effect on related windows.  The problem of adding a
character to one window and having the "_firstch" fields show the change in
other related windows exist too.  I still say that making every routine that
changes a window be responsible to show those changes to all the related
windows is NOT the way to go!  I have the fixes for SVR3 curses and sent them
to Mark Horton.  The changes should be that same for SVR2 and the code should
be portable to 4.2 with few changes.  I'm awaiting Mark's reply.
[ There are just TOO many routines that change windows.  You would have a
BIG problem with duplication of code => the work is being done at too deep of a
level. ]  My solution was to first modify winsterln, wdeleteln, and scroll to
use memcpy() instead of shuffling pointers.  This should be optimized to
do the shuffling when there are NO related windows to the given window, as I
mentioned to Mark.  The second thing I did was to write a couple of routines
that get called just before the updating goes on. These routines pull all the
changes up to the called window leaving the "_firstch" fields at "_NOCHNAGE"
since the change is now seen elsewhere.  And then pull all the changes from
all the parent windows (and their children expect this given window) down
to the given window.  These routines seem to do the trick!  I have a program
that has about 5 levels of subwindows many of which have children (and they
may have children). I add characters to each window and can selectively
refresh any window.

I'm sorry again about my misconception... I don't know how I got confused.
Luckily though, since SVR3 shares text, but not the other fields.  Therefore,
my fixes for SVR3 (we're a beta test site) will work for 4.2 with no changes to
the algorithm of propagating related window changes.  But there is one problem
area in the porting to 4.2.  I added a pointer to the immediate parent and an
array of pointers to the window's children.  This will have to change some
and I don't know exactly what would have to be done to get my routines to work
with 4.2.

I will keep y'all posted, if Mark doesn't.

		Mike Laman
		UUCP: {ucbvax,philabs,sdcsla}!sdcsvax!laman