|
|
1.1 ! root 1: /* ! 2: * $Source: /orpheus/u1/X11/clients/xterm/RCS/button.c,v $ ! 3: * $Header: button.c,v 1.19 87/09/10 17:20:59 swick Exp $ ! 4: */ ! 5: ! 6: ! 7: #include <X11/copyright.h> ! 8: ! 9: /* ! 10: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 11: * ! 12: * All Rights Reserved ! 13: * ! 14: * Permission to use, copy, modify, and distribute this software and its ! 15: * documentation for any purpose and without fee is hereby granted, ! 16: * provided that the above copyright notice appear in all copies and that ! 17: * both that copyright notice and this permission notice appear in ! 18: * supporting documentation, and that the name of Digital Equipment ! 19: * Corporation not be used in advertising or publicity pertaining to ! 20: * distribution of the software without specific, written prior permission. ! 21: * ! 22: * ! 23: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 24: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 25: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 26: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 27: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 28: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 29: * SOFTWARE. ! 30: */ ! 31: ! 32: /* ! 33: button.c Handles button events in the terminal emulator. ! 34: does cut/paste operations, change modes via menu, ! 35: passes button events through to some applications. ! 36: J. Gettys. ! 37: */ ! 38: #ifndef lint ! 39: static char rcs_id[] = "$Header: button.c,v 1.19 87/09/10 17:20:59 swick Exp $"; ! 40: #endif lint ! 41: #include <stdio.h> ! 42: #include <signal.h> ! 43: #include <setjmp.h> ! 44: #include <ctype.h> ! 45: #include <strings.h> ! 46: #include <X11/Xlib.h> ! 47: #include <X11/Intrinsic.h> ! 48: #include "ptyx.h" ! 49: #include "data.h" ! 50: #include "error.h" ! 51: #ifdef MODEMENU ! 52: #include "menu.h" ! 53: #endif MODEMENU ! 54: ! 55: extern char *malloc(); ! 56: ! 57: #define KeyState(x) ((x) & (ShiftMask|ControlMask|Mod1Mask)) ! 58: #define X10Map(state) ((state&ShiftMask?4:0) + (state&ControlMask?16:0) \ ! 59: + (state&Mod1Mask?8:0)) ! 60: ! 61: #define TEXTMODES 4 ! 62: #define NBUTS 3 ! 63: #define DIRS 2 ! 64: #define UP 1 ! 65: #define DOWN 0 ! 66: #define SHIFTS 8 /* three keys, so eight combinations */ ! 67: #define Coordinate(r,c) ((r) * (term.screen.max_col+1) + (c)) ! 68: ! 69: char *SaveText(); ! 70: extern UnSaltText(); ! 71: extern StartCut(); ! 72: extern StartExtend(); ! 73: extern EditorButton(); ! 74: extern TrackDown(); ! 75: ! 76: extern ModeMenu(); ! 77: extern char *xterm_name; ! 78: extern Bogus(), Silence(); ! 79: extern GINbutton(); ! 80: ! 81: /* due to LK201 limitations, not all of the below are actually possible */ ! 82: static int (*textfunc[TEXTMODES][SHIFTS][DIRS][NBUTS])() = { ! 83: /* left middle right */ ! 84: StartCut, Silence, StartExtend, /* down | */ ! 85: Silence, UnSaltText, Silence, /* up |no shift */ ! 86: ! 87: StartCut, Silence, StartExtend, /* down | */ ! 88: Silence, UnSaltText, Silence, /* up |shift */ ! 89: ! 90: Bogus, Bogus, Bogus, /* down | */ ! 91: Silence, Silence, Silence, /* up |meta */ ! 92: ! 93: Bogus, Bogus, Bogus, /* down | */ ! 94: Silence, Silence, Silence, /* up |meta shift */ ! 95: ! 96: ModeMenu, ModeMenu, ModeMenu, /* down | */ ! 97: Silence, Silence, Silence, /* up |control */ ! 98: ! 99: ModeMenu, ModeMenu, ModeMenu, /* down | */ ! 100: Silence, Silence, Silence, /* up |ctl shift */ ! 101: ! 102: Bogus, Bogus, Bogus, /* down | */ ! 103: Silence, Silence, Silence, /* up |ctl meta */ ! 104: ! 105: Bogus, Bogus, Bogus, /* down | control */ ! 106: Silence, Silence, Silence, /* up |meta shift*/ ! 107: ! 108: /* MIT mouse bogus sequence */ ! 109: /* button, shift keys, and direction */ ! 110: /* left middle right */ ! 111: EditorButton, EditorButton, EditorButton, /* down | */ ! 112: Silence, Silence, Silence, /* up |no shift */ ! 113: ! 114: StartCut, Silence, StartExtend, /* down | */ ! 115: Silence, UnSaltText, Silence, /* up |shift */ ! 116: ! 117: Bogus, Bogus, Bogus, /* down | */ ! 118: Silence, Silence, Silence, /* up |meta */ ! 119: ! 120: Bogus, Bogus, Bogus, /* down | */ ! 121: Silence, Silence, Silence, /* up |meta shift */ ! 122: ! 123: ModeMenu, ModeMenu, ModeMenu, /* down | */ ! 124: Silence, Silence, Silence, /* up |control */ ! 125: ! 126: ModeMenu, ModeMenu, ModeMenu, /* down | */ ! 127: Silence, Silence, Silence, /* up |ctl shift */ ! 128: ! 129: Bogus, Bogus, Bogus, /* down | */ ! 130: Silence, Silence, Silence, /* up |ctl meta */ ! 131: ! 132: Bogus, Bogus, Bogus, /* down | control */ ! 133: Silence, Silence, Silence, /* up |meta shift*/ ! 134: ! 135: /* DEC mouse bogus sequence */ ! 136: /* button, shift keys, and direction */ ! 137: /* left middle right */ ! 138: EditorButton, EditorButton, EditorButton, /* down | */ ! 139: EditorButton, EditorButton, EditorButton, /* up |no shift */ ! 140: ! 141: StartCut, Silence, StartExtend, /* down | */ ! 142: Silence, UnSaltText, Silence, /* up |shift */ ! 143: ! 144: Bogus, Bogus, Bogus, /* down | */ ! 145: Silence, Silence, Silence, /* up |meta */ ! 146: ! 147: Bogus, Bogus, Bogus, /* down | */ ! 148: Silence, Silence, Silence, /* up |meta shift */ ! 149: ! 150: EditorButton, EditorButton, EditorButton, /* down | */ ! 151: EditorButton, EditorButton, EditorButton, /* up |control */ ! 152: ! 153: ModeMenu, ModeMenu, ModeMenu, /* down | */ ! 154: Silence, Silence, Silence, /* up |ctl shift */ ! 155: ! 156: Bogus, Bogus, Bogus, /* down | */ ! 157: Silence, Silence, Silence, /* up |ctl meta */ ! 158: ! 159: Bogus, Bogus, Bogus, /* down | control */ ! 160: Silence, Silence, Silence, /* up |meta shift*/ ! 161: ! 162: /* Hilite tracking DEC mouse bogus sequence */ ! 163: /* button, shift keys, and direction */ ! 164: /* left middle right */ ! 165: TrackDown, EditorButton, EditorButton, /* down | */ ! 166: EditorButton, EditorButton, EditorButton, /* up |no shift */ ! 167: ! 168: StartCut, Silence, StartExtend, /* down | */ ! 169: Silence, UnSaltText, Silence, /* up |shift */ ! 170: ! 171: Bogus, Bogus, Bogus, /* down | */ ! 172: Silence, Silence, Silence, /* up |meta */ ! 173: ! 174: Bogus, Bogus, Bogus, /* down | */ ! 175: Silence, Silence, Silence, /* up |meta shift */ ! 176: ! 177: EditorButton, EditorButton, EditorButton, /* down | */ ! 178: EditorButton, EditorButton, EditorButton, /* up |control */ ! 179: ! 180: ModeMenu, ModeMenu, ModeMenu, /* down | */ ! 181: Silence, Silence, Silence, /* up |ctl shift */ ! 182: ! 183: Bogus, Bogus, Bogus, /* down | */ ! 184: Silence, Silence, Silence, /* up |ctl meta */ ! 185: ! 186: Bogus, Bogus, Bogus, /* down | control */ ! 187: Silence, Silence, Silence /* up |meta shift */ ! 188: ! 189: }; ! 190: ! 191: /* button and shift keys for Tek mode */ ! 192: static int (*Tbfunc[SHIFTS][NBUTS])() = { ! 193: /* left middle right */ ! 194: GINbutton, GINbutton, GINbutton, /* down |no shift */ ! 195: ! 196: GINbutton, GINbutton, GINbutton, /* down |shift */ ! 197: ! 198: Bogus, Bogus, Bogus, /* down |meta */ ! 199: ! 200: Bogus, Bogus, Bogus, /* down |meta shift */ ! 201: ! 202: ModeMenu, ModeMenu, ModeMenu, /* down |control */ ! 203: ! 204: ModeMenu, ModeMenu, ModeMenu, /* down |ctl shift */ ! 205: ! 206: Bogus, Bogus, Bogus, /* down |ctl meta */ ! 207: ! 208: Bogus, Bogus, Bogus, /* down | all */ ! 209: ! 210: }; /* button and shift keys */ ! 211: ! 212: extern Terminal term; ! 213: ! 214: /* Selection/extension variables */ ! 215: ! 216: /* Raw char position where the selection started */ ! 217: static int rawRow, rawCol; ! 218: ! 219: /* Hilited area */ ! 220: static int startHRow, startHCol, endHRow, endHCol, startHCoord, endHCoord = 0; ! 221: ! 222: /* Selected area before CHAR, WORD, LINE selectUnit processing */ ! 223: static int startRRow, startRCol, endRRow, endRCol = 0; ! 224: ! 225: /* Selected area after CHAR, WORD, LINE selectUnit processing */ ! 226: static int startSRow, startSCol, endSRow, endSCol = 0; ! 227: ! 228: /* Valid rows for selection clipping */ ! 229: static int firstValidRow, lastValidRow; ! 230: ! 231: /* Start, end of extension */ ! 232: static int startERow, startECol, endERow, endECol; ! 233: ! 234: /* Saved values of raw selection for extend to restore to */ ! 235: static int saveStartRRow, saveStartRCol, saveEndRRow, saveEndRCol; ! 236: ! 237: /* Multi-click handling */ ! 238: static int numberOfClicks = 0; ! 239: static long int lastButtonUpTime = 0; ! 240: typedef enum {SELECTCHAR, SELECTWORD, SELECTLINE} SelectUnit; ! 241: static SelectUnit selectUnit; ! 242: ! 243: /* Send emacs escape code when done selecting or extending? */ ! 244: static int replyToEmacs; ! 245: ! 246: ! 247: /*ARGSUSED*/ ! 248: XtEventReturnCode VTButtonPressed(event, eventdata) ! 249: register XButtonEvent *event; ! 250: caddr_t eventdata; ! 251: { ! 252: register TScreen *screen = &term.screen; ! 253: /* so table above will be nice, we index from 0 */ ! 254: int button = event->button - 1; ! 255: int shift = KeyState(event->state); ! 256: ! 257: if (eventMode != NORMAL) ! 258: return (XteventHandled); ! 259: if (screen->incopy) ! 260: CopyWait (screen); ! 261: textfunc[screen->send_mouse_pos][shift][0][button](event); ! 262: return (XteventHandled); ! 263: } ! 264: ! 265: /*ARGSUSED*/ ! 266: XtEventReturnCode VTMouseMoved(event, eventdata) ! 267: register XMotionEvent *event; ! 268: caddr_t eventdata; ! 269: { ! 270: switch (eventMode) { ! 271: case LEFTEXTENSION : ! 272: case RIGHTEXTENSION : ! 273: ExtendExtend(event->x, event->y); ! 274: break; ! 275: default : ! 276: /* Should get here rarely when everything ! 277: fixed with windows and the event mgr */ ! 278: /* fprintf(stderr, "Race mouse motion\n"); ! 279: */ break; ! 280: } ! 281: return (XteventHandled); ! 282: } ! 283: ! 284: ! 285: /*ARGSUSED*/ ! 286: XtEventReturnCode VTButtonReleased(event, eventdata) ! 287: register XButtonEvent *event; ! 288: caddr_t eventdata; ! 289: { ! 290: register TScreen *screen = &term.screen; ! 291: /* so table above will be nice, we index from 0 */ ! 292: int button = event->button - 1; ! 293: int shift = KeyState(event->state); ! 294: ! 295: switch (eventMode) { ! 296: case NORMAL : ! 297: textfunc[screen->send_mouse_pos][shift][1][button] ! 298: (event); ! 299: break; ! 300: case LEFTEXTENSION : ! 301: case RIGHTEXTENSION : ! 302: if AllButtonsUp(event->state, event->button) ! 303: EndExtend(event); ! 304: break; ! 305: } ! 306: return (XteventHandled); ! 307: } ! 308: ! 309: /*ARGSUSED*/ ! 310: XtEventReturnCode TekButtonPressed(event, eventdata) ! 311: register XButtonEvent *event; ! 312: caddr_t eventdata; ! 313: { ! 314: register TScreen *screen = &term.screen; ! 315: /* so table above will be nice, we index from 0 */ ! 316: int button = event->button - 1; ! 317: int shift = KeyState(event->state); ! 318: ! 319: if (screen->incopy) ! 320: CopyWait (screen); ! 321: Tbfunc[shift][button](event); ! 322: return (XteventHandled); ! 323: } ! 324: ! 325: ! 326: /*ARGSUSED*/ ! 327: UnSaltText(event) ! 328: XEvent *event; ! 329: { ! 330: int pty = term.screen.respond; /* file descriptor of pty */ ! 331: char *line; ! 332: int nbytes; ! 333: register char *lag, *cp, *end; ! 334: register TScreen *screen = &term.screen; ! 335: ! 336: line = XFetchBytes(screen->display,&nbytes); ! 337: if (!nbytes) return; ! 338: end = &line[nbytes]; ! 339: lag = line; ! 340: for (cp = line; cp != end; cp++) ! 341: { ! 342: if (*cp != '\n') continue; ! 343: *cp = '\r'; ! 344: v_write(pty, lag, cp - lag + 1); ! 345: lag = cp + 1; ! 346: } ! 347: if (lag != end) ! 348: v_write(pty, lag, end - lag); ! 349: free (line); /* free text from fetch */ ! 350: } ! 351: ! 352: ! 353: #define MULTICLICKTIME 250 ! 354: ! 355: SetSelectUnit(buttonDownTime, defaultUnit) ! 356: unsigned long buttonDownTime; ! 357: SelectUnit defaultUnit; ! 358: { ! 359: /* Do arithmetic as integers, but compare as unsigned solves clock wraparound */ ! 360: if ((long unsigned)((long int)buttonDownTime - lastButtonUpTime) ! 361: > MULTICLICKTIME) { ! 362: numberOfClicks = 1; ! 363: selectUnit = defaultUnit; ! 364: } else { ! 365: ++numberOfClicks; ! 366: /* Don't bitch. This is only temporary. */ ! 367: selectUnit = (SelectUnit) (((int) selectUnit + 1) % 3); ! 368: } ! 369: } ! 370: ! 371: StartCut(event) ! 372: register XButtonEvent *event; ! 373: { ! 374: register TScreen *screen = &term.screen; ! 375: int startrow, startcol; ! 376: ! 377: firstValidRow = 0; ! 378: lastValidRow = screen->max_row; ! 379: SetSelectUnit(event->time, SELECTCHAR); ! 380: PointToRowCol(event->y, event->x, &startrow, &startcol); ! 381: replyToEmacs = FALSE; ! 382: StartSelect(startrow, startcol); ! 383: } ! 384: ! 385: ! 386: TrackDown(event) ! 387: register XButtonEvent *event; ! 388: { ! 389: int startrow, startcol; ! 390: ! 391: SetSelectUnit(event->time, SELECTCHAR); ! 392: if (numberOfClicks > 1 ) { ! 393: PointToRowCol(event->y, event->x, &startrow, &startcol); ! 394: replyToEmacs = TRUE; ! 395: StartSelect(startrow, startcol); ! 396: } else { ! 397: waitingForTrackInfo = 1; ! 398: EditorButton(event); ! 399: } ! 400: } ! 401: ! 402: ! 403: TrackMouse(func, startrow, startcol, firstrow, lastrow) ! 404: int func, startrow, startcol, firstrow, lastrow; ! 405: { ! 406: if (!waitingForTrackInfo) { /* Timed out, so ignore */ ! 407: return; ! 408: } ! 409: waitingForTrackInfo = 0; ! 410: if (func == 0) return; ! 411: ! 412: firstValidRow = firstrow; ! 413: lastValidRow = lastrow; ! 414: replyToEmacs = TRUE; ! 415: StartSelect(startrow, startcol); ! 416: } ! 417: ! 418: StartSelect(startrow, startcol) ! 419: int startrow, startcol; ! 420: { ! 421: TScreen *screen = &term.screen; ! 422: ! 423: if (screen->cursor_state) ! 424: HideCursor (); ! 425: if (numberOfClicks == 1) { ! 426: /* set start of selection */ ! 427: rawRow = startrow; ! 428: rawCol = startcol; ! 429: ! 430: } /* else use old values in rawRow, Col */ ! 431: ! 432: saveStartRRow = startERow = rawRow; ! 433: saveStartRCol = startECol = rawCol; ! 434: saveEndRRow = endERow = rawRow; ! 435: saveEndRCol = endECol = rawCol; ! 436: if (Coordinate(startrow, startcol) < Coordinate(rawRow, rawCol)) { ! 437: eventMode = LEFTEXTENSION; ! 438: startERow = startrow; ! 439: startECol = startcol; ! 440: } else { ! 441: eventMode = RIGHTEXTENSION; ! 442: endERow = startrow; ! 443: endECol = startcol; ! 444: } ! 445: ComputeSelect(startERow, startECol, endERow, endECol); ! 446: ! 447: } ! 448: ! 449: EndExtend(event) ! 450: XButtonEvent *event; ! 451: { ! 452: int row, col; ! 453: TScreen *screen = &term.screen; ! 454: char line[9]; ! 455: ! 456: ExtendExtend(event->x, event->y); ! 457: ! 458: lastButtonUpTime = event->time; ! 459: PointToRowCol(event->y, event->x, &row, &col); ! 460: /* Only do select stuff if non-null select */ ! 461: if (startSRow != endSRow || startSCol != endSCol) { ! 462: if (replyToEmacs) { ! 463: if (rawRow == startSRow && rawCol == startSCol ! 464: && row == endSRow && col == endSCol) { ! 465: /* Use short-form emacs select */ ! 466: strcpy(line, "\033[t"); ! 467: line[3] = ' ' + endSCol + 1; ! 468: line[4] = ' ' + endSRow + 1; ! 469: v_write(screen->respond, line, 5); ! 470: } else { ! 471: /* long-form, specify everything */ ! 472: strcpy(line, "\033[T"); ! 473: line[3] = ' ' + startSCol + 1; ! 474: line[4] = ' ' + startSRow + 1; ! 475: line[5] = ' ' + endSCol + 1; ! 476: line[6] = ' ' + endSRow + 1; ! 477: line[7] = ' ' + col + 1; ! 478: line[8] = ' ' + row + 1; ! 479: v_write(screen->respond, line, 9); ! 480: } ! 481: } ! 482: SaltTextAway(startSRow, startSCol, endSRow, endSCol); ! 483: } ! 484: TrackText(0, 0, 0, 0); ! 485: eventMode = NORMAL; ! 486: } ! 487: ! 488: #define Abs(x) ((x) < 0 ? -(x) : (x)) ! 489: ! 490: StartExtend(event) ! 491: XButtonEvent *event; ! 492: { ! 493: TScreen *screen = &term.screen; ! 494: int row, col, coord; ! 495: ! 496: firstValidRow = 0; ! 497: lastValidRow = screen->max_row; ! 498: SetSelectUnit(event->time, selectUnit); ! 499: replyToEmacs = FALSE; ! 500: ! 501: if (numberOfClicks == 1) { ! 502: /* Save existing selection so we can reestablish it if the guy ! 503: extends past the other end of the selection */ ! 504: saveStartRRow = startERow = startRRow; ! 505: saveStartRCol = startECol = startRCol; ! 506: saveEndRRow = endERow = endRRow; ! 507: saveEndRCol = endECol = endRCol; ! 508: } else { ! 509: /* He just needed the selection mode changed, use old values. */ ! 510: startERow = startRRow = saveStartRRow; ! 511: startECol = startRCol = saveStartRCol; ! 512: endERow = endRRow = saveEndRRow; ! 513: endECol = endRCol = saveEndRCol; ! 514: ! 515: } ! 516: PointToRowCol(event->y, event->x, &row, &col); ! 517: coord = Coordinate(row, col); ! 518: ! 519: if (Abs(coord - Coordinate(startSRow, startSCol)) ! 520: < Abs(coord - Coordinate(endSRow, endSCol)) ! 521: || coord < Coordinate(startSRow, startSCol)) { ! 522: /* point is close to left side of selection */ ! 523: eventMode = LEFTEXTENSION; ! 524: startERow = row; ! 525: startECol = col; ! 526: } else { ! 527: /* point is close to left side of selection */ ! 528: eventMode = RIGHTEXTENSION; ! 529: endERow = row; ! 530: endECol = col; ! 531: } ! 532: ComputeSelect(startERow, startECol, endERow, endECol); ! 533: } ! 534: ! 535: ExtendExtend(x, y) ! 536: int x, y; ! 537: { ! 538: int row, col, coord; ! 539: ! 540: PointToRowCol(y, x, &row, &col); ! 541: coord = Coordinate(row, col); ! 542: ! 543: if (eventMode == LEFTEXTENSION ! 544: && (coord + (selectUnit!=SELECTCHAR)) > Coordinate(endSRow, endSCol)) { ! 545: /* Whoops, he's changed his mind. Do RIGHTEXTENSION */ ! 546: eventMode = RIGHTEXTENSION; ! 547: startERow = saveStartRRow; ! 548: startECol = saveStartRCol; ! 549: } else if (eventMode == RIGHTEXTENSION ! 550: && coord < Coordinate(startSRow, startSCol)) { ! 551: /* Whoops, he's changed his mind. Do LEFTEXTENSION */ ! 552: eventMode = LEFTEXTENSION; ! 553: endERow = saveEndRRow; ! 554: endECol = saveEndRCol; ! 555: } ! 556: if (eventMode == LEFTEXTENSION) { ! 557: startERow = row; ! 558: startECol = col; ! 559: } else { ! 560: endERow = row; ! 561: endECol = col; ! 562: } ! 563: ComputeSelect(startERow, startECol, endERow, endECol); ! 564: } ! 565: ! 566: ! 567: ScrollSelection(amount) ! 568: int amount; ! 569: { ! 570: /* Sent by scrollbar stuff, so amount never takes selection out of ! 571: saved text */ ! 572: startRRow += amount; endRRow += amount; startSRow += amount; endSRow += amount; ! 573: rawRow += amount; ! 574: } ! 575: ! 576: ! 577: PointToRowCol(y, x, r, c) ! 578: register int y, x; ! 579: int *r, *c; ! 580: /* Convert pixel coordinates to character coordinates. ! 581: Rows are clipped between firstValidRow and lastValidRow. ! 582: Columns are clipped between to be 0 or greater, but are not clipped to some ! 583: maximum value. */ ! 584: { ! 585: register TScreen *screen = &term.screen; ! 586: register row, col; ! 587: ! 588: row = (y - screen->border) / FontHeight(screen); ! 589: if(row < firstValidRow) ! 590: row = firstValidRow; ! 591: else if(row > lastValidRow) ! 592: row = lastValidRow; ! 593: col = (x - screen->border - screen->scrollbar) / FontWidth(screen); ! 594: if(col < 0) ! 595: col = 0; ! 596: else if(col > screen->max_col+1) { ! 597: col = screen->max_col+1; ! 598: } ! 599: *r = row; ! 600: *c = col; ! 601: } ! 602: ! 603: int LastTextCol(row) ! 604: register int row; ! 605: { ! 606: register TScreen *screen = &term.screen; ! 607: register int i; ! 608: register char *ch; ! 609: ! 610: for(i = screen->max_col, ! 611: ch = screen->buf[2 * (row + screen->topline)] + i ; ! 612: i > 0 && *ch == 0 ; ch--, i--); ! 613: return(i); ! 614: } ! 615: ! 616: static int charClass[128] = { ! 617: /* NUL SOH STX ETX EOT ENQ ACK BEL */ ! 618: 32, 1, 1, 1, 1, 1, 1, 1, ! 619: /* BS HT NL VT NP CR SO SI */ ! 620: 1, 32, 1, 1, 1, 1, 1, 1, ! 621: /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ ! 622: 1, 1, 1, 1, 1, 1, 1, 1, ! 623: /* CAN EM SUB ESC FS GS RS US */ ! 624: 1, 1, 1, 1, 1, 1, 1, 1, ! 625: /* SP ! " # $ % & ' */ ! 626: 32, 33, 34, 35, 36, 37, 38, 39, ! 627: /* ( ) * + , - . / */ ! 628: 40, 41, 42, 43, 44, 45, 46, 47, ! 629: /* 0 1 2 3 4 5 6 7 */ ! 630: 48, 48, 48, 48, 48, 48, 48, 48, ! 631: /* 8 9 : ; < = > ? */ ! 632: 48, 48, 58, 59, 60, 61, 62, 63, ! 633: /* @ A B C D E F G */ ! 634: 64, 48, 48, 48, 48, 48, 48, 48, ! 635: /* H I J K L M N O */ ! 636: 48, 48, 48, 48, 48, 48, 48, 48, ! 637: /* P Q R S T U V W */ ! 638: 48, 48, 48, 48, 48, 48, 48, 48, ! 639: /* X Y Z [ \ ] ^ _ */ ! 640: 48, 48, 48, 91, 92, 93, 94, 48, ! 641: /* ` a b c d e f g */ ! 642: 96, 48, 48, 48, 48, 48, 48, 48, ! 643: /* h i j k l m n o */ ! 644: 48, 48, 48, 48, 48, 48, 48, 48, ! 645: /* p q r s t u v w */ ! 646: 48, 48, 48, 48, 48, 48, 48, 48, ! 647: /* x y z { | } ~ DEL */ ! 648: 48, 48, 48, 123, 124, 125, 126, 1}; ! 649: ! 650: ! 651: ComputeSelect(startRow, startCol, endRow, endCol) ! 652: int startRow, startCol, endRow, endCol; ! 653: { ! 654: register TScreen *screen = &term.screen; ! 655: register char *ptr; ! 656: register int length; ! 657: register int class; ! 658: ! 659: if (Coordinate(startRow, startCol) <= Coordinate(endRow, endCol)) { ! 660: startSRow = startRRow = startRow; ! 661: startSCol = startRCol = startCol; ! 662: endSRow = endRRow = endRow; ! 663: endSCol = endRCol = endCol; ! 664: } else { /* Swap them */ ! 665: startSRow = startRRow = endRow; ! 666: startSCol = startRCol = endCol; ! 667: endSRow = endRRow = startRow; ! 668: endSCol = endRCol = startCol; ! 669: } ! 670: ! 671: switch (selectUnit) { ! 672: case SELECTCHAR : ! 673: if (startSCol > (LastTextCol(startSRow) + 1)) { ! 674: startSCol = 0; ! 675: startSRow++; ! 676: } ! 677: if (endSCol > (LastTextCol(endSRow) + 1)) { ! 678: endSCol = 0; ! 679: endSRow++; ! 680: } ! 681: break; ! 682: case SELECTWORD : ! 683: if (startSCol > (LastTextCol(startSRow) + 1)) { ! 684: startSCol = 0; ! 685: startSRow++; ! 686: } else { ! 687: ptr = screen->buf[2*(startSRow+screen->topline)] ! 688: + startSCol; ! 689: class = charClass[*ptr]; ! 690: do { ! 691: --startSCol; ! 692: --ptr; ! 693: } while (startSCol >= 0 ! 694: && charClass[*ptr] == class); ! 695: ++startSCol; ! 696: } ! 697: if (endSCol > (LastTextCol(endSRow) + 1)) { ! 698: endSCol = 0; ! 699: endSRow++; ! 700: } else { ! 701: length = LastTextCol(endSRow); ! 702: ptr = screen->buf[2*(endSRow+screen->topline)] ! 703: + endSCol; ! 704: class = charClass[*ptr]; ! 705: do { ! 706: ++endSCol; ! 707: ++ptr; ! 708: } while (endSCol <= length ! 709: && charClass[*ptr] == class); ! 710: /* Word select selects if pointing to any char ! 711: in "word", especially in that it includes ! 712: the last character in a word. So no --endSCol ! 713: and do special eol handling */ ! 714: if (endSCol > length+1) { ! 715: endSCol = 0; ! 716: ++endSRow; ! 717: } ! 718: } ! 719: break; ! 720: case SELECTLINE : ! 721: startSCol = 0; ! 722: endSCol = 0; ! 723: ++endSRow; ! 724: break; ! 725: } ! 726: TrackText(startSRow, startSCol, endSRow, endSCol); ! 727: return; ! 728: } ! 729: ! 730: ! 731: TrackText(frow, fcol, trow, tcol) ! 732: register int frow, fcol, trow, tcol; ! 733: /* Guaranteed (frow, fcol) <= (trow, tcol) */ ! 734: { ! 735: register int from, to; ! 736: register TScreen *screen = &term.screen; ! 737: ! 738: /* (frow, fcol) may have been scrolled off top of display */ ! 739: if (frow < 0) ! 740: frow = fcol = 0; ! 741: /* (trow, tcol) may have been scrolled off bottom of display */ ! 742: if (trow > screen->max_row+1) { ! 743: trow = screen->max_row+1; ! 744: tcol = 0; ! 745: } ! 746: from = Coordinate(frow, fcol); ! 747: to = Coordinate(trow, tcol); ! 748: if (to <= startHCoord || from > endHCoord) { ! 749: /* No overlap whatsoever between old and new hilite */ ! 750: HiliteText(startHRow, startHCol, endHRow, endHCol, FALSE); ! 751: HiliteText(frow, fcol, trow, tcol, TRUE); ! 752: } else { ! 753: if (from < startHCoord) { ! 754: /* Extend left end */ ! 755: HiliteText(frow, fcol, startHRow, startHCol, TRUE); ! 756: } else if (from > startHCoord) { ! 757: /* Shorten left end */ ! 758: HiliteText(startHRow, startHCol, frow, fcol, FALSE); ! 759: } ! 760: if (to > endHCoord) { ! 761: /* Extend right end */ ! 762: HiliteText(endHRow, endHCol, trow, tcol, TRUE); ! 763: } else if (to < endHCoord) { ! 764: /* Shorten right end */ ! 765: HiliteText(trow, tcol, endHRow, endHCol, FALSE); ! 766: } ! 767: } ! 768: startHRow = frow; ! 769: startHCol = fcol; ! 770: endHRow = trow; ! 771: endHCol = tcol; ! 772: startHCoord = from; ! 773: endHCoord = to; ! 774: } ! 775: ! 776: HiliteText(frow, fcol, trow, tcol, hilite) ! 777: register int frow, fcol, trow, tcol; ! 778: int hilite; ! 779: /* Guaranteed that (frow, fcol) <= (trow, tcol) */ ! 780: { ! 781: register TScreen *screen = &term.screen; ! 782: register int i, j; ! 783: GC tempgc; ! 784: ! 785: if (frow == trow && fcol == tcol) ! 786: return; ! 787: if(hilite) { ! 788: tempgc = screen->normalGC; ! 789: screen->normalGC = screen->reverseGC; ! 790: screen->reverseGC = tempgc; ! 791: tempgc = screen->normalboldGC; ! 792: screen->normalboldGC = screen->reverseboldGC; ! 793: screen->reverseboldGC = tempgc; ! 794: ! 795: ! 796: i = screen->foreground; ! 797: screen->foreground = screen->background; ! 798: screen->background = i; ! 799: XSetWindowBackground(screen->display,VWindow(screen),screen->background); ! 800: ! 801: } ! 802: if(frow != trow) { /* do multiple rows */ ! 803: if((i = screen->max_col - fcol + 1) > 0) { /* first row */ ! 804: XClearArea( ! 805: screen->display, ! 806: VWindow(screen), ! 807: (int) CursorX(screen, fcol), ! 808: (int) frow * FontHeight(screen) + screen->border, ! 809: (unsigned) i*FontWidth(screen), ! 810: (unsigned) FontHeight(screen), ! 811: FALSE); ! 812: ScrnRefresh(screen, frow, fcol, 1, i); ! 813: } ! 814: if((i = trow - frow - 1) > 0) { /* middle rows*/ ! 815: j = screen->max_col + 1; ! 816: XClearArea( ! 817: screen->display, ! 818: VWindow(screen), ! 819: (int) screen->border + screen->scrollbar, ! 820: (int) (frow+1)*FontHeight(screen) + screen->border, ! 821: (unsigned) j * FontWidth(screen), ! 822: (unsigned) i * FontHeight(screen), ! 823: FALSE); ! 824: ScrnRefresh(screen, frow + 1, 0, i, j); ! 825: } ! 826: if(tcol > 0 && trow <= screen->max_row) { /* last row */ ! 827: XClearArea( ! 828: screen->display, ! 829: VWindow(screen), ! 830: (int) screen->border + screen->scrollbar, ! 831: (int) trow * FontHeight(screen) + screen->border, ! 832: (unsigned) tcol * FontWidth(screen), ! 833: (unsigned) FontHeight(screen), ! 834: FALSE); ! 835: ScrnRefresh(screen, trow, 0, 1, tcol); ! 836: } ! 837: } else { /* do single row */ ! 838: i = tcol - fcol; ! 839: XClearArea( ! 840: screen->display, ! 841: VWindow(screen), ! 842: (int) CursorX(screen, fcol), ! 843: (int) frow * FontHeight(screen) + screen->border, ! 844: (unsigned) i * FontWidth(screen), ! 845: (unsigned) FontHeight(screen), ! 846: FALSE); ! 847: ScrnRefresh(screen, frow, fcol, 1, tcol - fcol); ! 848: } ! 849: if(hilite) { ! 850: tempgc = screen->normalGC; ! 851: screen->normalGC = screen->reverseGC; ! 852: screen->reverseGC = tempgc; ! 853: tempgc = screen->normalboldGC; ! 854: screen->normalboldGC = screen->reverseboldGC; ! 855: screen->reverseboldGC = tempgc; ! 856: ! 857: i = screen->foreground; ! 858: screen->foreground = screen->background; ! 859: screen->background = i; ! 860: XSetWindowBackground(screen->display,VWindow(screen),screen->background); ! 861: ! 862: } ! 863: } ! 864: ! 865: SaltTextAway(crow, ccol, row, col) ! 866: register crow, ccol, row, col; ! 867: /* Guaranteed that (crow, ccol) <= (row, col), and that both points are valid ! 868: (may have row = screen->max_row+1, col = 0) */ ! 869: { ! 870: register TScreen *screen = &term.screen; ! 871: register int i, j = 0; ! 872: char *line, *lp; ! 873: ! 874: --col; ! 875: /* first we need to know how long the string is before we can save it*/ ! 876: ! 877: if ( row == crow ) j = Length(screen, crow, ccol, col); ! 878: else { /* two cases, cut is on same line, cut spans multiple lines */ ! 879: j += Length(screen, crow, ccol, screen->max_col) + 1; ! 880: for(i = crow + 1; i < row; i++) ! 881: j += Length(screen, i, 0, screen->max_col) + 1; ! 882: if (col >= 0) ! 883: j += Length(screen, row, 0, col); ! 884: } ! 885: ! 886: /* now get some memory to save it in */ ! 887: ! 888: if((line = malloc((unsigned) j + 1)) == (char *)NULL) ! 889: SysError(ERROR_BMALLOC2); ! 890: line[j] = '\0'; /* make sure it is null terminated */ ! 891: lp = line; /* lp points to where to save the text */ ! 892: if ( row == crow ) lp = SaveText(screen, row, ccol, col, lp); ! 893: else { ! 894: lp = SaveText(screen, crow, ccol, screen->max_col, lp); ! 895: *lp ++ = '\n'; /* put in newline at end of line */ ! 896: for(i = crow +1; i < row; i++) { ! 897: lp = SaveText(screen, i, 0, screen->max_col, lp); ! 898: *lp ++ = '\n'; ! 899: } ! 900: if (col >= 0) ! 901: lp = SaveText(screen, row, 0, col, lp); ! 902: } ! 903: *lp = '\0'; /* make sure we have end marked */ ! 904: ! 905: XStoreBytes(screen->display,line, j); ! 906: free(line); ! 907: } ! 908: ! 909: /* returns number of chars in line from scol to ecol out */ ! 910: int Length(screen, row, scol, ecol) ! 911: register int row, scol, ecol; ! 912: register TScreen *screen; ! 913: { ! 914: register char *ch; ! 915: ! 916: ch = screen->buf[2 * (row + screen->topline)]; ! 917: while (ecol >= scol && ch[ecol] == 0) ! 918: ecol--; ! 919: return (ecol - scol + 1); ! 920: } ! 921: ! 922: /* copies text into line, preallocated */ ! 923: char *SaveText(screen, row, scol, ecol, lp) ! 924: int row; ! 925: int scol, ecol; ! 926: TScreen *screen; ! 927: register char *lp; /* pointer to where to put the text */ ! 928: { ! 929: register int i = 0; ! 930: register char *ch = screen->buf[2 * (row + screen->topline)]; ! 931: register int c; ! 932: ! 933: if ((i = Length(screen, row, scol, ecol)) == 0) return(lp); ! 934: ecol = scol + i; ! 935: for (i = scol; i < ecol; i++) { ! 936: if ((c = ch[i]) == 0) ! 937: c = ' '; ! 938: else if(c < ' ') { ! 939: if(c == '\036') ! 940: c = '#'; ! 941: else ! 942: c += 0x5f; ! 943: } else if(c == 0x7f) ! 944: c = 0x5f; ! 945: *lp++ = c; ! 946: } ! 947: return(lp); ! 948: } ! 949: ! 950: EditorButton(event) ! 951: register XButtonEvent *event; ! 952: { ! 953: register TScreen *screen = &term.screen; ! 954: int pty = screen->respond; ! 955: char line[6]; ! 956: register unsigned row, col; ! 957: int button; ! 958: ! 959: button = event->button - 1; ! 960: ! 961: row = (event->y - screen->border) ! 962: / FontHeight(screen); ! 963: col = (event->x - screen->border - screen->scrollbar) ! 964: / FontWidth(screen); ! 965: (void) strcpy(line, "\033[M"); ! 966: if (screen->send_mouse_pos == 1) { ! 967: line[3] = ' ' + button; ! 968: } else { ! 969: line[3] = ' ' + X10Map(event->state) + ! 970: ((event->type == ButtonPress)? button:3); ! 971: } ! 972: line[4] = ' ' + col + 1; ! 973: line[5] = ' ' + row + 1; ! 974: v_write(pty, line, 6); ! 975: } ! 976: ! 977: #ifdef MODEMENU ! 978: #define XTERMMENU 0 ! 979: #define VTMENU 1 ! 980: #define TEKMENU 2 ! 981: #define NMENUS 3 ! 982: ! 983: static Menu *menus[NMENUS]; ! 984: static int type; ! 985: extern TekLink *TekRefresh; ! 986: ! 987: ModeMenu(event) ! 988: register XButtonEvent *event; ! 989: { ! 990: register TScreen *screen = &term.screen; ! 991: register Menu *menu; ! 992: register int item; ! 993: static int inited; ! 994: extern Menu *setupmenu(), *Tsetupmenu(), *xsetupmenu(); ! 995: ! 996: ! 997: if(!inited) { ! 998: extern Pixmap Gray_Tile; ! 999: extern Cursor Menu_DefaultCursor; ! 1000: extern char *Menu_DefaultFont; ! 1001: extern XFontStruct *Menu_DefaultFontInfo; ! 1002: ! 1003: inited++; ! 1004: Gray_Tile = make_gray(BlackPixel(screen->display, ! 1005: DefaultScreen(screen->display)), ! 1006: WhitePixel(screen->display, DefaultScreen(screen->display)), 1); ! 1007: InitMenu(xterm_name); ! 1008: Menu_DefaultCursor = screen->arrow; ! 1009: /* if(XStrCmp(Menu_DefaultFont, f_t) == 0) ! 1010: Menu_DefaultFontInfo = screen->fnt_norm; ! 1011: */ ! 1012: } ! 1013: if((event->button) == Button1) ! 1014: type = XTERMMENU; ! 1015: else if((event->button) == Button3) ! 1016: { ! 1017: Bell(); ! 1018: return; ! 1019: } ! 1020: else if(event->window == VWindow(screen)) ! 1021: type = VTMENU; ! 1022: else if(event->window == TWindow(screen)) ! 1023: type = TEKMENU; ! 1024: else ! 1025: SysError(ERROR_BADMENU); ! 1026: switch(type) { ! 1027: case XTERMMENU: ! 1028: if((menu = xsetupmenu(&menus[XTERMMENU])) == NULL) ! 1029: return; ! 1030: break; ! 1031: case VTMENU: ! 1032: if((menu = setupmenu(&menus[VTMENU])) == NULL) ! 1033: return; ! 1034: break; ! 1035: case TEKMENU: ! 1036: if((menu = Tsetupmenu(&menus[TEKMENU])) == NULL) ! 1037: return; ! 1038: screen->waitrefresh = TRUE; ! 1039: break; ! 1040: } ! 1041: /* ! 1042: * Set the select mode manually. ! 1043: */ ! 1044: TrackMenu(menu, event); /* MenuButtonReleased calls FinishModeMenu */ ! 1045: } ! 1046: ! 1047: FinishModeMenu(item) ! 1048: register int item; ! 1049: { ! 1050: TScreen *screen = &term.screen; ! 1051: ! 1052: menusync(); ! 1053: screen->waitrefresh = FALSE; ! 1054: reselectwindow(screen); ! 1055: ! 1056: if (item < 0) { ! 1057: if(type == TEKMENU && TekRefresh) ! 1058: dorefresh(); ! 1059: return; ! 1060: } ! 1061: switch(type) { ! 1062: case XTERMMENU: ! 1063: xdomenufunc(item); ! 1064: break; ! 1065: case VTMENU: ! 1066: domenufunc(item); ! 1067: break; ! 1068: case TEKMENU: ! 1069: Tdomenufunc(item); ! 1070: break; ! 1071: } ! 1072: } ! 1073: ! 1074: menusync() ! 1075: { ! 1076: TScreen *screen = &term.screen; ! 1077: XSync(screen->display, 0); ! 1078: if (QLength(screen->display) > 0) ! 1079: xevents(); ! 1080: } ! 1081: ! 1082: #define XMENU_VISUALBELL 0 ! 1083: #define XMENU_LOG (XMENU_VISUALBELL+1) ! 1084: #define XMENU_LINE (XMENU_LOG+1) ! 1085: #define XMENU_REDRAW (XMENU_LINE+1) ! 1086: #define XMENU_RESUME (XMENU_REDRAW+1) ! 1087: #define XMENU_SUSPEND (XMENU_RESUME+1) ! 1088: #define XMENU_INTR (XMENU_SUSPEND+1) ! 1089: #define XMENU_HANGUP (XMENU_INTR+1) ! 1090: #define XMENU_TERM (XMENU_HANGUP+1) ! 1091: #define XMENU_KILL (XMENU_TERM+1) ! 1092: ! 1093: static char *xtext[] = { ! 1094: "Visual Bell", ! 1095: "Logging", ! 1096: "-", ! 1097: "Redraw", ! 1098: "Continue", ! 1099: "Suspend", ! 1100: "Interrupt", ! 1101: "Hangup", ! 1102: "Terminate", ! 1103: "Kill", ! 1104: 0, ! 1105: }; ! 1106: ! 1107: static int xbell; ! 1108: static int xlog; ! 1109: ! 1110: Menu *xsetupmenu(menu) ! 1111: register Menu **menu; ! 1112: { ! 1113: register TScreen *screen = &term.screen; ! 1114: register char **cp; ! 1115: register int i; ! 1116: ! 1117: if (*menu == NULL) { ! 1118: if ((*menu = NewMenu("xterm X11", re_verse)) == NULL) ! 1119: return(NULL); ! 1120: for(cp = xtext ; *cp ; cp++) ! 1121: AddMenuItem(*menu, *cp); ! 1122: if(xbell = screen->visualbell) ! 1123: CheckItem(*menu, XMENU_VISUALBELL); ! 1124: if(xlog = screen->logging) ! 1125: CheckItem(*menu, XMENU_LOG); ! 1126: DisableItem(*menu, XMENU_LINE); ! 1127: if((screen->inhibit & I_LOG) || ! 1128: /* if login window, check for completed login */ ! 1129: (L_flag && !checklogin())) ! 1130: DisableItem(*menu, XMENU_LOG); ! 1131: if(screen->inhibit & I_SIGNAL) ! 1132: for(i = XMENU_SUSPEND ; i <= XMENU_KILL ; i++) ! 1133: DisableItem(*menu, i); ! 1134: return(*menu); ! 1135: } ! 1136: /* if login window, check for completed login */ ! 1137: if (!(L_flag && !checklogin()) && !(screen->inhibit & I_LOG)) ! 1138: EnableItem(*menu, XMENU_LOG); ! 1139: if (xbell != screen->visualbell) ! 1140: SetItemCheck(*menu, XMENU_VISUALBELL, (xbell = ! 1141: screen->visualbell)); ! 1142: if (xlog != screen->logging) ! 1143: SetItemCheck(*menu, XMENU_LOG, (xlog = screen->logging)); ! 1144: return(*menu); ! 1145: } ! 1146: ! 1147: xdomenufunc(item) ! 1148: int item; ! 1149: { ! 1150: register TScreen *screen = &term.screen; ! 1151: ! 1152: switch (item) { ! 1153: case XMENU_VISUALBELL: ! 1154: screen->visualbell = !screen->visualbell; ! 1155: break; ! 1156: ! 1157: case XMENU_LOG: ! 1158: if(screen->logging) ! 1159: CloseLog(screen); ! 1160: else ! 1161: StartLog(screen); ! 1162: break; ! 1163: ! 1164: case XMENU_REDRAW: ! 1165: Redraw(); ! 1166: break; ! 1167: ! 1168: case XMENU_RESUME: ! 1169: if(screen->pid > 1) ! 1170: killpg(getpgrp(screen->pid), SIGCONT); ! 1171: break; ! 1172: ! 1173: case XMENU_SUSPEND: ! 1174: if(screen->pid > 1) ! 1175: killpg(getpgrp(screen->pid), SIGTSTP); ! 1176: break; ! 1177: ! 1178: case XMENU_INTR: ! 1179: if(screen->pid > 1) ! 1180: killpg(getpgrp(screen->pid), SIGINT); ! 1181: break; ! 1182: ! 1183: case XMENU_HANGUP: ! 1184: if(screen->pid > 1) ! 1185: killpg(getpgrp(screen->pid), SIGHUP); ! 1186: break; ! 1187: ! 1188: case XMENU_TERM: ! 1189: if(screen->pid > 1) ! 1190: killpg(getpgrp(screen->pid), SIGTERM); ! 1191: break; ! 1192: ! 1193: case XMENU_KILL: ! 1194: if(screen->pid > 1) ! 1195: killpg(getpgrp(screen->pid), SIGKILL); ! 1196: break; ! 1197: } ! 1198: } ! 1199: ! 1200: ! 1201: MenuNewCursor(cur) ! 1202: register Cursor cur; ! 1203: { ! 1204: register Menu **menu; ! 1205: register int i; ! 1206: register TScreen *screen = &term.screen; ! 1207: extern Cursor Menu_DefaultCursor; ! 1208: ! 1209: Menu_DefaultCursor = cur; ! 1210: for(i = XTERMMENU, menu = menus ; i <= TEKMENU ; menu++, i++) { ! 1211: if(!*menu) ! 1212: continue; ! 1213: (*menu)->menuCursor = cur; ! 1214: if((*menu)->menuWindow) ! 1215: XDefineCursor(screen->display, (*menu)->menuWindow, ! 1216: cur); ! 1217: } ! 1218: } ! 1219: #else MODEMENU ! 1220: ! 1221: /*ARGSUSED*/ ! 1222: ModeMenu(event) register XButtonEvent *event; { Bell(); } ! 1223: #endif MODEMENU ! 1224: ! 1225: GINbutton(event) ! 1226: XButtonEvent *event; ! 1227: { ! 1228: register TScreen *screen = &term.screen; ! 1229: register int i; ! 1230: ! 1231: if(screen->TekGIN) { ! 1232: i = "rml"[event->button - 1]; ! 1233: if(event->state & ShiftMask) ! 1234: i = toupper(i); ! 1235: TekEnqMouse(i | 0x80); /* set high bit */ ! 1236: TekGINoff(); ! 1237: } else ! 1238: Bell(); ! 1239: } ! 1240: ! 1241: /*ARGSUSED*/ ! 1242: Bogus(event) ! 1243: XButtonEvent *event; ! 1244: { ! 1245: Bell(); ! 1246: } ! 1247: ! 1248: /*ARGSUSED*/ ! 1249: Silence(event) ! 1250: XButtonEvent *event; ! 1251: { ! 1252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.