📄 ttysw_main.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)ttysw_main.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * Very active terminal emulator subwindow pty code. */#include <errno.h>#include <signal.h>#include <stdio.h>#include <sgtty.h>#include <ctype.h>#include <sys/types.h>#include <sys/uio.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/time.h>#include <sundev/kbd.h>#include <pixrect/pixrect.h>#include <pixrect/pixfont.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/pixwin.h>#include <sunwindow/win_input.h>#include <sunwindow/win_struct.h>#include <sunwindow/win_cursor.h>#include <sunwindow/win_lock.h>#include <suntool/icon.h>#include <suntool/ttysw.h>#include <suntool/tool.h> /* tool.h must be before any indirect include of textsw.h */#include <suntool/ttysw_impl.h>#include <suntool/ttytlsw_impl.h>#include <suntool/selection_svc.h>/* #ifndef CMDSW */extern struct pixwin *csr_pixwin; /* For pw_batch calls *//* #endif CMDSW */extern int errno;extern void ttysw_lighten_cursor();extern void ttysetselection();void pw_batch();extern Textsw_index textsw_insert();/* shorthand */#define iwbp ttysw->ttysw_ibuf.cb_wbp#define irbp ttysw->ttysw_ibuf.cb_rbp#define iebp ttysw->ttysw_ibuf.cb_ebp#define ibuf ttysw->ttysw_ibuf.cb_buf#define owbp ttysw->ttysw_obuf.cb_wbp#define orbp ttysw->ttysw_obuf.cb_rbp#define oebp ttysw->ttysw_obuf.cb_ebp#define obuf ttysw->ttysw_obuf.cb_buf/* #ifdef CMDSW */#ifdef notdef/*The basic strategy for building a line-oriented command subwindow (terminalemulator subwindow) on top of the text subwindow is as follows.The idle state has no user input still to be processed, and no outstandingactive processes at the other end of the pty (except the shell).When the user starts creating input events, they are passed through to thetextsw unless they fall in the class of "activating events" (which right nowconsists of \n, \r, \033, ^C and ^Z). In addition, the end of the textsw'sbacking store is recorded when the first event is created.When an activating event is entered, all of the characters in the textswfrom the recorded former end to the current end of the backing store areadded to the list of characters to be sent to the pty. In addition, thecurrent end is set to be the insertion place for response from the pty.If the user has started to enter a command, then in order to avoid messes onthe display, the first response from the pty will be suffixed with a \n(unless it ends in a \n), and the pty will be marked as "owing" a \n.In the meantime, if the user continues to create input events, they areappended at the end of the textsw, after the response from the pty. Whenan activating event is entered, all of the markers, etc. are updated asdescribed above.The most general situation is: Old stuff in the log file ^User editing here More old stuff Completed commands enqueued for the pty Pty inserting here^ (Prompt)Partial user command*/#endifextern Cmdsw *cmdsw;extern Textswttysw_to_textsw(ttysw) struct ttysubwindow *ttysw;{ return((Textsw)ttysw->ttysw_hist);}/* #endif CMDSW *//* * Main pty processing. */ /* * Write window input to pty */ttysw_pty_output(ttysw, pty) register struct ttysubwindow *ttysw; int pty;{ register int cc; if (ttysw_getopt((caddr_t) ttysw, TTYOPT_TEXT)) { if (cmdsw->pty_eot > -1) { char *eot_bp = ibuf + cmdsw->pty_eot; char nullc = '\0'; /* write everything up to pty_eot */ if (eot_bp > irbp) { cc = write(pty, irbp, eot_bp - irbp); if (cc > 0) { irbp += cc; } else if (cc < 0) { perror("TTYSW pty write failure"); } } /* write the eot */ if (irbp == eot_bp) { cc = write(pty, &nullc, 0); if (cc < 0) { perror("TTYSW pty write failure"); } else { cmdsw->pty_eot = -1; } } } /* cmdsw->pty_eot > -1 */ /* only write the rest of the buffer if it doesn't have an eot in it */ if (cmdsw->pty_eot > -1) return; } if (iwbp > irbp) { cc = write(pty, irbp, iwbp - irbp); if (cc > 0) { irbp += cc; if (irbp == iwbp) irbp = iwbp = ibuf; } else if (cc < 0) { perror("TTYSW pty write failure"); } }}voidttysw_process_STI(ttysw, cp, cc) register struct ttysubwindow *ttysw; register char *cp; register int cc;{ register short post_id; register Textsw textsw = (Textsw) ttysw->ttysw_hist; Textsw_index pty_index; Textsw_index cmd_start;#ifdef DEBUG fprintf(stderr, "STI "); fwrite(cp, 1, cc, stderr); fprintf(stderr, "\n");#endif DEBUG if (!textsw) { return; } /* Assume app wants STI text echoed at cursor position */ if (cmdsw->cooked_echo) { pty_index = textsw_find_mark(textsw, cmdsw->pty_mark); if (cmdsw->cmd_started) { cmd_start = textsw_find_mark(textsw, cmdsw->user_mark); } else { cmd_start = (Textsw_index) window_get(textsw, TEXTSW_LENGTH); } if (cmd_start > pty_index) { if (cmdsw->append_only_log) { textsw_remove_mark(textsw, cmdsw->read_only_mark); } (void) textsw_delete(textsw, pty_index, cmd_start); if (cmdsw->append_only_log) { cmdsw->read_only_mark = textsw_add_mark(textsw, pty_index, TEXTSW_MARK_READ_ONLY); } cmdsw->pty_owes_newline = 0; } } /* Pretend STI text came in from textsw window fd */ while (cc > 0) { post_id = (short) (*cp); win_post_id(textsw, post_id, NOTIFY_SAFE); cp++; cc--; } /* flush caches */ (void) window_get(textsw, TEXTSW_LENGTH);}/* * Read pty's input (which is output from program) */ttysw_pty_input(ttysw, pty) register struct ttysubwindow *ttysw; int pty;{ static struct iovec iov[2]; register int cc; char ucntl; register unsigned int_ucntl; /* use readv so can read packet header into separate char? */ iov[0].iov_base = &ucntl; iov[0].iov_len = 1; iov[1].iov_base = owbp; iov[1].iov_len = oebp - owbp; cc = readv(pty, iov, 2); if (cc < 0 && errno == EWOULDBLOCK) cc = 0; else if (cc <= 0) cc = -1; if (cc > 0) { int_ucntl = (unsigned)ucntl; if (int_ucntl != 0 && ttysw_getopt((caddr_t) ttysw, TTYOPT_TEXT)) { unsigned tiocsti = TIOCSTI; if (int_ucntl == (tiocsti & 0xff)) { ttysw_process_STI(ttysw, owbp, cc-1); } (void) ioctl(ttysw->ttysw_tty, TIOCGETC, &cmdsw->tchars); (void) ioctl(ttysw->ttysw_tty, TIOCGLTC, &cmdsw->ltchars); (void) ttysw_getp(ttysw); } else { owbp += cc-1; } }}/* * Send program output to terminal emulator. */ttysw_consume_output(ttysw) register struct ttysubwindow *ttysw;{ int cc; while (owbp > orbp && !ttysw->ttysw_frozen) { if (!ttysw_getopt((caddr_t) ttysw, TTYOPT_TEXT)) { if (ttysw->ttysw_primary.sel_made) { ttysel_deselect(&ttysw->ttysw_primary, SELN_PRIMARY); } if (ttysw->ttysw_secondary.sel_made) { ttysel_deselect(&ttysw->ttysw_secondary, SELN_SECONDARY); } pw_batch(csr_pixwin, PW_ALL); } cc = ttysw_output((Ttysubwindow)(LINT_CAST(ttysw)), orbp, owbp - orbp); if (!ttysw_getopt((caddr_t) ttysw, TTYOPT_TEXT)) { pw_batch(csr_pixwin, PW_NONE); } orbp += cc; if (orbp == owbp) orbp = owbp = obuf; }}/* * Add the string to the input queue. */ttysw_input(ttysw0, addr, len) caddr_t ttysw0; char *addr; int len;{ struct ttysubwindow *ttysw = (struct ttysubwindow *) LINT_CAST(ttysw0); if (ttysw_getopt((caddr_t) ttysw, TTYOPT_TEXT)) { register Textsw textsw = (Textsw)ttysw->ttysw_hist; (void)textsw_insert(textsw, addr, (long int)len); } else { if (iwbp + len >= iebp) return (0); /* won't fit */ bcopy(addr, iwbp, len); iwbp += len; ttysw->ttysw_lpp = 0; /* reset page mode counter */ if (ttysw->ttysw_frozen) (void) ttysw_freeze(ttysw, 0); if ( !(ttysw->ttysw_flags & TTYSW_FL_IN_PRIORITIZER) && (ttysw->ttysw_flags & TTYSW_FL_USING_NOTIFIER)) { (void)ttysw_reset_conditions(ttysw); } } return (len);}intttysw_append_to_ibuf(ttysw, p, len)struct ttysubwindow *ttysw;char *p;int len;{ int is_cmdtool; /* * Since command line editing is not supported in remote * cmdtools, report-generating tty escape sequences (e.g., * ESC[11t) must be handled separately. */ is_cmdtool = ttysw_getopt((caddr_t) ttysw, TTYOPT_TEXT); if (is_cmdtool && (!cmdsw->cooked_echo)) { /* remote cmdtool */ if (iwbp + len >= iebp) return (0); /* (won't fit) */ bcopy(p, iwbp, len); iwbp += len; } else { if (is_cmdtool && (cmdsw->cooked_echo)) /* local cmdtool */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -