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