Tekproc.c revision e39b573c
1/* $XTermId: Tekproc.c,v 1.189 2011/07/10 22:19:32 tom Exp $ */ 2 3/* 4 * Copyright 2001-2010,2011 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_NEXTAW) 94#include <X11/neXtaw/Form.h> 95#elif defined(HAVE_LIB_XAWPLUS) 96#include <X11/XawPlus/Form.h> 97#endif 98 99#endif /* OPT_TOOLBAR */ 100 101#include <assert.h> 102#include <stdio.h> 103#include <ctype.h> 104#include <signal.h> 105 106#include <Tekparse.h> 107#include <data.h> 108#include <error.h> 109#include <menu.h> 110#include <xstrings.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", ProgramName); 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 c = (IChar) (c & LINEMASK); 604 if (c != tekscr->cur.linetype) { 605 if (nplot > 0) 606 TekFlush(tw); 607 if (c <= TEKNUMLINES) 608 tekscr->cur.linetype = c; 609 } 610 Tparsestate = curstate; 611 break; 612 613 case CASE_CURSTATE: 614 Tparsestate = curstate; 615 break; 616 617 case CASE_PENUP: 618 TRACE(("case: Ipl: penup\n")); 619 tekscr->pen = PENUP; 620 break; 621 622 case CASE_PENDOWN: 623 TRACE(("case: Ipl: pendown\n")); 624 tekscr->pen = PENDOWN; 625 break; 626 627 case CASE_IPL_POINT: 628 TRACE(("case: Ipl: point\n")); 629 x = tekscr->cur_X; 630 y = tekscr->cur_Y; 631 if (c & NORTH) 632 y++; 633 else if (c & SOUTH) 634 y--; 635 if (c & EAST) 636 x++; 637 else if (c & WEST) 638 x--; 639 if (tekscr->pen == PENDOWN) 640 TekDraw(tw, x, y); 641 else 642 TekMove(tw, x, y); 643 break; 644 645 case CASE_PLT_VEC: 646 TRACE(("case: Plt: vector\n")); 647 unput(c); 648 if (getpoint(tw)) { 649 if (tekscr->pen == PENDOWN) { 650 TekDraw(tw, tekscr->cur.x, tekscr->cur.y); 651 } else { 652 TekMove(tw, tekscr->cur.x, tekscr->cur.y); 653 } 654 tekscr->pen = PENDOWN; 655 } 656 break; 657 658 case CASE_PT_POINT: 659 TRACE(("case: Pt: point\n")); 660 unput(c); 661 if (getpoint(tw)) { 662 TekMove(tw, tekscr->cur.x, tekscr->cur.y); 663 TekDraw(tw, tekscr->cur.x, tekscr->cur.y); 664 } 665 break; 666 667 case CASE_SPT_POINT: 668 TRACE(("case: Spt: point\n")); 669 /* ignore intensity character in c */ 670 if (getpoint(tw)) { 671 TekMove(tw, tekscr->cur.x, tekscr->cur.y); 672 TekDraw(tw, tekscr->cur.x, tekscr->cur.y); 673 } 674 break; 675 676 case CASE_CR: 677 TRACE(("case: CR\n")); 678 if (tekscr->TekGIN) 679 TekGINoff(tw); 680 if (nplot > 0) /* flush line VTbuffer */ 681 TekFlush(tw); 682 tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 : 683 TEKWIDTH / 2; 684 Tparsestate = curstate = Talptable; 685 break; 686 687 case CASE_ESC_STATE: 688 TRACE(("case: ESC\n")); 689 Tparsestate = Tesctable; 690 break; 691 692 case CASE_LF: 693 TRACE(("case: LF\n")); 694 if (tekscr->TekGIN) 695 TekGINoff(tw); 696 TCursorDown(tw); 697 if (!tekRefreshList) 698 do_xevents(); 699 break; 700 701 case CASE_SP: 702 TRACE(("case: SP\n")); 703 TCursorForward(tw); 704 break; 705 706 case CASE_PRINT: 707 TRACE(("case: printable character\n")); 708 ch = c; 709 x = (int) (tekscr->cur_X * TekScale(tekscr)) 710 + screen->border; 711 y = (int) ((TEKHEIGHT + TEKTOPPAD - tekscr->cur_Y) * TekScale(tekscr)) 712 + screen->border; 713 714#if OPT_WIDE_CHARS 715 if (screen->wide_chars 716 && (ch > 255)) { 717 XChar2b sbuf; 718 sbuf.byte2 = LO_BYTE(ch); 719 sbuf.byte1 = HI_BYTE(ch); 720 XDrawImageString16(XtDisplay(tw), 721 TWindow(tekscr), 722 tekscr->TnormalGC, 723 x, 724 y, 725 &sbuf, 726 1); 727 } else 728#endif 729 { 730 char ch2 = (char) ch; 731 XDrawString(XtDisplay(tw), 732 TWindow(tekscr), 733 tekscr->TnormalGC, 734 x, 735 y, 736 &ch2, 737 1); 738 } 739 TCursorForward(tw); 740 break; 741 case CASE_OSC: 742 /* FIXME: someone should disentangle the input queues 743 * of this code so that it can be state-driven. 744 */ 745 TRACE(("case: do osc escape\n")); 746 { 747 /* 748 * do_osc() can call TekExpose(), which calls TekRefresh(), 749 * and sends us recurring here - don't do that... 750 */ 751 static int nested; 752 753 Char buf2[512]; 754 IChar c2; 755 size_t len = 0; 756 while ((c2 = input()) != ANSI_BEL) { 757 if (!isprint((int) (c2 & 0x7f)) 758 || len + 2 >= (int) sizeof(buf2)) 759 break; 760 buf2[len++] = (Char) c2; 761 } 762 buf2[len] = 0; 763 if (!nested++) { 764 if (c2 == ANSI_BEL) 765 do_osc(xw, buf2, len, ANSI_BEL); 766 } 767 --nested; 768 } 769 Tparsestate = curstate; 770 break; 771 } 772 } 773} 774 775static int rcnt; 776static char *rptr; 777static PtySelect Tselect_mask; 778 779static IChar 780Tinput(TekWidget tw) 781{ 782 XtermWidget xw = term; 783 TekScreen *tekscr = TekScreenOf(tw); 784 TScreen *screen = TScreenOf(xw); 785 TekLink *tek; 786 787 if (Tpushback > Tpushb) 788 return (*--Tpushback); 789 if (tekRefreshList) { 790 if (rcnt-- > 0) 791 return (IChar) (*rptr++); 792 if ((tek = tekRefreshList->next) != 0) { 793 tekRefreshList = tek; 794 rptr = tek->data; 795 rcnt = tek->count - 1; 796 TekSetFontSize(tw, False, tek->fontsize); 797 return (IChar) (*rptr++); 798 } 799 tekRefreshList = (TekLink *) 0; 800 longjmp(Tekjump, 1); 801 } 802 again: 803 if (VTbuffer->next >= VTbuffer->last) { 804 int update = VTbuffer->update; 805 806 if (nplot > 0) /* flush line */ 807 TekFlush(tw); 808#ifdef VMS 809 Tselect_mask = pty_mask; /* force a read */ 810#else /* VMS */ 811 XFD_COPYSET(&pty_mask, &Tselect_mask); 812#endif /* VMS */ 813 for (;;) { 814#ifdef CRAY 815 struct timeval crocktimeout; 816 crocktimeout.tv_sec = 0; 817 crocktimeout.tv_usec = 0; 818 (void) Select(max_plus1, 819 &Tselect_mask, NULL, NULL, 820 &crocktimeout); 821#endif 822 if (readPtyData(xw, &Tselect_mask, VTbuffer)) { 823 break; 824 } 825 if (Ttoggled && curstate == Talptable) { 826 TCursorToggle(tw, TOGGLE); 827 Ttoggled = False; 828 } 829 if (XtAppPending(app_con) & XtIMXEvent) { 830#ifdef VMS 831 Tselect_mask = X_mask; 832#else /* VMS */ 833 XFD_COPYSET(&X_mask, &Tselect_mask); 834#endif /* VMS */ 835 } else { 836 XFlush(XtDisplay(tw)); 837#ifdef VMS 838 Tselect_mask = Select_mask; 839 840#else /* VMS */ 841 XFD_COPYSET(&Select_mask, &Tselect_mask); 842 if (Select(max_plus1, &Tselect_mask, NULL, NULL, NULL) < 0) { 843 if (errno != EINTR) 844 SysError(ERROR_TSELECT); 845 continue; 846 } 847#endif /* VMS */ 848 } 849#ifdef VMS 850 if (Tselect_mask & X_mask) { 851 xevents(); 852 if (VTbuffer->update != update) 853 goto again; 854 } 855#else /* VMS */ 856 if (FD_ISSET(ConnectionNumber(XtDisplay(tw)), &Tselect_mask)) { 857 xevents(); 858 if (VTbuffer->update != update) 859 goto again; 860 } 861#endif /* VMS */ 862 } 863 if (!Ttoggled && curstate == Talptable) { 864 TCursorToggle(tw, TOGGLE); 865 Ttoggled = True; 866 } 867 } 868 tek = TekRecord; 869 if (tek->count >= TEK_LINK_BLOCK_SIZE 870 || tek->fontsize != tekscr->cur.fontsize) { 871 if ((TekRecord = tek->next = CastMalloc(TekLink)) == 0) { 872 Panic("Tinput: malloc error (%d)\n", errno); 873 } else { 874 tek = tek->next; 875 tek->next = (TekLink *) 0; 876 tek->fontsize = (unsigned short) tekscr->cur.fontsize; 877 tek->count = 0; 878 tek->ptr = tek->data; 879 } 880 } 881 tek->count++; 882 883 (void) morePtyData(screen, VTbuffer); 884 return (IChar) (*tek->ptr++ = (char) nextPtyData(screen, VTbuffer)); 885} 886 887static void 888TekClear(TekWidget tw) 889{ 890 TekScreen *tekscr = TekScreenOf(tw); 891 892 if (TWindow(tekscr)) 893 XClearWindow(XtDisplay(tw), TWindow(tekscr)); 894} 895 896/* this should become the Tek Widget's Resize proc */ 897static void 898TekConfigure(Widget w) 899{ 900 TekWidget tw = getTekWidget(w); 901 if (tw != 0) { 902 XtermWidget xw = term; 903 TekScreen *tekscr = TekScreenOf(tw); 904 TScreen *screen = TScreenOf(xw); 905 int border = 2 * screen->border; 906 double d; 907 908 TekClear(tw); 909 TWidth(tekscr) = w->core.width - border; 910 THeight(tekscr) = w->core.height - border; 911 TekScale(tekscr) = (double) TWidth(tekscr) / TEKWIDTH; 912 if ((d = (double) THeight(tekscr) / (TEKHEIGHT + TEKTOPPAD + TEKBOTTOMPAD)) 913 < TekScale(tekscr)) 914 TekScale(tekscr) = d; 915 TFullWidth(tekscr) = w->core.width; 916 TFullHeight(tekscr) = w->core.height; 917 } 918} 919 920/*ARGSUSED*/ 921void 922TekExpose(Widget w, 923 XEvent * event GCC_UNUSED, 924 Region region GCC_UNUSED) 925{ 926 TekWidget tw = getTekWidget(w); 927 if (tw != 0) { 928 TekScreen *tekscr = TekScreenOf(tw); 929 930 TRACE(("TekExpose {{\n")); 931 932#ifdef lint 933 region = region; 934#endif 935 if (!Ttoggled) 936 TCursorToggle(tw, CLEAR); 937 Ttoggled = True; 938 Tpushback = Tpushb; 939 tekscr->cur_X = 0; 940 tekscr->cur_Y = TEKHOME; 941 tekscr->cur = tekscr->page; 942 TekSetFontSize(tw, False, tekscr->cur.fontsize); 943 tekscr->margin = MARGIN1; 944 if (tekscr->TekGIN) { 945 tekscr->TekGIN = NULL; 946 TekGINoff(tw); 947 } 948 tekRefreshList = &Tek0; 949 rptr = tekRefreshList->data; 950 rcnt = tekRefreshList->count; 951 Tparsestate = curstate = Talptable; 952 TRACE(("TekExpose resets data to replay %d bytes\n", rcnt)); 953 first_map_occurred(); 954 if (!tekscr->waitrefresh) 955 TekRefresh(tw); 956 TRACE(("}} TekExpose\n")); 957 } 958} 959 960void 961TekRefresh(TekWidget tw) 962{ 963 if (tw != 0) { 964 XtermWidget xw = term; 965 TScreen *screen = TScreenOf(xw); 966 TekScreen *tekscr = TekScreenOf(tw); 967 static Cursor wait_cursor = None; 968 969 if (wait_cursor == None) 970 wait_cursor = make_colored_cursor(XC_watch, 971 T_COLOR(screen, MOUSE_FG), 972 T_COLOR(screen, MOUSE_BG)); 973 XDefineCursor(XtDisplay(tw), TWindow(tekscr), wait_cursor); 974 XFlush(XtDisplay(tw)); 975 if (!setjmp(Tekjump)) 976 Tekparse(tw); 977 XDefineCursor(XtDisplay(tw), TWindow(tekscr), 978 (tekscr->TekGIN && GINcursor) ? GINcursor : tekscr->arrow); 979 } 980} 981 982void 983TekRepaint(TekWidget tw) 984{ 985 TRACE(("TekRepaint\n")); 986 TekClear(tw); 987 TekExpose((Widget) tw, (XEvent *) NULL, (Region) NULL); 988} 989 990static void 991TekPage(TekWidget tw) 992{ 993 TekScreen *tekscr = TekScreenOf(tw); 994 TekLink *tek; 995 996 TekClear(tw); 997 tekscr->cur_X = 0; 998 tekscr->cur_Y = TEKHOME; 999 tekscr->margin = MARGIN1; 1000 tekscr->page = tekscr->cur; 1001 if (tekscr->TekGIN) 1002 TekGINoff(tw); 1003 tek = TekRecord = &Tek0; 1004 tek->fontsize = (unsigned short) tekscr->cur.fontsize; 1005 tek->count = 0; 1006 tek->ptr = tek->data; 1007 tek = tek->next; 1008 if (tek) 1009 do { 1010 TekLink *tek2 = tek->next; 1011 1012 free(tek); 1013 tek = tek2; 1014 } while (tek); 1015 TekRecord->next = (TekLink *) 0; 1016 tekRefreshList = (TekLink *) 0; 1017 Ttoggled = True; 1018 Tparsestate = curstate = Talptable; /* Tek Alpha mode */ 1019} 1020 1021#define EXTRABITS 017 1022#define FIVEBITS 037 1023#define HIBITS (FIVEBITS << SHIFTHI) 1024#define LOBITS (FIVEBITS << SHIFTLO) 1025#define SHIFTHI 7 1026#define SHIFTLO 2 1027#define TWOBITS 03 1028 1029static int 1030getpoint(TekWidget tw) 1031{ 1032 int c, x, y, e, lo_y = 0; 1033 TekScreen *tekscr = TekScreenOf(tw); 1034 1035 x = tekscr->cur.x; 1036 y = tekscr->cur.y; 1037 for (;;) { 1038 if ((c = (int) input()) < ' ') { /* control character */ 1039 unput(c); 1040 return (0); 1041 } 1042 if (c < '@') { /* Hi X or Hi Y */ 1043 if (lo_y) { /* seen a Lo Y, so this must be Hi X */ 1044 x &= ~HIBITS; 1045 x |= (c & FIVEBITS) << SHIFTHI; 1046 continue; 1047 } 1048 /* else Hi Y */ 1049 y &= ~HIBITS; 1050 y |= (c & FIVEBITS) << SHIFTHI; 1051 continue; 1052 } 1053 if (c < '`') { /* Lo X */ 1054 x &= ~LOBITS; 1055 x |= (c & FIVEBITS) << SHIFTLO; 1056 tekscr->cur.x = x; 1057 tekscr->cur.y = y; 1058 return (1); /* OK */ 1059 } 1060 /* else Lo Y */ 1061 if (lo_y) { /* seen a Lo Y, so other must be extra bits */ 1062 e = (y >> SHIFTLO) & EXTRABITS; 1063 x &= ~TWOBITS; 1064 x |= e & TWOBITS; 1065 y &= ~TWOBITS; 1066 y |= (e >> SHIFTLO) & TWOBITS; 1067 } 1068 y &= ~LOBITS; 1069 y |= (c & FIVEBITS) << SHIFTLO; 1070 lo_y++; 1071 } 1072} 1073 1074static void 1075TCursorBack(TekWidget tw) 1076{ 1077 TekScreen *tekscr = TekScreenOf(tw); 1078 struct Tek_Char *t; 1079 int x, l; 1080 1081 x = (tekscr->cur_X -= 1082 (t = &TekChar[tekscr->cur.fontsize])->hsize 1083 ); 1084 1085 if (((tekscr->margin == MARGIN1) && (x < 0)) 1086 || ((tekscr->margin == MARGIN2) && (x < TEKWIDTH / 2))) { 1087 if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= 1088 t->nlines) { 1089 tekscr->margin = !tekscr->margin; 1090 l = 0; 1091 } 1092 tekscr->cur_Y = l * t->vsize; 1093 tekscr->cur_X = (t->charsperline - 1) * t->hsize; 1094 } 1095} 1096 1097static void 1098TCursorForward(TekWidget tw) 1099{ 1100 TekScreen *tekscr = TekScreenOf(tw); 1101 struct Tek_Char *t; 1102 int l; 1103 1104 if ((tekscr->cur_X += 1105 (t = &TekChar[tekscr->cur.fontsize])->hsize 1106 ) > TEKWIDTH 1107 ) { 1108 if ((l = tekscr->cur_Y / t->vsize - 1) < 0) { 1109 tekscr->margin = !tekscr->margin; 1110 l = t->nlines - 1; 1111 } 1112 tekscr->cur_Y = l * t->vsize; 1113 tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 : TEKWIDTH / 2; 1114 } 1115} 1116 1117static void 1118TCursorUp(TekWidget tw) 1119{ 1120 TekScreen *tekscr = TekScreenOf(tw); 1121 struct Tek_Char *t; 1122 int l; 1123 1124 t = &TekChar[tekscr->cur.fontsize]; 1125 1126 if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= t->nlines) { 1127 l = 0; 1128 if ((tekscr->margin = !tekscr->margin) != MARGIN1) { 1129 if (tekscr->cur_X < TEKWIDTH / 2) 1130 tekscr->cur_X += TEKWIDTH / 2; 1131 } else if (tekscr->cur_X >= TEKWIDTH / 2) 1132 tekscr->cur_X -= TEKWIDTH / 2; 1133 } 1134 tekscr->cur_Y = l * t->vsize; 1135} 1136 1137static void 1138TCursorDown(TekWidget tw) 1139{ 1140 TekScreen *tekscr = TekScreenOf(tw); 1141 struct Tek_Char *t; 1142 int l; 1143 1144 t = &TekChar[tekscr->cur.fontsize]; 1145 1146 if ((l = tekscr->cur_Y / t->vsize - 1) < 0) { 1147 l = t->nlines - 1; 1148 if ((tekscr->margin = !tekscr->margin) != MARGIN1) { 1149 if (tekscr->cur_X < TEKWIDTH / 2) 1150 tekscr->cur_X += TEKWIDTH / 2; 1151 } else if (tekscr->cur_X >= TEKWIDTH / 2) 1152 tekscr->cur_X -= TEKWIDTH / 2; 1153 } 1154 tekscr->cur_Y = l * t->vsize; 1155} 1156 1157static void 1158AddToDraw(TekWidget tw, int x1, int y1, int x2, int y2) 1159{ 1160 XtermWidget xw = term; 1161 TScreen *screen = TScreenOf(xw); 1162 TekScreen *tekscr = TekScreenOf(tw); 1163 XSegment *lp; 1164 1165 TRACE(("AddToDraw (%d,%d) (%d,%d)\n", x1, y1, x2, y2)); 1166 if (nplot >= MAX_PTS) { 1167 TekFlush(tw); 1168 } 1169 lp = line_pt++; 1170 lp->x1 = (short) (x1 * TekScale(tekscr) + screen->border); 1171 lp->y1 = (short) ((TEKHEIGHT + TEKTOPPAD - y1) * TekScale(tekscr) + 1172 screen->border); 1173 lp->x2 = (short) (x2 * TekScale(tekscr) + screen->border); 1174 lp->y2 = (short) ((TEKHEIGHT + TEKTOPPAD - y2) * TekScale(tekscr) + 1175 screen->border); 1176 nplot++; 1177 TRACE(("...AddToDraw %d points\n", nplot)); 1178} 1179 1180static void 1181TekDraw(TekWidget tw, int x, int y) 1182{ 1183 TekScreen *tekscr = TekScreenOf(tw); 1184 1185 if (nplot == 0 || T_lastx != tekscr->cur_X || T_lasty != tekscr->cur_Y) { 1186 /* 1187 * We flush on each unconnected line segment if the line 1188 * type is not solid. This solves a bug in X when drawing 1189 * points while the line type is not solid. 1190 */ 1191 if (nplot > 0 && tekscr->cur.linetype != SOLIDLINE) 1192 TekFlush(tw); 1193 } 1194 AddToDraw(tw, tekscr->cur_X, tekscr->cur_Y, x, y); 1195 T_lastx = tekscr->cur_X = x; 1196 T_lasty = tekscr->cur_Y = y; 1197} 1198 1199static void 1200TekFlush(TekWidget tw) 1201{ 1202 TekScreen *tekscr = TekScreenOf(tw); 1203 1204 TRACE(("TekFlush\n")); 1205 XDrawSegments(XtDisplay(tw), TWindow(tekscr), 1206 ((tekscr->cur.linetype == SOLIDLINE) 1207 ? tekscr->TnormalGC 1208 : tekscr->linepat[tekscr->cur.linetype - 1]), 1209 Tline, nplot); 1210 nplot = 0; 1211 line_pt = Tline; 1212} 1213 1214void 1215TekGINoff(TekWidget tw) 1216{ 1217 TekScreen *tekscr = TekScreenOf(tw); 1218 1219 TRACE(("TekGINoff\n")); 1220 XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow); 1221 if (GINcursor) 1222 XFreeCursor(XtDisplay(tw), GINcursor); 1223 if (tekscr->TekGIN) { 1224 *tekscr->TekGIN = ANSI_CAN; /* modify recording */ 1225 tekscr->TekGIN = NULL; 1226 } 1227} 1228 1229void 1230TekEnqMouse(TekWidget tw, int c) /* character pressed */ 1231{ 1232 XtermWidget xw = term; 1233 TScreen *screen = TScreenOf(xw); 1234 TekScreen *tekscr = TekScreenOf(tw); 1235 int mousex, mousey, rootx, rooty; 1236 unsigned int mask; /* XQueryPointer */ 1237 Window root, subw; 1238 1239 TRACE(("TekEnqMouse\n")); 1240 XQueryPointer( 1241 XtDisplay(tw), TWindow(tekscr), 1242 &root, &subw, 1243 &rootx, &rooty, 1244 &mousex, &mousey, 1245 &mask); 1246 if ((mousex = (int) ((mousex - screen->border) / TekScale(tekscr))) < 0) 1247 mousex = 0; 1248 else if (mousex >= TEKWIDTH) 1249 mousex = TEKWIDTH - 1; 1250 if ((mousey = (int) (TEKHEIGHT + TEKTOPPAD - (mousey - screen->border) / 1251 TekScale(tekscr))) < 0) 1252 mousey = 0; 1253 else if (mousey >= TEKHEIGHT) 1254 mousey = TEKHEIGHT - 1; 1255 TekEnq(tw, (unsigned) c, mousex, mousey); 1256} 1257 1258static void 1259TekEnq(TekWidget tw, 1260 unsigned status, 1261 int x, 1262 int y) 1263{ 1264 XtermWidget xw = term; 1265 TScreen *screen = TScreenOf(xw); 1266 TekScreen *tekscr = TekScreenOf(tw); 1267 Char cplot[7]; 1268 int len = 5; 1269 int adj = (status != 0) ? 0 : 1; 1270 1271 TRACE(("TekEnq\n")); 1272 cplot[0] = (Char) status; 1273 /* Translate x and y to Tektronix code */ 1274 cplot[1] = (Char) (040 | ((x >> SHIFTHI) & FIVEBITS)); 1275 cplot[2] = (Char) (040 | ((x >> SHIFTLO) & FIVEBITS)); 1276 cplot[3] = (Char) (040 | ((y >> SHIFTHI) & FIVEBITS)); 1277 cplot[4] = (Char) (040 | ((y >> SHIFTLO) & FIVEBITS)); 1278 1279 if (tekscr->gin_terminator != GIN_TERM_NONE) 1280 cplot[len++] = '\r'; 1281 if (tekscr->gin_terminator == GIN_TERM_EOT) 1282 cplot[len++] = '\004'; 1283#ifdef VMS 1284 tt_write(cplot + adj, len - adj); 1285#else /* VMS */ 1286 v_write(screen->respond, cplot + adj, (unsigned) (len - adj)); 1287#endif /* VMS */ 1288} 1289 1290void 1291TekRun(void) 1292{ 1293 XtermWidget xw = term; 1294 1295 assert(xw != 0); 1296 if (tekWidget == 0) { 1297 TekInit(); 1298 } 1299 if (tekWidget != 0) { 1300 TRACE(("TekRun ...\n")); 1301 1302 if (!TEK4014_SHOWN(xw)) { 1303 set_tek_visibility(True); 1304 } 1305 update_vttekmode(); 1306 update_vtshow(); 1307 update_tekshow(); 1308 set_tekhide_sensitivity(); 1309 1310 Tpushback = Tpushb; 1311 Ttoggled = True; 1312 if (!setjmp(Tekend)) 1313 Tekparse(tekWidget); 1314 if (!Ttoggled) { 1315 TCursorToggle(tekWidget, TOGGLE); 1316 Ttoggled = True; 1317 } 1318 TEK4014_ACTIVE(xw) = False; 1319 } else { 1320 TEK4014_ACTIVE(xw) = False; 1321 if (VWindow(TScreenOf(xw)) == 0) { 1322 Exit(ERROR_TINIT); 1323 } 1324 } 1325} 1326 1327#define DOTTED_LENGTH 2 1328#define DOT_DASHED_LENGTH 4 1329#define SHORT_DASHED_LENGTH 2 1330#define LONG_DASHED_LENGTH 2 1331 1332static int dash_length[TEKNUMLINES] = 1333{ 1334 DOTTED_LENGTH, 1335 DOT_DASHED_LENGTH, 1336 SHORT_DASHED_LENGTH, 1337 LONG_DASHED_LENGTH, 1338}; 1339 1340static unsigned char dotted[DOTTED_LENGTH] = 1341{3, 1}; 1342static unsigned char dot_dashed[DOT_DASHED_LENGTH] = 1343{3, 4, 3, 1}; 1344static unsigned char short_dashed[SHORT_DASHED_LENGTH] = 1345{4, 4}; 1346static unsigned char long_dashed[LONG_DASHED_LENGTH] = 1347{4, 7}; 1348 1349static unsigned char *dashes[TEKNUMLINES] = 1350{ 1351 dotted, 1352 dot_dashed, 1353 short_dashed, 1354 long_dashed, 1355}; 1356 1357/* 1358 * The following is called to create the tekWidget 1359 */ 1360 1361static void 1362TekInitialize(Widget wrequest, 1363 Widget new_arg, 1364 ArgList args GCC_UNUSED, 1365 Cardinal *num_args GCC_UNUSED) 1366{ 1367 TekWidget request = (TekWidget) wrequest; 1368 TekWidget wnew = (TekWidget) new_arg; 1369 Widget tekparent = SHELL_OF(wnew); 1370#ifndef NO_ACTIVE_ICON 1371 TekScreen *screen = TekScreenOf((TekWidget) wnew); 1372#endif 1373 int n; 1374 1375 TRACE(("TekInitialize\n")); 1376 1377 /* look for focus related events on the shell, because we need 1378 * to care about the shell's border being part of our focus. 1379 */ 1380 XtAddEventHandler(tekparent, EnterWindowMask, False, 1381 HandleEnterWindow, (Opaque) 0); 1382 XtAddEventHandler(tekparent, LeaveWindowMask, False, 1383 HandleLeaveWindow, (Opaque) 0); 1384 XtAddEventHandler(tekparent, FocusChangeMask, False, 1385 HandleFocusChange, (Opaque) 0); 1386 XtAddEventHandler(new_arg, PropertyChangeMask, False, 1387 HandleBellPropertyChange, (Opaque) 0); 1388 1389#ifndef NO_ACTIVE_ICON 1390 screen->whichTwin = &(screen->fullTwin); 1391#endif /* NO_ACTIVE_ICON */ 1392 1393 for (n = 0; n < TEKNUMFONTS; ++n) { 1394 wnew->tek.Tfont[n] = request->tek.Tfont[n]; 1395 } 1396 1397 init_Sres(tek.initial_font); 1398 init_Sres(tek.gin_terminator_str); 1399#if OPT_TOOLBAR 1400 init_Ires(tek.tb_info.menu_height); 1401 wnew->tek.tb_info.menu_bar = request->tek.tb_info.menu_bar; 1402#endif 1403} 1404 1405static void 1406TekRealize(Widget gw, 1407 XtValueMask * valuemaskp, 1408 XSetWindowAttributes * values) 1409{ 1410 XtermWidget xw = term; 1411 TScreen *screen = TScreenOf(xw); 1412 TekWidget tw = (TekWidget) gw; 1413 TekScreen *tekscr = TekScreenOf(tw); 1414 int i; 1415 TekLink *tek; 1416 double d; 1417 int border = 2 * screen->border; 1418 int pr; 1419 XGCValues gcv; 1420 int winX, winY; 1421 unsigned width, height; 1422 char Tdefault[32]; 1423 unsigned long TEKgcFontMask; 1424 1425 TRACE(("TekRealize\n")); 1426 memset(tekscr, 0, sizeof(*tekscr)); 1427 1428#ifndef NO_ACTIVE_ICON 1429 tekscr->whichTwin = &tekscr->fullTwin; 1430#endif /* NO_ACTIVE_ICON */ 1431 1432 BorderPixel(tw) = BorderPixel(xw); 1433 1434 tekscr->arrow = make_colored_cursor(XC_left_ptr, 1435 T_COLOR(screen, MOUSE_FG), 1436 T_COLOR(screen, MOUSE_BG)); 1437 1438 for (i = 0; i < TEKNUMFONTS; i++) { 1439 if (!tw->tek.Tfont[i]) { 1440 tw->tek.Tfont[i] = XQueryFont(XtDisplay(tw), DefaultGCID); 1441 } 1442 TRACE(("Tfont[%d] %dx%d\n", 1443 i, 1444 tw->tek.Tfont[i]->ascent + 1445 tw->tek.Tfont[i]->descent, 1446 tw->tek.Tfont[i]->max_bounds.width)); 1447 tw->tek.tobaseline[i] = tw->tek.Tfont[i]->ascent; 1448 } 1449 1450 if (!TekPtyData()) 1451 return; 1452 1453 if (xw->misc.T_geometry == NULL) { 1454 int defwidth, defheight; 1455 1456 if (xw->misc.tekSmall) { 1457 defwidth = TEKMINWIDTH; 1458 defheight = TEKMINHEIGHT; 1459 } else { 1460 defwidth = TEKDEFWIDTH; 1461 defheight = TEKDEFHEIGHT; 1462 } 1463 sprintf(Tdefault, "=%dx%d", defwidth + border, defheight + border); 1464 xw->misc.T_geometry = Tdefault; 1465 } 1466 1467 winX = 1; 1468 winY = 1; 1469 width = (unsigned) (TEKDEFWIDTH + border); 1470 height = (unsigned) (TEKDEFHEIGHT + border); 1471 1472 TRACE(("parsing T_geometry %s\n", NonNull(xw->misc.T_geometry))); 1473 pr = XParseGeometry(xw->misc.T_geometry, 1474 &winX, 1475 &winY, 1476 &width, 1477 &height); 1478 TRACE(("... position %d,%d size %dx%d\n", winY, winX, height, width)); 1479 if ((pr & XValue) && (pr & XNegative)) 1480 winX += DisplayWidth(XtDisplay(tw), DefaultScreen(XtDisplay(tw))) 1481 - (int) width - (BorderWidth(SHELL_OF(xw)) * 2); 1482 if ((pr & YValue) && (pr & YNegative)) 1483 winY += DisplayHeight(XtDisplay(tw), DefaultScreen(XtDisplay(tw))) 1484 - (int) height - (BorderWidth(SHELL_OF(xw)) * 2); 1485 1486 /* set up size hints */ 1487 tw->hints.min_width = TEKMINWIDTH + border; 1488 tw->hints.min_height = TEKMINHEIGHT + border; 1489 tw->hints.width_inc = 1; 1490 tw->hints.height_inc = 1; 1491 tw->hints.flags = PMinSize | PResizeInc; 1492 tw->hints.x = winX; 1493 tw->hints.y = winY; 1494 if ((XValue & pr) || (YValue & pr)) { 1495 tw->hints.flags |= USSize | USPosition; 1496 tw->hints.flags |= PWinGravity; 1497 switch (pr & (XNegative | YNegative)) { 1498 case 0: 1499 tw->hints.win_gravity = NorthWestGravity; 1500 break; 1501 case XNegative: 1502 tw->hints.win_gravity = NorthEastGravity; 1503 break; 1504 case YNegative: 1505 tw->hints.win_gravity = SouthWestGravity; 1506 break; 1507 default: 1508 tw->hints.win_gravity = SouthEastGravity; 1509 break; 1510 } 1511 } else { 1512 /* set a default size, but do *not* set position */ 1513 tw->hints.flags |= PSize; 1514 } 1515 tw->hints.width = (int) width; 1516 tw->hints.height = (int) height; 1517 if ((WidthValue & pr) || (HeightValue & pr)) 1518 tw->hints.flags |= USSize; 1519 else 1520 tw->hints.flags |= PSize; 1521 1522 (void) REQ_RESIZE((Widget) tw, 1523 (Dimension) width, (Dimension) height, 1524 &tw->core.width, &tw->core.height); 1525 1526 /* XXX This is bogus. We are parsing geometries too late. This 1527 * is information that the shell widget ought to have before we get 1528 * realized, so that it can do the right thing. 1529 */ 1530 if (tw->hints.flags & USPosition) 1531 XMoveWindow(XtDisplay(tw), TShellWindow, tw->hints.x, tw->hints.y); 1532 1533 XSetWMNormalHints(XtDisplay(tw), TShellWindow, &tw->hints); 1534 XFlush(XtDisplay(tw)); /* get it out to window manager */ 1535 1536 values->win_gravity = NorthWestGravity; 1537 values->background_pixel = T_COLOR(screen, TEK_BG); 1538 1539 XtWindow(tw) = TWindow(tekscr) = 1540 XCreateWindow(XtDisplay(tw), 1541 VShellWindow(tw), 1542 tw->core.x, tw->core.y, 1543 tw->core.width, tw->core.height, 1544 BorderWidth(tw), 1545 (int) tw->core.depth, 1546 InputOutput, CopyFromParent, 1547 ((*valuemaskp) | CWBackPixel | CWWinGravity), 1548 values); 1549 1550 TFullWidth(tekscr) = (Dimension) width; 1551 TFullHeight(tekscr) = (Dimension) height; 1552 TWidth(tekscr) = (int) width - border; 1553 THeight(tekscr) = (int) height - border; 1554 TekScale(tekscr) = (double) TWidth(tekscr) / TEKWIDTH; 1555 if ((d = (double) THeight(tekscr) / (TEKHEIGHT + TEKTOPPAD + 1556 TEKBOTTOMPAD)) < TekScale(tekscr)) 1557 TekScale(tekscr) = d; 1558 1559 tekscr->cur.fontsize = TEK_FONT_LARGE; 1560 if (tw->tek.initial_font) { 1561 int result = TekGetFontSize(tw->tek.initial_font); 1562 if (result >= 0) 1563 tekscr->cur.fontsize = result; 1564 } 1565#define TestGIN(s) XmuCompareISOLatin1(tw->tek.gin_terminator_str, s) 1566 1567 if (TestGIN(GIN_TERM_NONE_STR) == 0) 1568 tekscr->gin_terminator = GIN_TERM_NONE; 1569 else if (TestGIN(GIN_TERM_CR_STR) == 0) 1570 tekscr->gin_terminator = GIN_TERM_CR; 1571 else if (TestGIN(GIN_TERM_EOT_STR) == 0) 1572 tekscr->gin_terminator = GIN_TERM_EOT; 1573 else 1574 fprintf(stderr, "%s: illegal GIN terminator setting \"%s\"\n", 1575 ProgramName, tw->tek.gin_terminator_str); 1576 1577 gcv.graphics_exposures = True; /* default */ 1578 gcv.font = tw->tek.Tfont[tekscr->cur.fontsize]->fid; 1579 gcv.foreground = T_COLOR(screen, TEK_FG); 1580 gcv.background = T_COLOR(screen, TEK_BG); 1581 1582 /* if font wasn't successfully opened, then gcv.font will contain 1583 the Default GC's ID, meaning that we must use the server default font. 1584 */ 1585 TEKgcFontMask = (unsigned long) ((gcv.font == DefaultGCID) ? 0 : GCFont); 1586 tekscr->TnormalGC = XCreateGC(XtDisplay(tw), TWindow(tekscr), 1587 (TEKgcFontMask | GCGraphicsExposures | 1588 GCForeground | GCBackground), 1589 &gcv); 1590 1591 gcv.function = GXinvert; 1592 gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ 1593 T_COLOR(screen, TEK_CURSOR)); 1594 gcv.join_style = JoinMiter; /* default */ 1595 gcv.line_width = 1; 1596 tekscr->TcursorGC = XCreateGC(XtDisplay(tw), TWindow(tekscr), 1597 (GCFunction | GCPlaneMask), &gcv); 1598 1599 gcv.foreground = T_COLOR(screen, TEK_FG); 1600 gcv.line_style = LineOnOffDash; 1601 gcv.line_width = 0; 1602 for (i = 0; i < TEKNUMLINES; i++) { 1603 tekscr->linepat[i] = XCreateGC(XtDisplay(tw), TWindow(tekscr), 1604 (GCForeground | GCLineStyle), &gcv); 1605 XSetDashes(XtDisplay(tw), tekscr->linepat[i], 0, 1606 (char *) dashes[i], dash_length[i]); 1607 } 1608 1609 TekBackground(tw, screen); 1610 1611 tekscr->margin = MARGIN1; /* Margin 1 */ 1612 tekscr->TekGIN = False; /* GIN off */ 1613 1614 XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow); 1615 1616 { /* there's gotta be a better way... */ 1617 static Arg args[] = 1618 { 1619 {XtNtitle, (XtArgVal) NULL}, 1620 {XtNiconName, (XtArgVal) NULL}, 1621 }; 1622 char *icon_name, *title, *tek_icon_name, *tek_title; 1623 1624 args[0].value = (XtArgVal) & icon_name; 1625 args[1].value = (XtArgVal) & title; 1626 XtGetValues(SHELL_OF(tw), args, 2); 1627 tek_icon_name = XtMalloc((Cardinal) strlen(icon_name) + 7); 1628 strcpy(tek_icon_name, icon_name); 1629 strcat(tek_icon_name, "(Tek)"); 1630 tek_title = XtMalloc((Cardinal) strlen(title) + 7); 1631 strcpy(tek_title, title); 1632 strcat(tek_title, "(Tek)"); 1633 args[0].value = (XtArgVal) tek_icon_name; 1634 args[1].value = (XtArgVal) tek_title; 1635 XtSetValues(SHELL_OF(tw), args, 2); 1636 XtFree(tek_icon_name); 1637 XtFree(tek_title); 1638 } 1639 1640 tek = TekRecord = &Tek0; 1641 tek->next = (TekLink *) 0; 1642 tek->fontsize = (unsigned short) tekscr->cur.fontsize; 1643 tek->count = 0; 1644 tek->ptr = tek->data; 1645 Tpushback = Tpushb; 1646 tekscr->cur_X = 0; 1647 tekscr->cur_Y = TEKHOME; 1648 line_pt = Tline; 1649 Ttoggled = True; 1650 tekscr->page = tekscr->cur; 1651 return; 1652} 1653 1654int 1655TekGetFontSize(const char *param) 1656{ 1657 int result; 1658 1659 if (XmuCompareISOLatin1(param, "l") == 0 || 1660 XmuCompareISOLatin1(param, "large") == 0) 1661 result = TEK_FONT_LARGE; 1662 else if (XmuCompareISOLatin1(param, "2") == 0 || 1663 XmuCompareISOLatin1(param, "two") == 0) 1664 result = TEK_FONT_2; 1665 else if (XmuCompareISOLatin1(param, "3") == 0 || 1666 XmuCompareISOLatin1(param, "three") == 0) 1667 result = TEK_FONT_3; 1668 else if (XmuCompareISOLatin1(param, "s") == 0 || 1669 XmuCompareISOLatin1(param, "small") == 0) 1670 result = TEK_FONT_SMALL; 1671 else 1672 result = -1; 1673 1674 return result; 1675} 1676 1677void 1678TekSetFontSize(TekWidget tw, Bool fromMenu, int newitem) 1679{ 1680 if (tw != 0) { 1681 XtermWidget xw = term; 1682 TekScreen *tekscr = TekScreenOf(tw); 1683 int oldsize = tekscr->cur.fontsize; 1684 int newsize = MI2FS(newitem); 1685 Font fid; 1686 1687 TRACE(("TekSetFontSize(%d) size %d ->%d\n", newitem, oldsize, newsize)); 1688 if (newsize < 0 || newsize >= TEKNUMFONTS) { 1689 Bell(xw, XkbBI_MinorError, 0); 1690 } else if (oldsize != newsize) { 1691 if (!Ttoggled) 1692 TCursorToggle(tw, TOGGLE); 1693 set_tekfont_menu_item(oldsize, False); 1694 1695 tekscr->cur.fontsize = newsize; 1696 if (fromMenu) 1697 tekscr->page.fontsize = newsize; 1698 1699 fid = tw->tek.Tfont[newsize]->fid; 1700 if (fid == DefaultGCID) { 1701 /* we didn't succeed in opening a real font 1702 for this size. Instead, use server default. */ 1703 XCopyGC(XtDisplay(tw), 1704 DefaultGC(XtDisplay(tw), DefaultScreen(XtDisplay(tw))), 1705 GCFont, tekscr->TnormalGC); 1706 } else { 1707 XSetFont(XtDisplay(tw), tekscr->TnormalGC, fid); 1708 } 1709 1710 set_tekfont_menu_item(newsize, True); 1711 if (!Ttoggled) 1712 TCursorToggle(tw, TOGGLE); 1713 1714 if (fromMenu) { 1715 /* we'll get an exposure event after changing fontsize, so we 1716 * have to clear the screen to avoid painting over the previous 1717 * text. 1718 */ 1719 TekClear(tw); 1720 } 1721 } 1722 } 1723} 1724 1725void 1726ChangeTekColors(TekWidget tw, TScreen * screen, ScrnColors * pNew) 1727{ 1728 TekScreen *tekscr = TekScreenOf(tw); 1729 int i; 1730 XGCValues gcv; 1731 1732 if (COLOR_DEFINED(pNew, TEK_FG)) { 1733 T_COLOR(screen, TEK_FG) = COLOR_VALUE(pNew, TEK_FG); 1734 TRACE(("... TEK_FG: %#lx\n", T_COLOR(screen, TEK_FG))); 1735 } 1736 if (COLOR_DEFINED(pNew, TEK_BG)) { 1737 T_COLOR(screen, TEK_BG) = COLOR_VALUE(pNew, TEK_BG); 1738 TRACE(("... TEK_BG: %#lx\n", T_COLOR(screen, TEK_BG))); 1739 } 1740 if (COLOR_DEFINED(pNew, TEK_CURSOR)) { 1741 T_COLOR(screen, TEK_CURSOR) = COLOR_VALUE(pNew, TEK_CURSOR); 1742 TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR))); 1743 } else { 1744 T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG); 1745 TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR))); 1746 } 1747 1748 if (tw) { 1749 XSetForeground(XtDisplay(tw), tekscr->TnormalGC, 1750 T_COLOR(screen, TEK_FG)); 1751 XSetBackground(XtDisplay(tw), tekscr->TnormalGC, 1752 T_COLOR(screen, TEK_BG)); 1753 if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) { 1754 BorderPixel(tw) = T_COLOR(screen, TEK_FG); 1755 BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG); 1756 if (XtWindow(XtParent(tw))) 1757 XSetWindowBorder(XtDisplay(tw), 1758 XtWindow(XtParent(tw)), 1759 BorderPixel(tw)); 1760 } 1761 1762 for (i = 0; i < TEKNUMLINES; i++) { 1763 XSetForeground(XtDisplay(tw), tekscr->linepat[i], 1764 T_COLOR(screen, TEK_FG)); 1765 } 1766 1767 gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ 1768 T_COLOR(screen, TEK_CURSOR)); 1769 XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv); 1770 TekBackground(tw, screen); 1771 } 1772 return; 1773} 1774 1775void 1776TekReverseVideo(TekWidget tw) 1777{ 1778 XtermWidget xw = term; 1779 TScreen *screen = TScreenOf(xw); 1780 TekScreen *tekscr = TekScreenOf(tw); 1781 int i; 1782 Pixel tmp; 1783 XGCValues gcv; 1784 1785 EXCHANGE(T_COLOR(screen, TEK_FG), T_COLOR(screen, TEK_BG), tmp); 1786 1787 T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG); 1788 1789 if (tw) { 1790 XSetForeground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_FG)); 1791 XSetBackground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_BG)); 1792 1793 if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) { 1794 BorderPixel(tw) = T_COLOR(screen, TEK_FG); 1795 BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG); 1796 if (XtWindow(XtParent(tw))) 1797 XSetWindowBorder(XtDisplay(tw), 1798 XtWindow(XtParent(tw)), 1799 BorderPixel(tw)); 1800 } 1801 1802 for (i = 0; i < TEKNUMLINES; i++) { 1803 XSetForeground(XtDisplay(tw), tekscr->linepat[i], 1804 T_COLOR(screen, TEK_FG)); 1805 } 1806 1807 gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ 1808 T_COLOR(screen, TEK_CURSOR)); 1809 XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv); 1810 TekBackground(tw, screen); 1811 } 1812} 1813 1814static void 1815TekBackground(TekWidget tw, TScreen * screen) 1816{ 1817 TekScreen *tekscr = TekScreenOf(tw); 1818 1819 if (TWindow(tekscr)) 1820 XSetWindowBackground(XtDisplay(tw), TWindow(tekscr), 1821 T_COLOR(screen, TEK_BG)); 1822} 1823 1824/* 1825 * Toggles cursor on or off at cursor position in screen. 1826 */ 1827void 1828TCursorToggle(TekWidget tw, int toggle) /* TOGGLE or CLEAR */ 1829{ 1830 XtermWidget xw = term; 1831 TekScreen *tekscr = TekScreenOf(tw); 1832 TScreen *screen = TScreenOf(xw); 1833 int c, x, y; 1834 unsigned int cellwidth, cellheight; 1835 1836 if (!TEK4014_SHOWN(xw)) 1837 return; 1838 1839 TRACE(("TCursorToggle %s\n", (toggle == TOGGLE) ? "toggle" : "clear")); 1840 c = tekscr->cur.fontsize; 1841 cellwidth = (unsigned) tw->tek.Tfont[c]->max_bounds.width; 1842 cellheight = (unsigned) (tw->tek.Tfont[c]->ascent + 1843 tw->tek.Tfont[c]->descent); 1844 1845 x = (int) ((tekscr->cur_X * TekScale(tekscr)) + screen->border); 1846 y = (int) (((TEKHEIGHT + TEKTOPPAD - tekscr->cur_Y) * TekScale(tekscr)) 1847 + screen->border - tw->tek.tobaseline[c]); 1848 1849 if (toggle == TOGGLE) { 1850 if (screen->select || screen->always_highlight) 1851 XFillRectangle(XtDisplay(tw), TWindow(tekscr), 1852 tekscr->TcursorGC, x, y, 1853 cellwidth, cellheight); 1854 else { /* fix to use different GC! */ 1855 XDrawRectangle(XtDisplay(tw), TWindow(tekscr), 1856 tekscr->TcursorGC, x, y, 1857 cellwidth - 1, cellheight - 1); 1858 } 1859 } else { 1860 /* Clear the entire rectangle, even though we may only 1861 * have drawn an outline. This fits with our refresh 1862 * scheme of redrawing the entire window on any expose 1863 * event and is easier than trying to figure out exactly 1864 * which part of the cursor needs to be erased. 1865 */ 1866 XClearArea(XtDisplay(tw), TWindow(tekscr), x, y, 1867 cellwidth, cellheight, False); 1868 } 1869} 1870 1871void 1872TekSimulatePageButton(TekWidget tw, Bool reset) 1873{ 1874 if (tw != 0) { 1875 TekScreen *tekscr = TekScreenOf(tw); 1876 1877 if (reset) { 1878 memset(&tekscr->cur, 0, sizeof tekscr->cur); 1879 } 1880 tekRefreshList = (TekLink *) 0; 1881 TekPage(tw); 1882 tekscr->cur_X = 0; 1883 tekscr->cur_Y = TEKHOME; 1884 } 1885} 1886 1887/* write copy of screen to a file */ 1888 1889void 1890TekCopy(TekWidget tw) 1891{ 1892 if (tw != 0) { 1893 XtermWidget xw = term; 1894 TekScreen *tekscr = TekScreenOf(tw); 1895 TScreen *screen = TScreenOf(xw); 1896 1897 TekLink *Tp; 1898 char buf[TIMESTAMP_LEN + 10]; 1899 char initbuf[5]; 1900 int tekcopyfd; 1901 1902 timestamp_filename(buf, "COPY"); 1903 if (access(buf, F_OK) >= 0 1904 && access(buf, W_OK) < 0) { 1905 Bell(xw, XkbBI_MinorError, 0); 1906 return; 1907 } 1908#ifndef VMS 1909 if (access(".", W_OK) < 0) { /* can't write in directory */ 1910 Bell(xw, XkbBI_MinorError, 0); 1911 return; 1912 } 1913#endif 1914 1915 tekcopyfd = open_userfile(screen->uid, screen->gid, buf, False); 1916 if (tekcopyfd >= 0) { 1917 sprintf(initbuf, "%c%c%c%c", 1918 ANSI_ESC, (char) (tekscr->page.fontsize + '8'), 1919 ANSI_ESC, (char) (tekscr->page.linetype + '`')); 1920 IGNORE_RC(write(tekcopyfd, initbuf, (size_t) 4)); 1921 Tp = &Tek0; 1922 do { 1923 IGNORE_RC(write(tekcopyfd, Tp->data, (size_t) Tp->count)); 1924 Tp = Tp->next; 1925 } while (Tp); 1926 close(tekcopyfd); 1927 } 1928 } 1929} 1930 1931/*ARGSUSED*/ 1932void 1933HandleGINInput(Widget w, 1934 XEvent * event GCC_UNUSED, 1935 String * param_list, 1936 Cardinal *nparamsp) 1937{ 1938 XtermWidget xw = term; 1939 TekWidget tw = getTekWidget(w); 1940 1941 if (tw != 0) { 1942 TekScreen *tekscr = TekScreenOf(tw); 1943 1944 if (tekscr->TekGIN && *nparamsp == 1) { 1945 int c = param_list[0][0]; 1946 switch (c) { 1947 case 'l': 1948 case 'm': 1949 case 'r': 1950 case 'L': 1951 case 'M': 1952 case 'R': 1953 break; 1954 default: 1955 Bell(xw, XkbBI_MinorError, 0); /* let them know they goofed */ 1956 c = 'l'; /* provide a default */ 1957 } 1958 TekEnqMouse(tw, c | 0x80); 1959 TekGINoff(tw); 1960 } else { 1961 Bell(xw, XkbBI_MinorError, 0); 1962 } 1963 } 1964} 1965 1966/* 1967 * Check if the current widget, or any parent, is the VT100 "xterm" widget. 1968 */ 1969TekWidget 1970getTekWidget(Widget w) 1971{ 1972 TekWidget xw; 1973 1974 if (w == 0) { 1975 xw = (TekWidget) CURRENT_EMU(); 1976 if (!IsTekWidget(xw)) { 1977 xw = 0; 1978 } 1979 } else if (IsTekWidget(w)) { 1980 xw = (TekWidget) w; 1981 } else { 1982 xw = getTekWidget(XtParent(w)); 1983 } 1984 TRACE2(("getTekWidget %p -> %p\n", w, xw)); 1985 return xw; 1986} 1987