Annotation of researchv9/X11/src/X.V11R1/clients/xterm/button.c, revision 1.1.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.