|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T c ┃
Length: 58270 (0xe39e) Types: TextFile Names: »charproc.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─ ⟦this⟧ »./X.V10R4/xterm/charproc.c«
/* * $Source: /u1/X/xterm/RCS/charproc.c,v $ * $Header: charproc.c,v 10.103 86/12/08 09:31:15 swick Exp $ */ #include <X/mit-copyright.h> /* Copyright (c) 1985 Massachusetts Institute of Technology */ /* Copyright (c) 1985 Digital Equipment Corporation */ /* charproc.c */ #include <stdio.h> #include <sgtty.h> #include <ctype.h> #include <errno.h> #include <setjmp.h> #include <sys/ioctl.h> #include <sys/time.h> #include <X/Xlib.h> #include "scrollbar.h" #include "ptyx.h" #include "VTparse.h" #include "data.h" #include "error.h" #ifdef MODEMENU #include "menu.h" #endif MODEMENU #define DEFAULT -1 #define TEXT_BUF_SIZE 256 #define input() (bcnt-- > 0 ? *bptr++ : in_put()) #ifndef lint static char sccs_id[] = "@(#)charproc.c\tX10/6.6\t11/10/86"; #endif lint static long arg; static int ch; static int nparam; static ANSI reply; static int param[NPARAM]; static unsigned long ctotal; static unsigned long ntotal; static jmp_buf vtjmpbuf; extern int groundtable[]; extern int csitable[]; extern int dectable[]; extern int eigtable[]; extern int esctable[]; extern int iestable[]; extern int igntable[]; extern int scrtable[]; extern int scstable[]; VTparse() { register Screen *screen = &term.screen; register int *parsestate = groundtable; register int c; register char *cp; register int row, col, top, bot, scstype; WindowInfo wininfo; extern int bitset(), bitclr(), finput(); if(setjmp(vtjmpbuf)) parsestate = groundtable; for( ; ; ) switch(parsestate[c = input()]) { case CASE_GROUND_STATE: /* exit ignore mode */ parsestate = groundtable; break; case CASE_IGNORE_STATE: /* Ies: ignore anything else */ parsestate = igntable; break; case CASE_IGNORE_ESC: /* Ign: escape */ parsestate = iestable; break; case CASE_IGNORE: /* Ignore character */ break; case CASE_BELL: /* bell */ Bell(); break; case CASE_BS: /* backspace */ CursorBack(screen, 1); break; case CASE_CR: /* carriage return */ CarriageReturn(screen); break; case CASE_ESC: /* escape */ parsestate = esctable; break; case CASE_VMOT: /* * form feed, line feed, vertical tab, but not in * status line */ if(!screen->instatus) Index(screen, 1); if (term.flags & LINEFEED) CarriageReturn(screen); if(screen->display->qlen > 0 || (ioctl(screen->display->fd, FIONREAD, &arg), arg) > 0) xevents(); break; case CASE_TAB: /* tab */ screen->cur_col = TabNext(term.tabs, screen->cur_col); if (screen->cur_col > screen->max_col) screen->cur_col = screen->max_col; break; case CASE_SI: screen->curgl = 0; break; case CASE_SO: screen->curgl = 1; break; case CASE_SCR_STATE: /* enter scr state */ parsestate = scrtable; break; case CASE_SCS0_STATE: /* enter scs state 0 */ scstype = 0; parsestate = scstable; break; case CASE_SCS1_STATE: /* enter scs state 1 */ scstype = 1; parsestate = scstable; break; case CASE_SCS2_STATE: /* enter scs state 2 */ scstype = 2; parsestate = scstable; break; case CASE_SCS3_STATE: /* enter scs state 3 */ scstype = 3; parsestate = scstable; break; case CASE_ESC_IGNORE: /* unknown escape sequence */ parsestate = eigtable; break; case CASE_ESC_DIGIT: /* digit in csi or dec mode */ if((row = param[nparam - 1]) == DEFAULT) row = 0; param[nparam - 1] = 10 * row + (c - '0'); break; case CASE_ESC_SEMI: /* semicolon in csi or dec mode */ param[nparam++] = DEFAULT; break; case CASE_DEC_STATE: /* enter dec mode */ parsestate = dectable; break; case CASE_ICH: /* ICH */ if((c = param[0]) < 1) c = 1; InsertChar(screen, c); parsestate = groundtable; break; case CASE_CUU: /* CUU */ /* only if not in status line */ if(!screen->instatus) { if((c = param[0]) < 1) c = 1; CursorUp(screen, c); } parsestate = groundtable; break; case CASE_CUD: /* CUD */ /* only if not in status line */ if(!screen->instatus) { if((c = param[0]) < 1) c = 1; CursorDown(screen, c); } parsestate = groundtable; break; case CASE_CUF: /* CUF */ if((c = param[0]) < 1) c = 1; CursorForward(screen, c); parsestate = groundtable; break; case CASE_CUB: /* CUB */ if((c = param[0]) < 1) c = 1; CursorBack(screen, c); parsestate = groundtable; break; case CASE_CUP: /* CUP | HVP */ /* only if not in status line */ if(!screen->instatus) { if((row = param[0]) < 1) row = 1; if(nparam < 2 || (col = param[1]) < 1) col = 1; CursorSet(screen, row-1, col-1, term.flags); } parsestate = groundtable; break; case CASE_ED: /* ED */ switch (param[0]) { case DEFAULT: case 0: if(screen->instatus) ClearRight(screen); else ClearBelow(screen); break; case 1: if(screen->instatus) ClearLeft(screen); else ClearAbove(screen); break; case 2: if(screen->instatus) ClearLine(screen); else ClearScreen(screen); break; } parsestate = groundtable; break; case CASE_EL: /* EL */ switch (param[0]) { case DEFAULT: case 0: ClearRight(screen); break; case 1: ClearLeft(screen); break; case 2: ClearLine(screen); break; } parsestate = groundtable; break; case CASE_IL: /* IL */ /* only if not in status line */ if(!screen->instatus) { if((c = param[0]) < 1) c = 1; InsertLine(screen, c); } parsestate = groundtable; break; case CASE_DL: /* DL */ /* only if not in status line */ if(!screen->instatus) { if((c = param[0]) < 1) c = 1; DeleteLine(screen, c); } parsestate = groundtable; break; case CASE_DCH: /* DCH */ if((c = param[0]) < 1) c = 1; DeleteChar(screen, c); parsestate = groundtable; break; case CASE_DA1: /* DA1 */ if (param[0] <= 0) { /* less than means DEFAULT */ reply.a_type = CSI; reply.a_pintro = '?'; reply.a_nparam = 2; reply.a_param[0] = 1; /* VT102 */ reply.a_param[1] = 2; /* VT102 */ reply.a_inters = 0; reply.a_final = 'c'; unparseseq(&reply, screen->respond); } parsestate = groundtable; break; case CASE_TBC: /* TBC */ if ((c = param[0]) <= 0) /* less than means default */ TabClear(term.tabs, screen->cur_col); else if (c == 3) TabZonk(term.tabs); parsestate = groundtable; break; case CASE_SET: /* SET */ modes(&term, bitset); parsestate = groundtable; break; case CASE_RST: /* RST */ modes(&term, bitclr); parsestate = groundtable; break; case CASE_SGR: /* SGR */ for (c=0; c<nparam; ++c) { switch (param[c]) { case DEFAULT: case 0: term.flags &= ~(INVERSE|BOLD|UNDERLINE); break; case 1: case 5: /* Blink, really. */ term.flags |= BOLD; break; case 4: /* Underscore */ term.flags |= UNDERLINE; break; case 7: term.flags |= INVERSE; } } parsestate = groundtable; break; case CASE_CPR: /* CPR */ if ((c = param[0]) == 5) { reply.a_type = CSI; reply.a_pintro = 0; reply.a_nparam = 1; reply.a_param[0] = 0; reply.a_inters = 0; reply.a_final = 'n'; unparseseq(&reply, screen->respond); } else if (c == 6) { reply.a_type = CSI; reply.a_pintro = 0; reply.a_nparam = 2; reply.a_param[0] = screen->cur_row+1; reply.a_param[1] = screen->cur_col+1; reply.a_inters = 0; reply.a_final = 'R'; unparseseq(&reply, screen->respond); } parsestate = groundtable; break; case CASE_DECSTBM: /* DECSTBM */ /* only if not in status line */ if(!screen->instatus) { if((top = param[0]) < 1) top = 1; if(nparam < 2 || (bot = param[1]) == DEFAULT || bot > screen->max_row + 1 || bot == 0) bot = screen->max_row+1; if (bot > top) { if(screen->scroll_amt) FlushScroll(screen); screen->top_marg = top-1; screen->bot_marg = bot-1; CursorSet(screen, 0, 0, term.flags); } } parsestate = groundtable; break; case CASE_SUN_EMU: /* sub-set of sun tty emulation */ switch(param[0]) { case 3: /* move window */ if(nparam == 3) { XMoveWindow(VWindow(screen), param[1], param[2]); XSync(FALSE); /* synchronize */ if(QLength() > 0) xevents(); } break; case 4: /* resize window (pixels) */ if(nparam == 3) { XChangeWindow (VWindow(screen), param[1], param[2]); XSync(FALSE); /* synchronize */ if(QLength() > 0) xevents(); } break; case 5: /* raise window */ XRaiseWindow(VWindow(screen)); break; case 6: /* lower window */ XLowerWindow(VWindow(screen)); break; case 7: /* redisplay window */ Redraw(); break; case 8: /* resize window (rows and columns) */ if(nparam == 3) { XChangeWindow (VWindow(screen), FontWidth(screen) * param[2] + 2 * screen->border + screen->scrollbar, FontHeight(screen) * param[1] + screen->statusheight + Titlebar(screen) + 2 * screen->border); XSync(FALSE); /* synchronize */ if(QLength() > 0) xevents(); } break; case 13: /* send window position */ XQueryWindow(VWindow(screen), &wininfo); reply.a_type = CSI; reply.a_pintro = 0; reply.a_nparam = 3; reply.a_param[0] = 3; reply.a_param[1] = wininfo.x; reply.a_param[2] = wininfo.y; reply.a_inters = 0; reply.a_final = 't'; unparseseq(&reply, screen->respond); break; case 14: /* send window size (pixels) */ reply.a_type = CSI; reply.a_pintro = 0; reply.a_nparam = 3; reply.a_param[0] = 4; reply.a_param[1] = (screen->max_col + 1) * FontWidth(screen) + 2 * screen->border + screen->scrollbar; reply.a_param[2] = (screen->max_row + 1) * FontHeight(screen) + screen->statusheight + Titlebar(screen) + 2 * screen->border; reply.a_inters = 0; reply.a_final = 't'; unparseseq(&reply, screen->respond); break; case 18: /* send window size (rows and cols) */ reply.a_type = CSI; reply.a_pintro = 0; reply.a_nparam = 3; reply.a_param[0] = 8; reply.a_param[1] = screen->max_row + 1; reply.a_param[2] = screen->max_col + 1; reply.a_inters = 0; reply.a_final = 't'; unparseseq(&reply, screen->respond); break; } parsestate = groundtable; break; case CASE_DECREQTPARM: /* DECREQTPARM */ if ((c = param[0]) == DEFAULT) c = 0; if (c == 0 || c == 1) { reply.a_type = CSI; reply.a_pintro = 0; reply.a_nparam = 7; reply.a_param[0] = c + 2; reply.a_param[1] = 1; /* no parity */ reply.a_param[2] = 1; /* eight bits */ reply.a_param[3] = 112; /* transmit 9600 baud */ reply.a_param[4] = 112; /* receive 9600 baud */ reply.a_param[5] = 1; /* clock multiplier ? */ reply.a_param[6] = 0; /* STP flags ? */ reply.a_inters = 0; reply.a_final = 'x'; unparseseq(&reply, screen->respond); } parsestate = groundtable; break; case CASE_DECSET: /* DECSET */ dpmodes(&term, bitset); parsestate = groundtable; if(screen->TekEmu) return; break; case CASE_DECRST: /* DECRST */ dpmodes(&term, bitclr); parsestate = groundtable; break; case CASE_HIDDEN: /* special "hidden" sequence */ fprintf(stderr, "avg call = %ld char\n", ctotal/ntotal); parsestate = groundtable; break; case CASE_DECALN: /* DECALN */ if(screen->cursor_state) HideCursor(); for(row = screen->max_row ; row >= 0 ; row--) { bzero(screen->buf[2 * row + 1], col = screen->max_col + 1); for(cp = screen->buf[2 * row] ; col > 0 ; col--) *cp++ = 'E'; } ScrnRefresh(screen, 0, 0, screen->max_row + 1, screen->max_col + 1); parsestate = groundtable; break; case CASE_GSETS: screen->gsets[scstype] = c; parsestate = groundtable; break; case CASE_DECSC: /* DECSC */ CursorSave(&term, &screen->sc); parsestate = groundtable; break; case CASE_DECRC: /* DECRC */ CursorRestore(&term, &screen->sc); parsestate = groundtable; break; case CASE_DECKPAM: /* DECKPAM */ term.keyboard.flags |= KYPD_APL; parsestate = groundtable; break; case CASE_DECKPNM: /* DECKPNM */ term.keyboard.flags &= ~KYPD_APL; parsestate = groundtable; break; case CASE_IND: /* IND */ /* only if not in status line */ if(!screen->instatus) Index(screen, 1); if(screen->display->qlen > 0 || (ioctl(screen->display->fd, FIONREAD, &arg), arg) > 0) xevents(); parsestate = groundtable; break; case CASE_NEL: /* NEL */ /* only if not in status line */ if(!screen->instatus) Index(screen, 1); CarriageReturn(screen); if(screen->display->qlen > 0 || (ioctl(screen->display->fd, FIONREAD, &arg), arg) > 0) xevents(); parsestate = groundtable; break; case CASE_HTS: /* HTS */ TabSet(term.tabs, screen->cur_col); parsestate = groundtable; break; case CASE_RI: /* RI */ /* only if not in status line */ if(!screen->instatus) RevIndex(screen, 1); parsestate = groundtable; break; case CASE_SS2: /* SS2 */ screen->curss = 2; parsestate = groundtable; break; case CASE_SS3: /* SS3 */ screen->curss = 3; parsestate = groundtable; break; case CASE_CSI_STATE: /* enter csi state */ nparam = 1; param[0] = DEFAULT; parsestate = csitable; break; case CASE_OSC: /* do osc escapes */ do_osc(finput); parsestate = groundtable; break; case CASE_RIS: /* RIS */ VTReset(TRUE); parsestate = groundtable; break; case CASE_LS2: /* LS2 */ screen->curgl = 2; parsestate = groundtable; break; case CASE_LS3: /* LS3 */ screen->curgl = 3; parsestate = groundtable; break; case CASE_LS3R: /* LS3R */ screen->curgr = 3; parsestate = groundtable; break; case CASE_LS2R: /* LS2R */ screen->curgr = 2; parsestate = groundtable; break; case CASE_LS1R: /* LS1R */ screen->curgr = 1; parsestate = groundtable; break; case CASE_TO_STATUS: if((c = param[0]) < 1) c = 1; ToStatus(c - 1); parsestate = groundtable; break; case CASE_FROM_STATUS: FromStatus(); parsestate = groundtable; break; case CASE_SHOW_STATUS: ShowStatus(); parsestate = groundtable; break; case CASE_HIDE_STATUS: HideStatus(); parsestate = groundtable; break; case CASE_ERASE_STATUS: EraseStatus(); parsestate = groundtable; break; case CASE_XTERM_SAVE: savemodes(&term); parsestate = groundtable; break; case CASE_XTERM_RESTORE: restoremodes(&term); parsestate = groundtable; break; case CASE_PRINT: /* printable characters */ top = bcnt > TEXT_BUF_SIZE ? TEXT_BUF_SIZE : bcnt; cp = bptr; *--bptr = c; while(top > 0 && isprint(*cp)) { top--; bcnt--; cp++; } if(screen->curss) { dotext(screen, term.flags, screen->gsets[screen->curss], bptr, bptr + 1); screen->curss = 0; bptr++; } if(bptr < cp) dotext(screen, term.flags, screen->gsets[screen->curgl], bptr, cp); bptr = cp; break; } } finput() { return(input()); } static int select_mask; in_put() { register Screen *screen = &term.screen; register char *cp; register int i; select_mask = pty_mask; /* force initial read */ for( ; ; ) { if(select_mask & pty_mask) { if(screen->logging) FlushLog(screen); if((bcnt = read(screen->respond, bptr = buffer, BUF_SIZE)) < 0) { if(errno == EIO && am_slave) exit(0); else if(errno != EWOULDBLOCK) Panic( "input: read returned unexpected error (%d)\n", errno); } else if(bcnt == 0) Panic("input: read returned zero\n"); else { /* strip parity bit */ for(i = bcnt, cp = bptr ; i > 0 ; i--) *cp++ &= CHAR; if(screen->sb && screen->scrollinput && screen->topline < 0) ScrollToBottom(screen->sb); if(screen->icon_show && !screen->iconinput) { screen->iconinput = TRUE; IconBox(screen); } break; } } 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(); } if(QLength()) select_mask = X_mask; else { XFlush(); select_mask = Select_mask; if((i = select(max_plus1, &select_mask, NULL, NULL, screen->timeout)) < 0){ if (errno != EINTR) SysError(ERROR_SELECT); continue; } else if(i == 0) { if(GetButtonState(screen->sb) & HILITED) WindowScroll(screen, ButtonRegion(screen->sb)); screen->timeout->tv_usec = STEPTIME; continue; } } if(select_mask & X_mask) xevents(); } bcnt--; return(*bptr++); } /* * process a string of characters according to the character set indicated * by charset. worry about end of line conditions (wraparound if selected). */ dotext(screen, flags, charset, buf, ptr) register Screen *screen; unsigned flags; char charset; char *buf; char *ptr; { register char *s; register int len; register int n; register int next_col; switch (charset) { case 'A': /* United Kingdom set */ for (s=buf; s<ptr; ++s) if (*s == '#') *s = '\036'; /* UK pound sign */ break; 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; default: /* any character sets we don't recognize */ return; } 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) && !screen->instatus) { 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); /* * 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. */ screen->do_wrap = (screen->cur_col < next_col); len -= n; ptr += n; } } /* * write a string str of length len onto the screen at * the current cursor position. update cursor position. */ WriteText(screen, str, len, flags) register Screen *screen; register char *str; register int len; unsigned flags; { register int pix, cx, cy; register unsigned fgs = flags; Font fnt; if(screen->instatus && screen->reversestatus) fgs ^= INVERSE; if(screen->cur_row - screen->topline <= screen->max_row || screen->instatus) { /* 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(); fnt = ActiveIcon(screen) ? screen->fnt_icon : (fgs & BOLD) ? screen->fnt_bold : screen->fnt_norm; 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); if (screen->show || ActiveIcon(screen)) { if (fgs & INVERSE) XText(VWindow(screen), cx, cy, str, len, fnt, pix = screen->background, screen->foreground); else XText(VWindow(screen), cx, cy, str, len, fnt, pix = screen->foreground, screen->background); if((fgs & BOLD) && screen->enbolden) XTextMask(VWindow(screen), cx + 1, cy, str, len, fnt, pix); if(fgs & UNDERLINE) { cy += FontHeight(screen) - 2; XLine(VWindow(screen), cx, cy, cx + len * FontWidth(screen), cy, 1, 1, pix, GXcopy, AllPlanes); } } /* * 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, len); CursorForward(screen, len); } /* * process ANSI modes set, reset */ modes(term, func) Terminal *term; int (*func)(); { register Screen *screen = &term->screen; register int i; for (i=0; i<nparam; ++i) { switch (param[i]) { case 4: /* IRM */ (*func)(&term->flags, INSERT); break; case 20: /* LNM */ (*func)(&term->flags, LINEFEED); break; } } } /* * process DEC private modes set, reset */ dpmodes(term, func) Terminal *term; int (*func)(); { register Screen *screen = &term->screen; register int i, j; extern int bitset(); for (i=0; i<nparam; ++i) { switch (param[i]) { case 1: /* DECCKM */ (*func)(&term->keyboard.flags, CURSOR_APL); break; case 3: /* DECCOLM */ if(screen->c132) { ClearScreen(screen); CursorSet(screen, 0, 0, term->flags); if((j = func == bitset ? 132 : 80) != ((term->flags & IN132COLUMNS) ? 132 : 80) || j != screen->max_col + 1) { XChangeWindow (VWindow(screen), FontWidth(screen) * j + 2*screen->border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + Titlebar(screen) + 2 * screen->border); XSync(FALSE); /* synchronize */ if(QLength() > 0) xevents(); } (*func)(&term->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)(&term->flags, SMOOTHSCROLL); break; case 5: /* DECSCNM */ j = term->flags; (*func)(&term->flags, REVERSE_VIDEO); if ((term->flags ^ j) & REVERSE_VIDEO) ReverseVideo(term); break; case 6: /* DECOM */ (*func)(&term->flags, ORIGIN); CursorSet(screen, 0, 0, term->flags); break; case 7: /* DECAWM */ (*func)(&term->flags, WRAPAROUND); break; case 8: /* DECARM */ j = term->flags; (*func)(&term->flags, AUTOREPEAT); if ((term->flags ^ j) & AUTOREPEAT) if(term->flags & AUTOREPEAT) XAutoRepeatOn(); else XAutoRepeatOff(); break; case 9: /* MIT bogus sequence */ (*func)(&screen->send_mouse_pos, 1); break; case 38: /* DECTEK */ if(func == bitset & !(screen->inhibit & I_TEK)) { if(screen->logging) { FlushLog(screen); screen->logstart = Tbuffer; } screen->TekEmu = TRUE; } break; case 40: /* 132 column mode */ (*func)(&screen->c132, 1); break; case 41: /* curses hack */ (*func)(&screen->curses, 1); break; case 42: /* scrollbar */ if(func == bitset) ScrollBarOn(screen, TRUE, FALSE); else ScrollBarOff(screen); break; case 43: /* lines off top */ if(screen->sb) SetSaveState(screen->sb, (func == bitset)); break; case 44: /* margin bell */ (*func)(&screen->marginbell, 1); if(!screen->marginbell) screen->bellarmed = -1; break; case 45: /* reverse wraparound */ (*func)(&term->flags, REVERSEWRAP); break; case 46: /* logging */ if(func == bitset) StartLog(screen); else CloseLog(screen); break; case 47: /* alternate buffer */ if(func == bitset) ToAlternate(screen); else FromAlternate(screen); break; case 48: /* reverse status line */ j = screen->reversestatus; (*func)(&screen->reversestatus, 1); if(j != screen->reversestatus) ScrnRefresh(screen, screen->max_row + 1, 0, 1, screen->max_col + 1); break; case 49: /* page mode */ j = screen->pagemode; (*func)(&screen->pagemode, 1); if(!j && screen->pagemode) screen->pagecnt = 0; break; } } } /* * process xterm private modes save */ savemodes(term) Terminal *term; { register Screen *screen = &term->screen; register int i; for (i = 0; i < nparam; i++) { switch (param[i]) { case 1: /* DECCKM */ screen->save_modes[0] = term->keyboard.flags & CURSOR_APL; break; case 3: /* DECCOLM */ if(screen->c132) screen->save_modes[1] = term->flags & IN132COLUMNS; break; case 4: /* DECSCLM (slow scroll) */ screen->save_modes[2] = term->flags & SMOOTHSCROLL; break; case 5: /* DECSCNM */ screen->save_modes[3] = term->flags & REVERSE_VIDEO; break; case 6: /* DECOM */ screen->save_modes[4] = term->flags & ORIGIN; break; case 7: /* DECAWM */ screen->save_modes[5] = term->flags & WRAPAROUND; break; case 8: /* DECARM */ screen->save_modes[6] = term->flags & AUTOREPEAT; break; case 9: /* MIT bogus sequence */ screen->save_modes[7] = screen->send_mouse_pos; break; case 40: /* 132 column mode */ screen->save_modes[8] = screen->c132; break; case 41: /* curses hack */ screen->save_modes[9] = screen->curses; break; case 42: /* scrollbar */ screen->save_modes[10] = screen->scrollbar; break; case 43: /* lines off top */ if(screen->sb) screen->save_modes[11] = GetSaveState(screen->sb); break; case 44: /* margin bell */ screen->save_modes[12] = screen->marginbell; break; case 45: /* reverse wraparound */ screen->save_modes[13] = term->flags & REVERSEWRAP; break; case 46: /* logging */ screen->save_modes[14] = screen->logging; break; case 47: /* alternate buffer */ screen->save_modes[15] = screen->alternate; break; case 48: /* reverse status line */ screen->save_modes[16] = screen->reversestatus; break; case 49: /* page mode */ screen->save_modes[17] = screen->pagemode; screen->save_modes[18] = screen->pagecnt; break; } } } /* * process xterm private modes restore */ restoremodes(term) Terminal *term; { register Screen *screen = &term->screen; register int i, j; for (i = 0; i < nparam; i++) { switch (param[i]) { case 1: /* DECCKM */ term->keyboard.flags &= ~CURSOR_APL; term->keyboard.flags |= screen->save_modes[0] & CURSOR_APL; break; case 3: /* DECCOLM */ if(screen->c132) { ClearScreen(screen); CursorSet(screen, 0, 0, term->flags); if((j = (screen->save_modes[1] & IN132COLUMNS) ? 132 : 80) != ((term->flags & IN132COLUMNS) ? 132 : 80) || j != screen->max_col + 1) { XChangeWindow (VWindow(screen), FontWidth(screen) * j + 2*screen->border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + Titlebar(screen) + 2 * screen->border); XSync(FALSE); /* synchronize */ if(QLength() > 0) xevents(); } term->flags &= ~IN132COLUMNS; term->flags |= screen->save_modes[1] & IN132COLUMNS; } break; case 4: /* DECSCLM (slow scroll) */ if (screen->save_modes[2] & SMOOTHSCROLL) { screen->jumpscroll = 0; if (screen->scroll_amt) FlushScroll(screen); } else screen->jumpscroll = 1; term->flags &= ~SMOOTHSCROLL; term->flags |= screen->save_modes[2] & SMOOTHSCROLL; break; case 5: /* DECSCNM */ if((screen->save_modes[3] ^ term->flags) & REVERSE_VIDEO) { term->flags &= ~REVERSE_VIDEO; term->flags |= screen->save_modes[3] & REVERSE_VIDEO; ReverseVideo(term); } break; case 6: /* DECOM */ term->flags &= ~ORIGIN; term->flags |= screen->save_modes[4] & ORIGIN; CursorSet(screen, 0, 0, term->flags); break; case 7: /* DECAWM */ term->flags &= ~WRAPAROUND; term->flags |= screen->save_modes[5] & WRAPAROUND; break; case 8: /* DECARM */ if((screen->save_modes[6] ^ term->flags) & AUTOREPEAT) { term->flags &= ~REVERSE_VIDEO; term->flags |= screen->save_modes[6] & REVERSE_VIDEO; if(term->flags & AUTOREPEAT) XAutoRepeatOn(); else XAutoRepeatOff(); } break; case 9: /* MIT bogus sequence */ screen->send_mouse_pos = screen->save_modes[7]; break; case 40: /* 132 column mode */ screen->c132 = screen->save_modes[8]; break; case 41: /* curses hack */ screen->curses = screen->save_modes[9]; break; case 42: /* scrollbar */ if(screen->save_modes[10]) ScrollBarOn(screen, TRUE, FALSE); else ScrollBarOff(screen); break; case 43: /* lines off top */ if(screen->sb) SetSaveState(screen->sb,screen->save_modes[11]); break; case 44: /* margin bell */ if(!(screen->marginbell = screen->save_modes[12])) screen->bellarmed = -1; break; case 45: /* reverse wraparound */ term->flags &= ~REVERSEWRAP; term->flags |= screen->save_modes[13] & REVERSEWRAP; break; case 46: /* logging */ if(screen->save_modes[14]) StartLog(screen); else CloseLog(screen); break; case 47: /* alternate buffer */ if(screen->save_modes[15]) ToAlternate(screen); else FromAlternate(screen); break; case 48: /* reverse status line */ if(screen->save_modes[16] != screen->reversestatus) { screen->reversestatus = screen->save_modes[16]; ScrnRefresh(screen, screen->max_row + 1, 0, 1, screen->max_col + 1); } break; case 49: /* page mode */ screen->pagemode = screen->save_modes[17]; screen->pagecnt = screen->save_modes[18]; break; } } } /* * set a bit in a word given a pointer to the word and a mask. */ bitset(p, mask) int *p; { *p |= mask; } /* * clear a bit in a word given a pointer to the word and a mask. */ bitclr(p, mask) int *p; { *p &= ~mask; } unparseseq(ap, fd) register ANSI *ap; { register int c; register int i; register int inters; c = ap->a_type; if (c>=0x80 && c<=0x9F) { unparseputc(ESC, fd); c -= 0x40; } unparseputc(c, fd); c = ap->a_type; if (c==ESC || c==DCS || c==CSI || c==OSC || c==PM || c==APC) { if (ap->a_pintro != 0) unparseputc(ap->a_pintro, fd); for (i=0; i<ap->a_nparam; ++i) { if (i != 0) unparseputc(';', fd); unparseputn(ap->a_param[i], fd); } inters = ap->a_inters; for (i=3; i>=0; --i) c = (inters >> (8*i)) & 0xff; if (c != 0) unparseputc(c, fd); unparseputc(ap->a_final, fd); } } unparseputn(n, fd) unsigned int n; { unsigned int q; q = n/10; if (q != 0) unparseputn(q, fd); unparseputc((n%10) + '0', fd); } unparseputc(c, fd) { char buf[2]; register i = 1; extern Terminal term; if((buf[0] = c) == '\r' && (term.flags & LINEFEED)) { buf[1] = '\n'; i++; } if (write(fd, buf, i) != i) Panic("unparseputc: error writing character\n", 0); } static int alt_pagecnt; static int alt_pagemode; static int alt_saving; ToAlternate(screen) register Screen *screen; { extern ScrnBuf Allocate(); if(screen->alternate) return; if(!screen->altbuf) screen->altbuf = Allocate(screen->max_row + 1, screen->max_col + 1); if(screen->sb) { alt_saving = GetSaveState(screen->sb); SetSaveState(screen->sb, FALSE); } else alt_saving = TRUE; if(alt_pagemode = screen->pagemode) alt_pagecnt = screen->pagecnt; screen->pagemode = FALSE; SwitchBufs(screen); screen->alternate = TRUE; } FromAlternate(screen) register Screen *screen; { if(!screen->alternate) return; screen->alternate = FALSE; if(screen->sb) SetSaveState(screen->sb, alt_saving); if(screen->pagemode = alt_pagemode) screen->pagecnt = alt_pagecnt; SwitchBufs(screen); } SwitchBufs(screen) register Screen *screen; { register int rows, top; char *save [2 * MAX_ROWS]; if(screen->cursor_state) HideCursor(); rows = screen->max_row + 1; bcopy((char *)screen->buf, (char *)save, 2 * sizeof(char *) * rows); bcopy((char *)screen->altbuf, (char *)screen->buf, 2 * sizeof(char *) * rows); bcopy((char *)save, (char *)screen->altbuf, 2 * sizeof(char *) * rows); if((top = -screen->topline) <= screen->max_row) { if(screen->scroll_amt) FlushScroll(screen); if(top == 0 && !screen->statusline) XClear(VWindow(screen)); else XTileSet(VWindow(screen), screen->border, top * FontHeight(screen) + screen->border + Titlebar(screen), Width(screen), (screen->max_row - top + 1) * FontHeight(screen), screen->bgndtile); } ScrnRefresh(screen, 0, 0, rows, screen->max_col + 1); } VTRun() { register Screen *screen = &term.screen; register int i; if(!VWindow(screen) && !VTInit()) { if(TWindow(screen)) { screen->TekEmu = TRUE; return; } Exit(ERROR_VINIT); } screen->cursor_state = OFF; screen->cursor_set = ON; if(screen->icon_show) { if(screen->icon_show < 0) { screen->icon_show = TRUE; screen->mappedVwin = &screen->iconVwin; XMapWindow(screen->iconVwin.window); } } else if(!screen->show) { screen->show = TRUE; screen->mappedVwin = &screen->fullVwin; XMapWindow(VWindow(screen)); } else XRaiseWindow(VWindow(screen)); if(screen->select) VTSelect(); if (L_flag > 0) { XWarpMouse (VWindow(screen), FullWidth(screen) >> 1, FullHeight(screen) >>1); L_flag = -1; } bcnt = 0; bptr = buffer; while(Tpushb > Tpushback) { *bptr++ = *--Tpushb; bcnt++; } bcnt += (i = Tbcnt); for( ; i > 0 ; i--) *bptr++ = *Tbptr++; bptr = buffer; if(!setjmp(VTend)) VTparse(); HideCursor(); screen->cursor_set = OFF; VTUnselect(); } VTInit() { int width, height; FontInfo *fInfo, *ifInfo; register Screen *screen = &term.screen; register Vertex *vp; register int i, j; char *def = "=80x24+1+1"; char iconname[128]; static short failed; Color cdef; OpaqueFrame twindow; WindowInfo wininfo; int x, y; Window win; extern char *malloc(); if(failed) return(FALSE); screen->mappedVwin = &screen->fullVwin; TabReset (term.tabs); screen->fnt_norm = screen->fnt_bold = screen->fnt_icon = NULL; if ((fInfo = XOpenFont(f_n)) == NULL) { fprintf(stderr, "%s: Could not open font %s!\n", xterm_name, f_n); failed = TRUE; return(FALSE); } screen->fnt_norm = fInfo->id; if (!f_b || !(screen->fnt_bold = XGetFont(f_b))) { screen->fnt_bold = screen->fnt_norm; screen->enbolden = TRUE; } screen->fullVwin.f_width = fInfo->width; screen->fullVwin.f_height = fInfo->height; if (screen->active_icon) { if (!screen->fnt_icon) { if ((ifInfo = XOpenFont(f_i)) == NULL) { fprintf( stderr, "%s: Could not open font %s!\n", xterm_name, f_i); failed = TRUE; return( FALSE ); } screen->fnt_icon = ifInfo->id; } else XQueryFont( screen->fnt_icon, &ifInfo ); screen->iconVwin.f_width = ifInfo->width; screen->iconVwin.f_height = ifInfo->height; } screen->curs = make_xterm(screen->mousecolor, screen->background, GXcopy); twindow.bdrwidth = screen->borderwidth; twindow.border = screen->graybordertile; twindow.background = screen->bgndtile; if((screen->minrows = (MINSCROLLBARHEIGHT - 2 * screen->border + fInfo->height - 1) / fInfo->height) < 0) screen->minrows = 0; i = 2 * screen->border + screen->scrollbar; j = 2 * screen->border + Titlebar(screen); if(screen->statusline) j += (screen->statusheight = fInfo->height + 2); if((screen->fullVwin.window = XCreateTerm ("Terminal Emulator", xterm_name, geo_metry, def, &twindow, 12, screen->minrows, i, j, &width, &height, fInfo, fInfo->width, fInfo->height)) == NULL) { fprintf(stderr, "%s: Can't create VT window\n"); XCloseFont(fInfo); return(FALSE); } XSelectInput(VWindow(screen), WINDOWEVENTS); /* * XCreateTerm flushes all events, which might include an EnterWindow * or LeaveWindow. So if the cursor is not where it is supposed to * be, we set select to the appropriate thing. */ if(TWindow(screen) && XQueryMouse(RootWindow, &x, &y, &win)) { if(screen->timer) { Timer(0L); screen->timer = 0; } if(win == TWindow(screen)) screen->select |= INWINDOW; else screen->select &= ~INWINDOW; } screen->fullVwin.fullwidth = twindow.width; screen->fullVwin.fullheight = twindow.height; screen->fullVwin.width = twindow.width - i; screen->fullVwin.height = twindow.height - j; /* Reset variables used by ANSI emulation. */ screen->gsets[0] = 'B'; /* ASCII_G */ screen->gsets[1] = 'B'; screen->gsets[2] = 'B'; /* DEC supplemental. */ screen->gsets[3] = 'B'; screen->curgl = 0; /* G0 => GL. */ screen->curgr = 2; /* G2 => GR. */ screen->curss = 0; /* No single shift. */ if(screen->iconTwin.window) { XQueryWindow(screen->iconTwin.window, &wininfo); x = wininfo.x; y = wininfo.y; } else { x = twindow.x + (twindow.width - screen->iconVwin.width) / 2; y = twindow.y + (twindow.height - screen->iconVwin.height) / 2; IconGeometry(screen, &x, &y); } screen->iconVwin.window = XCreateWindow( RootWindow, x, y, 1, 1, screen->borderwidth, screen->bordertile, screen->bgndtile ); XSetIconWindow( screen->fullVwin.window, screen->iconVwin.window ); XDefineCursor( screen->iconVwin.window, screen->arrow ); XSelectInput( screen->iconVwin.window, screen->active_icon ? ((term.flags & ICONINPUT) ? ICONWINDOWEVENTS | ICONINPUTEVENTS : ICONWINDOWEVENTS) : TICONWINDOWEVENTS ); XDefineCursor( VWindow(screen), screen->curs ); XStoreName (VWindow(screen), screen->winname); strcpy(iconname, screen->winname); strcat(iconname, " (icon)"); XStoreName (screen->iconVwin.window, iconname); XSetResizeHint (VWindow(screen), 2 * screen->border + screen->scrollbar, 2 * screen->border + Titlebar(screen) + screen->statusheight, fInfo->width, fInfo->height); screen->cur_col = screen->cur_row = 0; screen->max_col = Width(screen) / fInfo->width - 1; screen->top_marg = 0; screen->bot_marg = screen->max_row = Height(screen) / fInfo->height - 1; screen->sc.row = screen->sc.col = screen->sc.flags = NULL; SetIconSize( screen ); /* requires max_col, max_row */ /* allocate memory for screen buffer (including one for status line */ screen->buf = screen->allbuf = (ScrnBuf) Allocate (screen->max_row + 2, screen->max_col +1); screen->do_wrap = NULL; screen->scrolls = screen->incopy = 0; free((char *)fInfo); vp = &VTbox[1]; (vp++)->x = FontWidth(screen) - 1; (vp++)->y = FontHeight(screen) - 1; (vp++)->x = -(FontWidth(screen) - 1); vp->y = -(FontHeight(screen) - 1); screen->box = VTbox; status_box[0].x = screen->border - 1; screen->savelines = save_lines; if(screen->scrollbar) { screen->scrollbar = 0; ScrollBarOn(screen, TRUE, TRUE); screen->sb->action = NONE; } screen->nmarginbell = n_marginbell; if(Titlebar(screen)) VTTitleShow(TRUE); return(TRUE); } VTExpose(rep) register XExposeWindowEvent *rep; { register Screen *screen = &term.screen; if (rep && ScreenResize (screen, rep->width, rep->height, &term.flags) == -1) return; XClear (VWindow(screen)); ScrnRefresh(screen, 0, 0, screen->max_row + 1 + screen->statusline, screen->max_col + 1); } /* * Shows cursor at new cursor position in screen. */ ShowCursor() { register Screen *screen = &term.screen; register int fg; register int bg; register int x, y, flags; register Font fnt; char c; if (screen->icon_show && !screen->active_icon) return; if(!screen->instatus && screen->cur_row - screen->topline > screen->max_row) return; c = screen->buf[y = 2 * (screen->cursor_row = screen->cur_row)] [x = screen->cursor_col = screen->cur_col]; flags = screen->buf[y + 1][x]; if (c == 0) c = ' '; if(screen->instatus) flags ^= INVERSE; if(screen->select) { if(flags & INVERSE) { if(screen->cursorcolor != screen->foreground) { fg = screen->foreground; bg = screen->cursorcolor; } else { fg = screen->background; bg = screen->foreground; } } else { fg = screen->background; bg = screen->cursorcolor; } } else { if(flags & INVERSE) { fg = screen->background; bg = screen->foreground; } else { fg = screen->foreground; bg = screen->background; } } fnt = ActiveIcon(screen) ? screen->fnt_icon : (flags & BOLD) ? screen->fnt_bold : screen->fnt_norm; XText(VWindow(screen), x = CursorX (screen, screen->cur_col), y = CursorY(screen, screen->cur_row), &c, 1, fnt, fg, bg); if((flags & BOLD) && screen->enbolden) XTextMask(VWindow(screen), x + 1, y, &c, 1, fnt, fg); if(flags & UNDERLINE) { bg = y + FontHeight(screen) - 2; XLine(VWindow(screen), x, bg, x + FontWidth(screen), bg, 1, 1, fg, GXcopy, AllPlanes); } if(!screen->select && !ActiveIcon(screen)) { screen->box->x = x; screen->box->y = y; XDraw(VWindow(screen), screen->box, NBOX, 1, 1, fg, GXcopy, AllPlanes); } screen->cursor_state = ON; } /* * hide cursor at previous cursor position in screen. */ HideCursor() { register Screen *screen = &term.screen; register int fg; register int bg; register int x, y, flags, instatus; register Font fnt; char c; if (screen->icon_show && !screen->active_icon) return; if(!(instatus = screen->cursor_row > screen->max_row) && screen->cursor_row - screen->topline > screen->max_row) return; c = screen->buf[y = 2 * screen->cursor_row][x = screen->cursor_col]; flags = screen->buf[y + 1][x]; if(instatus) flags ^= INVERSE; if(flags & INVERSE) { fg = screen->background; bg = screen->foreground; } else { fg = screen->foreground; bg = screen->background; } if (c == 0) c = ' '; y = (instatus ? (screen->cursor_row * FontHeight(screen) + 1) : ((screen->cursor_row - screen->topline) * FontHeight(screen))) + Titlebar(screen) + screen->border; fnt = ActiveIcon(screen) ? screen->fnt_icon : (flags & BOLD) ? screen->fnt_bold : screen->fnt_norm; XText(VWindow(screen), x = CursorX (screen, screen->cursor_col), y, &c, 1, fnt, fg, bg); if((flags & BOLD) && screen->enbolden) XTextMask(VWindow(screen), x + 1, y, &c, 1, fnt, fg); if(flags & UNDERLINE) { y += FontHeight(screen) - 2; XLine(VWindow(screen), x, y, x + FontWidth(screen), y, 1, 1, fg, GXcopy, AllPlanes); } screen->cursor_state = OFF; } VTSelect() { register Screen *screen = &term.screen; XChangeBorder(VWindow(screen), screen->bordertile); if(Titlebar(screen)) VTTitleHilite(); } VTUnselect() { register Screen *screen = &term.screen; XChangeBorder(VWindow(screen), screen->graybordertile); if(Titlebar(screen)) VTTitleUnhilite(); } VTReset(full) int full; { register Screen *screen = &term.screen; /* reset scrolling region */ screen->top_marg = 0; screen->bot_marg = screen->max_row; term.flags &= ~ORIGIN; if(full) { TabReset (term.tabs); term.keyboard.flags = NULL; screen->gsets[0] = 'B'; screen->gsets[1] = 'B'; screen->gsets[2] = 'B'; screen->gsets[3] = 'B'; screen->curgl = 0; screen->curgr = 2; screen->curss = 0; ClearScreen(screen); screen->cursor_state = OFF; if(!(term.flags & AUTOREPEAT)) XAutoRepeatOn(); if (term.flags & REVERSE_VIDEO) ReverseVideo(&term); term.flags = term.initflags; if(screen->c132 && (term.flags & IN132COLUMNS)) { XChangeWindow (VWindow(screen), 80 * FontWidth(screen) + 2 * screen->border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + Titlebar(screen) + 2 * screen->border); XSync(FALSE); /* synchronize */ if(QLength() > 0) xevents(); } CursorSet(screen, 0, 0, term.flags); } longjmp(vtjmpbuf, 1); /* force ground state in parser */ } ToStatus(col) int col; { register Screen *screen = &term.screen; if(col > screen->max_col) col = screen->max_col; if(!screen->instatus) { if(!screen->statusline) ShowStatus(); CursorSave(&term, &screen->statussc); screen->instatus = TRUE; screen->cur_row = screen->max_row + 1; } screen->cur_col = col; } FromStatus() { register Screen *screen = &term.screen; if(!screen->instatus) return; screen->instatus = FALSE; CursorRestore(&term, &screen->statussc); } ShowStatus() { register Screen *screen = &term.screen; register int border = 2 * screen->border; if(screen->statusline) return; screen->statusline = 1; screen->statusheight = FontHeight(screen) + 2; XSetResizeHint(VWindow(screen), border + screen->scrollbar, border + Titlebar(screen) + screen->statusheight, FontWidth(screen), FontHeight(screen)); XChangeWindow (VWindow(screen), FontWidth(screen) * (screen->max_col + 1) + border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + Titlebar(screen) + border); } HideStatus() { register Screen *screen = &term.screen; register int border = 2 * screen->border; register int i, j; if(!screen->statusline) return; if(screen->instatus) FromStatus(); screen->statusline = 0; screen->statusheight = 0; bzero(screen->buf[i = 2 * (screen->max_row + 1)], j = screen->max_col + 1); bzero(screen->buf[i + 1], j); XSetResizeHint(VWindow(screen), border + screen->scrollbar, border + Titlebar(screen), FontWidth(screen), FontHeight(screen)); XChangeWindow (VWindow(screen), FontWidth(screen) * j + border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + border + Titlebar(screen)); } EraseStatus() { register Screen *screen = &term.screen; register int i, j, pix; if(!screen->statusline) return; bzero(screen->buf[i = 2 * (screen->max_row + 1)], j = screen->max_col + 1); bzero(screen->buf[i + 1], j); XPixSet(VWindow(screen), screen->border - 1, (screen->max_row + 1) * FontHeight(screen) + screen->border + Titlebar(screen), j * FontWidth(screen) + 2, screen->statusheight, screen->reversestatus ? screen->foreground : screen->background); if(!screen->reversestatus) StatusBox(screen); } StatusBox(screen) register Screen *screen; { status_box[0].y = (screen->max_row + 1) * FontHeight(screen) + screen->border + Titlebar(screen); status_box[3].x = -(status_box[1].x = (screen->max_col + 1) * FontWidth(screen) + 1); status_box[4].y = -(status_box[2].y = FontHeight(screen) + 1); XDraw(VWindow(screen), status_box, NBOX, 1, 1, screen->foreground, GXcopy, AllPlanes); } VTTitleShow(init) int init; { register Screen *screen = &term.screen; register int border = 2 * screen->border; if(!screen->title.tbar) VTTitleInit(); if(!init) { XSetResizeHint(VWindow(screen), border + screen->scrollbar, border + Titlebar(screen) + screen->statusheight, FontWidth(screen), FontHeight(screen)); XChangeWindow (VWindow(screen), FontWidth(screen) * (screen->max_col + 1) + border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + Titlebar(screen) + border); } if(screen->select && !screen->TekEmu) VTTitleHilite(); else VTTitleUnhilite(); XMapWindow(screen->title.tbar); } VTTitleHide() { register Screen *screen = &term.screen; register int border = 2 * screen->border; XUnmapWindow(screen->title.tbar); XSetResizeHint(VWindow(screen), border + screen->scrollbar, border + screen->statusheight, FontWidth(screen), FontHeight(screen)); XChangeWindow (VWindow(screen), FontWidth(screen) * (screen->max_col + 1) + border + screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + border); } VTTitleHilite() { register Screen *screen = &term.screen; if(screen->title.hilited) return; XMapWindow(screen->title.left); XMapWindow(screen->title.right); screen->title.hilited = TRUE; } VTTitleUnhilite() { register Screen *screen = &term.screen; if(!screen->title.hilited) return; XUnmapWindow(screen->title.left); XUnmapWindow(screen->title.right); screen->title.hilited = FALSE; } VTTitleResize(width) register int width; { register Screen *screen = &term.screen; register int i, j; if((screen->title.width = i = screen->title.fullwidth) > (j = width - 2 * (MINHILITE + screen->title_n_size + 1))) screen->title.width = (i = j) + screen->title_n_size; j = width - i - 2 * (screen->title_n_size + 1); i = j / 2; j -= i; screen->title.x = i + 1 + screen->title_n_size; XChangeWindow(screen->title.tbar, width, screen->titleheight - 1); XChangeWindow(screen->title.left, i, screen->titlefont->height); XConfigureWindow(screen->title.right, width - j - 1, TITLEPAD, j, screen->titlefont->height); } VTTitleExpose(rep) register XExposeWindowEvent *rep; { register Screen *screen = &term.screen; if(rep && (rep->x > (screen->title.x + screen->title.width) || (rep->x + rep->width) < screen->title.x || rep->y > (screen->title.y + screen->titlefont->height) || (rep->y + rep->height) < screen->title.y)) return; XText(screen->title.tbar, screen->title.x, screen->title.y, screen->winname, screen->winnamelen, screen->titlefont->id, screen->foreground, screen->background); } VTTitleInit() { register Screen *screen = &term.screen; register int w, i, j; OpaqueFrame hilite[2]; extern Pixmap make_hilite(); if((screen->title.tbar = XCreateWindow(VWindow(screen), -1, -1, w = FullWidth(screen), screen->titleheight - 1, 1, screen->bordertile, screen->bgndtile)) == NULL) Error(ERROR_CRTITLE); XSelectInput(screen->title.tbar, ButtonPressed | ButtonReleased | ExposeWindow | EnterWindow | LeaveWindow | UnmapWindow); XDefineCursor(screen->title.tbar, screen->arrow); if(!screen->hilitetile && (screen->hilitetile = make_hilite(screen->foreground, screen->background)) == NULL) Error(ERROR_HILITE); screen->title.fullwidth = XQueryWidth(screen->winname, screen->titlefont->id); if((screen->title.width = i = screen->title.fullwidth) > (j = w - 2 * (MINHILITE + screen->title_n_size + 1))) screen->title.width = (i = j) + screen->title_n_size; j = w - i - 2 * (screen->title_n_size + 1); i = j / 2; j -= i; screen->title.x = i + 1 + screen->title_n_size; screen->title.y = TITLEPAD; hilite[0].x = 1; hilite[1].x = w - j - 1; hilite[0].y = hilite[1].y = TITLEPAD; hilite[0].width = i; hilite[1].width = j; hilite[0].height = hilite[1].height = screen->titlefont->height; hilite[0].bdrwidth = hilite[1].bdrwidth = 0; hilite[0].border = hilite[1].border = NULL; hilite[0].background = hilite[1].background = screen->hilitetile; if(XCreateWindows(screen->title.tbar, hilite, 2) != 2) Error(ERROR_CRLFRG); screen->title.left = hilite[0].self; screen->title.right = hilite[1].self; } #ifdef MODEMENU #define MMENU_SCROLL 0 #define MMENU_VIDEO (MMENU_SCROLL+1) #define MMENU_WRAP (MMENU_VIDEO+1) #define MMENU_REVERSEWRAP (MMENU_WRAP+1) #define MMENU_NLM (MMENU_REVERSEWRAP+1) #define MMENU_CURSOR (MMENU_NLM+1) #define MMENU_PAD (MMENU_CURSOR+1) #define MMENU_REPEAT (MMENU_PAD+1) #define MMENU_SCROLLBAR (MMENU_REPEAT+1) #define MMENU_PAGEMODE (MMENU_SCROLLBAR+1) #define MMENU_STATUS (MMENU_PAGEMODE+1) #define MMENU_REVSTATUS (MMENU_STATUS+1) #define MMENU_C132 (MMENU_REVSTATUS+1) #define MMENU_CURSES (MMENU_C132+1) #define MMENU_MARGBELL (MMENU_CURSES+1) #define MMENU_TEKWIN (MMENU_MARGBELL+1) #define MMENU_ALTERN (MMENU_TEKWIN+1) #define MMENU_LINE (MMENU_ALTERN+1) #define MMENU_RESET (MMENU_LINE+1) #define MMENU_FULLRESET (MMENU_RESET+1) #define MMENU_TEKMODE (MMENU_FULLRESET+1) #define MMENU_HIDEVT (MMENU_TEKMODE+1) static char *vtext[] = { "Jump Scroll", "Reverse Video", "Auto Wraparound", "Reverse Wraparound", "Auto Linefeed", "Application Cursors", "Application Pad", "Auto Repeat", "Scrollbar", "Page Scroll", "Status Line", "Reverse Status Line", "80 <-> 132 Columns", "Curses Emulation", "Margin Bell", "Tek Window Showing", "Alternate Screen", "-", "Soft Reset", "Full Reset", "Select Tek Mode", "Hide VT Window", 0, }; static int menutermflags; static int menukbdflags; static int t132; static int taltern; static int tcurses; static int tmarginbell; static int tpagemode; static int trevstatus; static int tscrollbar; static int tshow; static int tstatusline; Menu *setupmenu(menu) register Menu **menu; { register Screen *screen = &term.screen; register char **cp; register int flags = term.flags; register int kflags = term.keyboard.flags; if (*menu == NULL) { if ((*menu = NewMenu("Modes", re_verse)) == NULL) return(NULL); for(cp = vtext ; *cp ; cp++) AddMenuItem(*menu, *cp); if(!(flags & SMOOTHSCROLL)) CheckItem(*menu, MMENU_SCROLL); if(flags & REVERSE_VIDEO) CheckItem(*menu, MMENU_VIDEO); if(flags & WRAPAROUND) CheckItem(*menu, MMENU_WRAP); if(flags & REVERSEWRAP) CheckItem(*menu, MMENU_REVERSEWRAP); if(flags & LINEFEED) CheckItem(*menu, MMENU_NLM); if(kflags & CURSOR_APL) CheckItem(*menu, MMENU_CURSOR); if(kflags & KYPD_APL) CheckItem(*menu, MMENU_PAD); if(flags & AUTOREPEAT) CheckItem(*menu, MMENU_REPEAT); if(tscrollbar = (screen->scrollbar > 0)) CheckItem(*menu, MMENU_SCROLLBAR); if(tpagemode = screen->pagemode) CheckItem(*menu, MMENU_PAGEMODE); if(tstatusline = screen->statusline) CheckItem(*menu, MMENU_STATUS); if(trevstatus = screen->reversestatus) CheckItem(*menu, MMENU_REVSTATUS); if(t132 = screen->c132) CheckItem(*menu, MMENU_C132); if(tcurses = screen->curses) CheckItem(*menu, MMENU_CURSES); if(tmarginbell = screen->marginbell) CheckItem(*menu, MMENU_MARGBELL); if(tshow = screen->Tshow) CheckItem(*menu, MMENU_TEKWIN); else DisableItem(*menu, MMENU_HIDEVT); DisableItem(*menu, MMENU_ALTERN); if(taltern = screen->alternate) { CheckItem(*menu, MMENU_ALTERN); DisableItem(*menu, MMENU_PAGEMODE); } DisableItem(*menu, MMENU_LINE); if(screen->inhibit & I_TEK) { DisableItem(*menu, MMENU_TEKWIN); DisableItem(*menu, MMENU_TEKMODE); } menutermflags = flags; menukbdflags = kflags; return(*menu); } if ((menutermflags ^= flags) & SMOOTHSCROLL) SetItemCheck(*menu, MMENU_SCROLL, !(flags & SMOOTHSCROLL)); if (menutermflags & REVERSE_VIDEO) SetItemCheck(*menu, MMENU_VIDEO, flags & REVERSE_VIDEO); if (menutermflags & WRAPAROUND) SetItemCheck(*menu, MMENU_WRAP, flags & WRAPAROUND); if (menutermflags & REVERSEWRAP) SetItemCheck(*menu, MMENU_REVERSEWRAP, flags & REVERSEWRAP); if (menutermflags & LINEFEED) SetItemCheck(*menu, MMENU_NLM, flags & LINEFEED); if ((menukbdflags ^= kflags) & CURSOR_APL) SetItemCheck(*menu, MMENU_CURSOR, kflags & CURSOR_APL); if (menukbdflags & KYPD_APL) SetItemCheck(*menu, MMENU_PAD, NULL, kflags & KYPD_APL); if(tscrollbar != (screen->scrollbar > 0)) SetItemCheck(*menu, MMENU_SCROLLBAR, (tscrollbar = (screen->scrollbar > 0))); if(tpagemode != screen->pagemode) SetItemCheck(*menu, MMENU_PAGEMODE, (tpagemode = screen->pagemode)); if(tstatusline != screen->statusline) SetItemCheck(*menu, MMENU_STATUS, (tstatusline = screen->statusline)); if(trevstatus != screen->reversestatus) SetItemCheck(*menu, MMENU_REVSTATUS, (trevstatus = screen->reversestatus)); if(t132 != screen->c132) SetItemCheck(*menu, MMENU_C132, (t132 = screen->c132)); if(tcurses != screen->curses) SetItemCheck(*menu, MMENU_CURSES, (tcurses = screen->curses)); if(tmarginbell != screen->marginbell) SetItemCheck(*menu, MMENU_MARGBELL, (tmarginbell = screen->marginbell)); if(tshow != screen->Tshow) { SetItemCheck(*menu, MMENU_TEKWIN, (tshow = screen->Tshow)); SetItemDisable(*menu, MMENU_HIDEVT, !tshow); } if(taltern != screen->alternate) { SetItemCheck(*menu, MMENU_ALTERN, (taltern = screen->alternate)); SetItemDisable(*menu, MMENU_PAGEMODE, taltern); } menutermflags = flags; menukbdflags = kflags; return(*menu); } domenufunc(item) int item; { register Screen *screen = &term.screen; switch (item) { case MMENU_SCROLL: term.flags ^= SMOOTHSCROLL; if (term.flags & SMOOTHSCROLL) { screen->jumpscroll = FALSE; if (screen->scroll_amt) FlushScroll(screen); } else screen->jumpscroll = TRUE; break; case MMENU_VIDEO: term.flags ^= REVERSE_VIDEO; ReverseVideo(&term); break; case MMENU_WRAP: term.flags ^= WRAPAROUND; break; case MMENU_REVERSEWRAP: term.flags ^= REVERSEWRAP; break; case MMENU_NLM: term.flags ^= LINEFEED; break; case MMENU_CURSOR: term.keyboard.flags ^= CURSOR_APL; break; case MMENU_PAD: term.keyboard.flags ^= KYPD_APL; break; case MMENU_REPEAT: term.flags ^= AUTOREPEAT; if (term.flags & AUTOREPEAT) XAutoRepeatOn(); else XAutoRepeatOff(); break; case MMENU_SCROLLBAR: if(screen->scrollbar) ScrollBarOff(screen); else ScrollBarOn(screen, TRUE, FALSE); break; case MMENU_PAGEMODE: if(screen->pagemode = !screen->pagemode) screen->pagecnt = 0; break; case MMENU_STATUS: if(screen->statusline) HideStatus(); else ShowStatus(); break; case MMENU_REVSTATUS: screen->reversestatus = !screen->reversestatus; ScrnRefresh(screen, screen->max_row + 1, 0, 1, screen->max_col + 1); break; case MMENU_C132: screen->c132 = !screen->c132; break; case MMENU_MARGBELL: if(!(screen->marginbell = !screen->marginbell)) screen->bellarmed = -1; break; case MMENU_CURSES: screen->curses = !screen->curses; break; case MMENU_FULLRESET: VTReset(TRUE); break; case MMENU_RESET: VTReset(FALSE); break; case MMENU_HIDEVT: screen->show = FALSE; XUnmapWindow(VWindow(screen)); reselectwindow(screen); SyncUnmap(VWindow(screen), WINDOWEVENTS); /* drop through */ case MMENU_TEKMODE: if(!screen->TekEmu) { if(screen->logging) { FlushLog(screen); screen->logstart = Tbuffer; } screen->TekEmu = TRUE; if(screen->pagemode) { Scroll(screen, screen->pagecnt); screen->pagecnt = 0; ioctl(screen->respond, TIOCSTART, NULL); } longjmp(VTend, 1); } else XRaiseWindow(TWindow(screen)); break; case MMENU_TEKWIN: if(screen->Tshow = !screen->Tshow) { if(TWindow(screen) || TekInit()) { XMapWindow(TWindow(screen)); screen->Tshow = TRUE; } } else { screen->Tshow = FALSE; XUnmapWindow(TWindow(screen)); SyncUnmap(TWindow(screen), TWINDOWEVENTS); if(screen->TekEmu) { if(screen->logging) { FlushLog(screen); screen->logstart = buffer; } longjmp(Tekend, 1); } } reselectwindow(screen); break; } } #endif MODEMENU