root/foundation-apps/mxterm-maxx/Tekproc.c

Revision 8, 50.5 KB (checked in by emasson, 3 years ago)

initial import for the community edition

Line 
1/* $XTermId: Tekproc.c,v 1.159 2008/02/21 20:21:51 tom Exp $ */
2
3/*
4 * Warning, there be crufty dragons here.
5 */
6/* $XFree86: xc/programs/xterm/Tekproc.c,v 3.57 2006/02/13 01:14:57 dickey Exp $ */
7
8/*
9
10Copyright 2001-2007,2008 by Thomas E. Dickey
11
12                        All Rights Reserved
13
14Permission is hereby granted, free of charge, to any person obtaining a
15copy of this software and associated documentation files (the
16"Software"), to deal in the Software without restriction, including
17without limitation the rights to use, copy, modify, merge, publish,
18distribute, sublicense, and/or sell copies of the Software, and to
19permit persons to whom the Software is furnished to do so, subject to
20the following conditions:
21
22The above copyright notice and this permission notice shall be included
23in all copies or substantial portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
29CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
30TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
31SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
33Except as contained in this notice, the name(s) of the above copyright
34holders shall not be used in advertising or otherwise to promote the
35sale, use or other dealings in this Software without prior written
36authorization.
37
38Copyright 1988  The Open Group
39
40Permission to use, copy, modify, distribute, and sell this software and its
41documentation for any purpose is hereby granted without fee, provided that
42the above copyright notice appear in all copies and that both that
43copyright notice and this permission notice appear in supporting
44documentation.
45
46The above copyright notice and this permission notice shall be included in
47all copies or substantial portions of the Software.
48
49THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
52OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
53AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
54CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55
56Except as contained in this notice, the name of The Open Group shall not be
57used in advertising or otherwise to promote the sale, use or other dealings
58in this Software without prior written authorization from The Open Group.
59
60 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
61 *
62 *                         All Rights Reserved
63 *
64 * Permission to use, copy, modify, and distribute this software and its
65 * documentation for any purpose and without fee is hereby granted,
66 * provided that the above copyright notice appear in all copies and that
67 * both that copyright notice and this permission notice appear in
68 * supporting documentation, and that the name of Digital Equipment
69 * Corporation not be used in advertising or publicity pertaining to
70 * distribution of the software without specific, written prior permission.
71 *
72 *
73 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
74 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
75 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
76 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
77 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
78 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
79 * SOFTWARE.
80 */
81
82/* Tekproc.c */
83
84#define RES_OFFSET(field)       XtOffsetOf(TekWidgetRec, field)
85
86#include <xterm.h>
87
88#include <X11/Xatom.h>
89#include <X11/Xutil.h>
90#include <X11/cursorfont.h>
91#include <X11/Xmu/CharSet.h>
92
93#if OPT_TOOLBAR
94
95#if defined(HAVE_LIB_XAW)
96#include <X11/Xaw/Form.h>
97#elif defined(HAVE_LIB_XAW3D)
98#include <X11/Xaw3d/Form.h>
99#elif defined(HAVE_LIB_NEXTAW)
100#include <X11/neXtaw/Form.h>
101#elif defined(HAVE_LIB_XAWPLUS)
102#include <X11/XawPlus/Form.h>
103#endif
104
105#endif /* OPT_TOOLBAR */
106
107#include <stdio.h>
108#include <ctype.h>
109#include <signal.h>
110
111#include <Tekparse.h>
112#include <data.h>
113#include <error.h>
114#include <menu.h>
115
116#define DefaultGCID XGContextFromGC(DefaultGC(XtDisplay(tw), DefaultScreen(XtDisplay(tw))))
117
118/* Tek defines */
119
120#define DOTDASHEDLINE   2
121#define DOTTEDLINE      1
122#define EAST            01
123#define LINEMASK        07
124#define LONGDASHEDLINE  4
125#define MARGIN1         0
126#define MARGIN2         1
127#define MAX_PTS         150
128#define MAX_VTX         300
129#define NORTH           04
130#define PENDOWN         1
131#define PENUP           0
132#define SHORTDASHEDLINE 3
133#define SOLIDLINE       0
134#define SOUTH           010
135#define TEKBOTTOMPAD    23
136#define TEKDEFHEIGHT    565
137#define TEKDEFWIDTH     750
138#define TEKHEIGHT       3072
139#define TEKHOME         ( (TekChar[tekscr->page.fontsize].nlines - 1) \
140                         * TekChar[tekscr->page.fontsize].vsize)
141#define TEKMINHEIGHT    452
142#define TEKMINWIDTH     600
143#define TEKTOPPAD       34
144#define TEKWIDTH        4096
145#define WEST            02
146
147#define TekMove(tw,x,y) tekscr->cur_X = x; tekscr->cur_Y = y
148#define input()         Tinput(tw)
149#define unput(c)        *Tpushback++ = c
150/* *INDENT-OFF* */
151static struct Tek_Char {
152    int hsize;                  /* in Tek units */
153    int vsize;                  /* in Tek units */
154    int charsperline;
155    int nlines;
156} TekChar[TEKNUMFONTS] = {
157    {56, 88, 74, 35},           /* large */
158    {51, 82, 81, 38},           /* #2 */
159    {34, 53, 121, 58},          /* #3 */
160    {31, 48, 133, 64},          /* small */
161};
162/* *INDENT-ON* */
163
164static Cursor GINcursor;
165static XSegment *line_pt;
166static int nplot;
167static TekLink Tek0;
168static jmp_buf Tekjump;
169static TekLink *TekRecord;
170static XSegment *Tline;
171
172static Const int *curstate = Talptable;
173static Const int *Tparsestate = Talptable;
174
175static char defaultTranslations[] = "\
176                ~Meta<KeyPress>: insert-seven-bit() \n\
177                 Meta<KeyPress>: insert-eight-bit() \n\
178               !Ctrl <Btn1Down>: popup-menu(mainMenu) \n\
179          !Lock Ctrl <Btn1Down>: popup-menu(mainMenu) \n\
180!Lock Ctrl @Num_Lock <Btn1Down>: popup-menu(mainMenu) \n\
181     !Ctrl @Num_Lock <Btn1Down>: popup-menu(mainMenu) \n\
182               !Ctrl <Btn2Down>: popup-menu(tekMenu) \n\
183          !Lock Ctrl <Btn2Down>: popup-menu(tekMenu) \n\
184!Lock Ctrl @Num_Lock <Btn2Down>: popup-menu(tekMenu) \n\
185     !Ctrl @Num_Lock <Btn2Down>: popup-menu(tekMenu) \n\
186          Shift ~Meta<Btn1Down>: gin-press(L) \n\
187                ~Meta<Btn1Down>: gin-press(l) \n\
188          Shift ~Meta<Btn2Down>: gin-press(M) \n\
189                ~Meta<Btn2Down>: gin-press(m) \n\
190          Shift ~Meta<Btn3Down>: gin-press(R) \n\
191                ~Meta<Btn3Down>: gin-press(r)";
192/* *INDENT-OFF* */
193static XtActionsRec actionsList[] = {
194    { "string", HandleStringEvent },
195    { "insert", HandleKeyPressed },     /* alias for insert-seven-bit */
196    { "insert-seven-bit",       HandleKeyPressed },
197    { "insert-eight-bit",       HandleEightBitKeyPressed },
198    { "gin-press",              HandleGINInput },
199    { "secure",                 HandleSecure },
200    { "create-menu",            HandleCreateMenu },
201    { "popup-menu",             HandlePopupMenu },
202    /* menu actions */
203    { "allow-send-events",      HandleAllowSends },
204    { "set-visual-bell",        HandleSetVisualBell },
205#ifdef ALLOWLOGGING
206    { "set-logging",            HandleLogging },
207#endif
208    { "redraw",                 HandleRedraw },
209    { "send-signal",            HandleSendSignal },
210    { "quit",                   HandleQuit },
211    { "set-scrollbar",          HandleScrollbar },
212    { "set-jumpscroll",         HandleJumpscroll },
213    { "set-reverse-video",      HandleReverseVideo },
214    { "set-autowrap",           HandleAutoWrap },
215    { "set-reversewrap",        HandleReverseWrap },
216    { "set-autolinefeed",       HandleAutoLineFeed },
217    { "set-appcursor",          HandleAppCursor },
218    { "set-appkeypad",          HandleAppKeypad },
219    { "set-scroll-on-key",      HandleScrollKey },
220    { "set-scroll-on-tty-output", HandleScrollTtyOutput },
221    { "set-allow132",           HandleAllow132 },
222    { "set-cursesemul",         HandleCursesEmul },
223    { "set-marginbell",         HandleMarginBell },
224    { "set-altscreen",          HandleAltScreen },
225    { "soft-reset",             HandleSoftReset },
226    { "hard-reset",             HandleHardReset },
227    { "set-terminal-type",      HandleSetTerminalType },
228    { "set-visibility",         HandleVisibility },
229    { "set-tek-text",           HandleSetTekText },
230    { "tek-page",               HandleTekPage },
231    { "tek-reset",              HandleTekReset },
232    { "tek-copy",               HandleTekCopy },
233#if OPT_TOOLBAR
234    { "set-toolbar",            HandleToolbar },
235#endif
236};
237/* *INDENT-ON* */
238
239static Dimension defOne = 1;
240
241#define GIN_TERM_NONE_STR       "none"
242#define GIN_TERM_CR_STR         "CRonly"
243#define GIN_TERM_EOT_STR        "CR&EOT"
244
245#define GIN_TERM_NONE   0
246#define GIN_TERM_CR     1
247#define GIN_TERM_EOT    2
248
249#ifdef VMS
250#define DFT_FONT_SMALL "FIXED"
251#else
252#define DFT_FONT_SMALL "6x10"
253#endif
254
255static XtResource resources[] =
256{
257    {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
258     XtOffsetOf(CoreRec, core.width), XtRDimension, (caddr_t) & defOne},
259    {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
260     XtOffsetOf(CoreRec, core.height), XtRDimension, (caddr_t) & defOne},
261    Fres("fontLarge", XtCFont, tek.Tfont[TEK_FONT_LARGE], "9x15"),
262    Fres("font2", XtCFont, tek.Tfont[TEK_FONT_2], "6x13"),
263    Fres("font3", XtCFont, tek.Tfont[TEK_FONT_3], "8x13"),
264    Fres("fontSmall", XtCFont, tek.Tfont[TEK_FONT_SMALL], DFT_FONT_SMALL),
265    Sres(XtNinitialFont, XtCInitialFont, tek.initial_font, "large"),
266    Sres("ginTerminator", "GinTerminator", tek.gin_terminator_str, GIN_TERM_NONE_STR),
267#if OPT_TOOLBAR
268    Wres(XtNmenuBar, XtCMenuBar, tek.tb_info.menu_bar, 0),
269    Ires(XtNmenuHeight, XtCMenuHeight, tek.tb_info.menu_height, 25),
270#endif
271};
272
273static IChar Tinput(TekWidget /* tw */ );
274static int getpoint(TekWidget /* tw */ );
275static void TCursorBack(TekWidget /* tw */ );
276static void TCursorDown(TekWidget /* tw */ );
277static void TCursorForward(TekWidget /* tw */ );
278static void TCursorUp(TekWidget /* tw */ );
279static void TekBackground(TekWidget /* tw */ ,
280                          TScreen * /* screen */ );
281static void TekConfigure(Widget /* w */ );
282static void TekDraw(TekWidget /* tw */ ,
283                    int /* x */ ,
284                    int /* y */ );
285static void TekEnq(TekWidget /* tw */ ,
286                   unsigned /* status */ ,
287                   int /* x */ ,
288                   int /* y */ );
289static void TekFlush(TekWidget /* tw */ );
290static void TekInitialize(Widget /* request */ ,
291                          Widget /* wnew */ ,
292                          ArgList /* args */ ,
293                          Cardinal * /* num_args */ );
294static void TekPage(TekWidget /* tw */ );
295static void TekRealize(Widget /* gw */ ,
296                       XtValueMask * /* valuemaskp */ ,
297                       XSetWindowAttributes * /* values */ );
298
299static WidgetClassRec tekClassRec =
300{
301    {
302/* core_class fields */
303        (WidgetClass) & widgetClassRec,         /* superclass     */
304        "Tek4014",              /* class_name                   */
305        sizeof(TekWidgetRec),   /* widget_size                  */
306        NULL,                   /* class_initialize             */
307        NULL,                   /* class_part_initialize        */
308        False,                  /* class_inited                 */
309        TekInitialize,          /* initialize                   */
310        NULL,                   /* initialize_hook              */
311        TekRealize,             /* realize                      */
312        actionsList,            /* actions                      */
313        XtNumber(actionsList),  /* num_actions                  */
314        resources,              /* resources                    */
315        XtNumber(resources),    /* num_resources                */
316        NULLQUARK,              /* xrm_class                    */
317        True,                   /* compress_motion              */
318        True,                   /* compress_exposure            */
319        True,                   /* compress_enterleave          */
320        False,                  /* visible_interest             */
321        NULL,                   /* destroy                      */
322        TekConfigure,           /* resize                       */
323        TekExpose,              /* expose                       */
324        NULL,                   /* set_values                   */
325        NULL,                   /* set_values_hook              */
326        XtInheritSetValuesAlmost,       /* set_values_almost    */
327        NULL,                   /* get_values_hook              */
328        NULL,                   /* accept_focus                 */
329        XtVersion,              /* version                      */
330        NULL,                   /* callback_offsets             */
331        defaultTranslations,    /* tm_table                     */
332        XtInheritQueryGeometry, /* query_geometry               */
333        XtInheritDisplayAccelerator,    /* display_accelerator  */
334        NULL                    /* extension                    */
335    }
336};
337WidgetClass tekWidgetClass = (WidgetClass) & tekClassRec;
338
339static Bool Tfailed = False;
340
341int
342TekInit(void)
343{
344    Widget form_top, menu_top;
345    Dimension menu_high;
346
347    if (!Tfailed
348        && tekWidget == 0) {
349        Cardinal nargs = 0;
350        Arg myArgs[3];
351        Boolean iconic = 0;
352
353        TRACE(("TekInit\n"));
354        XtSetArg(myArgs[nargs], XtNiconic, &iconic);
355        ++nargs;
356        XtGetValues(toplevel, myArgs, nargs);
357
358        nargs = 0;
359        XtSetArg(myArgs[nargs], XtNiconic, iconic);
360        ++nargs;
361        XtSetArg(myArgs[nargs], XtNallowShellResize, True);
362        ++nargs;
363        XtSetArg(myArgs[nargs], XtNinput, True);
364        ++nargs;
365
366        /* this causes the Initialize method to be called */
367        tekshellwidget =
368            XtCreatePopupShell("tektronix", topLevelShellWidgetClass,
369                               toplevel, myArgs, nargs);
370
371        SetupMenus(tekshellwidget, &form_top, &menu_top, &menu_high);
372
373        /* this causes the Realize method to be called */
374        tekWidget = (TekWidget)
375            XtVaCreateManagedWidget("tek4014",
376                                    tekWidgetClass, form_top,
377#if OPT_TOOLBAR
378                                    XtNmenuBar, menu_top,
379                                    XtNresizable, True,
380                                    XtNfromVert, menu_top,
381                                    XtNtop, XawChainTop,
382                                    XtNleft, XawChainLeft,
383                                    XtNright, XawChainRight,
384                                    XtNbottom, XawChainBottom,
385                                    XtNmenuHeight, menu_high,
386#endif
387                                    (XtPointer) 0);
388#if OPT_TOOLBAR
389        ShowToolbar(resource.toolBar);
390#endif
391    }
392    return (!Tfailed);
393}
394
395/*
396 * If we haven't allocated the PtyData struct, do so.
397 */
398int
399TekPtyData(void)
400{
401    if (Tpushb == 0) {
402        if ((Tpushb = TypeMallocN(Char, 10)) == NULL
403            || (Tline = TypeMallocN(XSegment, MAX_VTX)) == NULL) {
404            fprintf(stderr, "%s: Not enough core for Tek mode\n", xterm_name);
405            if (Tpushb)
406                free(Tpushb);
407            Tfailed = True;
408            return 0;
409        }
410    }
411    return 1;
412}
413
414static void
415Tekparse(TekWidget tw)
416{
417    TScreen *screen = TScreenOf(term);
418    TekScreen *tekscr = TekScreenOf(tw);
419    int x, y;
420    IChar c = 0;
421    IChar ch;
422    int nextstate;
423
424    for (;;) {
425        c = input();
426        /*
427         * The parsing tables all have 256 entries.  If we're supporting
428         * wide characters, we handle them by treating them the same as
429         * printing characters.
430         */
431#if OPT_WIDE_CHARS
432        if (c > 255) {
433            nextstate = (Tparsestate == Talptable)
434                ? CASE_PRINT
435                : CASE_IGNORE;
436        } else
437#endif
438            nextstate = Tparsestate[c];
439        TRACE(("Tekparse %04X -> %d\n", c, nextstate));
440
441        switch (nextstate) {
442        case CASE_REPORT:
443            TRACE(("case: report address\n"));
444            if (tekscr->TekGIN) {
445                TekGINoff(tw);
446                TekEnqMouse(tw, 0);
447            } else {
448                c = 064;        /* has hard copy unit */
449                if (tekscr->margin == MARGIN2)
450                    c |= 02;
451                TekEnq(tw, c, tekscr->cur_X, tekscr->cur_Y);
452            }
453            TekRecord->ptr[-1] = ANSI_NAK;      /* remove from recording */
454            Tparsestate = curstate;
455            break;
456
457        case CASE_VT_MODE:
458            TRACE(("case: special return to vt102 mode\n"));
459            Tparsestate = curstate;
460            TekRecord->ptr[-1] = ANSI_NAK;      /* remove from recording */
461            FlushLog(&(term->screen));
462            return;
463
464        case CASE_SPT_STATE:
465            TRACE(("case: Enter Special Point Plot mode\n"));
466            if (tekscr->TekGIN)
467                TekGINoff(tw);
468            Tparsestate = curstate = Tspttable;
469            break;
470
471        case CASE_GIN:
472            TRACE(("case: Do Tek GIN mode\n"));
473            tekscr->TekGIN = &TekRecord->ptr[-1];
474            /* Set cross-hair cursor raster array */
475            if ((GINcursor =
476                 make_colored_cursor(XC_tcross,
477                                     T_COLOR(screen, MOUSE_FG),
478                                     T_COLOR(screen, MOUSE_BG))) != 0) {
479                XDefineCursor(XtDisplay(tw), TWindow(tekscr),
480                              GINcursor);
481            }
482            Tparsestate = Tbyptable;    /* Bypass mode */
483            break;
484
485        case CASE_BEL:
486            TRACE(("case: BEL\n"));
487            if (tekscr->TekGIN)
488                TekGINoff(tw);
489            if (!tekRefreshList)
490                Bell(XkbBI_TerminalBell, 0);
491            Tparsestate = curstate;     /* clear bypass condition */
492            break;
493
494        case CASE_BS:
495            TRACE(("case: BS\n"));
496            if (tekscr->TekGIN)
497                TekGINoff(tw);
498            Tparsestate = curstate;     /* clear bypass condition */
499            TCursorBack(tw);
500            break;
501
502        case CASE_PT_STATE:
503            TRACE(("case: Enter Tek Point Plot mode\n"));
504            if (tekscr->TekGIN)
505                TekGINoff(tw);
506            Tparsestate = curstate = Tpttable;
507            break;
508
509        case CASE_PLT_STATE:
510            TRACE(("case: Enter Tek Plot mode\n"));
511            if (tekscr->TekGIN)
512                TekGINoff(tw);
513            Tparsestate = curstate = Tplttable;
514            if ((c = input()) == ANSI_BEL)
515                tekscr->pen = PENDOWN;
516            else {
517                unput(c);
518                tekscr->pen = PENUP;
519            }
520            break;
521
522        case CASE_TAB:
523            TRACE(("case: HT\n"));
524            if (tekscr->TekGIN)
525                TekGINoff(tw);
526            Tparsestate = curstate;     /* clear bypass condition */
527            TCursorForward(tw);
528            break;
529
530        case CASE_IPL_STATE:
531            TRACE(("case: Enter Tek Incremental Plot mode\n"));
532            if (tekscr->TekGIN)
533                TekGINoff(tw);
534            Tparsestate = curstate = Tipltable;
535            break;
536
537        case CASE_ALP_STATE:
538            TRACE(("case: Enter Tek Alpha mode from any other mode\n"));
539            if (tekscr->TekGIN)
540                TekGINoff(tw);
541            /* if in one of graphics states, move alpha cursor */
542            if (nplot > 0)      /* flush line VTbuffer */
543                TekFlush(tw);
544            Tparsestate = curstate = Talptable;
545            break;
546
547        case CASE_UP:
548            TRACE(("case: cursor up\n"));
549            if (tekscr->TekGIN)
550                TekGINoff(tw);
551            Tparsestate = curstate;     /* clear bypass condition */
552            TCursorUp(tw);
553            break;
554
555        case CASE_COPY:
556            TRACE(("case: make copy\n"));
557            if (tekscr->TekGIN)
558                TekGINoff(tw);
559            TekCopy(tw);
560            TekRecord->ptr[-1] = ANSI_NAK;      /* remove from recording */
561            Tparsestate = curstate;     /* clear bypass condition */
562            break;
563
564        case CASE_PAGE:
565            TRACE(("case: Page Function\n"));
566            if (tekscr->TekGIN)
567                TekGINoff(tw);
568            TekPage(tw);        /* clear bypass condition */
569            break;
570
571        case CASE_BES_STATE:
572            TRACE(("case: Byp: an escape char\n"));
573            Tparsestate = Tbestable;
574            break;
575
576        case CASE_BYP_STATE:
577            TRACE(("case: set bypass condition\n"));
578            Tparsestate = Tbyptable;
579            break;
580
581        case CASE_IGNORE:
582            TRACE(("case: Esc: totally ignore CR, ESC, LF, ~\n"));
583            break;
584
585        case CASE_ASCII:
586            TRACE(("case: Select ASCII char set\n"));
587            /* ignore for now */
588            Tparsestate = curstate;
589            break;
590
591        case CASE_APL:
592            TRACE(("case: Select APL char set\n"));
593            /* ignore for now */
594            Tparsestate = curstate;
595            break;
596
597        case CASE_CHAR_SIZE:
598            TRACE(("case: character size selector\n"));
599            TekSetFontSize(tw, (int) (c & 03));
600            Tparsestate = curstate;
601            break;
602
603        case CASE_BEAM_VEC:
604            TRACE(("case: beam and vector selector\n"));
605            /* only line types */
606            if ((c &= LINEMASK) != tekscr->cur.linetype) {
607                if (nplot > 0)
608                    TekFlush(tw);
609                if (c <= TEKNUMLINES)
610                    tekscr->cur.linetype = c;
611            }
612            Tparsestate = curstate;
613            break;
614
615        case CASE_CURSTATE:
616            Tparsestate = curstate;
617            break;
618
619        case CASE_PENUP:
620            TRACE(("case: Ipl: penup\n"));
621            tekscr->pen = PENUP;
622            break;
623
624        case CASE_PENDOWN:
625            TRACE(("case: Ipl: pendown\n"));
626            tekscr->pen = PENDOWN;
627            break;
628
629        case CASE_IPL_POINT:
630            TRACE(("case: Ipl: point\n"));
631            x = tekscr->cur_X;
632            y = tekscr->cur_Y;
633            if (c & NORTH)
634                y++;
635            else if (c & SOUTH)
636                y--;
637            if (c & EAST)
638                x++;
639            else if (c & WEST)
640                x--;
641            if (tekscr->pen == PENDOWN)
642                TekDraw(tw, x, y);
643            else
644                TekMove(tw, x, y);
645            break;
646
647        case CASE_PLT_VEC:
648            TRACE(("case: Plt: vector\n"));
649            unput(c);
650            if (getpoint(tw)) {
651                if (tekscr->pen == PENDOWN) {
652                    TekDraw(tw, tekscr->cur.x, tekscr->cur.y);
653                } else {
654                    TekMove(tw, tekscr->cur.x, tekscr->cur.y);
655                }
656                tekscr->pen = PENDOWN;
657            }
658            break;
659
660        case CASE_PT_POINT:
661            TRACE(("case: Pt: point\n"));
662            unput(c);
663            if (getpoint(tw)) {
664                TekMove(tw, tekscr->cur.x, tekscr->cur.y);
665                TekDraw(tw, tekscr->cur.x, tekscr->cur.y);
666            }
667            break;
668
669        case CASE_SPT_POINT:
670            TRACE(("case: Spt: point\n"));
671            /* ignore intensity character in c */
672            if (getpoint(tw)) {
673                TekMove(tw, tekscr->cur.x, tekscr->cur.y);
674                TekDraw(tw, tekscr->cur.x, tekscr->cur.y);
675            }
676            break;
677
678        case CASE_CR:
679            TRACE(("case: CR\n"));
680            if (tekscr->TekGIN)
681                TekGINoff(tw);
682            if (nplot > 0)      /* flush line VTbuffer */
683                TekFlush(tw);
684            tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 :
685                TEKWIDTH / 2;
686            Tparsestate = curstate = Talptable;
687            break;
688
689        case CASE_ESC_STATE:
690            TRACE(("case: ESC\n"));
691            Tparsestate = Tesctable;
692            break;
693
694        case CASE_LF:
695            TRACE(("case: LF\n"));
696            if (tekscr->TekGIN)
697                TekGINoff(tw);
698            TCursorDown(tw);
699            if (!tekRefreshList)
700                do_xevents();
701            break;
702
703        case CASE_SP:
704            TRACE(("case: SP\n"));
705            TCursorForward(tw);
706            break;
707
708        case CASE_PRINT:
709            TRACE(("case: printable character\n"));
710            ch = c;
711            c = tekscr->cur.fontsize;
712            x = (int) (tekscr->cur_X * TekScale(tekscr))
713                + screen->border;
714            y = (int) ((TEKHEIGHT + TEKTOPPAD - tekscr->cur_Y) * TekScale(tekscr))
715                + screen->border;
716
717#if OPT_WIDE_CHARS
718            if (screen->wide_chars
719                && (ch > 255)) {
720                XChar2b sbuf;
721                sbuf.byte2 = LO_BYTE(ch);
722                sbuf.byte1 = HI_BYTE(ch);
723                XDrawImageString16(XtDisplay(tw),
724                                   TWindow(tekscr),
725                                   tekscr->TnormalGC,
726                                   x,
727                                   y,
728                                   &sbuf,
729                                   1);
730            } else
731#endif
732            {
733                char ch2 = (char) ch;
734                XDrawString(XtDisplay(tw),
735                            TWindow(tekscr),
736                            tekscr->TnormalGC,
737                            x,
738                            y,
739                            &ch2,
740                            1);
741            }
742            TCursorForward(tw);
743            break;
744        case CASE_OSC:
745            /* FIXME:  someone should disentangle the input queues
746             * of this code so that it can be state-driven.
747             */
748            TRACE(("case: do osc escape\n"));
749            {
750                /*
751                 * do_osc() can call TekExpose(), which calls TekRefresh(),
752                 * and sends us recurring here - don't do that...
753                 */
754                static int nested;
755
756                Char buf2[512];
757                IChar c2;
758                unsigned len = 0;
759                while ((c2 = input()) != ANSI_BEL) {
760                    if (!isprint(c2 & 0x7f)
761                        || len + 2 >= (int) sizeof(buf2))
762                        break;
763                    buf2[len++] = c2;
764                }
765                buf2[len] = 0;
766                if (!nested++) {
767                    if (c2 == ANSI_BEL)
768                        do_osc(term, buf2, len, ANSI_BEL);
769                }
770                --nested;
771            }
772            Tparsestate = curstate;
773            break;
774        }
775    }
776}
777
778static int rcnt;
779static char *rptr;
780static PtySelect Tselect_mask;
781
782static IChar
783Tinput(TekWidget tw)
784{
785    TekScreen *tekscr = TekScreenOf(tw);
786    TScreen *screen = TScreenOf(term);
787    TekLink *tek;
788
789    if (Tpushback > Tpushb)
790        return (*--Tpushback);
791    if (tekRefreshList) {
792        if (rcnt-- > 0)
793            return (*rptr++);
794        if ((tek = tekRefreshList->next) != 0) {
795            tekRefreshList = tek;
796            rptr = tek->data;
797            rcnt = tek->count - 1;
798            TekSetFontSize(tw, tek->fontsize);
799            return (*rptr++);
800        }
801        tekRefreshList = (TekLink *) 0;
802        longjmp(Tekjump, 1);
803    }
804  again:
805    if (VTbuffer->next >= VTbuffer->last) {
806        int update = VTbuffer->update;
807
808        if (nplot > 0)          /* flush line */
809            TekFlush(tw);
810#ifdef VMS
811        Tselect_mask = pty_mask;        /* force a read */
812#else /* VMS */
813        XFD_COPYSET(&pty_mask, &Tselect_mask);
814#endif /* VMS */
815        for (;;) {
816#ifdef CRAY
817            struct timeval crocktimeout;
818            crocktimeout.tv_sec = 0;
819            crocktimeout.tv_usec = 0;
820            (void) Select(max_plus1,
821                          &Tselect_mask, NULL, NULL,
822                          &crocktimeout);
823#endif
824            if (readPtyData(screen, &Tselect_mask, VTbuffer)) {
825                break;
826            }
827            if (Ttoggled && curstate == Talptable) {
828                TCursorToggle(tw, TOGGLE);
829                Ttoggled = False;
830            }
831            if (XtAppPending(app_con) & XtIMXEvent) {
832#ifdef VMS
833                Tselect_mask = X_mask;
834#else /* VMS */
835                XFD_COPYSET(&X_mask, &Tselect_mask);
836#endif /* VMS */
837            } else {
838                XFlush(XtDisplay(tw));
839#ifdef VMS
840                Tselect_mask = Select_mask;
841
842#else /* VMS */
843                XFD_COPYSET(&Select_mask, &Tselect_mask);
844                if (Select(max_plus1, &Tselect_mask, NULL, NULL, NULL) < 0) {
845                    if (errno != EINTR)
846                        SysError(ERROR_TSELECT);
847                    continue;
848                }
849#endif /* VMS */
850            }
851#ifdef VMS
852            if (Tselect_mask & X_mask) {
853                xevents();
854                if (VTbuffer->update != update)
855                    goto again;
856            }
857#else /* VMS */
858            if (FD_ISSET(ConnectionNumber(XtDisplay(tw)), &Tselect_mask)) {
859                xevents();
860                if (VTbuffer->update != update)
861                    goto again;
862            }
863#endif /* VMS */
864        }
865        if (!Ttoggled && curstate == Talptable) {
866            TCursorToggle(tw, TOGGLE);
867            Ttoggled = True;
868        }
869    }
870    tek = TekRecord;
871    if (tek->count >= TEK_LINK_BLOCK_SIZE
872        || tek->fontsize != tekscr->cur.fontsize) {
873        if ((TekRecord = tek->next = CastMalloc(TekLink)) == 0)
874            Panic("Tinput: malloc error (%d)\n", errno);
875        tek = tek->next;
876        tek->next = (TekLink *) 0;
877        tek->fontsize = tekscr->cur.fontsize;
878        tek->count = 0;
879        tek->ptr = tek->data;
880    }
881    tek->count++;
882
883    (void) morePtyData(screen, VTbuffer);
884    return (*tek->ptr++ = nextPtyData(screen, VTbuffer));
885}
886
887static void
888TekClear(TekWidget tw)
889{
890    TekScreen *tekscr = TekScreenOf(tw);
891
892    if (TWindow(tekscr))
893        XClearWindow(XtDisplay(tw), TWindow(tekscr));
894}
895
896/* this should become the Tek Widget's Resize proc */
897static void
898TekConfigure(Widget w)
899{
900    if (IsTekWidget(w)) {
901        TekWidget tw = (TekWidget) w;
902        TekScreen *tekscr = TekScreenOf(tw);
903        TScreen *screen = TScreenOf(term);
904        int border = 2 * screen->border;
905        double d;
906
907        TekClear(tw);
908        TWidth(tekscr) = w->core.width - border;
909        THeight(tekscr) = w->core.height - border;
910        TekScale(tekscr) = (double) TWidth(tekscr) / TEKWIDTH;
911        if ((d = (double) THeight(tekscr) / (TEKHEIGHT + TEKTOPPAD + TEKBOTTOMPAD))
912            < TekScale(tekscr))
913            TekScale(tekscr) = d;
914        TFullWidth(tekscr) = w->core.width;
915        TFullHeight(tekscr) = w->core.height;
916    }
917}
918
919/*ARGSUSED*/
920void
921TekExpose(Widget w,
922          XEvent * event GCC_UNUSED,
923          Region region GCC_UNUSED)
924{
925    if (IsTekWidget(w)) {
926        TekWidget tw = (TekWidget) w;
927        TekScreen *tekscr = TekScreenOf(tw);
928
929        TRACE(("TekExpose\n"));
930
931#ifdef lint
932        region = region;
933#endif
934        if (!Ttoggled)
935            TCursorToggle(tw, CLEAR);
936        Ttoggled = True;
937        Tpushback = Tpushb;
938        tekscr->cur_X = 0;
939        tekscr->cur_Y = TEKHOME;
940        TekSetFontSize(tw, tekscr->page.fontsize);
941        tekscr->cur = tekscr->page;
942        tekscr->margin = MARGIN1;
943        if (tekscr->TekGIN) {
944            tekscr->TekGIN = NULL;
945            TekGINoff(tw);
946        }
947        tekRefreshList = &Tek0;
948        rptr = tekRefreshList->data;
949        rcnt = tekRefreshList->count;
950        Tparsestate = curstate = Talptable;
951        TRACE(("TekExpose resets data to replay %d bytes\n", rcnt));
952        first_map_occurred();
953        if (!tekscr->waitrefresh)
954            TekRefresh(tw);
955    }
956}
957
958void
959TekRefresh(TekWidget tw)
960{
961    if (tw != 0) {
962        TekScreen *tekscr = TekScreenOf(tw);
963        TScreen *screen = TScreenOf(term);
964        static Cursor wait_cursor = None;
965
966        if (wait_cursor == None)
967            wait_cursor = make_colored_cursor(XC_watch,
968                                              T_COLOR(screen, MOUSE_FG),
969                                              T_COLOR(screen, MOUSE_BG));
970        XDefineCursor(XtDisplay(tw), TWindow(tekscr), wait_cursor);
971        XFlush(XtDisplay(tw));
972        if (!setjmp(Tekjump))
973            Tekparse(tw);
974        XDefineCursor(XtDisplay(tw), TWindow(tekscr),
975                      (tekscr->TekGIN && GINcursor) ? GINcursor : tekscr->arrow);
976    }
977}
978
979void
980TekRepaint(TekWidget tw)
981{
982    TekClear(tw);
983    TekExpose((Widget) tw, (XEvent *) NULL, (Region) NULL);
984}
985
986static void
987TekPage(TekWidget tw)
988{
989    TekScreen *tekscr = TekScreenOf(tw);
990    TekLink *tek;
991
992    TekClear(tw);
993    tekscr->cur_X = 0;
994    tekscr->cur_Y = TEKHOME;
995    tekscr->margin = MARGIN1;
996    tekscr->page = tekscr->cur;
997    if (tekscr->TekGIN)
998        TekGINoff(tw);
999    tek = TekRecord = &Tek0;
1000    tek->fontsize = tekscr->cur.fontsize;
1001    tek->count = 0;
1002    tek->ptr = tek->data;
1003    tek = tek->next;
1004    if (tek)
1005        do {
1006            TekLink *tek2 = tek->next;
1007
1008            free(tek);
1009            tek = tek2;
1010        } while (tek);
1011    TekRecord->next = (TekLink *) 0;
1012    tekRefreshList = (TekLink *) 0;
1013    Ttoggled = True;
1014    Tparsestate = curstate = Talptable;         /* Tek Alpha mode */
1015}
1016
1017#define EXTRABITS       017
1018#define FIVEBITS        037
1019#define HIBITS          (FIVEBITS << SHIFTHI)
1020#define LOBITS          (FIVEBITS << SHIFTLO)
1021#define SHIFTHI         7
1022#define SHIFTLO         2
1023#define TWOBITS         03
1024
1025static int
1026getpoint(TekWidget tw)
1027{
1028    int c, x, y, e, lo_y = 0;
1029    TekScreen *tekscr = TekScreenOf(tw);
1030
1031    x = tekscr->cur.x;
1032    y = tekscr->cur.y;
1033    for (;;) {
1034        if ((c = input()) < ' ') {      /* control character */
1035            unput(c);
1036            return (0);
1037        }
1038        if (c < '@') {          /* Hi X or Hi Y */
1039            if (lo_y) {         /* seen a Lo Y, so this must be Hi X */
1040                x &= ~HIBITS;
1041                x |= (c & FIVEBITS) << SHIFTHI;
1042                continue;
1043            }
1044            /* else Hi Y */
1045            y &= ~HIBITS;
1046            y |= (c & FIVEBITS) << SHIFTHI;
1047            continue;
1048        }
1049        if (c < '`') {          /* Lo X */
1050            x &= ~LOBITS;
1051            x |= (c & FIVEBITS) << SHIFTLO;
1052            tekscr->cur.x = x;
1053            tekscr->cur.y = y;
1054            return (1);         /* OK */
1055        }
1056        /* else Lo Y */
1057        if (lo_y) {             /* seen a Lo Y, so other must be extra bits */
1058            e = (y >> SHIFTLO) & EXTRABITS;
1059            x &= ~TWOBITS;
1060            x |= e & TWOBITS;
1061            y &= ~TWOBITS;
1062            y |= (e >> SHIFTLO) & TWOBITS;
1063        }
1064        y &= ~LOBITS;
1065        y |= (c & FIVEBITS) << SHIFTLO;
1066        lo_y++;
1067    }
1068}
1069
1070static void
1071TCursorBack(TekWidget tw)
1072{
1073    TekScreen *tekscr = TekScreenOf(tw);
1074    struct Tek_Char *t;
1075    int x, l;
1076
1077    x = (tekscr->cur_X -=
1078         (t = &TekChar[tekscr->cur.fontsize])->hsize
1079        );
1080
1081    if (((tekscr->margin == MARGIN1) && (x < 0))
1082        || ((tekscr->margin == MARGIN2) && (x < TEKWIDTH / 2))) {
1083        if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >=
1084            t->nlines) {
1085            tekscr->margin = !tekscr->margin;
1086            l = 0;
1087        }
1088        tekscr->cur_Y = l * t->vsize;
1089        tekscr->cur_X = (t->charsperline - 1) * t->hsize;
1090    }
1091}
1092
1093static void
1094TCursorForward(TekWidget tw)
1095{
1096    TekScreen *tekscr = TekScreenOf(tw);
1097    struct Tek_Char *t;
1098    int l;
1099
1100    if ((tekscr->cur_X +=
1101         (t = &TekChar[tekscr->cur.fontsize])->hsize
1102        ) > TEKWIDTH
1103        ) {
1104        if ((l = tekscr->cur_Y / t->vsize - 1) < 0) {
1105            tekscr->margin = !tekscr->margin;
1106            l = t->nlines - 1;
1107        }
1108        tekscr->cur_Y = l * t->vsize;
1109        tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 : TEKWIDTH / 2;
1110    }
1111}
1112
1113static void
1114TCursorUp(TekWidget tw)
1115{
1116    TekScreen *tekscr = TekScreenOf(tw);
1117    struct Tek_Char *t;
1118    int l;
1119
1120    t = &TekChar[tekscr->cur.fontsize];
1121
1122    if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= t->nlines) {
1123        l = 0;
1124        if ((tekscr->margin = !tekscr->margin) != MARGIN1) {
1125            if (tekscr->cur_X < TEKWIDTH / 2)
1126                tekscr->cur_X += TEKWIDTH / 2;
1127        } else if (tekscr->cur_X >= TEKWIDTH / 2)
1128            tekscr->cur_X -= TEKWIDTH / 2;
1129    }
1130    tekscr->cur_Y = l * t->vsize;
1131}
1132
1133static void
1134TCursorDown(TekWidget tw)
1135{
1136    TekScreen *tekscr = TekScreenOf(tw);
1137    struct Tek_Char *t;
1138    int l;
1139
1140    t = &TekChar[tekscr->cur.fontsize];
1141
1142    if ((l = tekscr->cur_Y / t->vsize - 1) < 0) {
1143        l = t->nlines - 1;
1144        if ((tekscr->margin = !tekscr->margin) != MARGIN1) {
1145            if (tekscr->cur_X < TEKWIDTH / 2)
1146                tekscr->cur_X += TEKWIDTH / 2;
1147        } else if (tekscr->cur_X >= TEKWIDTH / 2)
1148            tekscr->cur_X -= TEKWIDTH / 2;
1149    }
1150    tekscr->cur_Y = l * t->vsize;
1151}
1152
1153static void
1154AddToDraw(TekWidget tw, int x1, int y1, int x2, int y2)
1155{
1156    TekScreen *tekscr = TekScreenOf(tw);
1157    TScreen *screen = TScreenOf(term);
1158    XSegment *lp;
1159
1160    TRACE(("AddToDraw (%d,%d) (%d,%d)\n", x1, y1, x2, y2));
1161    if (nplot >= MAX_PTS) {
1162        TekFlush(tw);
1163    }
1164    lp = line_pt++;
1165    lp->x1 = x1 = (int) (x1 * TekScale(tekscr) + screen->border);
1166    lp->y1 = y1 = (int) ((TEKHEIGHT + TEKTOPPAD - y1) * TekScale(tekscr) +
1167                         screen->border);
1168    lp->x2 = x2 = (int) (x2 * TekScale(tekscr) + screen->border);
1169    lp->y2 = y2 = (int) ((TEKHEIGHT + TEKTOPPAD - y2) * TekScale(tekscr) +
1170                         screen->border);
1171    nplot++;
1172    TRACE(("...AddToDraw %d points\n", nplot));
1173}
1174
1175static void
1176TekDraw(TekWidget tw, int x, int y)
1177{
1178    TekScreen *tekscr = TekScreenOf(tw);
1179
1180    if (nplot == 0 || T_lastx != tekscr->cur_X || T_lasty != tekscr->cur_Y) {
1181        /*
1182         * We flush on each unconnected line segment if the line
1183         * type is not solid.  This solves a bug in X when drawing
1184         * points while the line type is not solid.
1185         */
1186        if (nplot > 0 && tekscr->cur.linetype != SOLIDLINE)
1187            TekFlush(tw);
1188    }
1189    AddToDraw(tw, tekscr->cur_X, tekscr->cur_Y, x, y);
1190    T_lastx = tekscr->cur_X = x;
1191    T_lasty = tekscr->cur_Y = y;
1192}
1193
1194static void
1195TekFlush(TekWidget tw)
1196{
1197    TekScreen *tekscr = TekScreenOf(tw);
1198
1199    TRACE(("TekFlush\n"));
1200    XDrawSegments(XtDisplay(tw), TWindow(tekscr),
1201                  ((tekscr->cur.linetype == SOLIDLINE)
1202                   ? tekscr->TnormalGC
1203                   : tekscr->linepat[tekscr->cur.linetype - 1]),
1204                  Tline, nplot);
1205    nplot = 0;
1206    line_pt = Tline;
1207}
1208
1209void
1210TekGINoff(TekWidget tw)
1211{
1212    TekScreen *tekscr = TekScreenOf(tw);
1213
1214    TRACE(("TekGINoff\n"));
1215    XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow);
1216    if (GINcursor)
1217        XFreeCursor(XtDisplay(tw), GINcursor);
1218    if (tekscr->TekGIN) {
1219        *tekscr->TekGIN = ANSI_CAN;     /* modify recording */
1220        tekscr->TekGIN = NULL;
1221    }
1222}
1223
1224void
1225TekEnqMouse(TekWidget tw, int c)        /* character pressed */
1226{
1227    TekScreen *tekscr = TekScreenOf(tw);
1228    TScreen *screen = TScreenOf(term);
1229    int mousex, mousey, rootx, rooty;
1230    unsigned int mask;          /* XQueryPointer */
1231    Window root, subw;
1232
1233    TRACE(("TekEnqMouse\n"));
1234    XQueryPointer(
1235                     XtDisplay(tw), TWindow(tekscr),
1236                     &root, &subw,
1237                     &rootx, &rooty,
1238                     &mousex, &mousey,
1239                     &mask);
1240    if ((mousex = (int) ((mousex - screen->border) / TekScale(tekscr))) < 0)
1241        mousex = 0;
1242    else if (mousex >= TEKWIDTH)
1243        mousex = TEKWIDTH - 1;
1244    if ((mousey = (int) (TEKHEIGHT + TEKTOPPAD - (mousey - screen->border) /
1245                         TekScale(tekscr))) < 0)
1246        mousey = 0;
1247    else if (mousey >= TEKHEIGHT)
1248        mousey = TEKHEIGHT - 1;
1249    TekEnq(tw, (unsigned) c, mousex, mousey);
1250}
1251
1252static void
1253TekEnq(TekWidget tw,
1254       unsigned status,
1255       int x,
1256       int y)
1257{
1258    TekScreen *tekscr = TekScreenOf(tw);
1259    TScreen *screen = TScreenOf(term);
1260    Char cplot[7];
1261    int len = 5;
1262    int adj = (status != 0) ? 0 : 1;
1263
1264    TRACE(("TekEnq\n"));
1265    cplot[0] = status;
1266    /* Translate x and y to Tektronix code */
1267    cplot[1] = 040 | ((x >> SHIFTHI) & FIVEBITS);
1268    cplot[2] = 040 | ((x >> SHIFTLO) & FIVEBITS);
1269    cplot[3] = 040 | ((y >> SHIFTHI) & FIVEBITS);
1270    cplot[4] = 040 | ((y >> SHIFTLO) & FIVEBITS);
1271
1272    if (tekscr->gin_terminator != GIN_TERM_NONE)
1273        cplot[len++] = '\r';
1274    if (tekscr->gin_terminator == GIN_TERM_EOT)
1275        cplot[len++] = '\004';
1276#ifdef VMS
1277    tt_write(cplot + adj, len - adj);
1278#else /* VMS */
1279    v_write(screen->respond, cplot + adj, (unsigned) (len - adj));
1280#endif /* VMS */
1281}
1282
1283void
1284TekRun(void)
1285{
1286    if (tekWidget == 0) {
1287        TekInit();
1288    }
1289    if (tekWidget != 0) {
1290        TRACE(("TekRun ...\n"));
1291
1292        if (!TEK4014_SHOWN(term)) {
1293            set_tek_visibility(True);
1294        }
1295        update_vttekmode();
1296        update_vtshow();
1297        update_tekshow();
1298        set_tekhide_sensitivity();
1299
1300        Tpushback = Tpushb;
1301        Ttoggled = True;
1302        if (!setjmp(Tekend))
1303            Tekparse(tekWidget);
1304        if (!Ttoggled) {
1305            TCursorToggle(tekWidget, TOGGLE);
1306            Ttoggled = True;
1307        }
1308        TEK4014_ACTIVE(term) = False;
1309    } else {
1310        TEK4014_ACTIVE(term) = False;
1311        if (VWindow(&(term->screen)) == 0) {
1312            Exit(ERROR_TINIT);
1313        }
1314    }
1315}
1316
1317#define DOTTED_LENGTH 2
1318#define DOT_DASHED_LENGTH 4
1319#define SHORT_DASHED_LENGTH 2
1320#define LONG_DASHED_LENGTH 2
1321
1322static int dash_length[TEKNUMLINES] =
1323{
1324    DOTTED_LENGTH,
1325    DOT_DASHED_LENGTH,
1326    SHORT_DASHED_LENGTH,
1327    LONG_DASHED_LENGTH,
1328};
1329
1330static unsigned char dotted[DOTTED_LENGTH] =
1331{3, 1};
1332static unsigned char dot_dashed[DOT_DASHED_LENGTH] =
1333{3, 4, 3, 1};
1334static unsigned char short_dashed[SHORT_DASHED_LENGTH] =
1335{4, 4};
1336static unsigned char long_dashed[LONG_DASHED_LENGTH] =
1337{4, 7};
1338
1339static unsigned char *dashes[TEKNUMLINES] =
1340{
1341    dotted,
1342    dot_dashed,
1343    short_dashed,
1344    long_dashed,
1345};
1346
1347/*
1348 * The following is called to create the tekWidget
1349 */
1350
1351static void
1352TekInitialize(Widget request GCC_UNUSED,
1353              Widget wnew GCC_UNUSED,
1354              ArgList args GCC_UNUSED,
1355              Cardinal *num_args GCC_UNUSED)
1356{
1357    Widget tekparent = SHELL_OF(wnew);
1358
1359    TRACE(("TekInitialize\n"));
1360
1361    /* look for focus related events on the shell, because we need
1362     * to care about the shell's border being part of our focus.
1363     */
1364    XtAddEventHandler(tekparent, EnterWindowMask, False,
1365                      HandleEnterWindow, (Opaque) 0);
1366    XtAddEventHandler(tekparent, LeaveWindowMask, False,
1367                      HandleLeaveWindow, (Opaque) 0);
1368    XtAddEventHandler(tekparent, FocusChangeMask, False,
1369                      HandleFocusChange, (Opaque) 0);
1370    XtAddEventHandler(wnew, PropertyChangeMask, False,
1371                      HandleBellPropertyChange, (Opaque) 0);
1372
1373#ifndef NO_ACTIVE_ICON
1374    ((TekWidget) wnew)->screen.whichTwin = &((TekWidget) wnew)->screen.fullTwin;
1375#endif /* NO_ACTIVE_ICON */
1376
1377}
1378
1379static void
1380TekRealize(Widget gw,
1381           XtValueMask * valuemaskp,
1382           XSetWindowAttributes * values)
1383{
1384    TekWidget tw = (TekWidget) gw;
1385    TekScreen *tekscr = TekScreenOf(tw);
1386    TScreen *screen = TScreenOf(term);
1387    int i;
1388    TekLink *tek;
1389    double d;
1390    int border = 2 * screen->border;
1391    int pr;
1392    XGCValues gcv;
1393    int winX, winY, width, height;
1394    char Tdefault[32];
1395    unsigned TEKgcFontMask;
1396
1397    TRACE(("TekRealize\n"));
1398    memset(tekscr, 0, sizeof(tekscr));
1399
1400#ifndef NO_ACTIVE_ICON
1401    tekscr->whichTwin = &tekscr->fullTwin;
1402#endif /* NO_ACTIVE_ICON */
1403
1404    BorderPixel(tw) = BorderPixel(term);
1405
1406    tekscr->arrow = make_colored_cursor(XC_left_ptr,
1407                                        T_COLOR(screen, MOUSE_FG),
1408                                        T_COLOR(screen, MOUSE_BG));
1409
1410    for (i = 0; i < TEKNUMFONTS; i++) {
1411        if (!tw->tek.Tfont[i]) {
1412            tw->tek.Tfont[i] = XQueryFont(XtDisplay(tw), DefaultGCID);
1413        }
1414        TRACE(("Tfont[%d] %dx%d\n",
1415               i,
1416               tw->tek.Tfont[i]->ascent +
1417               tw->tek.Tfont[i]->descent,
1418               tw->tek.Tfont[i]->max_bounds.width));
1419        tw->tek.tobaseline[i] = tw->tek.Tfont[i]->ascent;
1420    }
1421
1422    if (!TekPtyData())
1423        return;
1424
1425    if (term->misc.T_geometry == NULL) {
1426        int defwidth, defheight;
1427
1428        if (term->misc.tekSmall) {
1429            defwidth = TEKMINWIDTH;
1430            defheight = TEKMINHEIGHT;
1431        } else {
1432            defwidth = TEKDEFWIDTH;
1433            defheight = TEKDEFHEIGHT;
1434        }
1435        sprintf(Tdefault, "=%dx%d", defwidth + border, defheight + border);
1436        term->misc.T_geometry = Tdefault;
1437    }
1438
1439    winX = 1;
1440    winY = 1;
1441    width = TEKDEFWIDTH + border;
1442    height = TEKDEFHEIGHT + border;
1443
1444    TRACE(("parsing T_geometry %s\n", NonNull(term->misc.T_geometry)));
1445    pr = XParseGeometry(term->misc.T_geometry,
1446                        &winX,
1447                        &winY,
1448                        (unsigned int *) &width,
1449                        (unsigned int *) &height);
1450    TRACE(("... position %d,%d size %dx%d\n", winY, winX, height, width));
1451    if ((pr & XValue) && (pr & XNegative))
1452        winX += DisplayWidth(XtDisplay(tw), DefaultScreen(XtDisplay(tw)))
1453            - width - (BorderWidth(SHELL_OF(term)) * 2);
1454    if ((pr & YValue) && (pr & YNegative))
1455        winY += DisplayHeight(XtDisplay(tw), DefaultScreen(XtDisplay(tw)))
1456            - height - (BorderWidth(SHELL_OF(term)) * 2);
1457
1458    /* set up size hints */
1459    tw->hints.min_width = TEKMINWIDTH + border;
1460    tw->hints.min_height = TEKMINHEIGHT + border;
1461    tw->hints.width_inc = 1;
1462    tw->hints.height_inc = 1;
1463    tw->hints.flags = PMinSize | PResizeInc;
1464    tw->hints.x = winX;
1465    tw->hints.y = winY;
1466    if ((XValue & pr) || (YValue & pr)) {
1467        tw->hints.flags |= USSize | USPosition;
1468        tw->hints.flags |= PWinGravity;
1469        switch (pr & (XNegative | YNegative)) {
1470        case 0:
1471            tw->hints.win_gravity = NorthWestGravity;
1472            break;
1473        case XNegative:
1474            tw->hints.win_gravity = NorthEastGravity;
1475            break;
1476        case YNegative:
1477            tw->hints.win_gravity = SouthWestGravity;
1478            break;
1479        default:
1480            tw->hints.win_gravity = SouthEastGravity;
1481            break;
1482        }
1483    } else {
1484        /* set a default size, but do *not* set position */
1485        tw->hints.flags |= PSize;
1486    }
1487    tw->hints.width = width;
1488    tw->hints.height = height;
1489    if ((WidthValue & pr) || (HeightValue & pr))
1490        tw->hints.flags |= USSize;
1491    else
1492        tw->hints.flags |= PSize;
1493
1494    TRACE(("make resize request %dx%d\n", height, width));
1495    (void) XtMakeResizeRequest((Widget) tw,
1496                               width, height,
1497                               &tw->core.width, &tw->core.height);
1498    TRACE(("...made resize request %dx%d\n", tw->core.height, tw->core.width));
1499
1500    /* XXX This is bogus.  We are parsing geometries too late.  This
1501     * is information that the shell widget ought to have before we get
1502     * realized, so that it can do the right thing.
1503     */
1504    if (tw->hints.flags & USPosition)
1505        XMoveWindow(XtDisplay(tw), TShellWindow, tw->hints.x, tw->hints.y);
1506
1507    XSetWMNormalHints(XtDisplay(tw), TShellWindow, &tw->hints);
1508    XFlush(XtDisplay(tw));      /* get it out to window manager */
1509
1510    values->win_gravity = NorthWestGravity;
1511    values->background_pixel = T_COLOR(screen, TEK_BG);
1512
1513    XtWindow(tw) = TWindow(tekscr) =
1514        XCreateWindow(XtDisplay(tw),
1515                      XtWindow(SHELL_OF(tw)),
1516                      tw->core.x, tw->core.y,
1517                      tw->core.width, tw->core.height,
1518                      BorderWidth(tw),
1519                      (int) tw->core.depth,
1520                      InputOutput, CopyFromParent,
1521                      ((*valuemaskp) | CWBackPixel | CWWinGravity),
1522                      values);
1523
1524    TFullWidth(tekscr) = width;
1525    TFullHeight(tekscr) = height;
1526    TWidth(tekscr) = width - border;
1527    THeight(tekscr) = height - border;
1528    TekScale(tekscr) = (double) TWidth(tekscr) / TEKWIDTH;
1529    if ((d = (double) THeight(tekscr) / (TEKHEIGHT + TEKTOPPAD +
1530                                         TEKBOTTOMPAD)) < TekScale(tekscr))
1531        TekScale(tekscr) = d;
1532
1533    tekscr->cur.fontsize = TEK_FONT_LARGE;
1534    if (tw->tek.initial_font) {
1535        int result = TekGetFontSize(tw->tek.initial_font);
1536        if (result >= 0)
1537            tekscr->cur.fontsize = result;
1538    }
1539#define TestGIN(s) XmuCompareISOLatin1(tw->tek.gin_terminator_str, s)
1540
1541    if (TestGIN(GIN_TERM_NONE_STR) == 0)
1542        tekscr->gin_terminator = GIN_TERM_NONE;
1543    else if (TestGIN(GIN_TERM_CR_STR) == 0)
1544        tekscr->gin_terminator = GIN_TERM_CR;
1545    else if (TestGIN(GIN_TERM_EOT_STR) == 0)
1546        tekscr->gin_terminator = GIN_TERM_EOT;
1547    else
1548        fprintf(stderr, "%s: illegal GIN terminator setting \"%s\"\n",
1549                xterm_name, tw->tek.gin_terminator_str);
1550
1551    gcv.graphics_exposures = True;      /* default */
1552    gcv.font = tw->tek.Tfont[tekscr->cur.fontsize]->fid;
1553    gcv.foreground = T_COLOR(screen, TEK_FG);
1554    gcv.background = T_COLOR(screen, TEK_BG);
1555
1556    /* if font wasn't successfully opened, then gcv.font will contain
1557       the Default GC's ID, meaning that we must use the server default font.
1558     */
1559    TEKgcFontMask = (gcv.font == DefaultGCID) ? 0 : GCFont;
1560    tekscr->TnormalGC = XCreateGC(XtDisplay(tw), TWindow(tekscr),
1561                                  (TEKgcFontMask | GCGraphicsExposures |
1562                                   GCForeground | GCBackground),
1563                                  &gcv);
1564
1565    gcv.function = GXinvert;
1566    gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^
1567                      T_COLOR(screen, TEK_CURSOR));
1568    gcv.join_style = JoinMiter; /* default */
1569    gcv.line_width = 1;
1570    tekscr->TcursorGC = XCreateGC(XtDisplay(tw), TWindow(tekscr),
1571                                  (GCFunction | GCPlaneMask), &gcv);
1572
1573    gcv.foreground = T_COLOR(screen, TEK_FG);
1574    gcv.line_style = LineOnOffDash;
1575    gcv.line_width = 0;
1576    for (i = 0; i < TEKNUMLINES; i++) {
1577        tekscr->linepat[i] = XCreateGC(XtDisplay(tw), TWindow(tekscr),
1578                                       (GCForeground | GCLineStyle), &gcv);
1579        XSetDashes(XtDisplay(tw), tekscr->linepat[i], 0,
1580                   (char *) dashes[i], dash_length[i]);
1581    }
1582
1583    TekBackground(tw, screen);
1584
1585    tekscr->margin = MARGIN1;   /* Margin 1             */
1586    tekscr->TekGIN = False;     /* GIN off              */
1587
1588    XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow);
1589
1590    {                           /* there's gotta be a better way... */
1591        static Arg args[] =
1592        {
1593            {XtNtitle, (XtArgVal) NULL},
1594            {XtNiconName, (XtArgVal) NULL},
1595        };
1596        char *icon_name, *title, *tek_icon_name, *tek_title;
1597
1598        args[0].value = (XtArgVal) & icon_name;
1599        args[1].value = (XtArgVal) & title;
1600        XtGetValues(SHELL_OF(tw), args, 2);
1601        tek_icon_name = XtMalloc(strlen(icon_name) + 7);
1602        strcpy(tek_icon_name, icon_name);
1603        strcat(tek_icon_name, "(Tek)");
1604        tek_title = XtMalloc(strlen(title) + 7);
1605        strcpy(tek_title, title);
1606        strcat(tek_title, "(Tek)");
1607        args[0].value = (XtArgVal) tek_icon_name;
1608        args[1].value = (XtArgVal) tek_title;
1609        XtSetValues(SHELL_OF(tw), args, 2);
1610        XtFree(tek_icon_name);
1611        XtFree(tek_title);
1612    }
1613
1614    tek = TekRecord = &Tek0;
1615    tek->next = (TekLink *) 0;
1616    tek->fontsize = tekscr->cur.fontsize;
1617    tek->count = 0;
1618    tek->ptr = tek->data;
1619    Tpushback = Tpushb;
1620    tekscr->cur_X = 0;
1621    tekscr->cur_Y = TEKHOME;
1622    line_pt = Tline;
1623    Ttoggled = True;
1624    tekscr->page = tekscr->cur;
1625    return;
1626}
1627
1628int
1629TekGetFontSize(const char *param)
1630{
1631    int result;
1632
1633    if (XmuCompareISOLatin1(param, "l") == 0 ||
1634        XmuCompareISOLatin1(param, "large") == 0)
1635        result = TEK_FONT_LARGE;
1636    else if (XmuCompareISOLatin1(param, "2") == 0 ||
1637             XmuCompareISOLatin1(param, "two") == 0)
1638        result = TEK_FONT_2;
1639    else if (XmuCompareISOLatin1(param, "3") == 0 ||
1640             XmuCompareISOLatin1(param, "three") == 0)
1641        result = TEK_FONT_3;
1642    else if (XmuCompareISOLatin1(param, "s") == 0 ||
1643             XmuCompareISOLatin1(param, "small") == 0)
1644        result = TEK_FONT_SMALL;
1645    else
1646        result = -1;
1647
1648    return result;
1649}
1650
1651void
1652TekSetFontSize(TekWidget tw, int newitem)
1653{
1654    if (tw != 0) {
1655        TekScreen *tekscr = TekScreenOf(tw);
1656        int oldsize = tekscr->cur.fontsize;
1657        int newsize = MI2FS(newitem);
1658        Font fid;
1659
1660        TRACE(("TekSetFontSize(%d)\n", newitem));
1661        if (newsize < 0 || newsize >= TEKNUMFONTS) {
1662            Bell(XkbBI_MinorError, 0);
1663        } else if (oldsize != newsize) {
1664            if (!Ttoggled)
1665                TCursorToggle(tw, TOGGLE);
1666            set_tekfont_menu_item(oldsize, False);
1667
1668            fid = tw->tek.Tfont[newsize]->fid;
1669            if (fid == DefaultGCID) {
1670                /* we didn't succeed in opening a real font
1671                   for this size.  Instead, use server default. */
1672                XCopyGC(XtDisplay(tw),
1673                        DefaultGC(XtDisplay(tw), DefaultScreen(XtDisplay(tw))),
1674                        GCFont, tekscr->TnormalGC);
1675            } else {
1676                XSetFont(XtDisplay(tw), tekscr->TnormalGC, fid);
1677            }
1678
1679            tekscr->cur.fontsize = newsize;
1680            set_tekfont_menu_item(newsize, True);
1681            if (!Ttoggled)
1682                TCursorToggle(tw, TOGGLE);
1683        }
1684    }
1685}
1686
1687void
1688ChangeTekColors(TekWidget tw, TScreen * screen, ScrnColors * pNew)
1689{
1690    TekScreen *tekscr = TekScreenOf(tw);
1691    int i;
1692    XGCValues gcv;
1693
1694    if (COLOR_DEFINED(pNew, TEK_FG)) {
1695        T_COLOR(screen, TEK_FG) = COLOR_VALUE(pNew, TEK_FG);
1696        TRACE(("... TEK_FG: %#lx\n", T_COLOR(screen, TEK_FG)));
1697    }
1698    if (COLOR_DEFINED(pNew, TEK_BG)) {
1699        T_COLOR(screen, TEK_BG) = COLOR_VALUE(pNew, TEK_BG);
1700        TRACE(("... TEK_BG: %#lx\n", T_COLOR(screen, TEK_BG)));
1701    }
1702    if (COLOR_DEFINED(pNew, TEK_CURSOR)) {
1703        T_COLOR(screen, TEK_CURSOR) = COLOR_VALUE(pNew, TEK_CURSOR);
1704        TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR)));
1705    } else {
1706        T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG);
1707        TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR)));
1708    }
1709
1710    if (tw) {
1711        XSetForeground(XtDisplay(tw), tekscr->TnormalGC,
1712                       T_COLOR(screen, TEK_FG));
1713        XSetBackground(XtDisplay(tw), tekscr->TnormalGC,
1714                       T_COLOR(screen, TEK_BG));
1715        if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) {
1716            BorderPixel(tw) = T_COLOR(screen, TEK_FG);
1717            BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG);
1718            if (XtWindow(XtParent(tw)))
1719                XSetWindowBorder(XtDisplay(tw),
1720                                 XtWindow(XtParent(tw)),
1721                                 BorderPixel(tw));
1722        }
1723
1724        for (i = 0; i < TEKNUMLINES; i++) {
1725            XSetForeground(XtDisplay(tw), tekscr->linepat[i],
1726                           T_COLOR(screen, TEK_FG));
1727        }
1728
1729        gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^
1730                          T_COLOR(screen, TEK_CURSOR));
1731        XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv);
1732        TekBackground(tw, screen);
1733    }
1734    return;
1735}
1736
1737void
1738TekReverseVideo(TekWidget tw)
1739{
1740    TScreen *screen = TScreenOf(term);
1741    TekScreen *tekscr = TekScreenOf(tw);
1742    int i;
1743    XGCValues gcv;
1744
1745    EXCHANGE(T_COLOR(screen, TEK_FG), T_COLOR(screen, TEK_BG), i);
1746
1747    T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG);
1748
1749    if (tw) {
1750        XSetForeground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_FG));
1751        XSetBackground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_BG));
1752
1753        if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) {
1754            BorderPixel(tw) = T_COLOR(screen, TEK_FG);
1755            BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG);
1756            if (XtWindow(XtParent(tw)))
1757                XSetWindowBorder(XtDisplay(tw),
1758                                 XtWindow(XtParent(tw)),
1759                                 BorderPixel(tw));
1760        }
1761
1762        for (i = 0; i < TEKNUMLINES; i++) {
1763            XSetForeground(XtDisplay(tw), tekscr->linepat[i],
1764                           T_COLOR(screen, TEK_FG));
1765        }
1766
1767        gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^
1768                          T_COLOR(screen, TEK_CURSOR));
1769        XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv);
1770        TekBackground(tw, screen);
1771    }
1772}
1773
1774static void
1775TekBackground(TekWidget tw, TScreen * screen)
1776{
1777    TekScreen *tekscr = TekScreenOf(tw);
1778
1779    if (TWindow(tekscr))
1780        XSetWindowBackground(XtDisplay(tw), TWindow(tekscr),
1781                             T_COLOR(screen, TEK_BG));
1782}
1783
1784/*
1785 * Toggles cursor on or off at cursor position in screen.
1786 */
1787void
1788TCursorToggle(TekWidget tw, int toggle)         /* TOGGLE or CLEAR */
1789{
1790    TekScreen *tekscr = TekScreenOf(tw);
1791    TScreen *screen = TScreenOf(term);
1792    int c, x, y;
1793    unsigned int cellwidth, cellheight;
1794
1795    if (!TEK4014_SHOWN(term))
1796        return;
1797
1798    c = tekscr->cur.fontsize;
1799    cellwidth = (unsigned) tw->tek.Tfont[c]->max_bounds.width;
1800    cellheight = (unsigned) (tw->tek.Tfont[c]->ascent +
1801                             tw->tek.Tfont[c]->descent);
1802
1803    x = (int) ((tekscr->cur_X * TekScale(tekscr)) + screen->border);
1804    y = (int) (((TEKHEIGHT + TEKTOPPAD - tekscr->cur_Y) * TekScale(tekscr))
1805               + screen->border - tw->tek.tobaseline[c]);
1806
1807    if (toggle == TOGGLE) {
1808        if (screen->select || screen->always_highlight)
1809            XFillRectangle(XtDisplay(tw), TWindow(tekscr),
1810                           tekscr->TcursorGC, x, y,
1811                           cellwidth, cellheight);
1812        else {                  /* fix to use different GC! */
1813            XDrawRectangle(XtDisplay(tw), TWindow(tekscr),
1814                           tekscr->TcursorGC, x, y,
1815                           cellwidth - 1, cellheight - 1);
1816        }
1817    } else {
1818        /* Clear the entire rectangle, even though we may only
1819         * have drawn an outline.  This fits with our refresh
1820         * scheme of redrawing the entire window on any expose
1821         * event and is easier than trying to figure out exactly
1822         * which part of the cursor needs to be erased.
1823         */
1824        XClearArea(XtDisplay(tw), TWindow(tekscr), x, y,
1825                   cellwidth, cellheight, False);
1826    }
1827}
1828
1829void
1830TekSimulatePageButton(TekWidget tw, Bool reset)
1831{
1832    if (tw != 0) {
1833        TekScreen *tekscr = TekScreenOf(tw);
1834
1835        if (reset) {
1836            bzero((char *) &tekscr->cur, sizeof tekscr->cur);
1837        }
1838        tekRefreshList = (TekLink *) 0;
1839        TekPage(tw);
1840        tekscr->cur_X = 0;
1841        tekscr->cur_Y = TEKHOME;
1842    }
1843}
1844
1845/* write copy of screen to a file */
1846
1847void
1848TekCopy(TekWidget tw)
1849{
1850    if (tw != 0) {
1851        TekScreen *tekscr = TekScreenOf(tw);
1852        TScreen *screen = TScreenOf(term);
1853
1854        TekLink *Tp;
1855        char buf[32];
1856        char initbuf[5];
1857        int tekcopyfd;
1858
1859        timestamp_filename(buf, "COPY");
1860        if (access(buf, F_OK) >= 0
1861            && access(buf, W_OK) < 0) {
1862            Bell(XkbBI_MinorError, 0);
1863            return;
1864        }
1865#ifndef VMS
1866        if (access(".", W_OK) < 0) {    /* can't write in directory */
1867            Bell(XkbBI_MinorError, 0);
1868            return;
1869        }
1870#endif
1871
1872        tekcopyfd = open_userfile(screen->uid, screen->gid, buf, False);
1873        if (tekcopyfd >= 0) {
1874            sprintf(initbuf, "%c%c%c%c",
1875                    ANSI_ESC, (char) (tekscr->page.fontsize + '8'),
1876                    ANSI_ESC, (char) (tekscr->page.linetype + '`'));
1877            write(tekcopyfd, initbuf, 4);
1878            Tp = &Tek0;
1879            do {
1880                write(tekcopyfd, Tp->data, Tp->count);
1881                Tp = Tp->next;
1882            } while (Tp);
1883            close(tekcopyfd);
1884        }
1885    }
1886}
1887
1888/*ARGSUSED*/
1889void
1890HandleGINInput(Widget w,
1891               XEvent * event GCC_UNUSED,
1892               String * param_list,
1893               Cardinal *nparamsp)
1894{
1895    if (IsTekWidget(w)) {
1896        TekWidget tw = (TekWidget) w;
1897        TekScreen *tekscr = TekScreenOf(tw);
1898
1899        if (tekscr->TekGIN && *nparamsp == 1) {
1900            int c = param_list[0][0];
1901            switch (c) {
1902            case 'l':
1903            case 'm':
1904            case 'r':
1905            case 'L':
1906            case 'M':
1907            case 'R':
1908                break;
1909            default:
1910                Bell(XkbBI_MinorError, 0);      /* let them know they goofed */
1911                c = 'l';        /* provide a default */
1912            }
1913            TekEnqMouse(tw, c | 0x80);
1914            TekGINoff(tw);
1915        } else {
1916            Bell(XkbBI_MinorError, 0);
1917        }
1918    }
1919}
Note: See TracBrowser for help on using the browser.