📄 charproc.c
字号:
c = 0; } } } if (v_bufend >= v_bufptr + len) { /* new stuff will fit */ bcopy(d, v_bufptr, len); v_bufptr += len; } } /* * Write out as much of the buffer as we can. * Be careful not to overflow the pty's input silo. * We are conservative here and only write * a small amount at a time. * * If we can't push all the data into the pty yet, we expect write * to return a non-negative number less than the length requested * (if some data written) or -1 and set errno to EAGAIN, * EWOULDBLOCK, or EINTR (if no data written). * * (Not all systems do this, sigh, so the code is actually * a little more forgiving.) */#define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */ if (v_bufptr > v_bufstr) { riten = write(f, v_bufstr, v_bufptr - v_bufstr <= MAX_PTY_WRITE ? v_bufptr - v_bufstr : MAX_PTY_WRITE); if (riten < 0) {#ifdef DEBUG perror("write");#endif riten = 0; }#ifdef DEBUG fprintf(stderr, "write called with %d, wrote %d\n", v_bufptr - v_bufstr <= MAX_PTY_WRITE ? v_bufptr - v_bufstr : MAX_PTY_WRITE, riten);#endif v_bufstr += riten; if (v_bufstr >= v_bufptr) /* we wrote it all */ v_bufstr = v_bufptr = v_buffer; } /* * If we have lots of unused memory allocated, return it */ if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */ /* save pointers across realloc */ int start = v_bufstr - v_buffer; int size = v_bufptr - v_buffer; int allocsize = size ? size : 1; v_buffer = realloc(v_buffer, allocsize); if (v_buffer) { v_bufstr = v_buffer + start; v_bufptr = v_buffer + size; v_bufend = v_buffer + allocsize;#ifdef DEBUG fprintf(stderr, "shrunk buffer to %d\n", allocsize);#endif } else { /* should we print a warning if couldn't return memory? */ v_buffer = v_bufstr - start; /* restore clobbered pointer */ } } return(c);}static int select_mask;static int write_mask;static int pty_read_bytes;in_put(){ register TScreen *screen = &term->screen; register int i; static struct timeval select_timeout;#ifdef DEBUGGING fprintf(stderr, "entering in_put()\n");#endif for( ; ; ) { if (select_mask & pty_mask && eventMode == NORMAL) {#ifdef ALLOWLOGGING if (screen->logging) FlushLog(screen);#endif bcnt = read(screen->respond, (char *)(bptr = buffer), BUF_SIZE); if (bcnt < 0) { if (errno == EIO) Cleanup (0); else if (!E_TEST(errno)) Panic( "input: read returned unexpected error (%d)\n", errno); } else if (bcnt == 0) Panic("input: read returned zero\n", 0); else { /* read from pty was successful */ if (!screen->output_eight_bits) { register int bc = bcnt; register Char *b = bptr; for (; bc > 0; bc--, b++) { *b &= (Char) 0x7f; } } if ( screen->scrollWidget && screen->scrollttyoutput && screen->topline < 0) WindowScroll(screen, 0); /* Scroll to bottom */ pty_read_bytes += bcnt; /* stop speed reading at some point to look for X stuff */ /* (4096 is just a random large number.) */ if (pty_read_bytes > 4096) { select_mask &= ~pty_mask; } break; } } pty_read_bytes = 0; /* update the screen */ if (screen->scroll_amt) FlushScroll(screen); if (screen->cursor_set && (screen->cursor_col != screen->cur_col || screen->cursor_row != screen->cur_row)) { if (screen->cursor_state) HideCursor(); ShowCursor(); } else if (screen->cursor_set != screen->cursor_state) { if (screen->cursor_set) ShowCursor(); else HideCursor(); } XFlush(screen->display); /* always flush writes before waiting */ /* * Update the masks and, unless X events are already in the queue, * wait for I/O to be possible. */ select_mask = Select_mask; write_mask = ptymask(); select_timeout.tv_sec = 0; /* * if there's either an XEvent or an XtTimeout pending, just take * a quick peek, i.e. timeout from the select() immediately. If * there's nothing pending, let select() block a little while, but * for a shorter interval than the arrow-style scrollbar timeout. */ if (XtAppPending(app_con)) select_timeout.tv_usec = 0; else select_timeout.tv_usec = 50000; i = select(max_plus1, &select_mask, &write_mask, (int *)NULL, &select_timeout); if (i < 0) { if (errno != EINTR) SysError(ERROR_SELECT); continue; } /* if there is room to write more data to the pty, go write more */ if (write_mask & ptymask()) { v_write(screen->respond, 0, 0); /* flush buffer */ } /* if there are X events already in our queue, it counts as being readable */ if (XtAppPending(app_con) || (select_mask & X_mask)) { xevents(); } } bcnt--;#ifdef DEBUGGING fprintf(stderr, "leaving in_put()\n");#endif return(*bptr++);}/* * process a string of characters according to the character set indicated * by charset. worry about end of line conditions (wraparound if selected). */static void#ifdef DONT_PROTOTYPE_DOTEXTdotext(screen, flags, charset, buf, ptr, fg, bg ) register TScreen *screen; unsigned flags, fg, bg; char charset; Char *buf; /* start of characters to process */ Char *ptr; /* end */#elsedotext(register TScreen *screen, unsigned flags, char charset, Char *buf, Char *ptr, unsigned fg, unsigned bg)#endif{ register Char *s; register int len; register int n; register int next_col;#ifdef DEBUGGING fprintf(stderr, "entering dotext\n");#endif switch (charset) { case 'A': /* United Kingdom set */ for (s=buf; s<ptr; ++s) if (*s == '#') *s = '\036'; /* UK pound sign*/ break; default: /* any character sets we don't recognize*/ case 'B': /* ASCII set */ break; case '0': /* special graphics (line drawing) */ for (s=buf; s<ptr; ++s) if (*s>=0x5f && *s<=0x7e) *s = *s == 0x5f ? 0x7f : *s - 0x5f; break; } len = ptr - buf; ptr = buf; while (len > 0) { n = screen->max_col - screen->cur_col +1; if (n <= 1) { if (screen->do_wrap && (flags&WRAPAROUND)) { /* mark that we had to wrap this line */ ScrnSetAttributes(screen, screen->cur_row, 0, LINEWRAPPED, LINEWRAPPED, 1); Index(screen, 1); screen->cur_col = 0; screen->do_wrap = 0; n = screen->max_col+1; } else n = 1; } if (len < n) n = len; next_col = screen->cur_col + n; WriteText(screen, ptr, n, flags, fg, bg ); /* * the call to WriteText updates screen->cur_col. * If screen->cur_col != next_col, we must have * hit the right margin, so set the do_wrap flag. */#ifdef DEBUGGING fprintf(stderr, "Made it to screen->do_wrap");#endif screen->do_wrap = (screen->cur_col < next_col); len -= n; ptr += n; }#ifdef DEBUGGING fprintf(stderr, "leaving dotext()\n");#endif} /* * write a string str of length len onto the screen at * the current cursor position. update cursor position. */static voidWriteText(screen, str, len, flags, fg, bg ) register TScreen *screen; register char *str; register int len; unsigned flags, fg, bg;{ register int cx, cy; register unsigned fgs = flags; register Pixel fg_pix, bg_pix; GC currentGC; #ifdef DEBUGGING fprintf(stderr, "entering WriteText\n");#endif fg_pix = (fgs&FG_COLOR) ? screen->colors[fg] : screen->foreground; bg_pix = (fgs&BG_COLOR) ? screen->colors[bg] : term->core.background_pixel; if(screen->cur_row - screen->topline <= screen->max_row) { /* if(screen->cur_row == screen->cursor_row && screen->cur_col <= screen->cursor_col && screen->cursor_col <= screen->cur_col + len - 1) screen->cursor_state = OFF; */ if(screen->cursor_state) HideCursor(); /* * make sure that the correct GC is current */ if (fgs & INVERSE) { if (fgs & SHOWBOLD) currentGC = screen->reverseboldGC; else currentGC = screen->reverseGC; XSetForeground(screen->display, currentGC, bg_pix); XSetBackground(screen->display, currentGC, fg_pix); } else { if (fgs & SHOWBOLD) currentGC = screen->normalboldGC; else /* not bold */ currentGC = screen->normalGC; XSetForeground(screen->display, currentGC, fg_pix); XSetBackground(screen->display, currentGC, bg_pix); } if (fgs & INSERT) InsertChar(screen, len); if (!(AddToRefresh(screen))) { if(screen->scroll_amt) FlushScroll(screen); cx = CursorX(screen, screen->cur_col); cy = CursorY(screen, screen->cur_row)+screen->fnt_norm->ascent; XDrawImageString(screen->display, TextWindow(screen), currentGC, cx, cy, str, len); if((fgs & SHOWBOLD) && screen->enbolden) if (currentGC == screen->normalGC || screen->reverseGC) XDrawString(screen->display, TextWindow(screen), currentGC,cx + 1, cy, str, len); if(fgs & UNDERLINE) XDrawLine(screen->display, TextWindow(screen), currentGC, cx, cy+1, cx + len * FontWidth(screen), cy+1); /* * the following statements compile data to compute the average * number of characters written on each call to XText. The data * may be examined via the use of a "hidden" escape sequence. */ ctotal += len; ++ntotal; } } ScreenWrite(screen, str, flags, fg, bg, len); CursorForward(screen, len);#ifdef DEBUGGING fprintf(stderr, "Leaving WriteText\n");#endif} /* * process ANSI modes set, reset */ansi_modes(termw, func) XtermWidget termw; int (*func)();{ register int i;#ifdef DEBUGGING fprintf(stderr, "entering ansi_modes\n");#endif for (i=0; i<nparam; ++i) { switch (param[i]) { case 4: /* IRM */ (*func)(&termw->flags, INSERT); break; case 20: /* LNM */ (*func)(&termw->flags, LINEFEED); update_autolinefeed(); break; } }}/* * process DEC private modes set, reset */dpmodes(termw, func) XtermWidget termw; void (*func)();{ register TScreen *screen = &termw->screen; register int i, j;#ifdef DEBUGGING fprintf(stderr, "entering dpmodes\n");#endif for (i=0; i<nparam; ++i) { switch (param[i]) { case 1: /* DECCKM */ (*func)(&termw->keyboard.flags, CURSOR_APL); update_appcursor(); break; case 2: /* ANSI/VT52 mode */ if (func == bitset) { screen->gsets[0] = screen->gsets[1] = screen->gsets[2] = screen->gsets[3] = 'B'; screen->curgl = 0; } break; case 3: /* DECCOLM */ if(screen->c132) { ClearScreen(screen); CursorSet(screen, 0, 0, termw->flags); if((j = func == bitset ? 132 : 80) != ((termw->flags & IN132COLUMNS) ? 132 : 80) || j != screen->max_col + 1) { Dimension replyWidth, replyHeight; XtGeometryResult status; status = XtMakeResizeRequest ( (Widget) termw, (Dimension) FontWidth(screen) * j + 2*screen->border + screen->scrollbar, (Dimension) FontHeight(screen) * (screen->max_row + 1) + 2 * screen->border, &replyWidth, &replyHeight); if (status == XtGeometryYes || status == XtGeometryDone) { ScreenResize (&termw->screen, replyWidth, replyHeight, &termw->flags); } } (*func)(&termw->flags, IN132COLUMNS); } break; case 4: /* DECSCLM (slow scroll) */ if (func == bitset) { screen->jumpscroll = 0; if (screen->scroll_amt) FlushScroll(screen); } else screen->jumpscroll = 1; (*func)(&termw->flags, SMOOTHSCROLL); update_jumpscroll(); break; case 5: /* DECSCNM */ j = termw->flags; (*func)(&termw->flags, REVERSE_VIDEO); if ((termw->flags ^ j) & REVERSE_VIDEO) ReverseVideo(termw); /* update_reversevideo done in RevVid */ break; case 6: /* DECOM */ (*func)(&termw->flags, ORIGIN); CursorSet(screen, 0, 0, termw->flags); break; case 7: /* DECAWM */ (*func)(&termw->flags, WRAPAROUND); update_autowrap(); break; case 8: /* DECARM */ /* ignore autorepeat */ break; case 9: /* MIT bogus sequence */ if(func == bitset) screen->send_mouse_pos = 1; else screen->send_mouse_pos = 0; break; case 38: /* DECTEK */ if(func == bitset && !(screen->inhibit & I_TEK)) {#ifdef ALLOWLOGGING if(screen->logging) { FlushLog(screen); screen->logstart = Tbuffer; }#endif screen->TekEmu = TRUE; } break; case 40: /* 132 column mode */ screen->c132 = (func == bitset); update_allow132(); break; case 41: /* curses hack */ screen->curses = (func == bitset); update_cursesemul(); break; case 44: /* margin bell */ screen->marginbell = (func == bitset); if(!screen->marginbell) screen->bellarmed = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -