steve@gapos.bt.co.uk (Steve Rooke) (04/25/91)
I have just started to get MH 6.7.1 running under Uniplus+ SVR2 on our machines here but have hit a problem with vmh. When I run vmh -vmhproc msh the screen splits normally, the top window shows a scan of msgbox and I get the (vmh) prompt in the bottom window okay. If I scan then the bottom screen fills up but then immediately clears and I am left with a blank bottom window apart from the (top: bottom:) prompt. A refresh will not repaint the missing text and I can get the next screen but all I see is a quick flash of the bottom line of text before it disappears. I have started to look in vmh.c and think that the problem is somewhere in the region of linsert (perhaps). It looks like the screen is written by part of the code then a linked list of line structures is read back out of the curses window, only in my case this seems to read blank strings. I see the correct display for a quick flash at the time that the first wrefresh is called in WINloop but, after the lbottom/waddstr bit is run, the next wrefresh clears the window. Has anyone else had this problem and can help me please. If it is covered in FAQ then please excuse this posting as I have only just started to read the group and have not seen one yet (if you have a copy, please send it to me or tell me where I can get a copy, see my other posting). version: MH 6.7.1 #3[UCI] (azh01) of Tue Apr 23 11:54:41 BST 1991 options: [SYS5] [MORE='"/usr/bin/more"'] [NDIR] [SYSNDIR] [UK] [MHE] [SENDMTS] [SPRINTFTYPE=int] SYSNDIR = local hack for <sys/ndir> Thanks for your time Steve -- Steve Rooke steve@gapos.bt.co.uk (...mcsun!ukc!gapos!steve) UK + 394 693595 BT, CS/OPSE, Area 106, Anzani House, | Live to Hack - Trinity Ave, FELIXSTOWE, Suffolk, UK | Hack to Live. #include <std/disclaimer> | The_Caged_Lion - DoD #0287
david@cwi.UUCP ("David J. Fiander") (04/26/91)
|From: Steve Rooke <steve@gapos.bt.co.uk> | |I have just started to get MH 6.7.1 running under Uniplus+ SVR2 on our |machines here but have hit a problem with vmh. When I run vmh -vmhproc msh |the screen splits normally, the top window shows a scan of msgbox and I |get the (vmh) prompt in the bottom window okay. If I scan then the bottom |screen fills up but then immediately clears and I am left with a blank |bottom window apart from the (top: bottom:) prompt. A refresh will not |repaint the missing text and I can get the next screen but all I see is |a quick flash of the bottom line of text before it disappears. The problem is that vmh thinks that it knows how curses is implemented, and insists on "diddling the private bits" of the WIN structure. Unfortunately it gets it wrong for System V curses. I have the patches to MH 6.7.1 lying about somewhere, and should probably post them, or something. - David
david@cwi.UUCP ("David J. Fiander") (04/26/91)
Include below, as promised, are my patches to uip/vmh.c so that it will work with System V curses. Unfortunately, I don't have a BSD system to try them on, so I don't know whether I broke anything or not. I have also included a patch to uip/vmhsbr.c which fixes an off-by-one allocation error which was walking on the heap. After this patch has been applied, you have to rebuild both vmh _and_ msh, since the both use it. - David --------- Cut here ---8<-------- *** vmh.orig.c Thu Apr 25 20:45:47 1991 --- vmh.c Sun Mar 10 13:34:44 1991 *************** *** 346,352 **** (void) sprintf (bp, "%d %d", RC_VRSN, numwins); bp += strlen (bp); for (w = windows; *w; w++) { ! (void) sprintf (bp, " %d", (*w) -> _maxy); bp += strlen (bp); } --- 347,355 ---- (void) sprintf (bp, "%d %d", RC_VRSN, numwins); bp += strlen (bp); for (w = windows; *w; w++) { ! int x, y; ! getmaxyx(*w, y, x); ! (void) sprintf (bp, " %d", y); bp += strlen (bp); } *************** *** 694,699 **** --- 697,703 ---- { register int c; register char *bp; + int x, y; bp = buffer; *bp = NULL; *************** *** 712,718 **** *bp = NULL; if (bp > buffer) { leaveok (curscr, FALSE); ! wmove (w, 0, w -> _curx - (bp - buffer)); wrefresh (w); leaveok (curscr, TRUE); } --- 716,723 ---- *bp = NULL; if (bp > buffer) { leaveok (curscr, FALSE); ! getyx(w, y, x); ! wmove (w, 0, x - (bp - buffer)); wrefresh (w); leaveok (curscr, TRUE); } *************** *** 736,742 **** if (c == ERASE) { if (bp <= buffer) continue; ! bp--, w -> _curx--; wclrtoeol (w); break; } --- 741,749 ---- if (c == ERASE) { if (bp <= buffer) continue; ! getyx(w, y, x); ! bp--, x--; ! wmove(w, y, x); wclrtoeol (w); break; } *************** *** 743,749 **** if (c == KILL) { if (bp <= buffer) continue; ! w -> _curx -= bp - buffer; bp = buffer; wclrtoeol (w); break; --- 750,757 ---- if (c == KILL) { if (bp <= buffer) continue; ! getyx(w, y, x); ! x -= bp - buffer; wmove(w, y, x); bp = buffer; wclrtoeol (w); break; *************** *** 751,767 **** if (c == WERASC) { if (bp <= buffer) continue; do { ! bp--, w -> _curx--; } while (isspace (*bp) && bp > buffer); if (bp > buffer) { do { ! bp--, w -> _curx--; } while (!isspace (*bp) && bp > buffer); if (isspace (*bp)) ! bp++, w -> _curx++; } wclrtoeol (w); break; } --- 759,777 ---- if (c == WERASC) { if (bp <= buffer) continue; + getyx(w, y, x); do { ! bp--, x--; } while (isspace (*bp) && bp > buffer); if (bp > buffer) { do { ! bp--, x--; } while (!isspace (*bp) && bp > buffer); if (isspace (*bp)) ! bp++, x++; } + wmove(w, y, x); wclrtoeol (w); break; } *************** *** 830,835 **** --- 840,846 ---- nwait; char *cp; register struct line *lbottom; + int x, y; did_less++; *************** *** 843,848 **** --- 854,860 ---- nwait = 0; wrefresh (w); + getmaxyx(w, y, x); for (;;) { if (nfresh || nwait) { nfresh = 0; *************** *** 856,862 **** if (ltop == NULL) if (fin) { ! (void) lgo (ltail -> l_no - w -> _maxy + 1); if (ltop == NULL) ltop = lhead; } --- 868,874 ---- if (ltop == NULL) if (fin) { ! (void) lgo (ltail -> l_no - y + 1); if (ltop == NULL) ltop = lhead; } *************** *** 961,967 **** break; case 'G': ! if (lgo (n ? n : ltail -> l_no - w -> _maxy + 1)) nfresh++; break; --- 973,979 ---- break; case 'G': ! if (lgo (n ? n : ltail -> l_no - y + 1)) nfresh++; break; *************** *** 1027,1032 **** --- 1039,1048 ---- register int x, y; + register int maxx, + maxy; + + getmaxyx(w, maxy, maxx); switch (c) { default: if (!isascii (c)) { *************** *** 1050,1057 **** if (w != Scan) return waddch (w, c); ! if ((x = w -> _curx) < 0 || x >= w -> _maxx ! || (y = w -> _cury) < 0 || y >= w -> _maxy) return DONE; switch (c) { --- 1066,1073 ---- if (w != Scan) return waddch (w, c); ! getyx(w, y, x); ! if (x < 0 || x >= maxx || y < 0 || y >= maxy) return DONE; switch (c) { *************** *** 1062,1068 **** break; case '\n': ! if (++y < w -> _maxy) (void) waddch (w, c); else wclrtoeol (w); --- 1078,1084 ---- break; case '\n': ! if (++y < maxy) (void) waddch (w, c); else wclrtoeol (w); *************** *** 1069,1075 **** break; default: ! if (++x < w -> _maxx) (void) waddch (w, c); break; } --- 1085,1091 ---- break; default: ! if (++x < maxx) (void) waddch (w, c); break; } *************** *** 1095,1100 **** --- 1111,1118 ---- static linsert (w) WINDOW *w; { + int origx, origy, maxx, maxy; /* origy and maxy are ignored */ + register int x; register char *cp; register struct line *lp; *************** *** 1101,1108 **** if ((lp = (struct line *) calloc ((unsigned) 1, sizeof *lp)) == NULL) adios (NULLCP, "unable to allocate line storage"); lp -> l_no = (ltail ? ltail -> l_no : 0) + 1; ! lp -> l_buf = getcpy (w -> _y[w -> _cury]); for (cp = lp -> l_buf + strlen (lp -> l_buf) - 1; cp >= lp -> l_buf; cp--) if (isspace (*cp)) *cp = NULL; --- 1119,1134 ---- if ((lp = (struct line *) calloc ((unsigned) 1, sizeof *lp)) == NULL) adios (NULLCP, "unable to allocate line storage"); + getmaxyx(w, maxy, maxx); + getyx(w, origy, origx); lp -> l_no = (ltail ? ltail -> l_no : 0) + 1; ! lp -> l_buf = malloc(maxx + 1); ! if (lp -> l_buf == 0) ! adios(NULLCP, "unable to allocate string storage"); ! for (x = 0; x < maxx; ++x) ! lp -> l_buf[x] = mvwinch(w, origy, x); ! lp -> l_buf[maxx] = '\0'; ! wmove(w, origy, origx); for (cp = lp -> l_buf + strlen (lp -> l_buf) - 1; cp >= lp -> l_buf; cp--) if (isspace (*cp)) *cp = NULL; *** vmhsbr.orig.c Thu Apr 25 20:47:46 1991 --- vmhsbr.c Sun Mar 10 13:34:44 1991 *************** *** 44,50 **** if ((cp = getenv ("MHVDEBUG")) && *cp ! && (fp = fopen (sprintf (buffer, "%s.out", invo_name), "w"))) { (void) fseek (fp, 0L, 2); fprintf (fp, "%d: rcinit (%d, %d)\n", getpid (), rfd, wfd); (void) fflush (fp); --- 45,52 ---- if ((cp = getenv ("MHVDEBUG")) && *cp ! && sprintf (buffer, "%s.out", invo_name) > 0 ! && (fp = fopen (buffer, "w"))) { (void) fseek (fp, 0L, 2); fprintf (fp, "%d: rcinit (%d, %d)\n", getpid (), rfd, wfd); (void) fflush (fp); *************** *** 101,107 **** if (read (PEERrfd, (char *) rc_head (rc), RHSIZE (rc)) != RHSIZE (rc)) return rclose (rc, "read from peer lost(1)"); if (rc -> rc_len) { ! if ((rc -> rc_data = malloc ((unsigned) rc -> rc_len)) == NULL) return rclose (rc, "malloc of %d lost", rc -> rc_len); if (read (PEERrfd, rc -> rc_data, rc -> rc_len) != rc -> rc_len) return rclose (rc, "read from peer lost(2)"); --- 103,109 ---- if (read (PEERrfd, (char *) rc_head (rc), RHSIZE (rc)) != RHSIZE (rc)) return rclose (rc, "read from peer lost(1)"); if (rc -> rc_len) { ! if ((rc -> rc_data = malloc ((unsigned) rc -> rc_len + 1)) == NULL) return rclose (rc, "malloc of %d lost", rc -> rc_len); if (read (PEERrfd, rc -> rc_data, rc -> rc_len) != rc -> rc_len) return rclose (rc, "read from peer lost(2)"); ---------- End of patches
gs@ynetfrsp.inria.fr (gs@ynetfrsp.inria.fr) (04/26/91)
In article <steve.672572789@azh01.gapos.bt.co.uk>, steve@gapos.bt.co.uk (Steve Rooke) writes: > > I have just started to get MH 6.7.1 running under Uniplus+ SVR2 on our > machines here but have hit a problem with vmh. When I run vmh -vmhproc msh > the screen splits normally, the top window shows a scan of msgbox and I > get the (vmh) prompt in the bottom window okay. If I scan then the bottom > screen fills up but then immediately clears and I am left with a blank > bottom window apart from the (top: bottom:) prompt. A refresh will not > repaint the missing text and I can get the next screen but all I see is > a quick flash of the bottom line of text before it disappears. We had the same problem here (on DPX2000 in SPIX32). The only solution we have found is the following correction in the code of vmh.c : in the routine WINless: ......... #endif notdef lbottom = ltail; while (waddstr (w, "~\n") != ERR) continue; } else { wrefresh (w); return 0; } if (!nwait) <---------- suppress this line wrefresh (w); <---------- suppress this line } ........
steve@gapos.bt.co.uk (Steve Rooke) (04/30/91)
In <2114@seti.inria.fr> gs@ynetfrsp.inria.fr (gs@ynetfrsp.inria.fr) writes: >In article <steve.672572789@azh01.gapos.bt.co.uk>, steve@gapos.bt.co.uk >(Steve Rooke) writes: >> >> I have just started to get MH 6.7.1 running under Uniplus+ SVR2 on our >> machines here but have hit a problem with vmh. When I run vmh -vmhproc msh >> the screen splits normally, the top window shows a scan of msgbox and I >> get the (vmh) prompt in the bottom window okay. If I scan then the bottom >> screen fills up but then immediately clears and I am left with a blank >> bottom window apart from the (top: bottom:) prompt. A refresh will not >> repaint the missing text and I can get the next screen but all I see is >> a quick flash of the bottom line of text before it disappears. >We had the same problem here (on DPX2000 in SPIX32). The only solution >we have found is >the following correction in the code of vmh.c : >in the routine WINless: > >......... >#endif notdef > lbottom = ltail; > while (waddstr (w, "~\n") != ERR) > continue; > } > else { > wrefresh (w); > return 0; > } > if (!nwait) <---------- suppress this line > wrefresh (w); <---------- suppress this line > } >........ Well does it work okay when you scroll the screen? I doubt it. I guess you have the same problem as me, the original BSD code has a habit of poking around a the window structure directly. Unfortunately it assumes that the characters are stored as char *'s but, as in my case, they are unsigned short *'s to allow extra room for attributes. MH initially writes it's output into the window, then reads it back into a structure (so that it can scroll the screen), it then writes it's idea of the screen back to the window and then calls wrefresh (as pointed to above). If you do not have char *'s then the read back screen will probably be blank and the screen will flash initially with the text and then will blank when it calls the wrefresh. David Fiander sent some patches to me (and posted them here a day or two ago) that fix the window dependencies for this problem. There is also another problem with long lines wrapping the window. If you have lines of text that wrap the window you will only see the tail end when the wrefresh is called. You will not see this problem if Show is using an mhl filter as this splits up long lines so that they show correctly on the screen. I have some patches that cure this problem and could post as a diff on David's work if wanted. Cheers Steve -- Steve Rooke steve@gapos.bt.co.uk (...mcsun!ukc!gapos!steve) UK + 394 693595 BT, CS/OPSE, Area 106, Anzani House, | Live to Hack - Trinity Ave, FELIXSTOWE, Suffolk, UK | Hack to Live. #include <std/disclaimer> | The_Caged_Lion - DoD #0287