📄 tekproc.c
字号:
#define DOTTED_LENGTH 2#define DOT_DASHED_LENGTH 4#define SHORT_DASHED_LENGTH 2#define LONG_DASHED_LENGTH 2static int dash_length[TEKNUMLINES] = { DOTTED_LENGTH, DOT_DASHED_LENGTH, SHORT_DASHED_LENGTH, LONG_DASHED_LENGTH,};static unsigned char dotted[DOTTED_LENGTH] = {3, 1};static unsigned char dot_dashed[DOT_DASHED_LENGTH] = {3, 4, 3, 1};static unsigned char short_dashed[SHORT_DASHED_LENGTH] = {4, 4};static unsigned char long_dashed[LONG_DASHED_LENGTH] = {4, 7};static unsigned char *dashes[TEKNUMLINES] = { dotted, dot_dashed, short_dashed, long_dashed,};/* * The following is called the create the tekWidget */#include <X11/Xlibint.h>static void TekInitialize(request, new, args, num_args) Widget request, new; ArgList args; Cardinal *num_args;{ /* look for focus related events on the shell, because we need * to care about the shell's border being part of our focus. */ XtAddEventHandler(XtParent(new), EnterWindowMask, FALSE, HandleEnterWindow, (caddr_t)NULL); XtAddEventHandler(XtParent(new), LeaveWindowMask, FALSE, HandleLeaveWindow, (caddr_t)NULL); XtAddEventHandler(XtParent(new), FocusChangeMask, FALSE, HandleFocusChange, (caddr_t)NULL); XtAddEventHandler((Widget)new, PropertyChangeMask, FALSE, HandleBellPropertyChange, (Opaque)NULL);}static void TekRealize (gw, valuemaskp, values) Widget gw; XtValueMask *valuemaskp; XSetWindowAttributes *values;{ TekWidget tw = (TekWidget) gw; register TScreen *screen = &term->screen; register int i; register TekLink *tek; register double d; register int border = 2 * screen->border; int pr; XGCValues gcv; int winX, winY, width, height; XSizeHints sizehints; char Tdefault[32]; tw->core.border_pixel = term->core.border_pixel; for (i = 0; i < TEKNUMFONTS; i++) { if (!tw->tek.Tfont[i]) tw->tek.Tfont[i] = XQueryFont (screen->display, DefaultGCID); tw->tek.tobaseline[i] = tw->tek.Tfont[i]->ascent; } if((Tbuffer = (Char *)malloc(BUF_SIZE)) == NULL || (Tpushb = (Char *)malloc(10)) == NULL || (Tline = (XSegment *)malloc(MAX_VTX * sizeof(XSegment))) == NULL) { fprintf (stderr, "%s: Not enough core for Tek mode\n", xterm_name); if(Tpushb) free((char *)Tpushb); if(Tbuffer) free((char *)Tbuffer); Tfailed = TRUE; return; } screen->xorplane = 1; screen->Tbackground = term->core.background_pixel; screen->Tforeground = screen->foreground; screen->Tcursorcolor = screen->cursorcolor; if (term->misc.T_geometry == NULL) { int defwidth, defheight; if (term->misc.tekSmall) { defwidth = TEKMINWIDTH; defheight = TEKMINHEIGHT; } else { defwidth = TEKDEFWIDTH; defheight = TEKDEFHEIGHT; } sprintf (Tdefault, "=%dx%d", defwidth + border, defheight + border); term->misc.T_geometry = Tdefault; } winX = 1; winY = 1; width = TEKDEFWIDTH + border; height = TEKDEFHEIGHT + border; pr = XParseGeometry(term->misc.T_geometry, &winX, &winY, (unsigned int *)&width, (unsigned int *)&height); if ((pr & XValue) && (pr & XNegative)) winX += DisplayWidth(screen->display, DefaultScreen(screen->display)) - width - (term->core.parent->core.border_width * 2); if ((pr & YValue) && (pr & YNegative)) winY += DisplayHeight(screen->display, DefaultScreen(screen->display)) - height - (term->core.parent->core.border_width * 2); /* set up size hints */ sizehints.min_width = TEKMINWIDTH + border; sizehints.min_height = TEKMINHEIGHT + border; sizehints.width_inc = 1; sizehints.height_inc = 1; sizehints.flags = PMinSize|PResizeInc; sizehints.x = winX; sizehints.y = winY; if ((XValue&pr) || (YValue&pr)) { sizehints.flags |= USSize|USPosition; sizehints.flags |= PWinGravity; switch (pr & (XNegative | YNegative)) { case 0: sizehints.win_gravity = NorthWestGravity; break; case XNegative: sizehints.win_gravity = NorthEastGravity; break; case YNegative: sizehints.win_gravity = SouthWestGravity; break; default: sizehints.win_gravity = SouthEastGravity; break; } } else { sizehints.flags |= PSize; } sizehints.width = width; sizehints.height = height; if ((WidthValue&pr) || (HeightValue&pr)) sizehints.flags |= USSize; else sizehints.flags |= PSize; (void) XtMakeResizeRequest ((Widget) tw, width, height, &tw->core.width, &tw->core.height); /* XXX This is bogus. We are parsing geometries too late. This * is information that the shell widget ought to have before we get * realized, so that it can do the right thing. */ if (sizehints.flags & USPosition) XMoveWindow (XtDisplay(tw), tw->core.parent->core.window, sizehints.x, sizehints.y); XSetWMNormalHints (XtDisplay(tw), tw->core.parent->core.window, &sizehints); XFlush (XtDisplay(tw)); /* get it out to window manager */ values->win_gravity = NorthWestGravity; values->background_pixel = screen->Tbackground; tw->core.window = TWindow(screen) = XCreateWindow (screen->display, tw->core.parent->core.window, tw->core.x, tw->core.y, tw->core.width, tw->core.height, tw->core.border_width, (int) tw->core.depth, InputOutput, CopyFromParent, ((*valuemaskp)|CWBackPixel|CWWinGravity), values); TFullWidth(screen) = width; TFullHeight(screen) = height; TWidth(screen) = width - border; THeight(screen) = height - border; TekScale(screen) = (double)TWidth(screen) / TEKWIDTH; if((d = (double)THeight(screen) / (TEKHEIGHT + TEKTOPPAD + TEKBOTTOMPAD)) < TekScale(screen)) TekScale(screen) = d; screen->cur.fontsize = TEK_FONT_LARGE; if (tw->tek.initial_font) { char *s = tw->tek.initial_font; if (XmuCompareISOLatin1 (s, "large") == 0) screen->cur.fontsize = TEK_FONT_LARGE; else if (XmuCompareISOLatin1 (s, "2") == 0 || XmuCompareISOLatin1 (s, "two") == 0) screen->cur.fontsize = TEK_FONT_2; else if (XmuCompareISOLatin1 (s, "3") == 0 || XmuCompareISOLatin1 (s, "three") == 0) screen->cur.fontsize = TEK_FONT_3; else if (XmuCompareISOLatin1 (s, "small") == 0) screen->cur.fontsize = TEK_FONT_SMALL; } if(XmuCompareISOLatin1(tw->tek.gin_terminator_str, GIN_TERM_NONE_STR) == 0) screen->gin_terminator = GIN_TERM_NONE; else if(XmuCompareISOLatin1(tw->tek.gin_terminator_str, GIN_TERM_CR_STR) == 0) screen->gin_terminator = GIN_TERM_CR; else if(XmuCompareISOLatin1(tw->tek.gin_terminator_str, GIN_TERM_EOT_STR) == 0) screen->gin_terminator = GIN_TERM_EOT; else fprintf(stderr, "%s: illegal GIN terminator setting \"%s\"\n", xterm_name, tw->tek.gin_terminator_str); gcv.graphics_exposures = TRUE; /* default */ gcv.font = tw->tek.Tfont[screen->cur.fontsize]->fid; gcv.foreground = screen->Tforeground; gcv.background = screen->Tbackground; /* if font wasn't successfully opened, then gcv.font will contain the Default GC's ID, meaning that we must use the server default font. */ TEKgcFontMask = (gcv.font == DefaultGCID) ? 0 : GCFont; screen->TnormalGC = XCreateGC (screen->display, TWindow(screen), (TEKgcFontMask|GCGraphicsExposures| GCForeground|GCBackground), &gcv); gcv.function = GXinvert; gcv.plane_mask = screen->xorplane = (screen->Tbackground ^ screen->Tcursorcolor); gcv.join_style = JoinMiter; /* default */ gcv.line_width = 1; screen->TcursorGC = XCreateGC (screen->display, TWindow(screen), (GCFunction|GCPlaneMask), &gcv); gcv.foreground = screen->Tforeground; gcv.line_style = LineOnOffDash; gcv.line_width = 0; for(i = 0 ; i < TEKNUMLINES ; i++) { screen->linepat[i] = XCreateGC (screen->display, TWindow(screen), (GCForeground|GCLineStyle), &gcv); XSetDashes (screen->display, screen->linepat[i], 0, (char *) dashes[i], dash_length[i]); } TekBackground(screen); screen->margin = MARGIN1; /* Margin 1 */ screen->TekGIN = FALSE; /* GIN off */ XDefineCursor(screen->display, TShellWindow, screen->pointer_cursor); { /* there's gotta be a better way... */ static Arg args[] = { {XtNtitle, (XtArgVal)NULL}, {XtNiconName, (XtArgVal)NULL}, }; char *icon_name, *title, *tek_icon_name, *tek_title; args[0].value = (XtArgVal)&icon_name; args[1].value = (XtArgVal)&title; XtGetValues (tw->core.parent, args, 2); tek_icon_name = XtMalloc(strlen(icon_name)+7); strcpy(tek_icon_name, icon_name); strcat(tek_icon_name, "(Tek)"); tek_title = XtMalloc(strlen(title)+7); strcpy(tek_title, title); strcat(tek_title, "(Tek)"); args[0].value = (XtArgVal)tek_icon_name; args[1].value = (XtArgVal)tek_title; XtSetValues (tw->core.parent, args, 2); XtFree( tek_icon_name ); XtFree( tek_title ); } tek = TekRecord = &Tek0; tek->next = (TekLink *)0; tek->fontsize = screen->cur.fontsize; tek->count = 0; tek->ptr = tek->data; Tpushback = Tpushb; Tbptr = Tbuffer; screen->cur_X = 0; screen->cur_Y = TEKHOME; line_pt = Tline; Ttoggled = TRUE; screen->page = screen->cur; return;}void TekSetFontSize (newitem) int newitem;{ register TScreen *screen = &term->screen; int oldsize = screen->cur.fontsize; int newsize = MI2FS(newitem); Font fid; if (!tekWidget || oldsize == newsize) return; if (!Ttoggled) TCursorToggle(TOGGLE); set_tekfont_menu_item (oldsize, FALSE); fid = tekWidget->tek.Tfont[newsize]->fid; if (fid == DefaultGCID) /* we didn't succeed in opening a real font for this size. Instead, use server default. */ XCopyGC (screen->display, DefaultGC(screen->display, DefaultScreen(screen->display)), GCFont, screen->TnormalGC); else XSetFont (screen->display, screen->TnormalGC, fid); screen->cur.fontsize = newsize; set_tekfont_menu_item (newsize, TRUE); if (!Ttoggled) TCursorToggle(TOGGLE);}void ChangeTekColors(screen,pNew)register TScreen *screen;ScrnColors *pNew;{ register int i; XGCValues gcv; if (COLOR_DEFINED(pNew,TEK_FG)) { screen->Tforeground= COLOR_VALUE(pNew,TEK_FG); XSetForeground(screen->display,screen->TnormalGC, screen->Tforeground); } if (COLOR_DEFINED(pNew,TEK_BG)) { screen->Tbackground= COLOR_VALUE(pNew,TEK_BG); XSetBackground(screen->display,screen->TnormalGC, screen->Tbackground); } if (tekWidget) { if (tekWidget->core.border_pixel == screen->Tbackground) { tekWidget->core.border_pixel = screen->Tforeground; tekWidget->core.parent->core.border_pixel = screen->Tforeground; if (tekWidget->core.parent->core.window) XSetWindowBorder (screen->display, tekWidget->core.parent->core.window, tekWidget->core.border_pixel); } } for(i = 0 ; i < TEKNUMLINES ; i++) { XSetForeground(screen->display, screen->linepat[i], screen->Tforeground); } screen->Tcursorcolor = screen->Tforeground; gcv.plane_mask = screen->xorplane = (screen->Tbackground ^ screen->Tcursorcolor); XChangeGC (screen->display, screen->TcursorGC, GCPlaneMask, &gcv); TekBackground(screen); return;}TekReverseVideo(screen)register TScreen *screen;{ register int i; XGCValues gcv; i = screen->Tbackground; screen->Tbackground = screen->Tforeground; screen->Tforeground = i; XSetForeground(screen->display, screen->TnormalGC, screen->Tforeground); XSetBackground(screen->display, screen->TnormalGC, screen->Tbackground); if (tekWidget) { if (tekWidget->core.border_pixel == screen->Tbackground) { tekWidget->core.border_pixel = screen->Tforeground; tekWidget->core.parent->core.border_pixel = screen->Tforeground; if (tekWidget->core.parent->core.window) XSetWindowBorder (screen->display, tekWidget->core.parent->core.window, tekWidget->core.border_pixel); } } for(i = 0 ; i < TEKNUMLINES ; i++) { XSetForeground(screen->display, screen->linepat[i], screen->Tforeground); } screen->Tcursorcolor = screen->Tforeground; gcv.plane_mask = screen->xorplane = (screen->Tbackground ^ screen->Tcursorcolor); XChangeGC (screen->display, screen->TcursorGC, GCPlaneMask, &gcv); TekBackground(screen);}TekBackground(screen)register TScreen *screen;{ if(TWindow(screen)) XSetWindowBackground(screen->display, TWindow(screen), screen->Tbackground);}/* * Toggles cursor on or off at cursor position in screen. */TCursorToggle(toggle) int toggle; /* TOGGLE or CLEAR */{ register TScreen *screen = &term->screen; register int c, x, y; unsigned int cellwidth, cellheight; if (!screen->Tshow) return; c = screen->cur.fontsize; cellwidth = (unsigned) tekWidget->tek.Tfont[c]->max_bounds.width; cellheight = (unsigned) (tekWidget->tek.Tfont[c]->ascent + tekWidget->tek.Tfont[c]->descent); x = (screen->cur_X * TekScale(screen)) + screen->border; y = ((TEKHEIGHT + TEKTOPPAD - screen->cur_Y) * TekScale(screen)) + screen->border - tekWidget->tek.tobaseline[c]; if (toggle == TOGGLE) { if (screen->select || screen->always_highlight) XFillRectangle(screen->display, TWindow(screen), screen->TcursorGC, x, y, cellwidth, cellheight); else { /* fix to use different GC! */ XDrawRectangle(screen->display, TWindow(screen), screen->TcursorGC, x, y, cellwidth-1, cellheight-1); } } else { /* Clear the entire rectangle, even though we may only * have drawn an outline. This fits with our refresh * scheme of redrawing the entire window on any expose * event and is easier than trying to figure out exactly * which part of the cursor needs to be erased. */ XClearArea(screen->display, TWindow(screen), x, y, cellwidth, cellheight, FALSE); }}void TekSimulatePageButton (reset) Bool reset;{ register TScreen *screen = &term->screen; if (!tekWidget) return; if (reset) {/* bzero ((char *)&curmodes, sizeof(Tmodes)); */ bzero ((char *) &screen->cur, sizeof screen->cur); } TekRefresh = (TekLink *)0;/* screen->cur = curmodes; */ TekPage (); screen->cur_X = 0; screen->cur_Y = TEKHOME;}#ifndef X_NOT_POSIX#define HAS_WAITPID#endif/* write copy of screen to a file */TekCopy(){ register TScreen *screen = &term->screen; register struct tm *tp; long l; char buf[32]; int waited; int pid;#ifndef HAS_WAITPID int (*chldfunc)(); chldfunc = signal(SIGCHLD, SIG_DFL);#endif time(&l); tp = localtime(&l); sprintf(buf, "COPY%02d-%02d-%02d.%02d:%02d:%02d", tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec); if(access(buf, F_OK) >= 0) { /* file exists */ if(access(buf, W_OK) < 0) { Bell(); return; } } else if(access(".", W_OK) < 0) { /* can't write in directory */ Bell(); return; } /* Write the file in an unprivileged child process because using access before the open still leaves a small window of opportunity. */ pid = fork(); switch (pid) { case 0: /* child */ { register int tekcopyfd; char initbuf[5]; register TekLink *Tp; setgid(screen->gid); setuid(screen->uid); tekcopyfd = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (tekcopyfd < 0) _exit(1); sprintf(initbuf, "\033%c\033%c", screen->page.fontsize + '8', screen->page.linetype + '`'); write(tekcopyfd, initbuf, 4); Tp = &Tek0; do { write(tekcopyfd, (char *)Tp->data, Tp->count); Tp = Tp->next; } while(Tp); close(tekcopyfd); _exit(0); } case -1: /* error */ Bell(); return; default: /* parent */#ifdef HAS_WAITPID waitpid(pid, NULL, 0);#else waited = wait(NULL); signal(SIGCHLD, chldfunc); /* Since we had the signal handler uninstalled for a while, we might have missed the termination of our screen child. If we can check for this possibility without hanging, do so. */ do if (waited == term->screen.pid) Cleanup(0); while ( (waited=nonblocking_wait()) > 0);#endif }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -