Annotation of researchv9/X11/src/X.V11R1/clients/xterm/button.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.