📄 ttyansi.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)ttyansi.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1985, 1986, 1987 by Sun Microsystems, Inc. */#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/time.h>#include <sys/signal.h>#include <pixrect/pixrect.h>#include <sunwindow/rect.h>#include <sunwindow/cms.h>#include <sunwindow/win_struct.h>#include <sunwindow/win_screen.h>#include <sunwindow/win_input.h>#include <sunwindow/win_ioctl.h>#include <suntool/ttysw.h>#include <suntool/ttysw_impl.h>#undef CTRL#include <suntool/ttyansi.h>#include <suntool/selection_attributes.h>extern Cmdsw *cmdsw;extern char *sprintf();extern void pos();extern void win_sync();extern char *getenv();char *strncpy();char *textsw_checkpoint_undo();Textsw_index textsw_replace_bytes(), textsw_erase();Textsw_status textsw_set();#ifdef DEBUG#define ERROR_RETURN(val) abort(); /* val */#else#define ERROR_RETURN(val) return(val);#endif DEBUGextern int sv_journal;extern char *shell_prompt;/* Logical state of window */int curscol; /* cursor column */int cursrow; /* cursor row */extern int tty_cursor;extern int scroll_disabled_from_menu; /* 0 -> NOCURSOR, 1 -> UNDERCURSOR, 2 -> BLOCKCURSOR */static int state; /* ALPHA, SKIPPING, etc, possibly w/ |ESC */static int saved_state;static int prefix; /* prefix to arg */static int scrlins = 1;/* How many lines to scroll when you have to */static int fillfunc; /* 0 -> reverse video */static char strtype; /* type of ansi string sequence *//* dimensions of window */int top; /* top row of window (0 for now) */int bottom; /* bottom row of window */int left; /* left column of window (0 for now) */int right; /* right column of window *//* * Interpret a string of characters of length <len>. Stash and restore * the cursor indicator. * * Note that characters with the high bit set will not be recognized. * This is good, for it reserves them for ASCII-8 X3.64 implementation. * It just means all sources of chars which might come here must mask * parity if necessary. * *//* #ifdef CMDSW */static unsigned char *from_pty_to_textsw(textsw, cp, buf) register Textsw textsw; register unsigned char *buf; register unsigned char *cp;{ int status = 0; int allow_enable = 1; register Textsw_index insert, cmd_start; if (cp == buf) { return (buf); } *cp = '\0'; /* Set up - remove marks, save positions, etc. */ if (cmdsw->append_only_log) { /* Remove read_only_mark to allow insert */ textsw_remove_mark(textsw, cmdsw->read_only_mark); } /* Save start of user command */ if (cmdsw->cmd_started) { if ((cmd_start = textsw_find_mark(textsw, cmdsw->user_mark)) == TEXTSW_INFINITY) ERROR_RETURN(0); textsw_remove_mark(textsw, cmdsw->user_mark); cmdsw->user_mark = textsw_add_mark(textsw, cmd_start+1, TEXTSW_MARK_MOVE_AT_INSERT); } else { cmd_start = (Textsw_index)textsw_get(textsw, TEXTSW_LENGTH); } /* Translate and edit in the pty input */ ttysw_doing_pty_insert(textsw, cmdsw, TRUE); status = send_input_to_textsw(textsw, buf, (long) (cp - buf), cmd_start); ttysw_doing_pty_insert(textsw, cmdsw, FALSE); /* Restore user_mark, if cmd_started */ if (cmdsw->cmd_started) { insert = textsw_find_mark(textsw, cmdsw->user_mark); textsw_remove_mark(textsw, cmdsw->user_mark); if (insert == TEXTSW_INFINITY) insert = cmd_start; else insert--; cmdsw->user_mark = textsw_add_mark(textsw, insert, TEXTSW_MARK_DEFAULTS); if (cmdsw->append_only_log) { cmdsw->read_only_mark = textsw_add_mark(textsw, cmdsw->cooked_echo ? insert : TEXTSW_INFINITY-1, TEXTSW_MARK_READ_ONLY); } } else { cmdsw->next_undo_point = (caddr_t)textsw_checkpoint_undo(textsw, (caddr_t)TEXTSW_INFINITY); if (cmdsw->append_only_log) { insert = (Textsw_index)textsw_get(textsw, TEXTSW_LENGTH); cmdsw->read_only_mark = textsw_add_mark(textsw, cmdsw->cooked_echo ? insert : TEXTSW_INFINITY-1, TEXTSW_MARK_READ_ONLY); if ((sv_journal) && (svj_strcmp(buf) == 0)) win_sync(WIN_SYNC_TEXT,-1); } } /* return (status ? (char *) 0 : buf); */ if (status) { cmdsw->enable_scroll_stay_on = TRUE; return(NULL); } else return(buf);}/* * A version of textsw_replace_bytes that allows you to * trivially check the error code. */static intlocal_replace_bytes(textsw, pty_insert, last_plus_one, buf, buf_len) Textsw textsw; Textsw_index pty_insert; Textsw_index last_plus_one; register char *buf; register long buf_len;{ int delta = 0; int status = 0; Textsw_mark tmp_mark; tmp_mark = textsw_add_mark(textsw, pty_insert, TEXTSW_MARK_MOVE_AT_INSERT); delta = textsw_replace_bytes(textsw, pty_insert, last_plus_one, buf, buf_len); if (!delta && (textsw_find_mark(textsw, tmp_mark) == pty_insert)) { status = 1; } textsw_remove_mark(textsw, tmp_mark); return (status);}/* Caller must be inserting text from pty and is responsible for unsetting * the user_mark and read_only_mark BEFORE calling, and AFTER call for * resetting them. */static intsend_input_to_textsw(textsw, buf, buf_len, end_transcript) Textsw textsw; register char *buf; register long buf_len; Textsw_index end_transcript;{ Textsw_index pty_insert = textsw_find_mark(textsw, cmdsw->pty_mark); Textsw_index insert = (Textsw_index)textsw_get(textsw, TEXTSW_INSERTION_POINT); Textsw_index last_plus_one; Textsw_index add_newline = 0; Textsw_index expanded_size;#define BUFSIZE 200 char expand_buf[BUFSIZE]; Textsw_mark owe_newline_mark; int status = 0; textsw_remove_mark(textsw, cmdsw->pty_mark); last_plus_one = end_transcript; if (cmdsw->pty_owes_newline) last_plus_one--; if (buf_len < (last_plus_one - pty_insert)) last_plus_one = pty_insert + buf_len; /* replace from pty_insert to last_plus_one with buf */ if (cmdsw->pty_owes_newline) { /* try to pay the newline back */ if (buf[buf_len-1] == '\n' && last_plus_one == end_transcript) { cmdsw->pty_owes_newline = 0; if (--buf_len == (long) 0) { return (status); } } } else { if ((cmdsw->cmd_started != 0) && (buf[buf_len-1] != '\n')) { add_newline = 1; owe_newline_mark = textsw_add_mark(textsw, end_transcript, TEXTSW_MARK_MOVE_AT_INSERT); } } /* in case of tabs or control chars, expand chars to be replaced */ expanded_size = last_plus_one - pty_insert; switch (textsw_expand( textsw, pty_insert, last_plus_one, expand_buf, BUFSIZE, (int *)(LINT_CAST(&expanded_size)))) { case TEXTSW_EXPAND_OK: break; case TEXTSW_EXPAND_FULL_BUF: case TEXTSW_EXPAND_OTHER_ERROR: default: expanded_size = last_plus_one - pty_insert; break; } if (expanded_size > buf_len) { (void)strncpy(buf + buf_len, expand_buf + buf_len, (int)expanded_size - buf_len); buf_len = expanded_size; } if ((status = local_replace_bytes(textsw, pty_insert, last_plus_one, buf, buf_len))) { add_newline = 0; buf_len = 0; } cmdsw->pty_mark = textsw_add_mark(textsw, pty_insert + buf_len, TEXTSW_MARK_DEFAULTS); if (add_newline != 0) { add_newline = textsw_find_mark(textsw, owe_newline_mark); textsw_remove_mark(textsw, owe_newline_mark); cmdsw->pty_owes_newline = textsw_replace_bytes(textsw, add_newline, add_newline, "\n", (long int) 1); if (!cmdsw->pty_owes_newline) { status = 1; } add_newline = 1; } if (status) return (status); /* * BUG ALERT! * If !append_only_log, and caret is in * text that is being replaced, you lose. */ if (cmdsw->cooked_echo && insert >= end_transcript) { /* if text before insertion point grew, move insertion point */ if (buf_len + add_newline > last_plus_one - pty_insert) { insert += buf_len + add_newline - (int) (last_plus_one - pty_insert); (void)textsw_set(textsw, TEXTSW_INSERTION_POINT, insert, 0); } } else if (!cmdsw->cooked_echo && insert == pty_insert) { insert += buf_len; (void)textsw_set(textsw, TEXTSW_INSERTION_POINT, insert, 0); } return (status);#undef BUFSIZE}/* #endif CMDSW */ansiinit(ttysw) struct ttysubwindow *ttysw;{ int ansi_escape(); int ansi_string(); char windowname[WIN_NAMESIZE]; /* * Need to we_setmywindow in case tty processes want to find out * which window running in. */ (void)win_fdtoname(ttysw->ttysw_wfd, windowname); (void)we_setmywindow(windowname); /* * Setup gfx window environment value for gfx processes. * Can be reset if a more appropriate window is available. */ (void)we_setgfxwindow(windowname); ttysw->ttysw_stringop = ansi_string; ttysw->ttysw_escapeop = ansi_escape;}/* ARGSUSED */ansi_string(data, type, c) caddr_t data; char type, c;{ return(TTY_OK);}/* #ifndef CMDSW *//* compatibility kludge */gfxstring(addr, len) unsigned char *addr; int len;{ extern struct ttysubwindow *_ttysw; (void) ttysw_output((Ttysubwindow)(LINT_CAST(_ttysw)), addr, len);}voidttysw_save_state() { saved_state = state; state = S_ALPHA;}voidttysw_restore_state() { state = saved_state;}/* #endif CMDSW */static interase_chars(textsw, pty_insert, end_span) Textsw textsw; Textsw_index pty_insert; Textsw_index end_span;{ int status = 0; if (pty_insert < 0) pty_insert = 0; if (end_span <= pty_insert) return (status); if (cmdsw->append_only_log) { /* Remove read_only_mark to allow insert */ textsw_remove_mark(textsw, cmdsw->read_only_mark); } ttysw_doing_pty_insert(textsw, cmdsw, TRUE); status = textsw_erase(textsw, pty_insert, end_span) ? 0 : 1; ttysw_doing_pty_insert(textsw, cmdsw, FALSE); if (cmdsw->append_only_log) { int cmd_start; if (cmdsw->cmd_started) { cmd_start = textsw_find_mark(textsw, cmdsw->user_mark); } else { cmd_start = (int)textsw_get(textsw, TEXTSW_LENGTH); } cmdsw->read_only_mark = textsw_add_mark(textsw, (Textsw_index) (cmdsw->cooked_echo ? cmd_start : TEXTSW_INFINITY-1), TEXTSW_MARK_READ_ONLY); } return (status);}static intreplace_chars(textsw, start_span, end_span, buf, buflen) Textsw textsw; Textsw_index start_span; Textsw_index end_span; char *buf; long int buflen;{ int status = 0; if (start_span < 0) start_span = 0; if (end_span < start_span) end_span = start_span; if (cmdsw->append_only_log) { /* Remove read_only_mark to allow insert */ textsw_remove_mark(textsw, cmdsw->read_only_mark); } ttysw_doing_pty_insert(textsw, cmdsw, TRUE); status = local_replace_bytes(textsw, start_span, end_span, buf, buflen); ttysw_doing_pty_insert(textsw, cmdsw, FALSE); if (cmdsw->append_only_log) { int cmd_start; if (cmdsw->cmd_started) { cmd_start = textsw_find_mark(textsw, cmdsw->user_mark); } else { cmd_start = (int)textsw_get(textsw, TEXTSW_LENGTH); } cmdsw->read_only_mark = textsw_add_mark(textsw, (Textsw_index) (cmdsw->cooked_echo ? cmd_start : TEXTSW_INFINITY-1), TEXTSW_MARK_READ_ONLY); } return (status);}static voidadjust_insertion_point(textsw, pty_index, new_pty_index)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -