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