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