/*==========================================================+ | =========================== | | TORCH XXX : 1ST WORD PLUS | | =========================== | | | | E D I T W I N D O W M A N A G E R | | | | 8888.1 GST 016 rev 0.01 | | | +===========================================================+ | | | Revision History: | | | | 0.01 Created on 15/4/86, by MCD, from WINDO101.C | | | +==========================================================*/ #include "opentop.h" #include "winhead.h" #page /* ----- library routines ----- */ extern strlen(); extern sign(); extern abs(); extern calloc(); extern at(); extern cursen(); extern scrchar(); extern scrstring(); extern setscreen(); extern cls(); extern pan(); extern scroll(); /* more display file routines */ extern dfofftop(); extern dfoffbot(); extern wrouttop(); extern wroutbot(); extern hookfill(); #page /* ----- whole-window routines ----- */ wminit ( wcb, width, height ) WORD * wcb, width, height; { BYTE *p; LONG *win = calloc ( WINDSZ, 4 ); if ( win == 0 ) return 0; if ( pginit(win) == 0 ) return 0; p = calloc(BUFBYTES,1); if ( p == 0 ) return 0; win[WCB] = wcb; win[TEXTBUFF] = p; win[WINWIDTH]=width; win[WINDEPTH]=height; wmreset( win ); redisplay ( win ); return win; } #page wmreset( win ) LONG win[]; { LONG i, *p; WORD *wcb = win[WCB]; BYTE *cursline, *cursattr; LONG botcount = win[BOTCOUNT]; LONG wpmode=win[WPMODE], wpever=win[WPEVER]; for ( i=WMRESET; i 0 ) while ( win[WINDUNDER] < diff ) if ( dfoffbot(win) != 0 ) break; win[WINDUNDER] -= diff; win[WINDEPTH] = height; } wmenable ( win, flag ) LONG win[]; FLAG flag; { if(flag) { if(win[WINDISABLED]) --win[WINDISABLED]; if(win[WINDISABLED]==0) wmupdate(win); } else ++win[WINDISABLED]; } redisplay(win) LONG win[]; { win[CHANGEALL] = YES; wmupdate(win); return 0; } /* clear a partial line at the bottom of the window */ clearstrip(win) LONG win[]; { wmcursor ( win, win[WINDXPOS], win[WINDLNO]+win[WINDEPTH]-1, OFF ); wcls ( win, PART_BOT ); } #page /* PAINTCHARS ** ** This routine writes some chars from a line to the screen. ** It collects groups of chars with similar attributes in a buffer ** when is then sent to the screen in routine FLUSHBUF */ paintchars ( win, line ) LONG win[], line; { BYTE *ap = attrs(win, line); BYTE *cp = lines(win, line); BYTE linebuff[BUFLEN]; WORD bpos = 0; WORD posonline = win[WINDXPOS]; BYTE currentatr = 0x80; WORD w = win[WINWIDTH]; WORD ch; if ( NOT enabled(win,line) ) return; if ( posonline >= (strlen(cp)-1) || line > win[BOTLINE] ) { blankline ( win, line ); show_pic ( win, line ); return; } cp += posonline; ap += posonline; wmcursor ( win, posonline, line, OFF ); while ( w-- ) { if ( currentatr != *ap ) { flushbuf ( win, linebuff, &bpos ); /* avoid garbage on screen when switching to italic */ if ( *ap & ~currentatr & (1< ESC ) ch = SPACE; ++posonline; linebuff[bpos++] = ch; ++ap; } flushbuf ( win, linebuff, &bpos ); /* if the line ends in italic, don't chop the last char */ if ( currentatr & (1< win[CURSLNO] ) -- p[MARKYPOS]; else if ( p[MARKYPOS] == win[CURSLNO] ) p[MARKXPOS] = 0; p = p[MARKNEXT]; } return 0; } wmjoin(win) LONG win[]; { LONG i, status, attr, *p=win[MARKS]; BYTE *p0, *p1, *p2; BYTE *cursattr; LONG lineno, len1, len2; /* check that the next line is in memory */ if ( win[CURSLNO]==win[BOTLINE] && win[WINDUNDER] <= 0 ) { status = dfoffbot(win); if(status) return(status); } /* set up some useful pointers */ lineno = win[CURSLNO]+1; cursattr = win[CURSATTR]; p1 = p0 = win[CURSLINE]; p2 = lines(win, lineno); /* check that the line will not be too long */ len1 = strlen(p1); len2 = strlen(p2); if ( (len1 + len2) > MAXLEN ) return ( ER_LL ); /* copy the next line into the cursor line */ attr = cursattr[len1-1]; /* attributes of newline char */ p1 += len1-1; fastcopy ( p2, p1, len2+1 ); /* copy text & terminating null */ fastcopy ( p2+BUFLEN, p1+BUFLEN, len2 ); /* copy attributes */ /* display line and cursor */ wmputcur ( win, len1-1, win[CURSLNO] ); cursattr[win[CURSPOS]] |= ( attr & CHANGEMASK ); /* KEEP ANY CHANGE BITS FROM END OF LINE */ paintline ( win, win[CURSLNO] ); fixcursor( win ); /* scroll up rest of screen */ status = scrollup(win, win[CURSLNO]+1); if(status) return(status); /* update markers */ while ( p ) { if ( p[MARKYPOS] >= lineno ) { if ( p[MARKYPOS] == lineno ) p[MARKXPOS] += win[CURSPOS]; -- p[MARKYPOS]; } p = p[MARKNEXT]; } return 0; } wminslin ( win, text ) LONG win[]; BYTE *text; { BYTE *cursattr = win[CURSATTR]; WORD colour = cursattr[0]; BYTE stylbuf[BUFLEN]; fastfill ( colour&ATTRMASK, stylbuf, BUFLEN ); wmlinestyl ( win, text, stylbuf ); } wmlinestyl ( win, text, style ) LONG win[]; BYTE *text, *style; { BYTE *cursattr, *cursline, *lineattr; LONG status, i, *p=win[MARKS], lineno = win[CURSLNO], len = strlen ( text ); status = scrolldown(win, win[CURSLNO]); /* make room for a new line */ if(status) return status; cursline = win[CURSLINE]; cursattr = win[CURSATTR]; fastcopy ( text, cursline, len+1 ); /* +1 to get terminatng null */ fastcopy ( style, cursattr, len ); lineattr = attrs( win, (win[CURSLNO]+1) ); wmputcur ( win, 0, win[CURSLNO] ); paintline ( win, win[CURSLNO] ); fixcursor( win ); /* update markers */ while ( p ) { if ( p[MARKYPOS] >= lineno ) ++ p[MARKYPOS]; p = p[MARKNEXT]; } return 0; } #page /* SCROLLUP ** This routine is called when deleting a line ** to scroll up the rest of the window. */ scrollup( win, scrolineno ) LONG win[], scrolineno; { LONG lineno, status=0; BYTE *linebuff, *nextbuff; BYTE *cursline; if ( win[WINDUNDER] <= 0 ) status = dfoffbot(win); for ( lineno = scrolineno; lineno < win[BOTLINE]; ++lineno ) { linebuff = lines(win, lineno); nextbuff = lines(win, (lineno+1)); fastcopy ( nextbuff, linebuff, BUFLEN*2 ); } if ( scrolineno == win[BOTLINE] /* on bottom line in buffer */ && win[WINDUNDER] <= 0 /* if no more lines ( so bottom of file) */ && scrolineno == win[CURSLNO] ) /* delete line (not join) */ { /* bottom line in the buffer */ cursline = win[CURSLINE]; cursline[0] = NL; cursline[1] = 0; blankline ( win, win[CURSLNO] ); win[CURSPOS] = 0; fixcursor(win); return 0; } ++win[WINSPARE]; --win[WINDUNDER]; --win[BOTLINE]; pgdellin ( win, scrolineno ); scrollpart ( win, scrolineno, -win[LINEHEIGHT] ); lineno = win[WINDLNO]+win[WINDEPTH]-1; wmcursor ( win, win[WINDXPOS], lineno, OFF ); if ( offscreen ( win[WCB] ) ) redisplay(win); else if ( status == 0 ) paintline ( win, lineno ); if ( scrolineno == win[CURSLNO] ) { if ( win[CURSLNO] > win[BOTLINE] ) --win[CURSLNO]; wmputcur ( win, 0, win[CURSLNO] ); } fixcursor(win); if(status==EOF) return 0; return status; } #page /* SCRODOWN ** This routine is called when inserting a line ** to scroll down the rest of the window. */ scrolldown(win, scrolineno) LONG win[], scrolineno; /* no of first line to scroll down */ { LONG lineno,status=0; BYTE *linebuff, *nextbuff; if ( win[WINSPARE] == 0 ) { if(win[WINDOVER]) status = wrouttop(win); else status = wroutbot(win); if(status) return status; } for (lineno = win[BOTLINE]; lineno >= scrolineno; --lineno ) { linebuff = lines(win, lineno); nextbuff = lines(win, (lineno+1)); fastcopy ( linebuff, nextbuff, BUFLEN*2 ); } --win[WINSPARE]; ++win[WINDUNDER]; ++win[BOTLINE]; linebuff = lines(win, scrolineno); *linebuff=NL; *++linebuff=0; pginslin ( win, win[CURSLNO] ); /* note that we do not use scrolineno in the above call. ** this means a split on the last line of a page puts the ** new line on the same page, rather than the next page! */ scrollpart ( win, scrolineno, win[LINEHEIGHT] ); return status; } #page wmsplit(win) LONG win[]; { LONG pos = win[CURSPOS], len, status=0, xpos = win[WINDXPOS], *p = win[MARKS], i; BYTE *cursline = win[CURSLINE], *cursattr = win[CURSATTR], *oldline=cursline, *oldattr=cursattr; len = strlen ( cursline ); status = scrolldown(win, win[CURSLNO]+1); /* make room for a line */ if(status) return status; wcls ( win, PART_EOL ); /* clear end of line */ status = wmputcur ( win, 0, win[CURSLNO]+1 ); /* move cursor down to next line */ if ( status ) return status; /* copy right hand end down to next line */ cursline = win[CURSLINE]; cursattr = win[CURSATTR]; fastcopy ( oldline+pos, cursline, len-pos+1 ); fastcopy ( oldattr+pos, cursattr, len-pos+1 ); oldline[pos]=NL; oldline[pos+1]=0; /* terminate the line */ oldattr[pos] = win[NEWSTYLE]; cursattr[0] &= ATTRMASK; /* remove change bits (now on NL) */ if ( xpos ) paintline ( win, win[CURSLNO]-1 ); if ( *cursline != NL ) paintline ( win, win[CURSLNO] ); /* display new cursor line */ fixcursor(win); while ( p ) { if ( p[MARKYPOS] > win[CURSLNO]-1 ) ++p[MARKYPOS]; else if ( p[MARKYPOS] == win[CURSLNO]-1 && p[MARKXPOS] > pos ) ++p[MARKYPOS], p[MARKXPOS] -= pos; p = p[MARKNEXT]; } return status; } #page /* ----- char-based routines ----- */ wmrdbyt ( win, dx ) LONG win[], dx; { BYTE *cursline; if(dx) { wcursen ( win, OFF ); moveit(win, dx); } if ( win[CURSPOS] < win[WINDXPOS] || win[CURSPOS] >= win[WINDXPOS]+win[WINWIDTH] ) wmputcur ( win, win[CURSPOS], win[CURSLNO] ); else if(dx) fixcursor(win); cursline = win[CURSLINE]; return cursline[win[CURSPOS]]; } wmwrbyt( win, ch ) LONG win[]; BYTE ch; { BYTE *cursline = win[CURSLINE], *cursattr = win[CURSATTR]; if ( ch == NL ) return(ERR); if ( cursline[win[CURSPOS]] == NL ) { if ( win[CURSPOS] >= MAXLEN ) return(ER_LL); return wminschr(win,ch); } cursline[win[CURSPOS]] = ch; setscreen ( win[WCB], cursattr[win[CURSPOS]] ); wscrchar ( win, ch ); fixcursor( win ); return 0; } wminschr ( win, ch ) LONG win[]; BYTE ch; { BYTE *cursline = win[CURSLINE], *cursattr = win[CURSATTR]; LONG len = strlen ( cursline ), pos = win[CURSPOS], stublen = len-pos+1, *p = win[MARKS], i; if ( len+1 >= MAXLEN ) return ER_LL; backshuffle ( cursline+len, 1, stublen ); backshuffle ( cursattr+len, 1, stublen ); wpan ( win, win[CHARWID], PART_EOL ); cursline[pos] = ch; cursattr[pos] = win[NEWSTYLE]; showchar ( win, pos ); if ( cursattr[pos-1] & (1<= win[WINDXPOS]+win[WINWIDTH] ) /* check for h-scroll */ wmputcur ( win, win[CURSPOS], win[CURSLNO] ); fixcursor(win); /* update markers */ while ( p ) { if ( p[MARKYPOS] == win[CURSLNO] ) if ( p[MARKXPOS] > pos ) ++p[MARKXPOS]; p = p[MARKNEXT]; } return 0; } wminsblk ( win, ptr, count ) LONG win[]; BYTE *ptr; int count; { LONG i,status=0; WORD savestyle = win[NEWSTYLE]; while(status==0) { i=0; while ( ptr[i] != NL && ptr[i] != ESC && i < count ) ++i; if ( i ) status = wminsert ( win, ptr, i ); if ( status || i == count ) break; if ( ptr[i] == NL ) status = wmsplit(win); else if ( ptr[i] == ESC ) win[NEWSTYLE] = ptr[++i] & 0x7f; ptr += ++i; count -= i; } win[NEWSTYLE] = savestyle; return status; } wminsert ( win, str, slen ) BYTE *str; LONG win[], slen; { BYTE *cursline = win[CURSLINE], *cursattr = win[CURSATTR]; LONG llen = strlen(cursline), pos = win[CURSPOS], stublen = llen-pos+1, *p = win[MARKS], i; if ( llen+slen >= MAXLEN ) return ER_LL; backshuffle ( cursline+llen, slen, stublen ); backshuffle ( cursattr+llen, slen, stublen ); fastcopy ( str, cursline+win[CURSPOS], slen ); fastfill ( win[NEWSTYLE], cursattr+win[CURSPOS], slen ); /* note inserted string gets new attributes */ win[CURSPOS]+=slen; if ( win[CURSPOS] < win[WINDXPOS]+win[WINWIDTH] ) paintline ( win, win[CURSLNO] ); /* else repainted by h-scrol */ wmputcur ( win, win[CURSPOS], win[CURSLNO] ); /* update markers */ while ( p ) { if ( p[MARKYPOS] == win[CURSLNO] ) if ( p[MARKXPOS] > pos ) p[MARKXPOS] += slen; p = p[MARKNEXT]; } return 0; } wmdelchr(win) LONG win[]; { BYTE *cursline = win[CURSLINE], *cursattr = win[CURSATTR], *temp; LONG len = strlen ( cursline ), pos = win[CURSPOS], stublen = len-pos, endposn = win[WINDXPOS]+win[WINWIDTH]-1, chbits, *p = win[MARKS], i; if ( cursline[pos] == NL ) return ERR; temp = cursline+pos; fastcopy ( temp+1, temp, stublen ); temp = cursattr+pos; chbits = *temp & CHANGEMASK; fastcopy ( temp+1, temp, stublen ); *temp |= chbits; /* keep any change bits */ wpan ( win, -win[CHARWID], PART_EOL ); /* if deleting near italic, repaint char */ if ( cursattr[pos-1] & (1< endposn+1 ) { showchar( win, endposn-1 ); showchar( win, endposn ); } fixcursor( win ); /* update markers */ while ( p ) { if ( p[MARKYPOS] == win[CURSLNO] ) if ( p[MARKXPOS] > win[CURSPOS] ) --p[MARKXPOS]; p = p[MARKNEXT]; } return 0; } #page /* ----- cursor and marker routines ----- */ /* WMGETBUF ** This routine is used by the editor to get a pointer ** to the buffer for the cursor line in order to do ** searches quickly */ wmgetbuf(win) LONG win[]; { return win[CURSLINE]; } wmcurena ( win, onoff ) LONG win[]; FLAG onoff; { win[CURSENABLED] = onoff; if ( onoff ) wmputcur ( win, win[CURSPOS], win[CURSLNO] ); wcursen ( win, onoff ); return 0; } wmgetcur( win, xp, yp ) LONG win[], *xp, *yp; { *xp = win[CURSPOS]; *yp = win[CURSLNO]; return 0; } wmputcur ( win, x, y ) LONG win[], x, y; { int target = y-win[WINDEPTH]/2; /* If the line we want is not in the window, scroll until ** the required line is in the middle of the window */ /* but if we're only moving 1 line out of the window, ** only scroll the window by 1 line */ if ( enabled(win,-2) ) { if ( y == win[WINDLNO]-1 ) target=y; if ( y == win[WINDLNO]+win[WINDEPTH] ) target = win[WINDLNO]+1; } if ( y >= win[WINDLNO] && y < (win[WINDLNO]+win[WINDEPTH]) ) target = win[WINDLNO]; wmscrto ( win, x, y, target ); } wmscrto ( win, x, y, target ) LONG win[], x, y, target; { LONG status=0, oldwlno = win[WINDLNO], saveenable=win[CURSENABLED], i, len; BYTE *cursline, *cursattr; wcursen(win,OFF); win[CURSENABLED]=OFF; while ( win[WINDLNO] > target ) { if ( (status = windup(win)) != 0 ) break; } while ( win[WINDLNO] < target && win[WINDUNDER] >= 0 ) { if ( (status = winddown(win)) != 0 ) break; } /* Now look for the required line amongst those lines in the window */ for ( i = win[WINDLNO]; i < y; ++i ) if ( i == win[BOTLINE] ) break; win[CURSLNO] = i; win[CURSLINE] = cursline = lines(win, win[CURSLNO]); win[CURSATTR] = cursattr = attrs(win, win[CURSLNO]); len = strlen(cursline); if(x>(len-1))x=len-1; if(x<0) x=0; win[CURSPOS]=x; /* horizontal scrolling */ if ( ( win[CURSPOS] < win[WINDXPOS] || win[CURSPOS] >= win[WINDXPOS]+win[WINWIDTH] ) && saveenable ) { if ( win[CURSPOS] < win[WINWIDTH] ) win[WINDXPOS]=0; else win[WINDXPOS]=win[CURSPOS]-(3*win[WINWIDTH]/4); redisplay(win); } else vsscroll(win, oldwlno-win[WINDLNO]); win[CURSENABLED]=saveenable; fixcursor(win); if ( win[CURSLNO] == y ) status=0; else if ( status == 0 ) status = EOF; return status; } #page /* WINDUP and WINDDOWN ** These routines are called when scrolling the window to move ** the window up or down with respect to the display file. */ windup(win) LONG win[]; { int status=0; if ( win[WINDOVER] == 0 ) status = dfofftop(win); if ( status == 0 ) { --win[WINDLNO]; --win[WINDOVER]; ++win[WINDUNDER]; } return status; } winddown(win) LONG win[]; { int status=0; if ( win[WINDUNDER] <= 0 ) status = dfoffbot(win); if ( status == 0 || status == EOF ) { ++win[WINDLNO]; ++win[WINDOVER]; --win[WINDUNDER]; } return status; } #page /* MARKER ROUTINES ** ** These routines are for manipulating markers. ** ** WMMARK sets a numbered marker at the current cursor position ** ** WMMKPOS returns the position of a marker ** ** WMMOVEMK moves the cursor to a numbered marker */ wmmark ( win, marker ) LONG win[], marker; { LONG *p = win[MARKS]; while ( marker-- ) { p = p[MARKNEXT]; if ( p == 0 ) return ERR; } p[MARKYPOS] = win[CURSLNO]; p[MARKXPOS] = win[CURSPOS]; return 0; } wmmkpos ( win, marker, xp, yp ) LONG win[], marker, *xp, *yp; { LONG *p = win[MARKS]; while ( marker-- ) { p = p[MARKNEXT]; if ( p == 0 ) return ERR; } *xp = p[MARKXPOS]; *yp = p[MARKYPOS]; return 0; } wmmovemk ( win, marker ) LONG win[], marker; { LONG *p = win[MARKS]; while ( marker-- ) { p = p[MARKNEXT]; if ( p == 0 ) return ERR; } return wmputcur ( win, p[MARKXPOS], p[MARKYPOS] ); } marklink ( win, markrec ) LONG win[], markrec[]; { LONG i=1, *p=win[MARKS]; /* add the marker to the end of the list, ** return position in chain */ while ( p[MARKNEXT] != 0 ) p = p[MARKNEXT], i++; p[MARKNEXT] = markrec; markrec[MARKNEXT]=0; return i; } markunlink ( win, markrec ) LONG win[], markrec[]; { LONG *p=win[MARKS]; /* remove the marker from the list */ while ( p[MARKNEXT] != markrec ) { p = p[MARKNEXT]; if ( p == 0 ) return ERR; } p[MARKNEXT] = markrec[MARKNEXT]; return 0; } #page /* SIMPLE CURSOR MOVEMENT ROUTINES ** ** These routines can be called to move the cursor up, down, ** left or right. */ wmup(win) LONG win[]; { return wmputcur ( win, win[CURSPOS], win[CURSLNO]-1 ); } wmdown(win) LONG win[]; { return wmputcur ( win, win[CURSPOS], win[CURSLNO]+1 ); } wmleft(win) LONG win[]; { return wmputcur ( win, win[CURSPOS]-1, win[CURSLNO] ); } wmright(win) LONG win[]; { return wmputcur ( win, win[CURSPOS]+1, win[CURSLNO] ); } #page /* MOVEIT ** This routine roughly corresponds to DFMOVEAP ** in the original DFM but is of course much simpler. ** ** DX specifies the offset on the cursor position. (There is ** now no separate AP). */ moveit(win,dx) LONG win[], dx; { BYTE *cursline = win[CURSLINE]; if ( dx > 0 ) while ( dx-- && cursline[win[CURSPOS]] != NL ) ++win[CURSPOS]; else while ( dx++ && win[CURSPOS] != 0 ) --win[CURSPOS]; } #page /* ----- COLOUR CHANGE ROUTINES ----- */ wmgetstyle(win) LONG win[]; { BYTE *attrptr = win[CURSATTR]; return attrptr[win[CURSPOS]]; } /* WMSCAN ** ** This routine is called to change the attributes ** of a large area of text: eg a marked block. ** The change stops at a marker point. ** Some of the attributes can be changed without ** affecting the others, by appropriate use of the mask. */ wmscan ( win, newattr, mask, marker ) LONG win[]; /* which window */ WORD newattr; /* the new attributes bits */ WORD mask; /* which bits to change */ WORD marker; /* where to stop */ { BYTE *cp, *ap, *cursattr = win[CURSATTR]; LONG num, endx, endy, lineno, ypos = win[CURSLNO], xpos = win[CURSPOS]; /* do nothing if at or past end point */ lineno = ypos; wmmkpos ( win, marker, &endx, &endy ); if ( lineno > endy || ( lineno == endy && xpos >= endx ) ) return; newattr &= mask; mask = ~mask; /* outer loop for lines */ while (1) { cp = lines ( win, lineno ) + xpos; ap = attrs ( win, lineno ) + xpos; /* calculate no of bytes to fill in this line */ num = BUFLEN; if ( lineno == endy ) num = endx; if ( lineno == ypos ) num -= xpos; /* update bytes in this line */ while ( num-- > 0 ) { if ( *cp++ == 0 ) break; /* quit at end of line */ *ap = (*ap & mask) + newattr; ap++; } /* repaint & set up for next line */ paintline ( win, lineno ); if ( lineno == endy ) break; xpos = 0; if ( wmputcur ( win, 0, ++lineno ) != 0 ) break; } } #page /* ---- sort of screen driver routines ---- */ showchar ( win, pos ) LONG win[], pos; { BYTE *cursattr = win[CURSATTR], *cursline = win[CURSLINE]; wmcursor ( win, pos, win[CURSLNO], OFF ); setscreen ( win[WCB], cursattr[pos] ); wscrchar ( win, cursline[pos] ); } wcls ( win, part ) LONG win[], part; { if ( enabled(win, -2) ) cls ( win[WCB], part ); } wcursen ( win, onoff ) LONG win[], onoff; { if ( enabled(win,-2) ) cursen(win[WCB],onoff); } wpan ( win, distance, part ) LONG win[], distance, part; { if ( enabled(win, win[CURSLNO]) ) pan ( win[WCB], distance, part ); } wscrchar ( win, ch ) LONG win[], ch; { if ( ch < SPACE && ch > ESC ) ch = SPACE; if ( enabled(win, win[CURSLNO]) ) scrchar( win[WCB], ch); } paintline ( win, lineno ) LONG win[], lineno; { if ( lineno >= win[WINDLNO] && lineno < win[WINDLNO]+win[WINDEPTH] ) paintchars ( win, lineno ); } blankline( win, line ) LONG win[], line; { wmcursor ( win, win[WINDXPOS], line, OFF ); cls ( win[WCB], PART_LINE ); } fixcursor(win) LONG win[]; { wmcursor ( win, win[CURSPOS], win[CURSLNO], win[CURSENABLED] ); } wmcursor ( win, x, y, onoff ) LONG win[], x, y; FLAG onoff; { if ( NOT enabled(win,-2) ) return; if ( onoff == OFF ) cursen ( win[WCB], OFF ); at ( win[WCB], y-win[WINDLNO], x-win[WINDXPOS] ); if ( onoff ) cursen ( win[WCB], ON ); } wmupdate(win) LONG win[]; { LONG line; BYTE *changed=&win[CHANGED]; if ( NOT enabled(win, -2) ) return 0; win[CURSENABLED]=OFF; wcursen(win, OFF); for ( line=0; line= win[WINDLNO] ) changed[chline-win[WINDLNO]]=YES; } else checktop(win[WCB]); return (win[WINDISABLED]==NO); } vsscroll ( win, distance ) LONG win[], distance; /* + means move text down (window up) */ { int firstline = 0; /* no of first line to repaint */ int numlines = abs(distance); /* work out no of lines to paint */ /* beware side effect */ if ( distance == 0 || NOT enabled(win,-1) ) return; if ( distance < 0 && numlines < win[WINDEPTH] ) firstline = win[WINDEPTH] - numlines; if ( numlines < win[WINDEPTH] ) scroll ( win[WCB], win[LINEHEIGHT] * distance, PART_ALL); else numlines = win[WINDEPTH]; wmcursor ( win, win[WINDXPOS], win[WINDLNO]+firstline, OFF ); if ( offscreen ( win[WCB] ) ) redisplay(win); else { wmrefresh ( win, firstline, numlines ); clearstrip(win); } pgdisplay(win, NO); scvertbar(win); /* update vertical scroll bar */ } wmrefresh ( win, y, h ) LONG win[], y, h; { LONG n; for ( n = win[WINDLNO]+y; n < win[WINDLNO]+y+h; ++n ) paintchars ( win, n ); fixcursor ( win ); return 0; } schorizbar(win) LONG win[]; { if ( win[WINDXPOS] != win[OLDXPOS] ) s_hbar ( win[WCB], win[OLDXPOS]=win[WINDXPOS], win[WINWIDTH], MAXLEN ); } scvertbar(win) LONG win[]; { LONG total = win[WINDLNO]+win[WINDEPTH]+win[BOTCOUNT]; if ( win[WINDUNDER] > 0 ) total += win[WINDUNDER]; s_vbar ( win[WCB], win[WINDLNO], win[WINDEPTH], total ); } #page scrollpart ( win, lineno, distance ) LONG win[], lineno, distance; { if ( NOT enabled(win, -1) ) return; cursen ( win[WCB], OFF ); if ( lineno == win[WINDLNO] ) scroll ( win[WCB], distance, PART_ALL ); else { wmcursor ( win, win[WINDXPOS], lineno-1, OFF ); scroll ( win[WCB], distance, PART_BOT ); } fixcursor(win); pgdisplay(win, NO); scvertbar(win); } #page fastcopy ( sce, dest, count ) register BYTE *sce; register BYTE *dest; register WORD count; { if ( dest >= sce ) /* account for possible overlap */ { sce += count; dest += count; while ( count-- ) *--dest = *--sce; } else { while ( count-- ) *dest++ = *sce++; } } fastfill ( value, pointer, count ) register BYTE value; register BYTE *pointer; register WORD count; { while ( count-- ) *pointer++ = value; } backshuffle ( sce, offset, count ) register BYTE *sce; WORD offset; register WORD count; { register BYTE *dst = sce + offset; while ( count-- ) *dst-- = *sce--; } lines ( win, line ) LONG win[], line; { return win[TEXTBUFF]+(line%BUFLINES)*(2*BUFLEN); } attrs ( win, line ) LONG win[], line; { return win[TEXTBUFF]+BUFLEN+(line%BUFLINES)*(2*BUFLEN); }