Tekproc.c revision e0a2b6df
1/* $XTermId: Tekproc.c,v 1.194 2012/09/07 09:08:44 tom Exp $ */ 2 3/* 4 * Copyright 2001-2011,2012 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 xtermWarning("Not enough core for Tek mode\n"); 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 (xtermAppPending() & 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 TRACE(("TekClear\n")); 893 nplot = 0; 894 line_pt = Tline; 895 if (TWindow(tekscr)) 896 XClearWindow(XtDisplay(tw), TWindow(tekscr)); 897} 898 899/* this should become the Tek Widget's Resize proc */ 900static void 901TekConfigure(Widget w) 902{ 903 TekWidget tw = getTekWidget(w); 904 if (tw != 0) { 905 XtermWidget xw = term; 906 TekScreen *tekscr = TekScreenOf(tw); 907 TScreen *screen = TScreenOf(xw); 908 int border = 2 * screen->border; 909 double d; 910 911 TRACE(("TekConfigure\n")); 912 TekClear(tw); 913 TWidth(tekscr) = w->core.width - border; 914 THeight(tekscr) = w->core.height - border; 915 TekScale(tekscr) = (double) TWidth(tekscr) / TEKWIDTH; 916 if ((d = (double) THeight(tekscr) / (TEKHEIGHT + TEKTOPPAD + TEKBOTTOMPAD)) 917 < TekScale(tekscr)) 918 TekScale(tekscr) = d; 919 TFullWidth(tekscr) = w->core.width; 920 TFullHeight(tekscr) = w->core.height; 921 } 922} 923 924/*ARGSUSED*/ 925void 926TekExpose(Widget w, 927 XEvent * event GCC_UNUSED, 928 Region region GCC_UNUSED) 929{ 930 TekWidget tw = getTekWidget(w); 931 if (tw != 0) { 932 TekScreen *tekscr = TekScreenOf(tw); 933 934 TRACE(("TekExpose {{\n")); 935 936#ifdef lint 937 region = region; 938#endif 939 if (!Ttoggled) 940 TCursorToggle(tw, CLEAR); 941 Ttoggled = True; 942 Tpushback = Tpushb; 943 tekscr->cur_X = 0; 944 tekscr->cur_Y = TEKHOME; 945 tekscr->cur = tekscr->page; 946 TekSetFontSize(tw, False, tekscr->cur.fontsize); 947 tekscr->margin = MARGIN1; 948 if (tekscr->TekGIN) { 949 tekscr->TekGIN = NULL; 950 TekGINoff(tw); 951 } 952 tekRefreshList = &Tek0; 953 rptr = tekRefreshList->data; 954 rcnt = tekRefreshList->count; 955 Tparsestate = curstate = Talptable; 956 TRACE(("TekExpose resets data to replay %d bytes\n", rcnt)); 957 first_map_occurred(); 958 if (!tekscr->waitrefresh) 959 TekRefresh(tw); 960 TRACE(("}} TekExpose\n")); 961 } 962} 963 964void 965TekRefresh(TekWidget tw) 966{ 967 if (tw != 0) { 968 XtermWidget xw = term; 969 TScreen *screen = TScreenOf(xw); 970 TekScreen *tekscr = TekScreenOf(tw); 971 static Cursor wait_cursor = None; 972 973 if (wait_cursor == None) 974 wait_cursor = make_colored_cursor(XC_watch, 975 T_COLOR(screen, MOUSE_FG), 976 T_COLOR(screen, MOUSE_BG)); 977 XDefineCursor(XtDisplay(tw), TWindow(tekscr), wait_cursor); 978 XFlush(XtDisplay(tw)); 979 if (!setjmp(Tekjump)) 980 Tekparse(tw); 981 XDefineCursor(XtDisplay(tw), TWindow(tekscr), 982 (tekscr->TekGIN && GINcursor) ? GINcursor : tekscr->arrow); 983 } 984} 985 986void 987TekRepaint(TekWidget tw) 988{ 989 TRACE(("TekRepaint\n")); 990 TekClear(tw); 991 TekExpose((Widget) tw, (XEvent *) NULL, (Region) NULL); 992} 993 994static void 995TekPage(TekWidget tw) 996{ 997 TekScreen *tekscr = TekScreenOf(tw); 998 TekLink *tek; 999 1000 TRACE(("TekPage\n")); 1001 TekClear(tw); 1002 tekscr->cur_X = 0; 1003 tekscr->cur_Y = TEKHOME; 1004 tekscr->margin = MARGIN1; 1005 tekscr->page = tekscr->cur; 1006 if (tekscr->TekGIN) 1007 TekGINoff(tw); 1008 tek = TekRecord = &Tek0; 1009 tek->fontsize = (unsigned short) tekscr->cur.fontsize; 1010 tek->count = 0; 1011 tek->ptr = tek->data; 1012 tek = tek->next; 1013 if (tek) 1014 do { 1015 TekLink *tek2 = tek->next; 1016 1017 free(tek); 1018 tek = tek2; 1019 } while (tek); 1020 TekRecord->next = (TekLink *) 0; 1021 tekRefreshList = (TekLink *) 0; 1022 Ttoggled = True; 1023 Tparsestate = curstate = Talptable; /* Tek Alpha mode */ 1024} 1025 1026#define EXTRABITS 017 1027#define FIVEBITS 037 1028#define HIBITS (FIVEBITS << SHIFTHI) 1029#define LOBITS (FIVEBITS << SHIFTLO) 1030#define SHIFTHI 7 1031#define SHIFTLO 2 1032#define TWOBITS 03 1033 1034static int 1035getpoint(TekWidget tw) 1036{ 1037 int c, x, y, e, lo_y = 0; 1038 TekScreen *tekscr = TekScreenOf(tw); 1039 1040 x = tekscr->cur.x; 1041 y = tekscr->cur.y; 1042 for (;;) { 1043 if ((c = (int) input()) < ' ') { /* control character */ 1044 unput(c); 1045 return (0); 1046 } 1047 if (c < '@') { /* Hi X or Hi Y */ 1048 if (lo_y) { /* seen a Lo Y, so this must be Hi X */ 1049 x &= ~HIBITS; 1050 x |= (c & FIVEBITS) << SHIFTHI; 1051 continue; 1052 } 1053 /* else Hi Y */ 1054 y &= ~HIBITS; 1055 y |= (c & FIVEBITS) << SHIFTHI; 1056 continue; 1057 } 1058 if (c < '`') { /* Lo X */ 1059 x &= ~LOBITS; 1060 x |= (c & FIVEBITS) << SHIFTLO; 1061 tekscr->cur.x = x; 1062 tekscr->cur.y = y; 1063 return (1); /* OK */ 1064 } 1065 /* else Lo Y */ 1066 if (lo_y) { /* seen a Lo Y, so other must be extra bits */ 1067 e = (y >> SHIFTLO) & EXTRABITS; 1068 x &= ~TWOBITS; 1069 x |= e & TWOBITS; 1070 y &= ~TWOBITS; 1071 y |= (e >> SHIFTLO) & TWOBITS; 1072 } 1073 y &= ~LOBITS; 1074 y |= (c & FIVEBITS) << SHIFTLO; 1075 lo_y++; 1076 } 1077} 1078 1079static void 1080TCursorBack(TekWidget tw) 1081{ 1082 TekScreen *tekscr = TekScreenOf(tw); 1083 struct Tek_Char *t; 1084 int x, l; 1085 1086 x = (tekscr->cur_X -= 1087 (t = &TekChar[tekscr->cur.fontsize])->hsize 1088 ); 1089 1090 if (((tekscr->margin == MARGIN1) && (x < 0)) 1091 || ((tekscr->margin == MARGIN2) && (x < TEKWIDTH / 2))) { 1092 if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= 1093 t->nlines) { 1094 tekscr->margin = !tekscr->margin; 1095 l = 0; 1096 } 1097 tekscr->cur_Y = l * t->vsize; 1098 tekscr->cur_X = (t->charsperline - 1) * t->hsize; 1099 } 1100} 1101 1102static void 1103TCursorForward(TekWidget tw) 1104{ 1105 TekScreen *tekscr = TekScreenOf(tw); 1106 struct Tek_Char *t; 1107 int l; 1108 1109 if ((tekscr->cur_X += 1110 (t = &TekChar[tekscr->cur.fontsize])->hsize 1111 ) > TEKWIDTH 1112 ) { 1113 if ((l = tekscr->cur_Y / t->vsize - 1) < 0) { 1114 tekscr->margin = !tekscr->margin; 1115 l = t->nlines - 1; 1116 } 1117 tekscr->cur_Y = l * t->vsize; 1118 tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 : TEKWIDTH / 2; 1119 } 1120} 1121 1122static void 1123TCursorUp(TekWidget tw) 1124{ 1125 TekScreen *tekscr = TekScreenOf(tw); 1126 struct Tek_Char *t; 1127 int l; 1128 1129 t = &TekChar[tekscr->cur.fontsize]; 1130 1131 if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= t->nlines) { 1132 l = 0; 1133 if ((tekscr->margin = !tekscr->margin) != MARGIN1) { 1134 if (tekscr->cur_X < TEKWIDTH / 2) 1135 tekscr->cur_X += TEKWIDTH / 2; 1136 } else if (tekscr->cur_X >= TEKWIDTH / 2) 1137 tekscr->cur_X -= TEKWIDTH / 2; 1138 } 1139 tekscr->cur_Y = l * t->vsize; 1140} 1141 1142static void 1143TCursorDown(TekWidget tw) 1144{ 1145 TekScreen *tekscr = TekScreenOf(tw); 1146 struct Tek_Char *t; 1147 int l; 1148 1149 t = &TekChar[tekscr->cur.fontsize]; 1150 1151 if ((l = tekscr->cur_Y / t->vsize - 1) < 0) { 1152 l = t->nlines - 1; 1153 if ((tekscr->margin = !tekscr->margin) != MARGIN1) { 1154 if (tekscr->cur_X < TEKWIDTH / 2) 1155 tekscr->cur_X += TEKWIDTH / 2; 1156 } else if (tekscr->cur_X >= TEKWIDTH / 2) 1157 tekscr->cur_X -= TEKWIDTH / 2; 1158 } 1159 tekscr->cur_Y = l * t->vsize; 1160} 1161 1162static void 1163AddToDraw(TekWidget tw, int x1, int y1, int x2, int y2) 1164{ 1165 XtermWidget xw = term; 1166 TScreen *screen = TScreenOf(xw); 1167 TekScreen *tekscr = TekScreenOf(tw); 1168 XSegment *lp; 1169 1170 TRACE(("AddToDraw (%d,%d) (%d,%d)\n", x1, y1, x2, y2)); 1171 if (nplot >= MAX_PTS) { 1172 TekFlush(tw); 1173 } 1174 lp = line_pt++; 1175 lp->x1 = (short) (x1 * TekScale(tekscr) + screen->border); 1176 lp->y1 = (short) ((TEKHEIGHT + TEKTOPPAD - y1) * TekScale(tekscr) + 1177 screen->border); 1178 lp->x2 = (short) (x2 * TekScale(tekscr) + screen->border); 1179 lp->y2 = (short) ((TEKHEIGHT + TEKTOPPAD - y2) * TekScale(tekscr) + 1180 screen->border); 1181 nplot++; 1182 TRACE(("...AddToDraw %d points\n", nplot)); 1183} 1184 1185static void 1186TekDraw(TekWidget tw, int x, int y) 1187{ 1188 TekScreen *tekscr = TekScreenOf(tw); 1189 1190 if (nplot == 0 || T_lastx != tekscr->cur_X || T_lasty != tekscr->cur_Y) { 1191 /* 1192 * We flush on each unconnected line segment if the line 1193 * type is not solid. This solves a bug in X when drawing 1194 * points while the line type is not solid. 1195 */ 1196 if (nplot > 0 && tekscr->cur.linetype != SOLIDLINE) 1197 TekFlush(tw); 1198 } 1199 AddToDraw(tw, tekscr->cur_X, tekscr->cur_Y, x, y); 1200 T_lastx = tekscr->cur_X = x; 1201 T_lasty = tekscr->cur_Y = y; 1202} 1203 1204static void 1205TekFlush(TekWidget tw) 1206{ 1207 TekScreen *tekscr = TekScreenOf(tw); 1208 1209 TRACE(("TekFlush\n")); 1210 XDrawSegments(XtDisplay(tw), TWindow(tekscr), 1211 ((tekscr->cur.linetype == SOLIDLINE) 1212 ? tekscr->TnormalGC 1213 : tekscr->linepat[tekscr->cur.linetype - 1]), 1214 Tline, nplot); 1215 nplot = 0; 1216 line_pt = Tline; 1217} 1218 1219void 1220TekGINoff(TekWidget tw) 1221{ 1222 TekScreen *tekscr = TekScreenOf(tw); 1223 1224 TRACE(("TekGINoff\n")); 1225 XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow); 1226 if (GINcursor) 1227 XFreeCursor(XtDisplay(tw), GINcursor); 1228 if (tekscr->TekGIN) { 1229 *tekscr->TekGIN = ANSI_CAN; /* modify recording */ 1230 tekscr->TekGIN = NULL; 1231 } 1232} 1233 1234void 1235TekEnqMouse(TekWidget tw, int c) /* character pressed */ 1236{ 1237 XtermWidget xw = term; 1238 TScreen *screen = TScreenOf(xw); 1239 TekScreen *tekscr = TekScreenOf(tw); 1240 int mousex, mousey, rootx, rooty; 1241 unsigned int mask; /* XQueryPointer */ 1242 Window root, subw; 1243 1244 TRACE(("TekEnqMouse\n")); 1245 XQueryPointer( 1246 XtDisplay(tw), TWindow(tekscr), 1247 &root, &subw, 1248 &rootx, &rooty, 1249 &mousex, &mousey, 1250 &mask); 1251 if ((mousex = (int) ((mousex - screen->border) / TekScale(tekscr))) < 0) 1252 mousex = 0; 1253 else if (mousex >= TEKWIDTH) 1254 mousex = TEKWIDTH - 1; 1255 if ((mousey = (int) (TEKHEIGHT + TEKTOPPAD - (mousey - screen->border) / 1256 TekScale(tekscr))) < 0) 1257 mousey = 0; 1258 else if (mousey >= TEKHEIGHT) 1259 mousey = TEKHEIGHT - 1; 1260 TekEnq(tw, (unsigned) c, mousex, mousey); 1261} 1262 1263static void 1264TekEnq(TekWidget tw, 1265 unsigned status, 1266 int x, 1267 int y) 1268{ 1269 XtermWidget xw = term; 1270 TScreen *screen = TScreenOf(xw); 1271 TekScreen *tekscr = TekScreenOf(tw); 1272 Char cplot[7]; 1273 int len = 5; 1274 int adj = (status != 0) ? 0 : 1; 1275 1276 TRACE(("TekEnq\n")); 1277 cplot[0] = (Char) status; 1278 /* Translate x and y to Tektronix code */ 1279 cplot[1] = (Char) (040 | ((x >> SHIFTHI) & FIVEBITS)); 1280 cplot[2] = (Char) (040 | ((x >> SHIFTLO) & FIVEBITS)); 1281 cplot[3] = (Char) (040 | ((y >> SHIFTHI) & FIVEBITS)); 1282 cplot[4] = (Char) (040 | ((y >> SHIFTLO) & FIVEBITS)); 1283 1284 if (tekscr->gin_terminator != GIN_TERM_NONE) 1285 cplot[len++] = '\r'; 1286 if (tekscr->gin_terminator == GIN_TERM_EOT) 1287 cplot[len++] = '\004'; 1288#ifdef VMS 1289 tt_write(cplot + adj, len - adj); 1290#else /* VMS */ 1291 v_write(screen->respond, cplot + adj, (unsigned) (len - adj)); 1292#endif /* VMS */ 1293} 1294 1295void 1296TekRun(void) 1297{ 1298 XtermWidget xw = term; 1299 1300 assert(xw != 0); 1301 if (tekWidget == 0) { 1302 TekInit(); 1303 } 1304 if (tekWidget != 0) { 1305 TRACE(("TekRun ...\n")); 1306 1307 if (!TEK4014_SHOWN(xw)) { 1308 set_tek_visibility(True); 1309 } 1310 update_vttekmode(); 1311 update_vtshow(); 1312 update_tekshow(); 1313 set_tekhide_sensitivity(); 1314 1315 Tpushback = Tpushb; 1316 Ttoggled = True; 1317 if (!setjmp(Tekend)) 1318 Tekparse(tekWidget); 1319 if (!Ttoggled) { 1320 TCursorToggle(tekWidget, TOGGLE); 1321 Ttoggled = True; 1322 } 1323 TEK4014_ACTIVE(xw) = False; 1324 } else { 1325 TEK4014_ACTIVE(xw) = False; 1326 if (VWindow(TScreenOf(xw)) == 0) { 1327 Exit(ERROR_TINIT); 1328 } 1329 } 1330} 1331 1332#define DOTTED_LENGTH 2 1333#define DOT_DASHED_LENGTH 4 1334#define SHORT_DASHED_LENGTH 2 1335#define LONG_DASHED_LENGTH 2 1336 1337static int dash_length[TEKNUMLINES] = 1338{ 1339 DOTTED_LENGTH, 1340 DOT_DASHED_LENGTH, 1341 SHORT_DASHED_LENGTH, 1342 LONG_DASHED_LENGTH, 1343}; 1344 1345static unsigned char dotted[DOTTED_LENGTH] = 1346{3, 1}; 1347static unsigned char dot_dashed[DOT_DASHED_LENGTH] = 1348{3, 4, 3, 1}; 1349static unsigned char short_dashed[SHORT_DASHED_LENGTH] = 1350{4, 4}; 1351static unsigned char long_dashed[LONG_DASHED_LENGTH] = 1352{4, 7}; 1353 1354static unsigned char *dashes[TEKNUMLINES] = 1355{ 1356 dotted, 1357 dot_dashed, 1358 short_dashed, 1359 long_dashed, 1360}; 1361 1362/* 1363 * The following is called to create the tekWidget 1364 */ 1365 1366static void 1367TekInitialize(Widget wrequest, 1368 Widget new_arg, 1369 ArgList args GCC_UNUSED, 1370 Cardinal *num_args GCC_UNUSED) 1371{ 1372 TekWidget request = (TekWidget) wrequest; 1373 TekWidget wnew = (TekWidget) new_arg; 1374 Widget tekparent = SHELL_OF(wnew); 1375#ifndef NO_ACTIVE_ICON 1376 TekScreen *screen = TekScreenOf((TekWidget) wnew); 1377#endif 1378 int n; 1379 1380 TRACE(("TekInitialize\n")); 1381 1382 /* look for focus related events on the shell, because we need 1383 * to care about the shell's border being part of our focus. 1384 */ 1385 XtAddEventHandler(tekparent, EnterWindowMask, False, 1386 HandleEnterWindow, (Opaque) 0); 1387 XtAddEventHandler(tekparent, LeaveWindowMask, False, 1388 HandleLeaveWindow, (Opaque) 0); 1389 XtAddEventHandler(tekparent, FocusChangeMask, False, 1390 HandleFocusChange, (Opaque) 0); 1391 XtAddEventHandler(new_arg, PropertyChangeMask, False, 1392 HandleBellPropertyChange, (Opaque) 0); 1393 1394#ifndef NO_ACTIVE_ICON 1395 screen->whichTwin = &(screen->fullTwin); 1396#endif /* NO_ACTIVE_ICON */ 1397 1398 for (n = 0; n < TEKNUMFONTS; ++n) { 1399 wnew->tek.Tfont[n] = request->tek.Tfont[n]; 1400 } 1401 1402 init_Sres(tek.initial_font); 1403 init_Sres(tek.gin_terminator_str); 1404#if OPT_TOOLBAR 1405 init_Ires(tek.tb_info.menu_height); 1406 wnew->tek.tb_info.menu_bar = request->tek.tb_info.menu_bar; 1407#endif 1408} 1409 1410static void 1411TekRealize(Widget gw, 1412 XtValueMask * valuemaskp, 1413 XSetWindowAttributes * values) 1414{ 1415 XtermWidget xw = term; 1416 TScreen *screen = TScreenOf(xw); 1417 TekWidget tw = (TekWidget) gw; 1418 TekScreen *tekscr = TekScreenOf(tw); 1419 int i; 1420 TekLink *tek; 1421 double d; 1422 int border = 2 * screen->border; 1423 int pr; 1424 XGCValues gcv; 1425 int winX, winY; 1426 unsigned width, height; 1427 char Tdefault[32]; 1428 unsigned long TEKgcFontMask; 1429 1430 TRACE(("TekRealize\n")); 1431 memset(tekscr, 0, sizeof(*tekscr)); 1432 1433#ifndef NO_ACTIVE_ICON 1434 tekscr->whichTwin = &tekscr->fullTwin; 1435#endif /* NO_ACTIVE_ICON */ 1436 1437 BorderPixel(tw) = BorderPixel(xw); 1438 1439 tekscr->arrow = make_colored_cursor(XC_left_ptr, 1440 T_COLOR(screen, MOUSE_FG), 1441 T_COLOR(screen, MOUSE_BG)); 1442 1443 for (i = 0; i < TEKNUMFONTS; i++) { 1444 if (!tw->tek.Tfont[i]) { 1445 tw->tek.Tfont[i] = XQueryFont(XtDisplay(tw), DefaultGCID); 1446 } 1447 TRACE(("Tfont[%d] %dx%d\n", 1448 i, 1449 tw->tek.Tfont[i]->ascent + 1450 tw->tek.Tfont[i]->descent, 1451 tw->tek.Tfont[i]->max_bounds.width)); 1452 tw->tek.tobaseline[i] = tw->tek.Tfont[i]->ascent; 1453 } 1454 1455 if (!TekPtyData()) 1456 return; 1457 1458 if (xw->misc.T_geometry == NULL) { 1459 int defwidth, defheight; 1460 1461 if (xw->misc.tekSmall) { 1462 defwidth = TEKMINWIDTH; 1463 defheight = TEKMINHEIGHT; 1464 } else { 1465 defwidth = TEKDEFWIDTH; 1466 defheight = TEKDEFHEIGHT; 1467 } 1468 sprintf(Tdefault, "=%dx%d", defwidth + border, defheight + border); 1469 xw->misc.T_geometry = Tdefault; 1470 } 1471 1472 winX = 1; 1473 winY = 1; 1474 width = (unsigned) (TEKDEFWIDTH + border); 1475 height = (unsigned) (TEKDEFHEIGHT + border); 1476 1477 TRACE(("parsing T_geometry %s\n", NonNull(xw->misc.T_geometry))); 1478 pr = XParseGeometry(xw->misc.T_geometry, 1479 &winX, 1480 &winY, 1481 &width, 1482 &height); 1483 TRACE(("... position %d,%d size %dx%d\n", winY, winX, height, width)); 1484 if ((pr & XValue) && (pr & XNegative)) 1485 winX += DisplayWidth(XtDisplay(tw), DefaultScreen(XtDisplay(tw))) 1486 - (int) width - (BorderWidth(SHELL_OF(xw)) * 2); 1487 if ((pr & YValue) && (pr & YNegative)) 1488 winY += DisplayHeight(XtDisplay(tw), DefaultScreen(XtDisplay(tw))) 1489 - (int) height - (BorderWidth(SHELL_OF(xw)) * 2); 1490 1491 /* set up size hints */ 1492 tw->hints.min_width = TEKMINWIDTH + border; 1493 tw->hints.min_height = TEKMINHEIGHT + border; 1494 tw->hints.width_inc = 1; 1495 tw->hints.height_inc = 1; 1496 tw->hints.flags = PMinSize | PResizeInc; 1497 tw->hints.x = winX; 1498 tw->hints.y = winY; 1499 if ((XValue & pr) || (YValue & pr)) { 1500 tw->hints.flags |= USSize | USPosition; 1501 tw->hints.flags |= PWinGravity; 1502 switch (pr & (XNegative | YNegative)) { 1503 case 0: 1504 tw->hints.win_gravity = NorthWestGravity; 1505 break; 1506 case XNegative: 1507 tw->hints.win_gravity = NorthEastGravity; 1508 break; 1509 case YNegative: 1510 tw->hints.win_gravity = SouthWestGravity; 1511 break; 1512 default: 1513 tw->hints.win_gravity = SouthEastGravity; 1514 break; 1515 } 1516 } else { 1517 /* set a default size, but do *not* set position */ 1518 tw->hints.flags |= PSize; 1519 } 1520 tw->hints.width = (int) width; 1521 tw->hints.height = (int) height; 1522 if ((WidthValue & pr) || (HeightValue & pr)) 1523 tw->hints.flags |= USSize; 1524 else 1525 tw->hints.flags |= PSize; 1526 1527 (void) REQ_RESIZE((Widget) tw, 1528 (Dimension) width, (Dimension) height, 1529 &tw->core.width, &tw->core.height); 1530 1531 /* XXX This is bogus. We are parsing geometries too late. This 1532 * is information that the shell widget ought to have before we get 1533 * realized, so that it can do the right thing. 1534 */ 1535 if (tw->hints.flags & USPosition) 1536 XMoveWindow(XtDisplay(tw), TShellWindow, tw->hints.x, tw->hints.y); 1537 1538 XSetWMNormalHints(XtDisplay(tw), TShellWindow, &tw->hints); 1539 XFlush(XtDisplay(tw)); /* get it out to window manager */ 1540 1541 values->win_gravity = NorthWestGravity; 1542 values->background_pixel = T_COLOR(screen, TEK_BG); 1543 1544 XtWindow(tw) = TWindow(tekscr) = 1545 XCreateWindow(XtDisplay(tw), 1546 VShellWindow(tw), 1547 tw->core.x, tw->core.y, 1548 tw->core.width, tw->core.height, 1549 BorderWidth(tw), 1550 (int) tw->core.depth, 1551 InputOutput, CopyFromParent, 1552 ((*valuemaskp) | CWBackPixel | CWWinGravity), 1553 values); 1554 1555 TFullWidth(tekscr) = (Dimension) width; 1556 TFullHeight(tekscr) = (Dimension) height; 1557 TWidth(tekscr) = (int) width - border; 1558 THeight(tekscr) = (int) height - border; 1559 TekScale(tekscr) = (double) TWidth(tekscr) / TEKWIDTH; 1560 if ((d = (double) THeight(tekscr) / (TEKHEIGHT + TEKTOPPAD + 1561 TEKBOTTOMPAD)) < TekScale(tekscr)) 1562 TekScale(tekscr) = d; 1563 1564 tekscr->cur.fontsize = TEK_FONT_LARGE; 1565 if (tw->tek.initial_font) { 1566 int result = TekGetFontSize(tw->tek.initial_font); 1567 if (result >= 0) 1568 tekscr->cur.fontsize = result; 1569 } 1570#define TestGIN(s) XmuCompareISOLatin1(tw->tek.gin_terminator_str, s) 1571 1572 if (TestGIN(GIN_TERM_NONE_STR) == 0) 1573 tekscr->gin_terminator = GIN_TERM_NONE; 1574 else if (TestGIN(GIN_TERM_CR_STR) == 0) 1575 tekscr->gin_terminator = GIN_TERM_CR; 1576 else if (TestGIN(GIN_TERM_EOT_STR) == 0) 1577 tekscr->gin_terminator = GIN_TERM_EOT; 1578 else 1579 xtermWarning("illegal GIN terminator setting \"%s\"\n", 1580 tw->tek.gin_terminator_str); 1581 1582 gcv.graphics_exposures = True; /* default */ 1583 gcv.font = tw->tek.Tfont[tekscr->cur.fontsize]->fid; 1584 gcv.foreground = T_COLOR(screen, TEK_FG); 1585 gcv.background = T_COLOR(screen, TEK_BG); 1586 1587 /* if font wasn't successfully opened, then gcv.font will contain 1588 the Default GC's ID, meaning that we must use the server default font. 1589 */ 1590 TEKgcFontMask = (unsigned long) ((gcv.font == DefaultGCID) ? 0 : GCFont); 1591 tekscr->TnormalGC = XCreateGC(XtDisplay(tw), TWindow(tekscr), 1592 (TEKgcFontMask | GCGraphicsExposures | 1593 GCForeground | GCBackground), 1594 &gcv); 1595 1596 gcv.function = GXinvert; 1597 gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ 1598 T_COLOR(screen, TEK_CURSOR)); 1599 gcv.join_style = JoinMiter; /* default */ 1600 gcv.line_width = 1; 1601 tekscr->TcursorGC = XCreateGC(XtDisplay(tw), TWindow(tekscr), 1602 (GCFunction | GCPlaneMask), &gcv); 1603 1604 gcv.foreground = T_COLOR(screen, TEK_FG); 1605 gcv.line_style = LineOnOffDash; 1606 gcv.line_width = 0; 1607 for (i = 0; i < TEKNUMLINES; i++) { 1608 tekscr->linepat[i] = XCreateGC(XtDisplay(tw), TWindow(tekscr), 1609 (GCForeground | GCLineStyle), &gcv); 1610 XSetDashes(XtDisplay(tw), tekscr->linepat[i], 0, 1611 (char *) dashes[i], dash_length[i]); 1612 } 1613 1614 TekBackground(tw, screen); 1615 1616 tekscr->margin = MARGIN1; /* Margin 1 */ 1617 tekscr->TekGIN = False; /* GIN off */ 1618 1619 XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow); 1620 1621 { /* there's gotta be a better way... */ 1622 static Arg args[] = 1623 { 1624 {XtNtitle, (XtArgVal) NULL}, 1625 {XtNiconName, (XtArgVal) NULL}, 1626 }; 1627 char *icon_name, *title, *tek_icon_name, *tek_title; 1628 1629 args[0].value = (XtArgVal) & icon_name; 1630 args[1].value = (XtArgVal) & title; 1631 XtGetValues(SHELL_OF(tw), args, 2); 1632 tek_icon_name = XtMalloc((Cardinal) strlen(icon_name) + 7); 1633 strcpy(tek_icon_name, icon_name); 1634 strcat(tek_icon_name, "(Tek)"); 1635 tek_title = XtMalloc((Cardinal) strlen(title) + 7); 1636 strcpy(tek_title, title); 1637 strcat(tek_title, "(Tek)"); 1638 args[0].value = (XtArgVal) tek_icon_name; 1639 args[1].value = (XtArgVal) tek_title; 1640 XtSetValues(SHELL_OF(tw), args, 2); 1641 XtFree(tek_icon_name); 1642 XtFree(tek_title); 1643 } 1644 1645 tek = TekRecord = &Tek0; 1646 tek->next = (TekLink *) 0; 1647 tek->fontsize = (unsigned short) tekscr->cur.fontsize; 1648 tek->count = 0; 1649 tek->ptr = tek->data; 1650 Tpushback = Tpushb; 1651 tekscr->cur_X = 0; 1652 tekscr->cur_Y = TEKHOME; 1653 line_pt = Tline; 1654 Ttoggled = True; 1655 tekscr->page = tekscr->cur; 1656 return; 1657} 1658 1659int 1660TekGetFontSize(const char *param) 1661{ 1662 int result; 1663 1664 if (XmuCompareISOLatin1(param, "l") == 0 || 1665 XmuCompareISOLatin1(param, "large") == 0) 1666 result = TEK_FONT_LARGE; 1667 else if (XmuCompareISOLatin1(param, "2") == 0 || 1668 XmuCompareISOLatin1(param, "two") == 0) 1669 result = TEK_FONT_2; 1670 else if (XmuCompareISOLatin1(param, "3") == 0 || 1671 XmuCompareISOLatin1(param, "three") == 0) 1672 result = TEK_FONT_3; 1673 else if (XmuCompareISOLatin1(param, "s") == 0 || 1674 XmuCompareISOLatin1(param, "small") == 0) 1675 result = TEK_FONT_SMALL; 1676 else 1677 result = -1; 1678 1679 return result; 1680} 1681 1682void 1683TekSetFontSize(TekWidget tw, Bool fromMenu, int newitem) 1684{ 1685 if (tw != 0) { 1686 XtermWidget xw = term; 1687 TekScreen *tekscr = TekScreenOf(tw); 1688 int oldsize = tekscr->cur.fontsize; 1689 int newsize = MI2FS(newitem); 1690 Font fid; 1691 1692 TRACE(("TekSetFontSize(%d) size %d ->%d\n", newitem, oldsize, newsize)); 1693 if (newsize < 0 || newsize >= TEKNUMFONTS) { 1694 Bell(xw, XkbBI_MinorError, 0); 1695 } else if (oldsize != newsize) { 1696 if (!Ttoggled) 1697 TCursorToggle(tw, TOGGLE); 1698 set_tekfont_menu_item(oldsize, False); 1699 1700 tekscr->cur.fontsize = newsize; 1701 if (fromMenu) 1702 tekscr->page.fontsize = newsize; 1703 1704 fid = tw->tek.Tfont[newsize]->fid; 1705 if (fid == DefaultGCID) { 1706 /* we didn't succeed in opening a real font 1707 for this size. Instead, use server default. */ 1708 XCopyGC(XtDisplay(tw), 1709 DefaultGC(XtDisplay(tw), DefaultScreen(XtDisplay(tw))), 1710 GCFont, tekscr->TnormalGC); 1711 } else { 1712 XSetFont(XtDisplay(tw), tekscr->TnormalGC, fid); 1713 } 1714 1715 set_tekfont_menu_item(newsize, True); 1716 if (!Ttoggled) 1717 TCursorToggle(tw, TOGGLE); 1718 1719 if (fromMenu) { 1720 /* we'll get an exposure event after changing fontsize, so we 1721 * have to clear the screen to avoid painting over the previous 1722 * text. 1723 */ 1724 TekClear(tw); 1725 } 1726 } 1727 } 1728} 1729 1730void 1731ChangeTekColors(TekWidget tw, TScreen * screen, ScrnColors * pNew) 1732{ 1733 TekScreen *tekscr = TekScreenOf(tw); 1734 int i; 1735 XGCValues gcv; 1736 1737 if (COLOR_DEFINED(pNew, TEK_FG)) { 1738 T_COLOR(screen, TEK_FG) = COLOR_VALUE(pNew, TEK_FG); 1739 TRACE(("... TEK_FG: %#lx\n", T_COLOR(screen, TEK_FG))); 1740 } 1741 if (COLOR_DEFINED(pNew, TEK_BG)) { 1742 T_COLOR(screen, TEK_BG) = COLOR_VALUE(pNew, TEK_BG); 1743 TRACE(("... TEK_BG: %#lx\n", T_COLOR(screen, TEK_BG))); 1744 } 1745 if (COLOR_DEFINED(pNew, TEK_CURSOR)) { 1746 T_COLOR(screen, TEK_CURSOR) = COLOR_VALUE(pNew, TEK_CURSOR); 1747 TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR))); 1748 } else { 1749 T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG); 1750 TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR))); 1751 } 1752 1753 if (tw) { 1754 XSetForeground(XtDisplay(tw), tekscr->TnormalGC, 1755 T_COLOR(screen, TEK_FG)); 1756 XSetBackground(XtDisplay(tw), tekscr->TnormalGC, 1757 T_COLOR(screen, TEK_BG)); 1758 if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) { 1759 BorderPixel(tw) = T_COLOR(screen, TEK_FG); 1760 BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG); 1761 if (XtWindow(XtParent(tw))) 1762 XSetWindowBorder(XtDisplay(tw), 1763 XtWindow(XtParent(tw)), 1764 BorderPixel(tw)); 1765 } 1766 1767 for (i = 0; i < TEKNUMLINES; i++) { 1768 XSetForeground(XtDisplay(tw), tekscr->linepat[i], 1769 T_COLOR(screen, TEK_FG)); 1770 } 1771 1772 gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ 1773 T_COLOR(screen, TEK_CURSOR)); 1774 XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv); 1775 TekBackground(tw, screen); 1776 } 1777 return; 1778} 1779 1780void 1781TekReverseVideo(TekWidget tw) 1782{ 1783 XtermWidget xw = term; 1784 TScreen *screen = TScreenOf(xw); 1785 TekScreen *tekscr = TekScreenOf(tw); 1786 int i; 1787 Pixel tmp; 1788 XGCValues gcv; 1789 1790 EXCHANGE(T_COLOR(screen, TEK_FG), T_COLOR(screen, TEK_BG), tmp); 1791 1792 T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG); 1793 1794 if (tw) { 1795 XSetForeground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_FG)); 1796 XSetBackground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_BG)); 1797 1798 if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) { 1799 BorderPixel(tw) = T_COLOR(screen, TEK_FG); 1800 BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG); 1801 if (XtWindow(XtParent(tw))) 1802 XSetWindowBorder(XtDisplay(tw), 1803 XtWindow(XtParent(tw)), 1804 BorderPixel(tw)); 1805 } 1806 1807 for (i = 0; i < TEKNUMLINES; i++) { 1808 XSetForeground(XtDisplay(tw), tekscr->linepat[i], 1809 T_COLOR(screen, TEK_FG)); 1810 } 1811 1812 gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ 1813 T_COLOR(screen, TEK_CURSOR)); 1814 XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv); 1815 TekBackground(tw, screen); 1816 } 1817} 1818 1819static void 1820TekBackground(TekWidget tw, TScreen * screen) 1821{ 1822 TekScreen *tekscr = TekScreenOf(tw); 1823 1824 if (TWindow(tekscr)) 1825 XSetWindowBackground(XtDisplay(tw), TWindow(tekscr), 1826 T_COLOR(screen, TEK_BG)); 1827} 1828 1829/* 1830 * Toggles cursor on or off at cursor position in screen. 1831 */ 1832void 1833TCursorToggle(TekWidget tw, int toggle) /* TOGGLE or CLEAR */ 1834{ 1835 XtermWidget xw = term; 1836 TekScreen *tekscr = TekScreenOf(tw); 1837 TScreen *screen = TScreenOf(xw); 1838 int c, x, y; 1839 unsigned int cellwidth, cellheight; 1840 1841 if (!TEK4014_SHOWN(xw)) 1842 return; 1843 1844 TRACE(("TCursorToggle %s\n", (toggle == TOGGLE) ? "toggle" : "clear")); 1845 c = tekscr->cur.fontsize; 1846 cellwidth = (unsigned) tw->tek.Tfont[c]->max_bounds.width; 1847 cellheight = (unsigned) (tw->tek.Tfont[c]->ascent + 1848 tw->tek.Tfont[c]->descent); 1849 1850 x = (int) ((tekscr->cur_X * TekScale(tekscr)) + screen->border); 1851 y = (int) (((TEKHEIGHT + TEKTOPPAD - tekscr->cur_Y) * TekScale(tekscr)) 1852 + screen->border - tw->tek.tobaseline[c]); 1853 1854 if (toggle == TOGGLE) { 1855 if (screen->select || screen->always_highlight) 1856 XFillRectangle(XtDisplay(tw), TWindow(tekscr), 1857 tekscr->TcursorGC, x, y, 1858 cellwidth, cellheight); 1859 else { /* fix to use different GC! */ 1860 XDrawRectangle(XtDisplay(tw), TWindow(tekscr), 1861 tekscr->TcursorGC, x, y, 1862 cellwidth - 1, cellheight - 1); 1863 } 1864 } else { 1865 /* Clear the entire rectangle, even though we may only 1866 * have drawn an outline. This fits with our refresh 1867 * scheme of redrawing the entire window on any expose 1868 * event and is easier than trying to figure out exactly 1869 * which part of the cursor needs to be erased. 1870 */ 1871 XClearArea(XtDisplay(tw), TWindow(tekscr), x, y, 1872 cellwidth, cellheight, False); 1873 } 1874} 1875 1876void 1877TekSimulatePageButton(TekWidget tw, Bool reset) 1878{ 1879 if (tw != 0) { 1880 TekScreen *tekscr = TekScreenOf(tw); 1881 1882 if (reset) { 1883 memset(&tekscr->cur, 0, sizeof tekscr->cur); 1884 } 1885 tekRefreshList = (TekLink *) 0; 1886 TekPage(tw); 1887 tekscr->cur_X = 0; 1888 tekscr->cur_Y = TEKHOME; 1889 } 1890} 1891 1892/* write copy of screen to a file */ 1893 1894void 1895TekCopy(TekWidget tw) 1896{ 1897 if (tw != 0) { 1898 XtermWidget xw = term; 1899 TekScreen *tekscr = TekScreenOf(tw); 1900 TScreen *screen = TScreenOf(xw); 1901 1902 TekLink *Tp; 1903 char buf[TIMESTAMP_LEN + 10]; 1904 char initbuf[5]; 1905 int tekcopyfd; 1906 1907 timestamp_filename(buf, "COPY"); 1908 if (access(buf, F_OK) >= 0 1909 && access(buf, W_OK) < 0) { 1910 Bell(xw, XkbBI_MinorError, 0); 1911 return; 1912 } 1913#ifndef VMS 1914 if (access(".", W_OK) < 0) { /* can't write in directory */ 1915 Bell(xw, XkbBI_MinorError, 0); 1916 return; 1917 } 1918#endif 1919 1920 tekcopyfd = open_userfile(screen->uid, screen->gid, buf, False); 1921 if (tekcopyfd >= 0) { 1922 sprintf(initbuf, "%c%c%c%c", 1923 ANSI_ESC, (char) (tekscr->page.fontsize + '8'), 1924 ANSI_ESC, (char) (tekscr->page.linetype + '`')); 1925 IGNORE_RC(write(tekcopyfd, initbuf, (size_t) 4)); 1926 Tp = &Tek0; 1927 do { 1928 IGNORE_RC(write(tekcopyfd, Tp->data, (size_t) Tp->count)); 1929 Tp = Tp->next; 1930 } while (Tp); 1931 close(tekcopyfd); 1932 } 1933 } 1934} 1935 1936/*ARGSUSED*/ 1937void 1938HandleGINInput(Widget w, 1939 XEvent * event GCC_UNUSED, 1940 String * param_list, 1941 Cardinal *nparamsp) 1942{ 1943 XtermWidget xw = term; 1944 TekWidget tw = getTekWidget(w); 1945 1946 if (tw != 0) { 1947 TekScreen *tekscr = TekScreenOf(tw); 1948 1949 if (tekscr->TekGIN && *nparamsp == 1) { 1950 int c = param_list[0][0]; 1951 switch (c) { 1952 case 'l': 1953 case 'm': 1954 case 'r': 1955 case 'L': 1956 case 'M': 1957 case 'R': 1958 break; 1959 default: 1960 Bell(xw, XkbBI_MinorError, 0); /* let them know they goofed */ 1961 c = 'l'; /* provide a default */ 1962 } 1963 TekEnqMouse(tw, c | 0x80); 1964 TekGINoff(tw); 1965 } else { 1966 Bell(xw, XkbBI_MinorError, 0); 1967 } 1968 } 1969} 1970 1971/* 1972 * Check if the current widget, or any parent, is the VT100 "xterm" widget. 1973 */ 1974TekWidget 1975getTekWidget(Widget w) 1976{ 1977 TekWidget xw; 1978 1979 if (w == 0) { 1980 xw = (TekWidget) CURRENT_EMU(); 1981 if (!IsTekWidget(xw)) { 1982 xw = 0; 1983 } 1984 } else if (IsTekWidget(w)) { 1985 xw = (TekWidget) w; 1986 } else { 1987 xw = getTekWidget(XtParent(w)); 1988 } 1989 TRACE2(("getTekWidget %p -> %p\n", w, xw)); 1990 return xw; 1991} 1992