home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / mxterm.zip / mxterm / Tekproc.c < prev    next >
C/C++ Source or Header  |  1992-10-17  |  42KB  |  1,593 lines

  1. /*
  2.  * $XConsortium: Tekproc.c,v 1.107 91/06/25 19:49:48 gildea Exp $
  3.  *
  4.  * Warning, there be crufty dragons here.
  5.  */
  6.  
  7.  
  8. /*
  9.  * Copyright 1988 Massachusetts Institute of Technology
  10.  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  11.  *
  12.  *                         All Rights Reserved
  13.  *
  14.  * Permission to use, copy, modify, and distribute this software and its
  15.  * documentation for any purpose and without fee is hereby granted,
  16.  * provided that the above copyright notice appear in all copies and that
  17.  * both that copyright notice and this permission notice appear in
  18.  * supporting documentation, and that the name of Digital Equipment
  19.  * Corporation not be used in advertising or publicity pertaining to
  20.  * distribution of the software without specific, written prior permission.
  21.  *
  22.  *
  23.  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  24.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  25.  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  26.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  27.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  28.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  29.  * SOFTWARE.
  30.  */
  31.  
  32. /* Tekproc.c */
  33.  
  34. #include "ptyx.h"
  35. #include "Tekparse.h"
  36. #include "data.h"
  37. #include "error.h"
  38. #include "menu.h"
  39. #include <X11/Xos.h>
  40. #include <X11/Xatom.h>
  41. #include <X11/Xutil.h>
  42. #include <X11/cursorfont.h>
  43. #include <X11/StringDefs.h>
  44. #include <X11/Shell.h>
  45. #include <X11/Xmu/CharSet.h>
  46. #include <stdio.h>
  47. #include <errno.h>
  48. #include <setjmp.h>
  49.  
  50. /*
  51.  * Check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
  52.  * systems are broken and return EWOULDBLOCK when they should return EAGAIN.
  53.  * Note that this macro may evaluate its argument more than once.
  54.  */
  55. #if defined(EAGAIN) && defined(EWOULDBLOCK)
  56. #define E_TEST(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
  57. #else
  58. #ifdef EAGAIN
  59. #define E_TEST(err) ((err) == EAGAIN)
  60. #else
  61. #define E_TEST(err) ((err) == EWOULDBLOCK)
  62. #endif
  63. #endif
  64.  
  65. extern jmp_buf Tekend;
  66.  
  67. #ifndef X_NOT_STDC_ENV
  68. #include <stdlib.h>
  69. #else
  70. extern char *malloc();
  71. extern void exit();
  72. extern long time();        /* included in <time.h> by Xos.h */
  73. #endif
  74.  
  75. #define TekColormap DefaultColormap( screen->display, \
  76.                     DefaultScreen(screen->display) )
  77. #define DefaultGCID DefaultGC(screen->display, DefaultScreen(screen->display))->gid
  78.  
  79. /* Tek defines */
  80.  
  81. #define    BEL        07
  82. #define    CANCEL        030
  83. #define    DOTDASHEDLINE    2
  84. #define    DOTTEDLINE    1
  85. #define    EAST        01
  86. #define    ETX        03
  87. #define    LINEMASK    07
  88. #define    LONGDASHEDLINE    4
  89. #define    MARGIN1        0
  90. #define    MARGIN2        1
  91. #define MAX_PTS        150
  92. #define MAX_VTX        300
  93. #define    NAK        025
  94. #define    NORTH        04
  95. #define    PENDOWN        1
  96. #define    PENUP        0
  97. #define    SHORTDASHEDLINE    3
  98. #define    SOLIDLINE    0
  99. #define    SOUTH        010
  100. #define    TEKBOTTOMPAD    23
  101. #define    TEKDEFHEIGHT    565
  102. #define    TEKDEFWIDTH    750
  103. #define    TEKHEIGHT    3072
  104. #define    TEKHOME        ((TekChar[screen->page.fontsize].nlines - 1)\
  105.              * TekChar[screen->page.fontsize].vsize)
  106. #define    TEKMINHEIGHT    452
  107. #define    TEKMINWIDTH    600
  108. #define    TEKTOPPAD    34
  109. #define    TEKWIDTH    4096
  110. #define    TEXT_BUF_SIZE    256
  111. #define    WEST        02
  112.  
  113. #define    TekMove(x,y)    screen->cur_X = x; screen->cur_Y = y
  114. #define    input()        Tinput()
  115. #define    unput(c)    *Tpushback++ = c
  116.  
  117. extern Widget toplevel;
  118.  
  119. static struct Tek_Char {
  120.     int hsize;    /* in Tek units */
  121.     int vsize;    /* in Tek units */
  122.     int charsperline;
  123.     int nlines;
  124. } TekChar[TEKNUMFONTS] = {
  125.     {56, 88, 74, 35},    /* large */
  126.     {51, 82, 81, 38},    /* #2 */
  127.     {34, 53, 121, 58},    /* #3 */
  128.     {31, 48, 133, 64},    /* small */
  129. };
  130.  
  131. static Cursor GINcursor;
  132. static XSegment *line_pt;
  133. static int nplot;
  134. static TekLink Tek0;
  135. static jmp_buf Tekjump;
  136. static TekLink *TekRecord;
  137. static XSegment *Tline;
  138.  
  139. extern int Talptable[];
  140. extern int Tbestable[];
  141. extern int Tbyptable[];
  142. extern int Tesctable[];
  143. extern int Tipltable[];
  144. extern int Tplttable[];
  145. extern int Tpttable[];
  146. extern int Tspttable[];
  147.  
  148. static int *curstate = Talptable;
  149. static int *Tparsestate = Talptable;
  150.  
  151. static void TekEnq();
  152.  
  153. /* event handlers */
  154. extern void HandleKeyPressed(), HandleEightBitKeyPressed();
  155. extern void HandleStringEvent();
  156. extern void HandleEnterWindow();
  157. extern void HandleLeaveWindow();
  158. extern void HandleFocusChange();
  159. extern void HandleBellPropertyChange();
  160. extern void HandleSecure();
  161. extern void HandleGINInput();
  162. extern void HandleCreateMenu(), HandlePopupMenu();
  163.  
  164. static char defaultTranslations[] = "\
  165.        ~Meta<KeyPress>:     insert-seven-bit()    \n\
  166.         Meta<KeyPress>:     insert-eight-bit()\n\
  167.       !Ctrl <Btn1Down>:         popup-menu(mainMenu) \n\
  168.  !Lock Ctrl <Btn1Down>:         popup-menu(mainMenu) \n\
  169.       !Ctrl <Btn2Down>:         popup-menu(tekMenu) \n\
  170.  !Lock Ctrl <Btn2Down>:         popup-menu(tekMenu) \n\
  171.  Shift ~Meta<Btn1Down>:         gin-press(L) \n\
  172.        ~Meta<Btn1Down>:         gin-press(l) \n\
  173.  Shift ~Meta<Btn2Down>:         gin-press(M) \n\
  174.        ~Meta<Btn2Down>:         gin-press(m) \n\
  175.  Shift ~Meta<Btn3Down>:         gin-press(R) \n\
  176.        ~Meta<Btn3Down>:         gin-press(r)";
  177.  
  178.  
  179. static XtActionsRec actionsList[] = { 
  180.     { "string",    HandleStringEvent },
  181.     { "insert",    HandleKeyPressed },    /* alias for insert-seven-bit */
  182.     { "insert-seven-bit",    HandleKeyPressed },
  183.     { "insert-eight-bit",    HandleEightBitKeyPressed },
  184.     { "gin-press",        HandleGINInput },
  185.     { "secure",         HandleSecure },
  186.     { "create-menu",        HandleCreateMenu },
  187.     { "popup-menu",        HandlePopupMenu },
  188.     /* menu actions */
  189.     { "allow-send-events",    HandleAllowSends },
  190.     { "set-logging",        HandleLogging },
  191.     { "redraw",            HandleRedraw },
  192.     { "send-signal",        HandleSendSignal },
  193.     { "quit",            HandleQuit },
  194.     { "set-scrollbar",        HandleScrollbar },
  195.     { "set-jumpscroll",        HandleJumpscroll },
  196.     { "set-reverse-video",    HandleReverseVideo },
  197.     { "set-autowrap",        HandleAutoWrap },
  198.     { "set-reversewrap",    HandleReverseWrap },
  199.     { "set-autolinefeed",    HandleAutoLineFeed },
  200.     { "set-appcursor",        HandleAppCursor },
  201.     { "set-appkeypad",        HandleAppKeypad },
  202.     { "set-scroll-on-key",    HandleScrollKey },
  203.     { "set-scroll-on-tty-output",    HandleScrollTtyOutput },
  204.     { "set-allow132",        HandleAllow132 },
  205.     { "set-cursesemul",        HandleCursesEmul },
  206.     { "set-marginbell",        HandleMarginBell },
  207.     { "set-altscreen",        HandleAltScreen },
  208.     { "soft-reset",        HandleSoftReset },
  209.     { "hard-reset",        HandleHardReset },
  210.     { "set-terminal-type",    HandleSetTerminalType },
  211.     { "set-visibility",        HandleVisibility },
  212.     { "set-tek-text",        HandleSetTekText },
  213.     { "tek-page",        HandleTekPage },
  214.     { "tek-reset",        HandleTekReset },
  215.     { "tek-copy",        HandleTekCopy },
  216. };
  217.  
  218. static Dimension defOne = 1;
  219.  
  220. #define GIN_TERM_NONE_STR    "none"
  221. #define GIN_TERM_CR_STR        "CRonly"
  222. #define GIN_TERM_EOT_STR    "CR&EOT"
  223.  
  224. #define GIN_TERM_NONE    0
  225. #define GIN_TERM_CR    1
  226. #define GIN_TERM_EOT    2
  227.  
  228. static XtResource resources[] = {
  229.     {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
  230.      XtOffsetOf(CoreRec, core.width), XtRDimension, (caddr_t)&defOne},
  231.     {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
  232.      XtOffsetOf(CoreRec, core.height), XtRDimension, (caddr_t)&defOne},
  233.     {"fontLarge", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  234.        XtOffsetOf(TekWidgetRec, tek.Tfont[TEK_FONT_LARGE]),
  235.        XtRString, "9x15"},
  236.     {"font2", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  237.        XtOffsetOf(TekWidgetRec, tek.Tfont[TEK_FONT_2]),
  238.        XtRString, "6x13"},
  239.     {"font3", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  240.        XtOffsetOf(TekWidgetRec, tek.Tfont[TEK_FONT_3]),
  241.        XtRString, "8x13"},
  242.     {"fontSmall", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  243.        XtOffsetOf(TekWidgetRec, tek.Tfont[TEK_FONT_SMALL]),
  244.        XtRString, "6x10"},
  245.     {"initialFont", "InitialFont", XtRString, sizeof(char *),
  246.        XtOffsetOf(TekWidgetRec, tek.initial_font),
  247.        XtRString, "large"},
  248.     {"ginTerminator", "GinTerminator", XtRString, sizeof(char *),
  249.        XtOffsetOf(TekWidgetRec, tek.gin_terminator_str),
  250.        XtRString, GIN_TERM_NONE_STR},
  251. };
  252.  
  253. static void TekInitialize(), TekRealize(), TekConfigure();
  254. static int getpoint();
  255. static int Tinput();
  256.  
  257. void TekExpose();
  258. void TekSetFontSize();
  259.  
  260. static WidgetClassRec tekClassRec = {
  261.   {
  262. /* core_class fields */    
  263.     /* superclass      */    (WidgetClass) &widgetClassRec,
  264.     /* class_name      */    "Tek4014",
  265.     /* widget_size      */    sizeof(TekWidgetRec),
  266.     /* class_initialize   */    NULL,
  267.     /* class_part_initialize */ NULL,
  268.     /* class_inited       */    FALSE,
  269.     /* initialize      */    TekInitialize,
  270.     /* initialize_hook    */    NULL,                
  271.     /* realize          */    TekRealize,
  272.     /* actions          */    actionsList,
  273.     /* num_actions      */    XtNumber(actionsList),
  274.     /* resources      */    resources,
  275.     /* num_resources      */    XtNumber(resources),
  276.     /* xrm_class      */    NULLQUARK,
  277.     /* compress_motion      */    TRUE,
  278.     /* compress_exposure  */    TRUE,
  279.     /* compress_enterleave */   TRUE,
  280.     /* visible_interest      */    FALSE,
  281.     /* destroy          */    NULL,
  282.     /* resize          */    TekConfigure,
  283.     /* expose          */    TekExpose,
  284.     /* set_values      */    NULL,
  285.     /* set_values_hook    */    NULL,
  286.     /* set_values_almost  */    NULL,
  287.     /* get_values_hook    */    NULL,
  288.     /* accept_focus      */    NULL,
  289.     /* version            */    XtVersion,
  290.     /* callback_offsets   */    NULL,
  291.     /* tm_table           */    defaultTranslations,
  292.     /* query_geometry     */    XtInheritQueryGeometry,
  293.     /* display_accelerator*/    XtInheritDisplayAccelerator,
  294.     /* extension          */    NULL
  295.   }
  296. };
  297. #define tekWidgetClass ((WidgetClass)&tekClassRec)
  298.  
  299. static Boolean Tfailed = FALSE;
  300.  
  301. static Widget tekshellwidget;
  302.  
  303. static TekWidget CreateTekWidget ()
  304. {
  305.     extern Arg ourTopLevelShellArgs[];
  306.     extern int number_ourTopLevelShellArgs;
  307.  
  308.     /* this causes the Initialize method to be called */
  309.     tekshellwidget = XtCreatePopupShell ("tektronix", topLevelShellWidgetClass,
  310.                      toplevel, ourTopLevelShellArgs, 
  311.                      number_ourTopLevelShellArgs);
  312.  
  313.     /* this causes the Realize method to be called */
  314.     tekWidget = (TekWidget) XtCreateManagedWidget ("tek4014", tekWidgetClass,
  315.                            tekshellwidget, NULL, 0);
  316.  
  317.     return (tekWidget);
  318. }
  319.  
  320.  
  321. int TekInit ()
  322. {
  323.     if (Tfailed) return (0);
  324.     if (tekWidget) return (1);
  325.     if (CreateTekWidget()) {
  326.     return (1);
  327.     }
  328.     return (0);
  329. }
  330.  
  331. static void Tekparse()
  332. {
  333.     register TScreen *screen = &term->screen;
  334.     register int c, x, y;
  335.     char ch;
  336.  
  337.     for( ; ; )
  338.         switch(Tparsestate[c = input()]) {
  339.          case CASE_REPORT:
  340.             /* report address */
  341.             if(screen->TekGIN) {
  342.                 TekGINoff();
  343.                 TekEnqMouse(0);
  344.             } else {
  345.                 c = 064;    /* has hard copy unit */
  346.                 if(screen->margin == MARGIN2)
  347.                     c |= 02;
  348.                 TekEnq(c, screen->cur_X, screen->cur_Y);
  349.             }
  350.             TekRecord->ptr[-1] = NAK; /* remove from recording */
  351.             Tparsestate = curstate;
  352.             break;
  353.  
  354.          case CASE_VT_MODE:
  355.             /* special return to vt102 mode */
  356.             Tparsestate = curstate;
  357.             TekRecord->ptr[-1] = NAK; /* remove from recording */
  358.             if(screen->logging) {
  359.                 FlushLog(screen);
  360.                 screen->logstart = buffer;
  361.             }
  362.             return;
  363.  
  364.          case CASE_SPT_STATE:
  365.             /* Enter Special Point Plot mode */
  366.             if(screen->TekGIN)
  367.                 TekGINoff();
  368.             Tparsestate = curstate = Tspttable;
  369.             break;
  370.  
  371.          case CASE_GIN:
  372.             /* Do Tek GIN mode */
  373.             screen->TekGIN = &TekRecord->ptr[-1];
  374.                 /* Set cross-hair cursor raster array */
  375.             if (GINcursor = 
  376.                 make_colored_cursor (XC_tcross, screen->mousecolor,
  377.                          screen->mousecolorback))
  378.                 XDefineCursor (screen->display, TShellWindow,
  379.                            GINcursor);
  380.             Tparsestate = Tbyptable;    /* Bypass mode */
  381.             break;
  382.  
  383.          case CASE_BEL:
  384.             /* BEL */
  385.             if(screen->TekGIN)
  386.                 TekGINoff();
  387.             if(!TekRefresh)
  388.                 Bell();
  389.             Tparsestate = curstate;    /* clear bypass condition */
  390.             break;
  391.  
  392.          case CASE_BS:
  393.             /* BS */
  394.             if(screen->TekGIN)
  395.                 TekGINoff();
  396.             Tparsestate = curstate;    /* clear bypass condition */
  397.             TCursorBack();
  398.             break;
  399.  
  400.          case CASE_PT_STATE:
  401.             /* Enter Tek Point Plot mode */
  402.             if(screen->TekGIN)
  403.                 TekGINoff();
  404.             Tparsestate = curstate = Tpttable;
  405.             break;
  406.  
  407.          case CASE_PLT_STATE:
  408.             /* Enter Tek Plot mode */
  409.             if(screen->TekGIN)
  410.                 TekGINoff();
  411.             Tparsestate = curstate = Tplttable;
  412.             if((c = input()) == BEL)
  413.                 screen->pen = PENDOWN;
  414.             else {
  415.                 unput(c);
  416.                 screen->pen = PENUP;
  417.             }
  418.             break;
  419.  
  420.          case CASE_TAB:
  421.             /* HT */
  422.             if(screen->TekGIN)
  423.                 TekGINoff();
  424.             Tparsestate = curstate;    /* clear bypass condition */
  425.             TCursorForward();
  426.             break;
  427.  
  428.          case CASE_IPL_STATE:
  429.             /* Enter Tek Incremental Plot mode */
  430.             if(screen->TekGIN)
  431.                 TekGINoff();
  432.             Tparsestate = curstate = Tipltable;
  433.             break;
  434.  
  435.          case CASE_ALP_STATE:
  436.             /* Enter Tek Alpha mode from any other mode */
  437.             if(screen->TekGIN)
  438.                 TekGINoff();
  439.             /* if in one of graphics states, move alpha cursor */
  440.             if(nplot > 0)    /* flush line Tbuffer */
  441.                 TekFlush();
  442.             Tparsestate = curstate = Talptable;
  443.             break;
  444.  
  445.          case CASE_UP:
  446.             /* cursor up */
  447.             if(screen->TekGIN)
  448.                 TekGINoff();
  449.             Tparsestate = curstate;    /* clear bypass condition */
  450.             TCursorUp();
  451.             break;
  452.  
  453.          case CASE_COPY:
  454.             /* make copy */
  455.             if(screen->TekGIN)
  456.                 TekGINoff();
  457.             TekCopy();
  458.             TekRecord->ptr[-1] = NAK; /* remove from recording */
  459.             Tparsestate = curstate;    /* clear bypass condition */
  460.             break;
  461.  
  462.          case CASE_PAGE:
  463.             /* Page Function */
  464.             if(screen->TekGIN)
  465.                 TekGINoff();
  466.             TekPage();    /* clear bypass condition */
  467.             break;
  468.  
  469.          case CASE_BES_STATE:
  470.             /* Byp: an escape char */
  471.             Tparsestate = Tbestable;
  472.             break;
  473.  
  474.          case CASE_BYP_STATE:
  475.             /* set bypass condition */
  476.             Tparsestate = Tbyptable;
  477.             break;
  478.  
  479.          case CASE_IGNORE:
  480.             /* Esc: totally ignore CR, ESC, LF, ~ */
  481.             break;
  482.  
  483.          case CASE_ASCII:
  484.             /* Select ASCII char set */
  485.             /* ignore for now */
  486.             Tparsestate = curstate;
  487.             break;
  488.  
  489.          case CASE_APL:
  490.             /* Select APL char set */
  491.             /* ignore for now */
  492.             Tparsestate = curstate;
  493.             break;
  494.  
  495.          case CASE_CHAR_SIZE: 
  496.             /* character size selector */
  497.                 TekSetFontSize (c & 03);
  498.             Tparsestate = curstate;
  499.             break;
  500.  
  501.          case CASE_BEAM_VEC:
  502.             /* beam and vector selector */
  503.             /* only line types */
  504.             if((c &= LINEMASK) != screen->cur.linetype) {
  505.                 if(nplot > 0)
  506.                     TekFlush();
  507.                 if (c <= TEKNUMLINES)
  508.                     screen->cur.linetype = c;
  509.             }
  510.             Tparsestate = curstate;
  511.             break;
  512.  
  513.          case CASE_CURSTATE:
  514.             Tparsestate = curstate;
  515.             break;
  516.  
  517.          case CASE_PENUP:
  518.             /* Ipl: penup */
  519.             screen->pen = PENUP;
  520.             break;
  521.  
  522.          case CASE_PENDOWN:
  523.             /* Ipl: pendown */
  524.             screen->pen = PENDOWN;
  525.             break;
  526.  
  527.          case CASE_IPL_POINT:
  528.             /* Ipl: point */
  529.             x = screen->cur_X;
  530.             y = screen->cur_Y;
  531.             if(c & NORTH)
  532.                 y++;
  533.             else if(c & SOUTH)
  534.                 y--;
  535.             if(c & EAST)
  536.                 x++;
  537.             else if(c & WEST)
  538.                 x--;
  539.             if(screen->pen == PENDOWN)
  540.                 TekDraw(x, y);
  541.             else
  542.                 TekMove(x, y);
  543.             break;
  544.  
  545.          case CASE_PLT_VEC:
  546.             /* Plt: vector */
  547.             unput(c);
  548.             if(getpoint()) {
  549.                 if(screen->pen == PENDOWN)
  550.                     TekDraw(screen->cur.x, screen->cur.y);
  551.                 else
  552.                     TekMove(screen->cur.x, screen->cur.y);
  553.                 screen->pen = PENDOWN;
  554.             }
  555.             break;
  556.  
  557.          case CASE_PT_POINT:
  558.             /* Pt: point */
  559.             unput(c);
  560.             if(getpoint()) {
  561.                 TekMove(screen->cur.x, screen->cur.y);
  562.                 TekDraw(screen->cur.x, screen->cur.y);
  563.             }
  564.             break;
  565.  
  566.          case CASE_SPT_POINT:
  567.             /* Spt: point */
  568.             /* ignore intensity character in c */
  569.             if(getpoint()) {
  570.                 TekMove(screen->cur.x, screen->cur.y);
  571.                 TekDraw(screen->cur.x, screen->cur.y);
  572.             }
  573.             break;
  574.  
  575.          case CASE_CR:
  576.             /* CR */
  577.             if(screen->TekGIN)
  578.                 TekGINoff();
  579.             if(nplot > 0)    /* flush line Tbuffer */
  580.                 TekFlush();
  581.             screen->cur_X = screen->margin == MARGIN1 ? 0 :
  582.              TEKWIDTH / 2;
  583.             Tparsestate = curstate = Talptable;
  584.             break;
  585.  
  586.          case CASE_ESC_STATE:
  587.             /* ESC */
  588.             Tparsestate = Tesctable;
  589.             break;
  590.  
  591.          case CASE_LF:
  592.             /* LF */
  593.             if(screen->TekGIN)
  594.                 TekGINoff();
  595.             TCursorDown();
  596.             if (!TekRefresh &&
  597.                 (QLength(screen->display) > 0 ||
  598.                  GetBytesAvailable (ConnectionNumber(screen->display)) > 0))
  599.               xevents();
  600.             break;
  601.  
  602.          case CASE_SP:
  603.             /* SP */
  604.             TCursorForward();
  605.             break;
  606.  
  607.          case CASE_PRINT:
  608.             /* printable character */
  609.             ch = c;
  610.             c = screen->cur.fontsize;
  611.  
  612.             XDrawString(
  613.                 screen->display,
  614.                 TWindow(screen), 
  615.                 screen->TnormalGC,
  616.                 (int)(screen->cur_X * TekScale(screen)) + screen->border,
  617.                 (int)((TEKHEIGHT + TEKTOPPAD - screen->cur_Y) * TekScale(screen)) + screen->border,
  618.                 &ch,
  619.                 1);
  620.             TCursorForward();
  621.             break;
  622.          case CASE_OSC:
  623.             /* do osc escape */
  624.             do_osc(Tinput);
  625.             Tparsestate = curstate;
  626.             break;
  627.         }
  628. }            
  629.  
  630. static int rcnt;
  631. static char *rptr;
  632. static int Tselect_mask;
  633.  
  634. static int Tinput()
  635. {
  636.     register TScreen *screen = &term->screen;
  637.     register int i;
  638.     register TekLink *tek;
  639.  
  640.     if(Tpushback > Tpushb)
  641.         return(*--Tpushback);
  642.     if(TekRefresh) {
  643.         if(rcnt-- > 0)
  644.             return(*rptr++);
  645.         if(tek = TekRefresh->next) {
  646.             TekRefresh = tek;
  647.             rptr = tek->data;
  648.             rcnt = tek->count - 1;
  649.             TekSetFontSize(tek->fontsize);
  650.             return(*rptr++);
  651.         }
  652.         TekRefresh = (TekLink *)0;
  653.         longjmp(Tekjump, 1);
  654.     }
  655. again:
  656.     if(Tbcnt-- <= 0) {
  657.         if(nplot > 0)    /* flush line Tbuffer */
  658.             TekFlush();
  659.         Tselect_mask = pty_mask;    /* force a read */
  660.         for( ; ; ) {
  661. #ifdef CRAY
  662.             struct timeval crocktimeout;
  663.             crocktimeout.tv_sec = 0;
  664.             crocktimeout.tv_usec = 0;
  665.             (void) select (max_plus1, &Tselect_mask, (int *) NULL,
  666.                        (int *) NULL, &crocktimeout);
  667. #endif
  668.             if(Tselect_mask & pty_mask) {
  669.                 if(screen->logging)
  670.                     FlushLog(screen);
  671.                 Tbcnt = read(screen->respond, Tbptr = Tbuffer, BUF_SIZE);
  672.                 if(Tbcnt < 0) {
  673.                     if(errno == EIO)
  674.                         Cleanup (0);
  675.                     else if(!E_TEST(errno))
  676.                         Panic(
  677.                  "Tinput:read returned unexpected error (%d)\n",
  678.                          errno);
  679.                 } else if(Tbcnt == 0)
  680.                     Panic("input: read returned zero\n", 0);
  681.                 else {
  682.                     if (!screen->output_eight_bits) {
  683.                     register int bc = Tbcnt;
  684.                     register Char *b = Tbptr;
  685.  
  686.                     for (; bc > 0; bc--, b++) {
  687.                         *b &= (Char) 0x7f;
  688.                     }
  689.                     }
  690.                     break;
  691.                 }
  692.             }
  693.             if (Ttoggled && curstate == Talptable) {
  694.                 TCursorToggle(TOGGLE);
  695.                 Ttoggled = FALSE;
  696.             }
  697.             if(QLength(screen->display))
  698.                 Tselect_mask = X_mask;
  699.             else {
  700.                 XFlush(screen->display);
  701.                 Tselect_mask = Select_mask;
  702.                 if((i = select(max_plus1, &Tselect_mask,
  703.                     (int *)NULL, (int *)NULL,
  704.                     (struct timeval *)NULL)) < 0){
  705.                     if (errno != EINTR)
  706.                         SysError(ERROR_TSELECT);
  707.                     continue;
  708.                 }
  709.             }
  710.             if(Tselect_mask & X_mask) {
  711.                 xevents();
  712.                 if(Tbcnt > 0)
  713.                     goto again;
  714.             }
  715.         }
  716.         Tbcnt--;
  717.         if (!Ttoggled && curstate == Talptable) {
  718.             TCursorToggle(TOGGLE);
  719.             Ttoggled = TRUE;
  720.         }
  721.     }
  722.     tek = TekRecord;
  723.     if(tek->count >= TEK_LINK_BLOCK_SIZE
  724.        || tek->fontsize != screen->cur.fontsize) {
  725.         if((TekRecord = tek->next = (TekLink *)malloc(sizeof(TekLink)))
  726.          == (TekLink *)0)
  727.             Panic("Tinput: malloc error (%d)\n", errno);
  728.         tek = tek->next;
  729.         tek->next = (TekLink *)0;
  730.         tek->fontsize = screen->cur.fontsize;
  731.         tek->count = 0;
  732.         tek->ptr = tek->data;
  733.     }
  734.     tek->count++;
  735.     return(*tek->ptr++ = *Tbptr++);
  736. }
  737.  
  738. /* this should become the Tek Widget's Resize proc */
  739. static void TekConfigure(w)
  740.     Widget w;
  741. {
  742.     register TScreen *screen = &term->screen;
  743.     register int border = 2 * screen->border;
  744.     register double d;
  745.  
  746.     if (TWindow(screen)) XClearWindow(screen->display, TWindow(screen));
  747.     TWidth(screen) = w->core.width - border;
  748.     THeight(screen) = w->core.height - border;
  749.     TekScale(screen) = (double)TWidth(screen) / TEKWIDTH;
  750.     if((d = (double)THeight(screen) / (TEKHEIGHT + TEKTOPPAD + TEKBOTTOMPAD))
  751.        < TekScale(screen))
  752.       TekScale(screen) = d;
  753.     TFullWidth(screen) = w->core.width;
  754.     TFullHeight(screen) = w->core.height;
  755. }
  756.  
  757. /*ARGSUSED*/
  758. void TekExpose(w, event, region)
  759.     Widget w;
  760.     XEvent *event;
  761.     Region region;
  762. {
  763.     register TScreen *screen = &term->screen;
  764.     extern Bool waiting_for_initial_map;
  765.  
  766. #ifdef lint
  767.     region = region;
  768. #endif
  769.     if(!Ttoggled)
  770.         TCursorToggle(CLEAR);
  771.     Ttoggled = TRUE;
  772.     Tpushback = Tpushb;
  773.     screen->cur_X = 0;
  774.     screen->cur_Y = TEKHOME;
  775.     TekSetFontSize(screen->page.fontsize);
  776.     screen->cur = screen->page;
  777.     screen->margin = MARGIN1;
  778.     if(screen->TekGIN) {
  779.         screen->TekGIN = NULL;
  780.         TekGINoff();
  781.     }
  782.     TekRefresh = &Tek0;
  783.     rptr = TekRefresh->data;
  784.     rcnt = TekRefresh->count;
  785.     Tparsestate = curstate = Talptable;
  786.     if (waiting_for_initial_map)
  787.         first_map_occurred ();
  788.     if(!screen->waitrefresh)
  789.         dorefresh();
  790. }
  791.  
  792. dorefresh()
  793. {
  794.     register TScreen *screen = &term->screen;
  795.     static Cursor wait_cursor = None;
  796.  
  797.     if (wait_cursor == None)
  798.             wait_cursor = make_colored_cursor (XC_watch, screen->mousecolor,
  799.                            screen->mousecolorback);
  800.         XDefineCursor(screen->display, TShellWindow, wait_cursor);
  801.     XFlush(screen->display);
  802.     if(!setjmp(Tekjump))
  803.         Tekparse();
  804.     XDefineCursor(screen->display, TShellWindow,
  805.      (screen->TekGIN && GINcursor) ? GINcursor : screen->arrow);
  806. }
  807.  
  808. TekPage()
  809. {
  810.     register TScreen *screen = &term->screen;
  811.     register TekLink *tek;
  812.  
  813.     XClearWindow(screen->display, TWindow(screen));
  814.     screen->cur_X = 0;
  815.     screen->cur_Y = TEKHOME;
  816.     screen->margin = MARGIN1;
  817.     screen->page = screen->cur;
  818.     if(screen->TekGIN)
  819.         TekGINoff();
  820.     tek = TekRecord = &Tek0;
  821.     tek->fontsize = screen->cur.fontsize;
  822.     tek->count = 0;
  823.     tek->ptr = tek->data;
  824.     tek = tek->next;
  825.     if(tek)
  826.         do {
  827.             TekLink *tek2 = tek->next;
  828.  
  829.             free((char *)tek);
  830.             tek = tek2;
  831.         } while(tek);
  832.     TekRecord->next = (TekLink *)0;
  833.     TekRefresh = (TekLink *)0;
  834.     Ttoggled = TRUE;
  835.     Tparsestate = curstate = Talptable;    /* Tek Alpha mode */
  836. }
  837.  
  838. #define    EXTRABITS    017
  839. #define    FIVEBITS    037
  840. #define    HIBITS        (FIVEBITS << SHIFTHI)
  841. #define    LOBITS        (FIVEBITS << SHIFTLO)
  842. #define    SHIFTHI        7
  843. #define    SHIFTLO        2
  844. #define    TWOBITS        03
  845.  
  846. static int
  847. getpoint()
  848. {
  849.     register int c, x, y, e, lo_y = 0;
  850.     register TScreen *screen = &term->screen;
  851.  
  852.     x = screen->cur.x;
  853.     y = screen->cur.y;
  854.     for( ; ; ) {
  855.         if((c = input()) < ' ') {    /* control character */
  856.             unput(c);
  857.             return(0);
  858.         }
  859.         if(c < '@') {    /* Hi X or Hi Y */
  860.             if(lo_y) {    /* seen a Lo Y, so this must be Hi X */
  861.                 x &= ~HIBITS;
  862.                 x |= (c & FIVEBITS) << SHIFTHI;
  863.                 continue;
  864.             }
  865.             /* else Hi Y */
  866.             y &= ~HIBITS;
  867.             y |= (c & FIVEBITS) << SHIFTHI;
  868.             continue;
  869.         }
  870.         if(c < '`') {    /* Lo X */
  871.             x &= ~LOBITS;
  872.             x |= (c & FIVEBITS) << SHIFTLO;
  873.             screen->cur.x = x;
  874.             screen->cur.y = y;
  875.             return(1);    /* OK */
  876.         }
  877.         /* else Lo Y */
  878.         if(lo_y) {    /* seen a Lo Y, so other must be extra bits */
  879.             e = (y >> SHIFTLO) & EXTRABITS;
  880.             x &= ~TWOBITS;
  881.             x |= e & TWOBITS;
  882.             y &= ~TWOBITS;
  883.             y |= (e >> SHIFTLO) & TWOBITS;
  884.         }
  885.         y &= ~LOBITS;
  886.         y |= (c & FIVEBITS) << SHIFTLO;
  887.         lo_y++;
  888.     }
  889. }
  890.  
  891. TCursorBack()
  892. {
  893.     register TScreen *screen = &term->screen;
  894.     register struct Tek_Char *t;
  895.     register int x, l;
  896.  
  897.     x = ( screen->cur_X -=
  898.         (t = &TekChar[screen->cur.fontsize])->hsize
  899.         );
  900.  
  901.     if(screen->margin == MARGIN1 && x < 0 || screen->margin == MARGIN2
  902.      && x < TEKWIDTH / 2) {
  903.         if((l = (screen->cur_Y + (t->vsize - 1)) / t->vsize + 1) >=
  904.          t->nlines) {
  905.             screen->margin = !screen->margin;
  906.             l = 0;
  907.         }
  908.         screen->cur_Y = l * t->vsize;
  909.         screen->cur_X = (t->charsperline - 1) * t->hsize;
  910.     }
  911. }
  912.  
  913. TCursorForward()
  914. {
  915.     register TScreen *screen = &term->screen;
  916.     register struct Tek_Char *t;
  917.     register int l;
  918.  
  919.     if( ( screen->cur_X +=
  920.         ( t = &TekChar[screen->cur.fontsize])->hsize
  921.         ) > TEKWIDTH
  922.       ) {
  923.         if((l = screen->cur_Y / t->vsize - 1) < 0) {
  924.             screen->margin = !screen->margin;
  925.             l = t->nlines - 1;
  926.         }
  927.         screen->cur_Y = l * t->vsize;
  928.         screen->cur_X = screen->margin == MARGIN1 ? 0 : TEKWIDTH / 2;
  929.     }
  930. }
  931.  
  932. TCursorUp()
  933. {
  934.     register TScreen *screen = &term->screen;
  935.     register struct Tek_Char *t;
  936.     register int l;
  937.  
  938.     t = &TekChar[screen->cur.fontsize];
  939.  
  940.     if((l = (screen->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= t->nlines) {
  941.         l = 0;
  942.         if((screen->margin = !screen->margin) != MARGIN1) {
  943.             if(screen->cur_X < TEKWIDTH / 2)
  944.                 screen->cur_X += TEKWIDTH / 2;
  945.         } else if(screen->cur_X >= TEKWIDTH / 2)
  946.             screen->cur_X -= TEKWIDTH / 2;
  947.     }
  948.     screen->cur_Y = l * t->vsize;
  949. }
  950.  
  951. TCursorDown()
  952. {
  953.     register TScreen *screen = &term->screen;
  954.     register struct Tek_Char *t;
  955.     register int l;
  956.  
  957.     t = &TekChar[screen->cur.fontsize];
  958.  
  959.     if((l = screen->cur_Y / t->vsize - 1) < 0) {
  960.         l = t->nlines - 1;
  961.         if((screen->margin = !screen->margin) != MARGIN1) {
  962.             if(screen->cur_X < TEKWIDTH / 2)
  963.                 screen->cur_X += TEKWIDTH / 2;
  964.         } else if(screen->cur_X >= TEKWIDTH / 2)
  965.             screen->cur_X -= TEKWIDTH / 2;
  966.     }
  967.     screen->cur_Y = l * t->vsize;
  968. }
  969.  
  970. static void
  971. AddToDraw(x1, y1, x2, y2)
  972.     int x1, y1, x2, y2;
  973. {
  974.     register TScreen *screen = &term->screen;
  975.     register XSegment *lp;
  976.  
  977.     if(nplot >= MAX_PTS) {
  978.         TekFlush();
  979.     }
  980.     lp = line_pt++;
  981.     lp->x1 = x1 = x1 * TekScale(screen) + screen->border;
  982.     lp->y1 = y1 = (TEKHEIGHT + TEKTOPPAD - y1) * TekScale(screen) +
  983.      screen->border;
  984.     lp->x2 = x2 = x2 * TekScale(screen) + screen->border;
  985.     lp->y2 = y2 = (TEKHEIGHT + TEKTOPPAD - y2) * TekScale(screen) +
  986.      screen->border;
  987.     nplot++;
  988. }
  989.  
  990. TekDraw (x, y)
  991.     int x, y;
  992. {
  993.     register TScreen *screen = &term->screen;
  994.  
  995.     if(nplot == 0 || T_lastx != screen->cur_X || T_lasty != screen->cur_Y) {
  996.         /*
  997.          * We flush on each unconnected line segment if the line
  998.          * type is not solid.  This solves a bug in X when drawing
  999.          * points while the line type is not solid.
  1000.          */
  1001.         if(nplot > 0 && screen->cur.linetype != SOLIDLINE)
  1002.             TekFlush();
  1003.     }
  1004.     AddToDraw(screen->cur_X, screen->cur_Y, x, y);
  1005.     T_lastx = screen->cur_X = x;
  1006.     T_lasty = screen->cur_Y = y;
  1007. }
  1008.  
  1009. TekFlush ()
  1010. {
  1011.     register TScreen *screen = &term->screen;
  1012.  
  1013.     XDrawSegments(screen->display, TWindow(screen), 
  1014.         ((screen->cur.linetype == SOLIDLINE)?  screen->TnormalGC :
  1015.          screen->linepat[screen->cur.linetype - 1]),
  1016.          Tline, nplot);
  1017.     nplot = 0;
  1018.     line_pt = Tline;
  1019. }
  1020.  
  1021. TekGINoff()
  1022. {
  1023.     register TScreen *screen = &term->screen;
  1024.     
  1025.     XDefineCursor(screen->display, TShellWindow, screen->arrow);
  1026.     if(GINcursor)
  1027.         XFreeCursor(screen->display, GINcursor);
  1028.     if(screen->TekGIN) {
  1029.         *screen->TekGIN = CANCEL;    /* modify recording */
  1030.         screen->TekGIN = NULL;
  1031.     }
  1032. }
  1033.  
  1034. TekEnqMouse(c)
  1035.     int c;            /* character pressed */
  1036. {
  1037.     register TScreen *screen = &term->screen;
  1038.     int mousex, mousey, rootx, rooty;
  1039.     unsigned int mask; /* XQueryPointer */
  1040.     Window root, subw;
  1041.  
  1042.     XQueryPointer(
  1043.         screen->display, TWindow(screen), 
  1044.         &root, &subw,
  1045.         &rootx, &rooty,
  1046.         &mousex, &mousey,
  1047.         &mask);
  1048.     if((mousex = (mousex - screen->border) / TekScale(screen)) < 0)
  1049.         mousex = 0;
  1050.     else if(mousex >= TEKWIDTH)
  1051.         mousex = TEKWIDTH - 1;
  1052.     if((mousey = TEKHEIGHT + TEKTOPPAD - (mousey - screen->border) /
  1053.          TekScale(screen)) < 0)
  1054.         mousey = 0;
  1055.     else if(mousey >= TEKHEIGHT)
  1056.         mousey = TEKHEIGHT - 1;
  1057.     TekEnq(c, mousex, mousey);
  1058. }
  1059.  
  1060. static void TekEnq (status, x, y)
  1061.     int status;
  1062.     register int x, y;
  1063. {
  1064.     register TScreen *screen = &term->screen;
  1065.     int pty = screen->respond;
  1066.     char cplot [7];
  1067.     int len = 5;
  1068.  
  1069.     cplot[0] = status;
  1070.     /* Translate x and y to Tektronix code */
  1071.     cplot[1] = 040 | ((x >> SHIFTHI) & FIVEBITS);
  1072.     cplot[2] = 040 | ((x >> SHIFTLO) & FIVEBITS);
  1073.     cplot[3] = 040 | ((y >> SHIFTHI) & FIVEBITS);
  1074.     cplot[4] = 040 | ((y >> SHIFTLO) & FIVEBITS);
  1075.  
  1076.     if (screen->gin_terminator != GIN_TERM_NONE)
  1077.     cplot[len++] = '\r';
  1078.     if (screen->gin_terminator == GIN_TERM_EOT)
  1079.     cplot[len++] = '\004';
  1080.  
  1081.     if(cplot[0])
  1082.     v_write(pty, cplot, len);
  1083.     else
  1084.     v_write(pty, cplot+1, len-1);
  1085. }
  1086.  
  1087. TekRun()
  1088. {
  1089.     register TScreen *screen = &term->screen;
  1090.     register int i;
  1091.     
  1092.     if(!TWindow(screen) && !TekInit()) {
  1093.         if(VWindow(screen)) {
  1094.             screen->TekEmu = FALSE;
  1095.             return;
  1096.         }
  1097.         Exit(ERROR_TINIT);
  1098.     }
  1099.     if(!screen->Tshow) {
  1100.         set_tek_visibility (TRUE);
  1101.     } 
  1102.     update_vttekmode();
  1103.     update_vtshow();
  1104.     update_tekshow();
  1105.     set_tekhide_sensitivity();
  1106.  
  1107.     Tpushback = Tpushb;
  1108.     Tbptr = Tbuffer;
  1109.     for(i = Tbcnt = bcnt ; i > 0 ; i--)
  1110.         *Tbptr++ = *bptr++;
  1111.     Tbptr = Tbuffer;
  1112.     Ttoggled = TRUE;
  1113.     if(!setjmp(Tekend))
  1114.         Tekparse();
  1115.     if(!Ttoggled) {
  1116.         TCursorToggle(TOGGLE);
  1117.         Ttoggled = TRUE;
  1118.     }
  1119.     screen->TekEmu = FALSE;
  1120. }
  1121.  
  1122. #define DOTTED_LENGTH 2
  1123. #define DOT_DASHED_LENGTH 4
  1124. #define SHORT_DASHED_LENGTH 2
  1125. #define LONG_DASHED_LENGTH 2
  1126.  
  1127. static int dash_length[TEKNUMLINES] = {
  1128.     DOTTED_LENGTH,
  1129.     DOT_DASHED_LENGTH,
  1130.     SHORT_DASHED_LENGTH,
  1131.     LONG_DASHED_LENGTH,
  1132. };
  1133.  
  1134. static unsigned char dotted[DOTTED_LENGTH] = {3, 1};
  1135. static unsigned char dot_dashed[DOT_DASHED_LENGTH] = {3, 4, 3, 1};
  1136. static unsigned char short_dashed[SHORT_DASHED_LENGTH] = {4, 4};
  1137. static unsigned char long_dashed[LONG_DASHED_LENGTH] = {4, 7};
  1138.  
  1139. static unsigned char *dashes[TEKNUMLINES] = {
  1140.     dotted,
  1141.     dot_dashed,
  1142.     short_dashed,
  1143.     long_dashed,
  1144. };
  1145.  
  1146.  
  1147.  
  1148. /*
  1149.  * The following is called the create the tekWidget
  1150.  */
  1151.  
  1152. static void TekInitialize(request, new)
  1153.     Widget request, new;
  1154. {
  1155.     /* look for focus related events on the shell, because we need
  1156.      * to care about the shell's border being part of our focus.
  1157.      */
  1158.     XtAddEventHandler(XtParent(new), EnterWindowMask, FALSE,
  1159.               HandleEnterWindow, (caddr_t)NULL);
  1160.     XtAddEventHandler(XtParent(new), LeaveWindowMask, FALSE,
  1161.               HandleLeaveWindow, (caddr_t)NULL);
  1162.     XtAddEventHandler(XtParent(new), FocusChangeMask, FALSE,
  1163.               HandleFocusChange, (caddr_t)NULL);
  1164.     XtAddEventHandler((Widget)new, PropertyChangeMask, FALSE,
  1165.               HandleBellPropertyChange, (Opaque)NULL);
  1166. }
  1167.  
  1168.  
  1169. static void TekRealize (gw, valuemaskp, values)
  1170.     Widget gw;
  1171.     XtValueMask *valuemaskp;
  1172.     XSetWindowAttributes *values;
  1173. {
  1174.     TekWidget tw = (TekWidget) gw;
  1175.     register TScreen *screen = &term->screen;
  1176.     register int i;
  1177.     register TekLink *tek;
  1178.     register double d;
  1179.     register int border = 2 * screen->border;
  1180.     int pr;
  1181.     XGCValues gcv;
  1182.     int winX, winY, width, height;
  1183.     XSizeHints sizehints;
  1184.     char Tdefault[32];
  1185.  
  1186.     tw->core.border_pixel = term->core.border_pixel;
  1187.  
  1188.     for (i = 0; i < TEKNUMFONTS; i++) {
  1189.     if (!tw->tek.Tfont[i]) 
  1190.       tw->tek.Tfont[i] = XQueryFont (screen->display, DefaultGCID);
  1191.     tw->tek.tobaseline[i] = tw->tek.Tfont[i]->ascent;
  1192.     }
  1193.  
  1194.     if((Tbuffer = (Char *)malloc(BUF_SIZE)) == NULL ||
  1195.        (Tpushb = (Char *)malloc(10)) == NULL ||
  1196.        (Tline = (XSegment *)malloc(MAX_VTX * sizeof(XSegment))) == NULL) {
  1197.     fprintf (stderr, "%s: Not enough core for Tek mode\n", xterm_name);
  1198.     if(Tpushb) free((char *)Tpushb);
  1199.     if(Tbuffer) free((char *)Tbuffer);
  1200.     Tfailed = TRUE;
  1201.     return;
  1202.     }
  1203.  
  1204.     screen->xorplane = 1;
  1205.  
  1206.     screen->Tbackground = term->core.background_pixel;
  1207.     screen->Tforeground = screen->foreground;
  1208.     screen->Tcursorcolor = screen->cursorcolor;
  1209.  
  1210.     if (term->misc.T_geometry == NULL) {
  1211.     int defwidth, defheight;
  1212.  
  1213.     if (term->misc.tekSmall) {
  1214.         defwidth = TEKMINWIDTH;
  1215.         defheight = TEKMINHEIGHT;
  1216.     } else {
  1217.         defwidth = TEKDEFWIDTH;
  1218.         defheight = TEKDEFHEIGHT;
  1219.     }
  1220.     sprintf (Tdefault, "=%dx%d", defwidth + border, defheight + border);
  1221.     term->misc.T_geometry = Tdefault;
  1222.     }
  1223.  
  1224.     winX = 1;
  1225.     winY = 1;
  1226.     width = TEKDEFWIDTH + border;
  1227.     height = TEKDEFHEIGHT + border;
  1228.  
  1229.     pr = XParseGeometry(term->misc.T_geometry, &winX, &winY, (unsigned int *)&width, (unsigned int *)&height);
  1230.     if ((pr & XValue) && (pr & XNegative))
  1231.       winX += DisplayWidth(screen->display, DefaultScreen(screen->display))
  1232.                         - width - (term->core.parent->core.border_width * 2);
  1233.     if ((pr & YValue) && (pr & YNegative))
  1234.       winY += DisplayHeight(screen->display, DefaultScreen(screen->display))
  1235.     - height - (term->core.parent->core.border_width * 2);
  1236.   
  1237.     /* set up size hints */
  1238.     sizehints.min_width = TEKMINWIDTH + border;
  1239.     sizehints.min_height = TEKMINHEIGHT + border;
  1240.     sizehints.width_inc = 1;
  1241.     sizehints.height_inc = 1;
  1242.     sizehints.flags = PMinSize|PResizeInc;
  1243.     sizehints.x = winX;
  1244.     sizehints.y = winY;
  1245.     if ((XValue&pr) || (YValue&pr)) {
  1246.     sizehints.flags |= USSize|USPosition;
  1247.     sizehints.flags |= PWinGravity;
  1248.     switch (pr & (XNegative | YNegative)) {
  1249.       case 0:
  1250.         sizehints.win_gravity = NorthWestGravity;
  1251.         break;
  1252.       case XNegative:
  1253.         sizehints.win_gravity = NorthEastGravity;
  1254.         break;
  1255.       case YNegative:
  1256.         sizehints.win_gravity = SouthWestGravity;
  1257.         break;
  1258.       default:
  1259.         sizehints.win_gravity = SouthEastGravity;
  1260.         break;
  1261.     }
  1262.     } else {
  1263.     sizehints.flags |= PSize;
  1264.     }
  1265.     sizehints.width = width;
  1266.     sizehints.height = height;
  1267.     if ((WidthValue&pr) || (HeightValue&pr))
  1268.       sizehints.flags |= USSize;
  1269.     else sizehints.flags |= PSize;
  1270.  
  1271.     (void) XtMakeResizeRequest ((Widget) tw, width, height,
  1272.                 &tw->core.width, &tw->core.height);
  1273.  
  1274.     /* XXX This is bogus.  We are parsing geometries too late.  This
  1275.      * is information that the shell widget ought to have before we get
  1276.      * realized, so that it can do the right thing.
  1277.      */
  1278.     if (sizehints.flags & USPosition)
  1279.       XMoveWindow (XtDisplay(tw), tw->core.parent->core.window,
  1280.            sizehints.x, sizehints.y);
  1281.  
  1282.     XSetWMNormalHints (XtDisplay(tw), tw->core.parent->core.window,
  1283.                &sizehints);
  1284.     XFlush (XtDisplay(tw));    /* get it out to window manager */
  1285.  
  1286.     values->win_gravity = NorthWestGravity;
  1287.     values->background_pixel = screen->Tbackground;
  1288.  
  1289.     tw->core.window = TWindow(screen) = 
  1290.     XCreateWindow (screen->display,
  1291.                tw->core.parent->core.window,
  1292.                tw->core.x, tw->core.y,
  1293.                tw->core.width, tw->core.height, tw->core.border_width,
  1294.                (int) tw->core.depth,
  1295.                InputOutput, CopyFromParent,
  1296.                ((*valuemaskp)|CWBackPixel|CWWinGravity),
  1297.                values);
  1298.  
  1299.     TFullWidth(screen) = width;
  1300.     TFullHeight(screen) = height;
  1301.     TWidth(screen) = width - border;
  1302.     THeight(screen) = height - border;
  1303.     TekScale(screen) = (double)TWidth(screen) / TEKWIDTH;
  1304.     if((d = (double)THeight(screen) / (TEKHEIGHT + TEKTOPPAD +
  1305.                        TEKBOTTOMPAD)) < TekScale(screen))
  1306.       TekScale(screen) = d;
  1307.     
  1308.  
  1309.     screen->cur.fontsize = TEK_FONT_LARGE;
  1310.     if (tw->tek.initial_font) {
  1311.     char *s = tw->tek.initial_font;
  1312.  
  1313.     if (XmuCompareISOLatin1 (s, "large") == 0)
  1314.       screen->cur.fontsize = TEK_FONT_LARGE;
  1315.     else if (XmuCompareISOLatin1 (s, "2") == 0 || 
  1316.          XmuCompareISOLatin1 (s, "two") == 0)
  1317.       screen->cur.fontsize = TEK_FONT_2;
  1318.     else if (XmuCompareISOLatin1 (s, "3") == 0 || 
  1319.          XmuCompareISOLatin1 (s, "three") == 0)
  1320.       screen->cur.fontsize = TEK_FONT_3;
  1321.     else if (XmuCompareISOLatin1 (s, "small") == 0)
  1322.       screen->cur.fontsize = TEK_FONT_SMALL;
  1323.     }
  1324.  
  1325.     if(XmuCompareISOLatin1(tw->tek.gin_terminator_str, GIN_TERM_NONE_STR) == 0)
  1326.     screen->gin_terminator = GIN_TERM_NONE;
  1327.     else if(XmuCompareISOLatin1(tw->tek.gin_terminator_str, GIN_TERM_CR_STR) == 0)
  1328.     screen->gin_terminator = GIN_TERM_CR;
  1329.     else if(XmuCompareISOLatin1(tw->tek.gin_terminator_str, GIN_TERM_EOT_STR) == 0)
  1330.     screen->gin_terminator = GIN_TERM_EOT;
  1331.     else
  1332.     fprintf(stderr, "%s: illegal GIN terminator setting \"%s\"\n",
  1333.         xterm_name, tw->tek.gin_terminator_str);
  1334.  
  1335.     gcv.graphics_exposures = TRUE;    /* default */
  1336.     gcv.font = tw->tek.Tfont[screen->cur.fontsize]->fid;
  1337.     gcv.foreground = screen->Tforeground;
  1338.     gcv.background = screen->Tbackground;
  1339.     
  1340.     /* if font wasn't successfully opened, then gcv.font will contain
  1341.        the Default GC's ID, meaning that we must use the server default font. 
  1342.      */
  1343.     TEKgcFontMask = (gcv.font == DefaultGCID) ? 0 : GCFont;
  1344.     screen->TnormalGC = XCreateGC (screen->display, TWindow(screen), 
  1345.                    (TEKgcFontMask|GCGraphicsExposures|
  1346.                     GCForeground|GCBackground), &gcv);
  1347.  
  1348.     gcv.function = GXinvert;
  1349.     gcv.plane_mask = screen->xorplane = (screen->Tbackground ^
  1350.                      screen->Tcursorcolor);
  1351.     gcv.join_style = JoinMiter;    /* default */
  1352.     gcv.line_width = 1;
  1353.     screen->TcursorGC = XCreateGC (screen->display, TWindow(screen), 
  1354.                    (GCFunction|GCPlaneMask), &gcv);
  1355.  
  1356.     gcv.foreground = screen->Tforeground;
  1357.     gcv.line_style = LineOnOffDash;
  1358.     gcv.line_width = 0;
  1359.     for(i = 0 ; i < TEKNUMLINES ; i++) {
  1360.     screen->linepat[i] = XCreateGC (screen->display, TWindow(screen),
  1361.                     (GCForeground|GCLineStyle), &gcv); 
  1362.     XSetDashes (screen->display, screen->linepat[i], 0,
  1363.             (char *) dashes[i], dash_length[i]);
  1364.     }
  1365.  
  1366.     TekBackground(screen);
  1367.  
  1368.     screen->margin = MARGIN1;        /* Margin 1        */
  1369.     screen->TekGIN = FALSE;            /* GIN off        */
  1370.  
  1371.  
  1372.     XDefineCursor(screen->display, TShellWindow, screen->pointer_cursor);
  1373.  
  1374.     {    /* there's gotta be a better way... */
  1375.     static Arg args[] = {
  1376.         {XtNtitle, (XtArgVal)NULL},
  1377.         {XtNiconName, (XtArgVal)NULL},
  1378.     };
  1379.     char *icon_name, *title, *tek_icon_name, *tek_title;
  1380.  
  1381.     args[0].value = (XtArgVal)&icon_name;
  1382.     args[1].value = (XtArgVal)&title;
  1383.     XtGetValues (tw->core.parent, args, 2);
  1384.     tek_icon_name = XtMalloc(strlen(icon_name)+7);
  1385.     strcpy(tek_icon_name, icon_name);
  1386.     strcat(tek_icon_name, "(Tek)");
  1387.     tek_title = XtMalloc(strlen(title)+7);
  1388.     strcpy(tek_title, title);
  1389.     strcat(tek_title, "(Tek)");
  1390.     args[0].value = (XtArgVal)tek_icon_name;
  1391.     args[1].value = (XtArgVal)tek_title;
  1392.     XtSetValues (tw->core.parent, args, 2);
  1393.     XtFree( tek_icon_name );
  1394.     XtFree( tek_title );
  1395.     }
  1396.  
  1397.     tek = TekRecord = &Tek0;
  1398.     tek->next = (TekLink *)0;
  1399.     tek->fontsize = screen->cur.fontsize;
  1400.     tek->count = 0;
  1401.     tek->ptr = tek->data;
  1402.     Tpushback = Tpushb;
  1403.     Tbptr = Tbuffer;
  1404.     screen->cur_X = 0;
  1405.     screen->cur_Y = TEKHOME;
  1406.     line_pt = Tline;
  1407.     Ttoggled = TRUE;
  1408.     screen->page = screen->cur;
  1409.     return;
  1410. }
  1411.  
  1412. void TekSetFontSize (newitem)
  1413.     int newitem;
  1414. {
  1415.     register TScreen *screen = &term->screen;
  1416.     int oldsize = screen->cur.fontsize;
  1417.     int newsize = MI2FS(newitem);
  1418.     Font fid;
  1419.     
  1420.     if (!tekWidget  ||  oldsize == newsize)
  1421.     return;
  1422.     if (!Ttoggled) TCursorToggle(TOGGLE);
  1423.     set_tekfont_menu_item (oldsize, FALSE);
  1424.  
  1425.     fid = tekWidget->tek.Tfont[newsize]->fid;
  1426.     if (fid == DefaultGCID) 
  1427.        /* we didn't succeed in opening a real font
  1428.       for this size.  Instead, use server default. */
  1429.        XCopyGC (screen->display,
  1430.         DefaultGC(screen->display, DefaultScreen(screen->display)),
  1431.         GCFont, screen->TnormalGC);
  1432.     else
  1433.        XSetFont (screen->display, screen->TnormalGC, fid);
  1434.  
  1435.     screen->cur.fontsize = newsize;
  1436.     set_tekfont_menu_item (newsize, TRUE);
  1437.     if (!Ttoggled) TCursorToggle(TOGGLE);
  1438. }
  1439.  
  1440. TekReverseVideo(screen)
  1441. register TScreen *screen;
  1442. {
  1443.     register int i;
  1444.     XGCValues gcv;
  1445.      
  1446.  
  1447.     i = screen->Tbackground;
  1448.     screen->Tbackground = screen->Tforeground;
  1449.     screen->Tforeground = i;
  1450.     
  1451.     XSetForeground(screen->display, screen->TnormalGC, 
  1452.      screen->Tforeground);
  1453.     XSetBackground(screen->display, screen->TnormalGC, 
  1454.      screen->Tbackground);
  1455.  
  1456.     if (tekWidget) {
  1457.         if (tekWidget->core.border_pixel == screen->Tbackground) {
  1458.         tekWidget->core.border_pixel = screen->Tforeground;
  1459.         tekWidget->core.parent->core.border_pixel =
  1460.           screen->Tforeground;
  1461.         if (tekWidget->core.parent->core.window)
  1462.           XSetWindowBorder (screen->display,
  1463.                     tekWidget->core.parent->core.window,
  1464.                     tekWidget->core.border_pixel);
  1465.         }
  1466.     }
  1467.  
  1468.     for(i = 0 ; i < TEKNUMLINES ; i++) {
  1469.         XSetForeground(screen->display, screen->linepat[i], 
  1470.          screen->Tforeground);
  1471.     }
  1472.  
  1473.     screen->Tcursorcolor = screen->Tforeground;
  1474.  
  1475.     gcv.plane_mask = screen->xorplane = (screen->Tbackground ^
  1476.                          screen->Tcursorcolor);
  1477.     XChangeGC (screen->display, screen->TcursorGC, GCPlaneMask, &gcv);
  1478.     TekBackground(screen);
  1479. }
  1480.  
  1481. TekBackground(screen)
  1482. register TScreen *screen;
  1483. {
  1484.     if(TWindow(screen))
  1485.         XSetWindowBackground(screen->display, TWindow(screen), 
  1486.          screen->Tbackground);
  1487. }
  1488.  
  1489. /*
  1490.  * Toggles cursor on or off at cursor position in screen.
  1491.  */
  1492. TCursorToggle(toggle)
  1493.     int toggle;            /* TOGGLE or CLEAR */
  1494. {
  1495.     register TScreen *screen = &term->screen;
  1496.     register int c, x, y;
  1497.     unsigned int cellwidth, cellheight;
  1498.  
  1499.     if (!screen->Tshow) return;
  1500.  
  1501.     c = screen->cur.fontsize;
  1502.     cellwidth = (unsigned) tekWidget->tek.Tfont[c]->max_bounds.width;
  1503.     cellheight = (unsigned) (tekWidget->tek.Tfont[c]->ascent + 
  1504.                  tekWidget->tek.Tfont[c]->descent);
  1505.  
  1506.     x = (screen->cur_X * TekScale(screen)) + screen->border;
  1507.     y = ((TEKHEIGHT + TEKTOPPAD - screen->cur_Y) * TekScale(screen)) +
  1508.         screen->border - tekWidget->tek.tobaseline[c];
  1509.  
  1510.     if (toggle == TOGGLE) {
  1511.        if (screen->select || screen->always_highlight) 
  1512.            XFillRectangle(screen->display, TWindow(screen),
  1513.                   screen->TcursorGC, x, y,
  1514.                   cellwidth, cellheight);
  1515.        else { /* fix to use different GC! */
  1516.            XDrawRectangle(screen->display, TWindow(screen),
  1517.                   screen->TcursorGC, x, y,
  1518.                   cellwidth-1, cellheight-1);
  1519.        }
  1520.     } else {
  1521.         /* Clear the entire rectangle, even though we may only
  1522.          * have drawn an outline.  This fits with our refresh
  1523.          * scheme of redrawing the entire window on any expose
  1524.          * event and is easier than trying to figure out exactly
  1525.          * which part of the cursor needs to be erased.
  1526.          */
  1527.         XClearArea(screen->display, TWindow(screen), x, y,
  1528.                cellwidth, cellheight, FALSE);
  1529.     }
  1530. }
  1531.  
  1532. void TekSimulatePageButton (reset)
  1533.     Bool reset;
  1534. {
  1535.     register TScreen *screen = &term->screen;
  1536.  
  1537.     if (!tekWidget)
  1538.     return;
  1539.     if (reset) {
  1540. /*      bzero ((char *)&curmodes, sizeof(Tmodes));             */
  1541.     bzero ((char *) &screen->cur, sizeof screen->cur);
  1542.     }
  1543.     TekRefresh = (TekLink *)0;
  1544. /*    screen->cur = curmodes; */
  1545.     TekPage ();
  1546.     screen->cur_X = 0;
  1547.     screen->cur_Y = TEKHOME;
  1548. }
  1549.  
  1550.  
  1551. /* write copy of screen to a file */
  1552.  
  1553. TekCopy()
  1554. {
  1555.     register TekLink *Tp;
  1556.     register int tekcopyfd;
  1557.     register TScreen *screen = &term->screen;
  1558.     register struct tm *tp;
  1559.     long l;
  1560.     char buf[32];
  1561.  
  1562.     time(&l);
  1563.     tp = localtime(&l);
  1564.     sprintf(buf, "COPY%02d-%02d-%02d.%02d:%02d:%02d", tp->tm_year,
  1565.      tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);
  1566.     if(access(buf, F_OK) >= 0) {    /* file exists */
  1567.         if(access(buf, W_OK) < 0) {
  1568.             Bell();
  1569.             return;
  1570.         }
  1571.     } else if(access(".", W_OK) < 0) {    /* can't write in directory */
  1572.         Bell();
  1573.         return;
  1574.     }
  1575.     if((tekcopyfd = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
  1576.         Bell();
  1577.         return;
  1578.     }
  1579.     chown(buf, screen->uid, screen->gid);
  1580.     sprintf(buf, "\033%c\033%c", screen->page.fontsize + '8',
  1581.      screen->page.linetype + '`');
  1582.     write(tekcopyfd, buf, 4);
  1583.     Tp = &Tek0; 
  1584.     do {
  1585.         write(tekcopyfd, (char *)Tp->data, Tp->count);
  1586.         Tp = Tp->next;
  1587.     } while(Tp);
  1588.     close(tekcopyfd);
  1589. }
  1590.  
  1591.  
  1592.  
  1593.