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