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