This is mark.c in view mode; [Download] [Up]
/* Copyright (c) 1991 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Copyright (c) 1987 Oliver Laumann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING); if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Noteworthy contributors to screen's design and implementation: * Wayne Davison (davison@borland.com) * Patrick Wolfe (pat@kai.com, kailand!pat) * Bart Schaefer (schaefer@cse.ogi.edu) * Nathan Glasser (nathan@brokaw.lcs.mit.edu) * Larry W. Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu) * Howard Chu (hyc@hanauma.jpl.nasa.gov) * Tim MacKenzie (tym@dibbler.cs.monash.edu.au) * Markku Jarvinen (mta@{cc,cs,ee}.tut.fi) * Marc Boucher (marc@CAM.ORG) * **************************************************************** */ #ifndef lint static char rcs_id[] = "$Id: mark.c,v 1.2 92/02/03 02:27:48 jnweiger Exp $ FAU"; #endif #include <sys/types.h> #ifdef BSD # include <sys/signal.h> #endif /* BSDI */ #include "config.h" #include "screen.h" #include "ansi.h" /* here we find A_SO, ASCII, EXPENSIVE */ #include "extern.h" static int is_letter __P((int)); static void nextword __P((int *, int *, int, int)); static int linestart __P((int)); static int lineend __P((int)); static int rem __P((int, int , int , int , int , char *, int)); static int eq __P((int, int )); static void revto __P((int, int)); static void revto_line __P((int, int, int)); static void MarkRedisplayLine __P((int, int, int, int)); static int MarkRewrite __P((int, int, int, int)); static void process_mark_input __P((char **, int *)); static void AbortMarkRoutine __P((void)); static int MarkScrollDownDisplay __P((int)); static int MarkScrollUpDisplay __P((int)); int join_with_cr = 0; extern struct win *fore, *wtab[]; extern int screenwidth, screenheight; extern int screentop, screenbot; extern char GlobalAttr, GlobalCharset; extern int in_ovl; extern int HS; extern int LP; extern char *null, *blank; #ifdef NETHACK extern nethackflag; #endif char *copybuffer = NULL; int copylen = 0; char mark_key_tab[256]; /* this array must be initialised first! */ static int in_mark; /* mark routine active */ static int left_mar, right_mar, nonl; static int x1, y1, second; /* y1 is in terms of WIN coordinates, not DISPLAY */ static int cx, cy; /* Cursor Position in WIN coords*/ static rep_cnt; /* no. of repeats are rep_cnt+1. jw. */ static int append_mode; /* shall we overwrite or append to copybuffer */ static write_buffer; /* shall we do a KEY_WRITE_EXCHANGE right away? */ static hist_offset; static int is_letter(c) char c; { if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '.' || c == '@' || c == ':' || c == '%' || c == '!' || c == '-' || c == '+') /* thus we can catch email-addresses as a word :-) */ return 1; else if (c != ' ') return 2; return 0; } /* * iWIN gives us a reference to line y of the *whole* image * where line 0 is the oldest line in our history. * y must be in WIN coordinate system, not in display. */ #define iWIN(y) ((y < fore->histheight) ? fore->ihist[(fore->histidx + y)\ % fore->histheight] : fore->image[y - fore->histheight]) #define aWIN(y) ((y < fore->histheight) ? fore->ahist[(fore->histidx + y)\ % fore->histheight] : fore->attr[y - fore->histheight]) #define fWIN(y) ((y < fore->histheight) ? fore->fhist[(fore->histidx + y)\ % fore->histheight] : fore->font[y - fore->histheight]) /* * hist_offset tells us, how many lines there are on top of the * visible screen. */ #define W2D(y) ((y)-hist_offset) #define D2W(y) ((y)+hist_offset) static int linestart(y) int y; { register int x; register char *i; for (x = left_mar, i = iWIN(y) + x; x < screenwidth-1; x++) if (*i++ != ' ') break; if (x == screenwidth-1) x = left_mar; return(x); } static int lineend(y) int y; { register int x; register char *i; for (x = right_mar, i = iWIN(y) + x; x >= 0; x--) if (*i-- != ' ') break; if (x < 0) x = left_mar; return(x); } /* * nextword calculates the cursor position of the num'th word. * If the cursor is on a word, it counts as the first. * NW_BACK: search backward * NW_ENDOFWORD: find the end of the word * NW_MUSTMOVE: move even if the position is correct. */ #define NW_BACK 1 #define NW_ENDOFWORD 2 #define NW_MUSTMOVE 4 static void nextword(xp, yp, flags, num) int *xp, *yp, flags, num; { int xx = screenwidth, yy = fore->histheight + screenheight; register int sx, oq, q, x, y; x = *xp; y = *yp; sx = (flags & NW_BACK) ? -1 : 1; if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE)) x += sx; for (oq = -1; ; x += sx, oq = q) { if (x >= xx || x < 0) q = 0; else q = is_letter(iWIN(y)[x]); if (oq >= 0 && oq != q) { if (oq == 0 || !(flags & NW_ENDOFWORD)) *xp = x; else *xp = x-sx; *yp = y; if ((!(flags & NW_ENDOFWORD) && q) || ((flags & NW_ENDOFWORD) && oq)) { if (--num <= 0) return; } } if (x == xx) { x = -1; if (++y >= yy) return; } else if (x < 0) { x = xx; if (--y < 0) return; } } } /* * y1, y2 are WIN coordinates * * redisplay: 0 - just copy * 1 - redisplay + copy * 2 - count + copy, don't redisplay */ static int rem(x1, y1, x2, y2, redisplay, pt, yend) int x1, y1, x2, y2, redisplay, yend; char *pt; { int i, j, from, to, ry; int l = 0; char *im; second = 0; if (y2 < y1 || ((y2 == y1) && (x2 < x1))) { i = y2; y2 = y1; y1 = i; i = x2; x2 = x1; x1 = i; } ry = y1 - hist_offset; i = y1; if (redisplay != 2 && pt == 0 && ry <0) { i -= ry; ry = 0; } for (; i <= y2; i++, ry++) { if (redisplay != 2 && pt == 0 && ry > yend) break; from = (i == y1) ? x1 : 0; if (from < left_mar) from = left_mar; for (to = screenwidth-1, im = iWIN(i)+to; to>=0; to--) if (*im-- != ' ') break; if (i == y2 && x2 < to) to = x2; if (to > right_mar) to = right_mar; if (redisplay == 1 && from <= to && ry >=0 && ry <= yend) MarkRedisplayLine(ry, from, to, 0); if (redisplay != 2 && pt == 0) /* don't count/copy */ continue; for (j = from, im = iWIN(i)+from; j <= to; j++) { if (pt) *pt++ = *im++; l++; } if (i != y2) { /* * this code defines, what glues lines together */ switch (nonl) { case 0: /* lines separated by newlines */ if (join_with_cr) { if (pt) *pt++ = '\r'; l++; } if (pt) *pt++ = '\n'; l++; break; case 1: /* nothing to separate lines */ break; case 2: /* lines separated by blanks */ if (pt) *pt++ = ' '; l++; break; } } } return(l); } static int eq(a, b) int a, b; { if (a == b) return 1; if (a == 0 || b == 0) return 1; if (a <= '9' && a >= '0' && b <= '9' && b >= '0') return 1; return 0; } static int crazychar = 0; static int crazy_y = -1; static int crazy_x = -1; int MarkRoutine(flag) /* return value 1 when copybuffer changed; */ int flag; { int x, y, i; hist_offset = fore->histheight; if (!fore->active) { Msg(0, "Fore window is not active !!!"); return 0; } second = 0; rep_cnt = 0; append_mode = 0; write_buffer = 0; nonl = left_mar = 0; right_mar = screenwidth-1; x = fore->x; y = D2W(fore->y); if (x >= screenwidth) x = screenwidth-1; if (flag == CRAZY && crazychar != 0 && crazy_x != -1 && crazy_y != -1) { Msg(0, "CRAZY mode not impl.\n"); } crazychar = 0; crazy_y = -1; crazy_x = -1; if (flag == TRICKY) { int f, q = 0, xx, yy; char *linep; debug2("cursor is at x=%d, y=%d\n", fore->x, D2W(fore->y)); for (xx = fore->x - 1, linep = iWIN(y) + xx; xx >= 0; xx--) if ((q = *linep--) != ' ' ) break; debug3("%c at (%d,%d)\n", q, xx, y); for (yy = D2W(fore->y) - 1; yy >= 0; yy--) if (xx < 0 || eq(iWIN(yy)[xx], q)) { /* line is matching... */ f = 0; for (i = fore->x; i < screenwidth-1; i++) { if (iWIN(yy)[i] != ' ') { f = 1; break; } } if (f) break; } if (yy < 0) return 0; xx = 0; for (i = screenwidth-1, linep = iWIN(yy)+i; i>0; i--) if (*linep-- != ' ') break; if (i < x) i = x; if (copybuffer != NULL) Free(copybuffer); if ((copybuffer = malloc((unsigned) (i - x + 2))) == NULL) { Msg(0, "Not enough memoooh!... Sorry."); return 0; } rem(x, yy, i, yy, 0, copybuffer, 0); copylen = i - x + 1; return 1; } InitOverlayPage(process_mark_input, MarkRedisplayLine, MarkRewrite, 1); GotoPos(x, W2D(y)); #ifdef NETHACK if (nethackflag) Msg(0, "Welcome to hacker's treasure zoo - Column %d Line %d(+%d) (%d,%d)", x+1, W2D(y+1), fore->histheight, fore->width, fore->height); else #endif Msg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)", x+1, W2D(y+1), fore->histheight, fore->width, fore->height); fflush(stdout); cx = x1 = x; cy = y1 = y; in_mark = 1; return 0; } static void process_mark_input(inbufp,inlenp) char **inbufp; int *inlenp; { char *inbuf, *pt; int inlen; int x2, y2, i, j, yend; int newcopylen = 0, od; /* char *extrap = 0, extrabuf[100]; */ if (inbufp == 0) { AbortMarkRoutine(); return; } inbuf= *inbufp; inlen= *inlenp; pt = inbuf; while (in_mark && (inlen /* || extrap */)) { if (!HS) RemoveStatus(); /* if (extrap) { od = *extrap++; if (*extrap == 0) extrap = 0; } else */ { od = mark_key_tab[*pt++]; inlen--; } if (od >= '0' && od <= '9') { if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0)) { rep_cnt = 10 * rep_cnt + od - '0'; continue; /* * Now what is that 1001 here? Well, we have a screen with * 25 * 80 = 2000 characters. Movement is at most across the full * screen. This we do with word by word movement, as character by * character movement never steps over line boundaries. The most words * we can place on the screen are 1000 single letter words. Thus 1001 * is sufficient. Users with bigger screens never write in single letter * words, as they should be more advanced. jw. * Oh, wrong. We still give even the experienced user a factor of ten. */ } } switch (od) { case '\014': /* CTRL-L Redisplay */ Redisplay(0); GotoPos(cx, W2D(cy)); break; case '\010': /* CTRL-H Backspace */ case 'h': if (rep_cnt == 0) rep_cnt = 1; revto(cx - rep_cnt, cy); break; case '\016': /* CTRL-N */ case 'j': if (rep_cnt == 0) rep_cnt = 1; revto(cx, cy + rep_cnt); break; case '+': if (rep_cnt == 0) rep_cnt = 1; j = cy + rep_cnt; if (j > fore->histheight + screenheight - 1) j = fore->histheight + screenheight - 1; revto(linestart(j), j); break; case '-': if (rep_cnt == 0) rep_cnt = 1; j = cy - rep_cnt; if (j < 0) j = 0; revto(linestart(j), j); break; case '^': revto(linestart(cy), cy); break; case '\n': revto(left_mar, cy + 1); break; case 'k': case '\020': /* CTRL-P */ if (rep_cnt == 0) rep_cnt = 1; revto(cx, cy - rep_cnt); break; case 'l': if (rep_cnt == 0) rep_cnt = 1; revto(cx + rep_cnt, cy); break; case '\001': /* CTRL-A from tcsh/emacs */ case '0': revto(left_mar, cy); break; case '\004': /* CTRL-D down half screen */ if (rep_cnt == 0) rep_cnt = (screenheight+1) >> 1; revto_line(cx, cy + rep_cnt, W2D(cy)); break; case '$': revto(lineend(cy), cy); break; case '\025': /* CTRL-U up half screen */ if (rep_cnt == 0) rep_cnt = (screenheight+1) >> 1; revto_line(cx, cy - rep_cnt, W2D(cy)); break; case '?': if (left_mar == 0 && right_mar == screenwidth - 1) Msg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1, hist_offset); else Msg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1, left_mar+1, right_mar+1, W2D(cy)+1, hist_offset); break; case '\002': /* CTRL-B back one page */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt *= (screenheight-1); revto(cx, cy - rep_cnt); break; case '\006': /* CTRL-F forward one page */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt *= (screenheight-1); revto(cx, cy + rep_cnt); break; case '\005': /* CTRL-E scroll up */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt = MarkScrollUpDisplay(rep_cnt); if (cy < D2W(0)) revto(cx, D2W(0)); else GotoPos(cx, W2D(cy)); break; case '\031': /* CTRL-Y scroll down */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt = MarkScrollDownDisplay(rep_cnt); if (cy > D2W(screenheight-1)) revto(cx, D2W(screenheight-1)); else GotoPos(cx, W2D(cy)); break; case '@': /* it may be usefull to have a key that does nothing */ break; case '%': rep_cnt--; /* rep_cnt is a percentage for the history buffer */ if (rep_cnt < 0) rep_cnt = 0; if (rep_cnt > 100) rep_cnt = 100; revto_line(left_mar, (rep_cnt * (fore->histheight + screenheight)) / 100, (screenheight-1)/2); break; case 'g': rep_cnt = 1; /* FALLTHROUGH */ case 'G': /* rep_cnt is here the WIN line number */ if (rep_cnt == 0) rep_cnt = fore->histheight + screenheight; revto_line(left_mar, --rep_cnt, (screenheight-1)/2); break; case 'H': revto(left_mar, D2W(0)); break; case 'M': revto(left_mar, D2W((screenheight-1) / 2)); break; case 'L': revto(left_mar, D2W(screenheight-1)); break; case '|': revto(--rep_cnt, cy); break; case 'w': i = cx; j = cy; if (rep_cnt == 0) rep_cnt = 1; nextword(&i, &j, NW_MUSTMOVE, rep_cnt); revto(i, j); break; case 'e': i = cx; j = cy; if (rep_cnt == 0) rep_cnt = 1; nextword(&i, &j, NW_ENDOFWORD|NW_MUSTMOVE, rep_cnt); revto(i, j); break; case 'b': i = cx; j = cy; if (rep_cnt == 0) rep_cnt = 1; nextword(&i, &j, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE, rep_cnt); revto(i, j); break; case 'a': append_mode = 1 - append_mode; debug1("append mode %d--\n", append_mode); Msg(0, (append_mode) ? ":set append" : ":set noappend"); break; case 'v': case 'V': /* this sets start column to column 9 for VI :set nu users */ if (left_mar == 8) rep_cnt = 1; else rep_cnt = 9; /* FALLTHROUGH */ case 'c': case 'C': /* set start column (c) and end column (C) */ if (second) { rem(x1, y1, cx, cy, 1, (char *)0, screenheight-1); /* Hack */ second = 1; /* rem turns off second */ } rep_cnt--; if (rep_cnt < 0) rep_cnt = cx; if (od != 'C') { left_mar = rep_cnt; if (left_mar > right_mar) left_mar = right_mar; } else { right_mar = rep_cnt; if (left_mar > right_mar) right_mar = left_mar; } if (second) { int x = cx, y = cy; cx = x1; cy = y1; revto(x, y); } if (od == 'v' || od == 'V') Msg(0, (left_mar != 8) ? ":set nonu" : ":set nu"); break; case 'J': /* how do you join lines in VI ? */ nonl = (nonl + 1) % 3; switch (nonl) { case 0: if (join_with_cr) Msg(0, "Multiple lines (CR/LF)"); else Msg(0, "Multiple lines (LF)"); break; case 1: Msg(0, "Lines joined"); break; case 2: Msg(0, "Lines joined with blanks"); break; } break; case 'y': case 'Y': if (!second) { revto(linestart(cy), cy); second++; x1 = cx; y1 = cy; } if (--rep_cnt > 0) revto(cx, cy + rep_cnt); revto(lineend(cy), cy); if (od == 'y') break; /* FALLTHROUGH */ case 'W': if (od == 'W') { if (rep_cnt == 0) rep_cnt = 1; if (!second) { i = cx; j = cy; nextword(&i, &j, NW_BACK|NW_ENDOFWORD, 1); revto(i, j); second++; x1 = cx; y1 = cy; } i = cx; j = cy; nextword(&i, &j, NW_ENDOFWORD, rep_cnt); revto(i, j); } /* FALLTHROUGH */ case 'A': if (od == 'A') append_mode = 1; /* FALLTHROUGH */ case '>': if (od == '>') write_buffer = 1; /* FALLTHROUGH */ case ' ': case '\r': if (!second) { second++; x1 = cx; y1 = cy; revto(x1, y1); #ifdef NETHACK if (nethackflag) Msg(0, "You drop a magic marker - Column %d Line %d", cx+1, W2D(cy)+1, hist_offset); else #endif Msg(0, "First mark set - Column %d Line %d", cx+1, cy+1); break; } else { x2 = cx; y2 = cy; newcopylen = rem(x1, y1, x2, y2, 2, (char *)0, 0); /* count */ if (copybuffer != NULL && !append_mode) { copylen = 0; Free(copybuffer); } if (newcopylen > 0) { /* the +3 below is for : cr + lf + \0 */ if (copybuffer != NULL) copybuffer = realloc(copybuffer, (unsigned) (copylen + newcopylen + 3)); else { copylen = 0; copybuffer = malloc((unsigned) (newcopylen + 3)); } if (copybuffer == NULL) { AbortMarkRoutine(); Msg(0, "Not enough memoooh!... Sorry."); copylen = 0; copybuffer = NULL; break; } if (append_mode) { switch (nonl) /* * this code defines, what glues lines together */ { case 0: if (join_with_cr) { copybuffer[copylen] = '\r'; copylen++; } copybuffer[copylen] = '\n'; copylen++; break; case 1: break; case 2: copybuffer[copylen] = ' '; copylen++; break; } } yend = screenheight - 1; if (fore->histheight - hist_offset < screenheight) { second = 0; yend -= MarkScrollUpDisplay(fore->histheight - hist_offset); } copylen += rem(x1, y1, x2, y2, hist_offset == fore->histheight, copybuffer + copylen, yend); } if (hist_offset != fore->histheight) { in_ovl = 0; /* So we can use Activate() */ Activate(0); } ExitOverlayPage(); if (append_mode) Msg(0, "Appended %d characters to buffer", newcopylen); else Msg(0, "Copied %d characters into buffer", copylen); if (write_buffer) WriteFile(DUMP_EXCHANGE); in_mark = 0; break; } default: AbortMarkRoutine(); #ifdef NETHACK if (nethackflag) Msg(0, "You escaped the dungeon."); else #endif Msg(0, "Copy mode aborted"); break; } rep_cnt = 0; } fflush(stdout); *inbufp = pt; *inlenp = inlen; } static void revto(tx, ty) int tx, ty; { revto_line(tx, ty, -1); } /* tx, ty: WINDOW, line: DISPLAY */ static void revto_line(tx, ty, line) int tx, ty, line; { int fx, fy; int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0; int ystart = 0, yend = screenheight-1; int i, ry; if (tx < 0) tx = 0; else if (tx > screenwidth - 1) tx = screenwidth -1; if (ty < 0) ty = 0; else if (ty > fore->histheight + screenheight - 1) ty = fore->histheight + screenheight - 1; fx = cx; fy = cy; cx = tx; cy = ty; /*debug2("revto(%d, %d, ", x1, y1); debug2("%d, %d, ", fx, fy); debug2("%d, %d)\n", tx, ty);*/ /* * if we go to a position that is currently offscreen * then scroll the screen */ i = 0; if (line >= 0 && line < screenheight) i = W2D(ty) - line; else if (ty < hist_offset) i = ty - hist_offset; else if (ty > hist_offset + (screenheight-1)) i = ty-hist_offset-(screenheight-1); if (i > 0) yend -= MarkScrollUpDisplay(i); else if (i < 0) ystart += MarkScrollDownDisplay(-i); if (second == 0) { GotoPos(tx, W2D(cy)); return; } qq = x1 + y1 * screenwidth; ff = fx + fy * screenwidth; /* "from" offset in WIN coords */ tt = tx + ty * screenwidth; /* "to" offset in WIN coords*/ if (ff > tt) { st = tt; en = ff; x = tx; y = ty; } else { st = ff; en = tt; x = fx; y = fy; } if (st > qq) { st++; x++; } if (en < qq) en--; if (tt > qq) { revst = qq; reven = tt; } else { revst = tt; reven = qq; } ry = y - hist_offset; if (ry < ystart) { y += (ystart - ry); x = 0; st = y * screenwidth; ry = ystart; } for (t = st; t <= en; t++, x++) { if (x >= screenwidth) { x = 0; y++, ry++; } if (ry > yend) break; if (t == st || x == 0) { for (ce = screenwidth-1; ce >= 0; ce--) if (iWIN(y)[ce] != ' ') break; } if (x <= ce && x >= left_mar && x <= right_mar && (LP || x < screenwidth-1 || ry < screenbot)) { GotoPos(x, W2D(y)); if (t >= revst && t <= reven) SaveSetAttr(A_SO, ASCII); else SaveSetAttr(aWIN(y)[x], fWIN(y)[x]); PUTCHAR(iWIN(y)[x]); } } GotoPos(tx, W2D(cy)); } static void AbortMarkRoutine() { int yend, redisp; yend = screenheight - 1; redisp = second; if (fore->histheight - hist_offset < screenheight) { second = 0; yend -= MarkScrollUpDisplay(fore->histheight - hist_offset); } if (hist_offset != fore->histheight) { in_ovl = 0; /* So we can use Activate() */ Activate(0); /* to do a complete redisplay */ } else { rem(x1, y1, cx, cy, redisp, (char *)0, yend); } ExitOverlayPage(); in_mark = 0; } static void MarkRedisplayLine(y, xs, xe, isblank) int y; /* NOTE: y is in DISPLAY coords system! */ int xs, xe; int isblank; { int x, i, rm; int sta, sto, cp; /* NOTE: these 3 are in WINDOW coords system */ char *wi, *wa, *wf, *oldi; InsertMode(0); /* Not done in DisplayLine() */ wi = iWIN(D2W(y)); wa = aWIN(D2W(y)); wf = fWIN(D2W(y)); oldi = isblank ? blank : null; if (second == 0) { DisplayLine(oldi, null, null, wi, wa, wf, y, xs, xe); return; } sta = y1 * screenwidth + x1; sto = cy * screenwidth + cx; if (sta > sto) { i=sta; sta=sto; sto=i; } cp = D2W(y) * screenwidth + xs; rm = right_mar; for (x = screenwidth - 1; x >= 0; x--) if (wi[x] != ' ') break; if (x < rm) rm = x; for (x = xs; x <= xe; x++, cp++) if (cp >= sta && x >= left_mar) break; if (x > xs) DisplayLine(oldi, null, null, wi, wa, wf, y, xs, x-1); for (; x <= xe; x++, cp++) { if (cp > sto || x > rm || (!LP && x >= screenwidth-1 && y == screenbot)) break; GotoPos(x, y); SaveSetAttr(A_SO, ASCII); PUTCHAR(wi[x]); } if (x<=xe) DisplayLine(oldi, null, null, wi, wa, wf, y, x, xe); } static int MarkRewrite(ry, xs, xe, doit) int ry, xs, xe, doit; { int dx, x, y, st, en, t, rm; char *a, *f, *i; y = D2W(ry); dx = xe - xs; if (doit) { i = iWIN(y) + xs; while (dx--) PUTCHAR(*i++); return(0); } a = aWIN(y) + xs, f = fWIN(y) + xs; if (second == 0) st = en = -1; else { st = y1 * screenwidth + x1; en = cy * screenwidth + cx; if (st > en) { t = st; st = en; en = t; } } t = y * screenwidth + xs; for (rm=screenwidth-1, i=iWIN(y) + screenwidth-1; rm>=0; rm--) if (*i-- != ' ') break; if (rm > right_mar) rm = right_mar; x = xs; while (dx--) { if (t >= st && t <= en && x >= left_mar && x <= rm) { if (GlobalAttr != A_SO || GlobalCharset != ASCII) return(EXPENSIVE); } else { if (GlobalAttr != *a || GlobalCharset != *f) return(EXPENSIVE); } a++, f++, t++, x++; } return(xe - xs); } /* * scroll the screen contents up/down. */ static int MarkScrollUpDisplay(n) int n; { int i; debug1("MarkScrollUpDisplay(%d)\n", n); if (n <= 0) return 0; if (n > fore->histheight - hist_offset) n = fore->histheight - hist_offset; i = (n < screenheight) ? n : (screenheight); ScrollRegion(0, screenheight - 1, i); hist_offset += n; while (i-- > 0) MarkRedisplayLine(screenheight-i-1, 0, screenwidth-1, 1); return n; } static int MarkScrollDownDisplay(n) int n; { int i; debug1("MarkScrollDownDisplay(%d)\n", n); if (n <= 0) return 0; if (n > hist_offset) n = hist_offset; i = (n < screenheight) ? n : (screenheight); ScrollRegion(0, screenheight - 1, -i); hist_offset -= n; while (i-- > 0) MarkRedisplayLine(i, 0, screenwidth-1, 1); return n; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.