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