void MarkRoutine() { int x, y; if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1)) return; flayer->l_encoding = fore->w_encoding; flayer->l_mode = 1; markdata = (struct markdata *)flayer->l_data; markdata->md_user = D_user; /* XXX: Correct? */ markdata->md_window = fore; markdata->second = 0; markdata->rep_cnt = 0; markdata->append_mode = 0; markdata->write_buffer = 0; markdata->nonl = 0; markdata->left_mar = 0; markdata->right_mar = fore->w_width - 1; markdata->hist_offset = fore->w_histheight; x = fore->w_x; y = D2W(fore->w_y); if (x >= fore->w_width) x = fore->w_width - 1; LGotoPos(flayer, x, W2D(y)); LMsg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)", x + 1, W2D(y + 1), fore->w_histheight, fore->w_width, fore->w_height); markdata->cx = markdata->x1 = x; markdata->cy = markdata->y1 = y; flayer->l_x = x; flayer->l_y = W2D(y); }
static void erase_chars(struct inpdata *inpdata, char *from, char *to, int x, int mv) { int chng; ASSERT(from < to); if (inpdata->inp.len > to - inpdata->inp.buf) memmove(from, to, inpdata->inp.len - (to - inpdata->inp.buf)); chng = to - from; if (mv) { x -= chng; inpdata->inp.pos -= chng; } inpdata->inp.len -= chng; if (!(inpdata->inpmode & INP_NOECHO)) { struct mchar mc; char *s = from < to ? from : to; mc = mchar_so; while (s < inpdata->inp.buf+inpdata->inp.len) { mc.image = *s++; LPutChar(flayer, &mc, x++, INPUTLINE); } while (chng--) LPutChar(flayer, &mchar_blank, x++, INPUTLINE); x = inpdata->inpstringlen + inpdata->inp.pos; LGotoPos(flayer, x, INPUTLINE); } }
/* tx, ty: WINDOW, line: DISPLAY */ void revto_line(int tx, int ty, int line) { int fx, fy; int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0; int ystart = 0, yend = fore->w_height - 1; int i, ry; uint32_t *wi; struct mline *ml; struct mchar mc; if (tx < 0) tx = 0; else if (tx > fore->w_width - 1) tx = fore->w_width - 1; if (ty < 0) ty = 0; else if (ty > fore->w_histheight + fore->w_height - 1) ty = fore->w_histheight + fore->w_height - 1; fx = markdata->cx; fy = markdata->cy; /* don't just move inside of a kanji, the user wants to see something */ ml = WIN(ty); if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1) tx++; if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx) tx--; markdata->cx = tx; markdata->cy = ty; /* * if we go to a position that is currently offscreen * then scroll the screen */ i = 0; if (line >= 0 && line < fore->w_height) i = W2D(ty) - line; else if (ty < markdata->hist_offset) i = ty - markdata->hist_offset; else if (ty > markdata->hist_offset + (fore->w_height - 1)) i = ty - markdata->hist_offset - (fore->w_height - 1); if (i > 0) yend -= MarkScrollUpDisplay(i); else if (i < 0) ystart += MarkScrollDownDisplay(-i); if (markdata->second == 0) { flayer->l_x = tx; flayer->l_y = W2D(ty); LGotoPos(flayer, tx, W2D(ty)); return; } qq = markdata->x1 + markdata->y1 * fore->w_width; ff = fx + fy * fore->w_width; /* "from" offset in WIN coords */ tt = tx + ty * fore->w_width; /* "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 - markdata->hist_offset; if (ry < ystart) { y += (ystart - ry); x = 0; st = y * fore->w_width; ry = ystart; } ml = WIN(y); for (t = st; t <= en; t++, x++) { if (x >= fore->w_width) { x = 0; y++, ry++; ml = WIN(y); } if (ry > yend) break; if (t == st || x == 0) { wi = ml->image + fore->w_width; for (ce = fore->w_width; ce >= 0; ce--, wi--) if (*wi != ' ') break; } if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar) { if (dw_right(ml, x, fore->w_encoding)) { if (t == revst) revst--; t--; x--; } if (t >= revst && t <= reven) { mc = mchar_so; if (pastefont) { mc.font = ml->font[x]; mc.fontx = ml->fontx[x]; } mc.image = ml->image[x]; } else copy_mline2mchar(&mc, ml, x); if (dw_left(ml, x, fore->w_encoding)) { mc.mbcs = ml->image[x + 1]; LPutChar(flayer, &mc, x, W2D(y)); t++; } LPutChar(flayer, &mc, x, W2D(y)); if (dw_left(ml, x, fore->w_encoding)) x++; } } flayer->l_x = tx; flayer->l_y = W2D(ty); LGotoPos(flayer, tx, W2D(ty)); }
static void MarkProcess(char **inbufp, size_t *inlenp) { char *inbuf, *pt; int inlen; int cx, cy, x2, y2, j, yend; int newcopylen = 0, od; int in_mark; int rep_cnt; struct acluser *md_user; /* char *extrap = 0, extrabuf[100]; */ markdata = (struct markdata *)flayer->l_data; fore = markdata->md_window; md_user = markdata->md_user; if (inbufp == 0) { MarkAbort(); return; } LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); inbuf = *inbufp; inlen = *inlenp; pt = inbuf; in_mark = 1; while (in_mark && (inlen /* || extrap */ )) { unsigned char ch = (unsigned char)*pt++; inlen--; if (flayer->l_mouseevent.start) { int r = LayProcessMouse(flayer, ch); if (r == -1) LayProcessMouseSwitch(flayer, 0); else { if (r) ch = 0222; else continue; } } od = mark_key_tab[(int)ch]; rep_cnt = markdata->rep_cnt; if (isdigit(od) && !markdata->f_cmd.flag) { if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0)) { markdata->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. */ } } cx = markdata->cx; cy = markdata->cy; if (markdata->f_cmd.flag) { markdata->f_cmd.flag = 0; markdata->rep_cnt = 0; if (isgraph(od)) { markdata->f_cmd.target = od; rep_cnt = (rep_cnt) ? rep_cnt : 1; nextchar(&cx, &cy, markdata->f_cmd.direction, od, rep_cnt); revto(cx, cy); continue; } } processchar: switch (od) { case 'f': /* fall through */ case 'F': /* fall through */ case 't': /* fall through */ case 'T': /* fall through */ /* * Set f_cmd to do a search on the next key stroke. * If we break, rep_cnt will be reset, so we * continue instead. It might be cleaner to * store the rep_count in f_cmd and * break here so later followon code will be * hit. */ markdata->f_cmd.flag = 1; markdata->f_cmd.direction = od; continue; case ';': case ',': if (!markdata->f_cmd.target) break; if (!rep_cnt) rep_cnt = 1; nextchar(&cx, &cy, od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20), markdata->f_cmd.target, rep_cnt); revto(cx, cy); break; case 'o': case 'x': if (!markdata->second) break; markdata->cx = markdata->x1; markdata->cy = markdata->y1; markdata->x1 = cx; markdata->y1 = cy; revto(markdata->cx, markdata->cy); break; case '\014': /* CTRL-L Redisplay */ Redisplay(0); LGotoPos(flayer, cx, W2D(cy)); break; case 0202: /* M-C-b */ case '\010': /* CTRL-H Backspace */ case 'h': if (rep_cnt == 0) rep_cnt = 1; revto(cx - rep_cnt, cy); break; case 0216: /* M-C-p */ 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->w_histheight + fore->w_height - 1) j = fore->w_histheight + fore->w_height - 1; revto(linestart(j), j); break; case '-': if (rep_cnt == 0) rep_cnt = 1; cy -= rep_cnt; if (cy < 0) cy = 0; revto(linestart(cy), cy); break; case '^': revto(linestart(cy), cy); break; case '\n': revto(markdata->left_mar, cy + 1); break; case 0220: /* M-C-p */ case '\020': /* CTRL-P */ case 'k': if (rep_cnt == 0) rep_cnt = 1; revto(cx, cy - rep_cnt); break; case 0206: /* M-C-f */ 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(markdata->left_mar, cy); break; case '\004': /* CTRL-D down half screen */ if (rep_cnt == 0) rep_cnt = (fore->w_height + 1) >> 1; revto_line(cx, cy + rep_cnt, W2D(cy)); break; case '$': revto(lineend(cy), cy); break; case '\022': /* CTRL-R emacs style backwards search */ ISearch(-1); in_mark = 0; break; case '\023': /* CTRL-S emacs style search */ ISearch(1); in_mark = 0; break; case '\025': /* CTRL-U up half screen */ if (rep_cnt == 0) rep_cnt = (fore->w_height + 1) >> 1; revto_line(cx, cy - rep_cnt, W2D(cy)); break; case '\007': /* CTRL-G show cursorpos */ if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1) LMsg(0, "Column %d Line %d(+%d)", cx + 1, W2D(cy) + 1, markdata->hist_offset); else LMsg(0, "Column %d(%d..%d) Line %d(+%d)", cx + 1, markdata->left_mar + 1, markdata->right_mar + 1, W2D(cy) + 1, markdata->hist_offset); break; case '\002': /* CTRL-B back one page */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt *= fore->w_height; revto(cx, cy - rep_cnt); break; case '\006': /* CTRL-F forward one page */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt *= fore->w_height; revto(cx, cy + rep_cnt); break; case '\005': /* CTRL-E scroll up */ if (rep_cnt == 0) rep_cnt = 1; MarkScrollUpDisplay(rep_cnt); if (cy < D2W(0)) revto(cx, D2W(0)); else LGotoPos(flayer, cx, W2D(cy)); break; case '\031': /* CTRL-Y scroll down */ if (rep_cnt == 0) rep_cnt = 1; MarkScrollDownDisplay(rep_cnt); if (cy > D2W(fore->w_height - 1)) revto(cx, D2W(fore->w_height - 1)); else LGotoPos(flayer, cx, W2D(cy)); break; case '@': /* it may be useful 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(markdata->left_mar, (rep_cnt * (fore->w_histheight + fore->w_height)) / 100, (fore->w_height - 1) / 2); break; case 0201: case 'g': rep_cnt = 1; /* FALLTHROUGH */ case 0205: case 'G': /* rep_cnt is here the WIN line number */ if (rep_cnt == 0) rep_cnt = fore->w_histheight + fore->w_height; revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2); break; case 'H': revto(markdata->left_mar, D2W(0)); break; case 'M': revto(markdata->left_mar, D2W((fore->w_height - 1) / 2)); break; case 'L': revto(markdata->left_mar, D2W(fore->w_height - 1)); break; case '|': revto(--rep_cnt, cy); break; case 'w': if (rep_cnt == 0) rep_cnt = 1; nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt); revto(cx, cy); break; case 'e': case 'E': if (rep_cnt == 0) rep_cnt = 1; nextword(&cx, &cy, NW_ENDOFWORD | NW_MUSTMOVE | (od == 'E' ? NW_BIG : 0), rep_cnt); revto(cx, cy); break; case 'b': case 'B': if (rep_cnt == 0) rep_cnt = 1; nextword(&cx, &cy, NW_BACK | NW_ENDOFWORD | NW_MUSTMOVE | (od == 'B' ? NW_BIG : 0), rep_cnt); revto(cx, cy); break; case 'a': markdata->append_mode = 1 - markdata->append_mode; LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend"); break; case 'v': case 'V': /* this sets start column to column 9 for VI :set nu users */ if (markdata->left_mar == 8) rep_cnt = 1; else rep_cnt = 9; /* FALLTHROUGH */ case 'c': case 'C': /* set start column (c) and end column (C) */ if (markdata->second) { rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height - 1); /* Hack */ markdata->second = 1; /* rem turns off second */ } rep_cnt--; if (rep_cnt < 0) rep_cnt = cx; if (od != 'C') { markdata->left_mar = rep_cnt; if (markdata->left_mar > markdata->right_mar) markdata->left_mar = markdata->right_mar; } else { markdata->right_mar = rep_cnt; if (markdata->left_mar > markdata->right_mar) markdata->right_mar = markdata->left_mar; } if (markdata->second) { markdata->cx = markdata->x1; markdata->cy = markdata->y1; revto(cx, cy); } if (od == 'v' || od == 'V') LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu"); break; case 'J': /* how do you join lines in VI ? */ markdata->nonl = (markdata->nonl + 1) % 4; switch (markdata->nonl) { case 0: if (join_with_cr) LMsg(0, "Multiple lines (CR/LF)"); else LMsg(0, "Multiple lines (LF)"); break; case 1: LMsg(0, "Lines joined"); break; case 2: LMsg(0, "Lines joined with blanks"); break; case 3: LMsg(0, "Lines joined with comma"); break; } break; case '/': Search(1); in_mark = 0; break; case '?': Search(-1); in_mark = 0; break; case 'n': Search(0); break; case 'N': markdata->isdir = -markdata->isdir; Search(0); markdata->isdir = -markdata->isdir; break; case 'y': case 'Y': if (markdata->second == 0) { revto(linestart(cy), cy); markdata->second++; cx = markdata->x1 = markdata->cx; cy = markdata->y1 = markdata->cy; } if (--rep_cnt > 0) revto(cx, cy + rep_cnt); revto(lineend(markdata->cy), markdata->cy); if (od == 'y') break; /* FALLTHROUGH */ case 'W': if (od == 'W') { if (rep_cnt == 0) rep_cnt = 1; if (!markdata->second) { nextword(&cx, &cy, NW_BACK | NW_ENDOFWORD, 1); revto(cx, cy); markdata->second++; cx = markdata->x1 = markdata->cx; cy = markdata->y1 = markdata->cy; } nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt); revto(cx, cy); } cx = markdata->cx; cy = markdata->cy; /* FALLTHROUGH */ case 'A': if (od == 'A') markdata->append_mode = 1; /* FALLTHROUGH */ case '>': if (od == '>') markdata->write_buffer = 1; /* FALLTHROUGH */ case ' ': case '\r': if (!markdata->second) { markdata->second++; markdata->x1 = cx; markdata->y1 = cy; revto(cx, cy); LMsg(0, "First mark set - Column %d Line %d", cx + 1, W2D(cy) + 1); break; } else { int append_mode = markdata->append_mode; int write_buffer = markdata->write_buffer; x2 = cx; y2 = cy; newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */ if (md_user->u_plop.buf && !append_mode) UserFreeCopyBuffer(md_user); yend = fore->w_height - 1; if (fore->w_histheight - markdata->hist_offset < fore->w_height) { markdata->second = 0; yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); } if (newcopylen > 0) { /* the +3 below is for : cr + lf + \0 */ if (md_user->u_plop.buf) md_user->u_plop.buf = realloc(md_user->u_plop.buf, (unsigned)(md_user->u_plop.len + newcopylen + 3)); else { md_user->u_plop.len = 0; md_user->u_plop.buf = malloc((unsigned)(newcopylen + 3)); } if (!md_user->u_plop.buf) { MarkAbort(); in_mark = 0; LMsg(0, "Not enough memory... Sorry."); md_user->u_plop.len = 0; md_user->u_plop.buf = 0; break; } if (append_mode) { switch (markdata->nonl) { /* * this code defines, what glues lines together */ case 0: if (join_with_cr) { md_user->u_plop.buf[md_user->u_plop.len] = '\r'; md_user->u_plop.len++; } md_user->u_plop.buf[md_user->u_plop.len] = '\n'; md_user->u_plop.len++; break; case 1: break; case 2: md_user->u_plop.buf[md_user->u_plop.len] = ' '; md_user->u_plop.len++; break; case 3: md_user->u_plop.buf[md_user->u_plop.len] = ','; md_user->u_plop.len++; break; } } md_user->u_plop.len += rem(markdata->x1, markdata->y1, x2, y2, markdata->hist_offset == fore->w_histheight, md_user->u_plop.buf + md_user->u_plop.len, yend); md_user->u_plop.enc = fore->w_encoding; } if (markdata->hist_offset != fore->w_histheight) { LAY_CALL_UP(LRefreshAll(flayer, 0)); } ExitOverlayPage(); WindowChanged(fore, 'P'); if (append_mode) LMsg(0, "Appended %d characters to buffer", newcopylen); else LMsg(0, "Copied %d characters into buffer", md_user->u_plop.len); if (write_buffer) WriteFile(md_user, (char *)0, DUMP_EXCHANGE); in_mark = 0; break; } case 0222: if (flayer->l_mouseevent.start) { int button = flayer->l_mouseevent.buffer[0]; if (button == 'a') { /* Scroll down */ od = 'j'; } else if (button == '`') { /* Scroll up */ od = 'k'; } else if (button == ' ') { /* Left click */ cx = flayer->l_mouseevent.buffer[1]; cy = D2W(flayer->l_mouseevent.buffer[2]); revto(cx, cy); od = ' '; } else od = 0; LayProcessMouseSwitch(flayer, 0); if (od) goto processchar; } else LayProcessMouseSwitch(flayer, 1); break; default: MarkAbort(); LMsg(0, "Copy mode aborted"); in_mark = 0; break; } if (in_mark) /* markdata may be freed */ markdata->rep_cnt = 0; } if (in_mark) { flayer->l_x = markdata->cx; flayer->l_y = W2D(markdata->cy); } *inbufp = pt; *inlenp = inlen; }
static void InpProcess(char **ppbuf, int *plen) { int len, x; char *pbuf; char ch; struct inpdata *inpdata; struct display *inpdisplay; int prev, next, search = 0; inpdata = (struct inpdata *)flayer->l_data; inpdisplay = display; #define RESET_SEARCH { if (inpdata->search) Free(inpdata->search); } LGotoPos(flayer, inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), INPUTLINE); if (ppbuf == 0) { InpAbort(); return; } x = inpdata->inpstringlen + inpdata->inp.pos; len = *plen; pbuf = *ppbuf; while (len) { char *p = inpdata->inp.buf + inpdata->inp.pos; ch = *pbuf++; len--; if (inpdata->inpmode & INP_EVERY) { inpdata->inp.buf[inpdata->inp.len] = ch; if (ch) { display = inpdisplay; (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv); ch = inpdata->inp.buf[inpdata->inp.len]; } } else if (inpdata->inpmode & INP_RAW) { display = inpdisplay; (*inpdata->inpfinfunc)(&ch, 1, inpdata->priv); /* raw */ if (ch) continue; } if (((unsigned char)ch & 0177) >= ' ' && ch != 0177 && inpdata->inp.len < inpdata->inpmaxlen) { if (inpdata->inp.len > inpdata->inp.pos) memmove(p+1, p, inpdata->inp.len - inpdata->inp.pos); inpdata->inp.buf[inpdata->inp.pos++] = ch; inpdata->inp.len++; if (!(inpdata->inpmode & INP_NOECHO)) { struct mchar mc; mc = mchar_so; mc.image = *p++; LPutChar(flayer, &mc, x, INPUTLINE); x++; if (p < inpdata->inp.buf+inpdata->inp.len) { while (p < inpdata->inp.buf+inpdata->inp.len) { mc.image = *p++; LPutChar(flayer, &mc, x++, INPUTLINE); } x = inpdata->inpstringlen + inpdata->inp.pos; LGotoPos(flayer, x, INPUTLINE); } } RESET_SEARCH; } else if ((ch == '\b' || ch == 0177) && inpdata->inp.pos > 0) { erase_chars(inpdata, p-1, p, x, 1); RESET_SEARCH; } else if (ch == '\025') /* CTRL-U */ { x = inpdata->inpstringlen; if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO)) { LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - 1, INPUTLINE, 0, 0); LGotoPos(flayer, x, INPUTLINE); } inpdata->inp.len = inpdata->inp.pos = 0; } else if (ch == '\013') /* CTRL-K */ { x = inpdata->inpstringlen + inpdata->inp.pos; if (inpdata->inp.len > inpdata->inp.pos && !(inpdata->inpmode & INP_NOECHO)) { LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - inpdata->inp.pos - 1, INPUTLINE, 0, 0); LGotoPos(flayer, x, INPUTLINE); } inpdata->inp.len = inpdata->inp.pos; } else if (ch == '\027' && inpdata->inp.pos > 0) /* CTRL-W */ { char *oldp = p--; while (p > inpdata->inp.buf && *p == ' ') p--; while (p > inpdata->inp.buf && *(p - 1) != ' ') p--; erase_chars(inpdata, p, oldp, x, 1); RESET_SEARCH; } else if (ch == '\004' && inpdata->inp.pos < inpdata->inp.len) /* CTRL-D */ { erase_chars(inpdata, p, p+1, x, 0); RESET_SEARCH; } else if (ch == '\001' || (unsigned char)ch == 0201) /* CTRL-A */ { LGotoPos(flayer, x -= inpdata->inp.pos, INPUTLINE); inpdata->inp.pos = 0; } else if ((ch == '\002' || (unsigned char)ch == 0202) && inpdata->inp.pos > 0) /* CTRL-B */ { LGotoPos(flayer, --x, INPUTLINE); inpdata->inp.pos--; } else if (ch == '\005' || (unsigned char)ch == 0205) /* CTRL-E */ { LGotoPos(flayer, x += inpdata->inp.len - inpdata->inp.pos, INPUTLINE); inpdata->inp.pos = inpdata->inp.len; } else if ((ch == '\006' || (unsigned char)ch == 0206) && inpdata->inp.pos < inpdata->inp.len) /* CTRL-F */ { LGotoPos(flayer, ++x, INPUTLINE); inpdata->inp.pos++; } else if ((prev = ((ch == '\020' || (unsigned char)ch == 0220) && /* CTRL-P */ inpdata->inp.prev)) || (next = ((ch == '\016' || (unsigned char)ch == 0216) && /* CTRL-N */ inpdata->inp.next)) || (search = ((ch == '\022' || (unsigned char)ch == 0222) && inpdata->inp.prev))) { struct mchar mc; struct inpline *sel; int pos = -1; mc = mchar_so; if (prev) sel = inpdata->inp.prev; else if (next) sel = inpdata->inp.next; else { /* search */ inpdata->inp.buf[inpdata->inp.len] = 0; /* Remove the ctrl-r from the end */ if (!inpdata->search) inpdata->search = SaveStr(inpdata->inp.buf); for (sel = inpdata->inp.prev; sel; sel = sel->prev) { char *f; if ((f = strstr(sel->buf, inpdata->search))) { pos = f - sel->buf; break; } } if (!sel) continue; /* Did not find a match. Process the next input. */ } if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO)) LClearArea(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0, 0); if ((prev || search) && !inpdata->inp.next) inphist = inpdata->inp; memcpy(&inpdata->inp, sel, sizeof(struct inpline)); if (pos != -1) inpdata->inp.pos = pos; if (inpdata->inp.len > inpdata->inpmaxlen) inpdata->inp.len = inpdata->inpmaxlen; if (inpdata->inp.pos > inpdata->inp.len) inpdata->inp.pos = inpdata->inp.len; x = inpdata->inpstringlen; p = inpdata->inp.buf; if (!(inpdata->inpmode & INP_NOECHO)) { while (p < inpdata->inp.buf+inpdata->inp.len) { mc.image = *p++; LPutChar(flayer, &mc, x++, INPUTLINE); } } x = inpdata->inpstringlen + inpdata->inp.pos; LGotoPos(flayer, x, INPUTLINE); } else if (ch == '\003' || ch == '\007' || ch == '\033' || ch == '\000' || ch == '\n' || ch == '\r') { if (ch != '\n' && ch != '\r') inpdata->inp.len = 0; inpdata->inp.buf[inpdata->inp.len] = 0; if (inpdata->inp.len && !(inpdata->inpmode & (INP_NOECHO | INP_RAW))) { struct inpline *store; /* Look for a duplicate first */ for (store = inphist.prev; store; store = store->prev) { if (strcmp(store->buf, inpdata->inp.buf) == 0) { if (store->next) store->next->prev = store->prev; if (store->prev) store->prev->next = store->next; store->pos = inpdata->inp.pos; break; } } if (!store) { store = malloc(sizeof(struct inpline)); memcpy(store, &inpdata->inp, sizeof(struct inpline)); } store->next = &inphist; store->prev = inphist.prev; if (inphist.prev) inphist.prev->next = store; inphist.prev = store; } flayer->l_data = 0; /* so inpdata does not get freed */ InpAbort(); /* redisplays... */ *ppbuf = pbuf; *plen = len; display = inpdisplay; if ((inpdata->inpmode & INP_RAW) == 0) (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv); else (*inpdata->inpfinfunc)(pbuf - 1, 0, inpdata->priv); if (inpdata->search) free(inpdata->search); free(inpdata); return; } else { /* The user was searching, and then pressed some non-control input. So reset * the search string. */ RESET_SEARCH; } } if (!(inpdata->inpmode & INP_RAW)) { flayer->l_x = inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos); flayer->l_y = INPUTLINE; } *ppbuf = pbuf; *plen = len; }