home *** CD-ROM | disk | FTP | other *** search
- /* $XConsortium: button.c,v 1.66 91/05/31 17:00:03 gildea Exp $ */
- /*
- * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Digital Equipment
- * Corporation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior permission.
- *
- *
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /*
- button.c Handles button events in the terminal emulator.
- does cut/paste operations, change modes via menu,
- passes button events through to some applications.
- J. Gettys.
- */
-
- #include "ptyx.h" /* Xlib headers included here. */
- #include <X11/Xatom.h>
- #include <stdio.h>
-
- #include <X11/Xmu/Atoms.h>
- #include <X11/Xmu/StdSel.h>
-
- #include "data.h"
- #include "error.h"
- #include "menu.h"
-
- extern char *malloc();
-
- extern void DoSecureKeyboard();
-
- #define KeyState(x) (((x) & (ShiftMask|ControlMask)) + (((x) & Mod1Mask) ? 2 : 0))
- /* adds together the bits:
- shift key -> 1
- meta key -> 2
- control key -> 4 */
-
- #define TEXTMODES 4
- #define NBUTS 3
- #define DIRS 2
- #define UP 1
- #define DOWN 0
- #define SHIFTS 8 /* three keys, so eight combinations */
- #define Coordinate(r,c) ((r) * (term->screen.max_col+1) + (c))
-
- extern char *xterm_name;
-
- static void PointToRowCol();
- static void SelectionReceived();
- static void TrackDown();
- static void ComputeSelect();
- static void EditorButton();
- static void ExtendExtend();
- static void ReHiliteText();
- static void SelectSet();
- static void StartSelect();
- static int Length();
- static char *SaveText();
-
- extern XtermWidget term;
-
- /* Selection/extension variables */
-
- /* Raw char position where the selection started */
- static int rawRow, rawCol;
-
- /* Selected area before CHAR, WORD, LINE selectUnit processing */
- static int startRRow, startRCol, endRRow, endRCol = 0;
-
- /* Selected area after CHAR, WORD, LINE selectUnit processing */
- static int startSRow, startSCol, endSRow, endSCol = 0;
-
- /* Valid rows for selection clipping */
- static int firstValidRow, lastValidRow;
-
- /* Start, end of extension */
- static int startERow, startECol, endERow, endECol;
-
- /* Saved values of raw selection for extend to restore to */
- static int saveStartRRow, saveStartRCol, saveEndRRow, saveEndRCol;
-
- /* Multi-click handling */
- static int numberOfClicks = 0;
- static long int lastButtonUpTime = 0;
- typedef int SelectUnit;
- #define SELECTCHAR 0
- #define SELECTWORD 1
- #define SELECTLINE 2
- #define NSELECTUNITS 3
- static SelectUnit selectUnit;
-
- /* Send emacs escape code when done selecting or extending? */
- static int replyToEmacs;
-
-
- Boolean SendMousePosition(w, event)
- Widget w;
- XEvent* event;
- {
- register TScreen *screen = &((XtermWidget)w)->screen;
-
- if (screen->send_mouse_pos == 0) return False;
-
- if (event->type != ButtonPress && event->type != ButtonRelease)
- return False;
-
- #define KeyModifiers \
- (event->xbutton.state & (ShiftMask | LockMask | ControlMask | Mod1Mask | \
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask ))
-
- #define ButtonModifiers \
- (event->xbutton.state & (ShiftMask | LockMask | ControlMask | Mod1Mask | \
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask ))
-
- switch (screen->send_mouse_pos) {
- case 1: /* X10 compatibility sequences */
-
- if (KeyModifiers == 0) {
- if (event->type == ButtonPress)
- EditorButton(event);
- return True;
- }
- return False;
-
- case 2: /* DEC vt200 compatible */
-
- if (KeyModifiers == 0 || KeyModifiers == ControlMask) {
- EditorButton(event);
- return True;
- }
- return False;
-
- case 3: /* DEC vt200 hilite tracking */
- if ( event->type == ButtonPress &&
- KeyModifiers == 0 &&
- event->xbutton.button == Button1 ) {
- TrackDown(event);
- return True;
- }
- if (KeyModifiers == 0 || KeyModifiers == ControlMask) {
- EditorButton(event);
- return True;
- }
- /* fall through */
-
- default:
- return False;
- }
- #undef KeyModifiers
- }
-
-
- /*ARGSUSED*/
- void HandleSelectExtend(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XMotionEvent */
- String *params; /* unused */
- Cardinal *num_params; /* unused */
- {
- register TScreen *screen = &((XtermWidget)w)->screen;
- int row, col;
-
- screen->selection_time = event->xmotion.time;
- switch (eventMode) {
- case LEFTEXTENSION :
- case RIGHTEXTENSION :
- PointToRowCol (event->xmotion.y, event->xmotion.x,
- &row, &col);
- ExtendExtend (row, col);
- break;
- case NORMAL :
- /* will get here if send_mouse_pos != 0 */
- break;
- }
- }
-
- static void EndExtend();
-
- static void do_select_end (w, event, params, num_params, use_cursor_loc)
- Widget w;
- XEvent *event; /* must be XButtonEvent */
- String *params; /* selections */
- Cardinal *num_params;
- Bool use_cursor_loc;
- {
- ((XtermWidget)w)->screen.selection_time = event->xbutton.time;
- switch (eventMode) {
- case NORMAL :
- (void) SendMousePosition(w, event);
- break;
- case LEFTEXTENSION :
- case RIGHTEXTENSION :
- EndExtend(w, event, params, *num_params, use_cursor_loc);
- break;
- }
- }
-
-
- void HandleSelectEnd(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XButtonEvent */
- String *params; /* selections */
- Cardinal *num_params;
- {
- do_select_end (w, event, params, num_params, False);
- }
-
-
- void HandleKeyboardSelectEnd(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XButtonEvent */
- String *params; /* selections */
- Cardinal *num_params;
- {
- do_select_end (w, event, params, num_params, True);
- }
-
-
-
-
- struct _SelectionList {
- String *params;
- Cardinal count;
- Time time;
- };
-
-
- static void _GetSelection(w, time, params, num_params)
- Widget w;
- Time time;
- String *params; /* selections in precedence order */
- Cardinal num_params;
- {
- Atom selection;
- int cutbuffer;
-
- XmuInternStrings(XtDisplay(w), params, (Cardinal)1, &selection);
- switch (selection) {
- case XA_CUT_BUFFER0: cutbuffer = 0; break;
- case XA_CUT_BUFFER1: cutbuffer = 1; break;
- case XA_CUT_BUFFER2: cutbuffer = 2; break;
- case XA_CUT_BUFFER3: cutbuffer = 3; break;
- case XA_CUT_BUFFER4: cutbuffer = 4; break;
- case XA_CUT_BUFFER5: cutbuffer = 5; break;
- case XA_CUT_BUFFER6: cutbuffer = 6; break;
- case XA_CUT_BUFFER7: cutbuffer = 7; break;
- default: cutbuffer = -1;
- }
- if (cutbuffer >= 0) {
- register TScreen *screen = &((XtermWidget)w)->screen;
- int inbytes;
- unsigned long nbytes;
- int fmt8 = 8;
- Atom type = XA_STRING;
- char *line = XFetchBuffer(screen->display, &inbytes, cutbuffer);
- nbytes = (unsigned long) inbytes;
- if (nbytes > 0)
- SelectionReceived(w, NULL, &selection, &type, (XtPointer)line,
- &nbytes, &fmt8);
- else if (num_params > 1)
- _GetSelection(w, time, params+1, num_params-1);
- } else {
- struct _SelectionList* list;
- if (--num_params) {
- list = XtNew(struct _SelectionList);
- list->params = params + 1;
- list->count = num_params; /* decremented above */
- list->time = time;
- } else list = NULL;
- XtGetSelectionValue(w, selection, XA_STRING, SelectionReceived,
- (XtPointer)list, time);
- }
- }
-
- /* SelectionReceived: stuff received selection text into pty */
-
- /* ARGSUSED */
- static void SelectionReceived(w, client_data, selection, type,
- value, length, format)
- Widget w;
- XtPointer client_data;
- Atom *selection, *type;
- XtPointer value;
- unsigned long *length;
- int *format;
- {
- int pty = ((XtermWidget)w)->screen.respond; /* file descriptor of pty */
- register char *lag, *cp, *end;
- char *line = (char*)value;
-
- if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0 || value == NULL) {
- /* could not get this selection, so see if there are more to try */
- struct _SelectionList* list = (struct _SelectionList*)client_data;
- if (list != NULL) {
- _GetSelection(w, list->time, list->params, list->count);
- XtFree(client_data);
- }
- return;
- }
-
- /* Write data to pty a line at a time. */
- /* Doing this one line at a time may no longer be necessary
- because v_write has been re-written. */
-
- end = &line[*length];
- lag = line;
- for (cp = line; cp != end; cp++)
- {
- if (*cp != '\n') continue;
- *cp = '\r';
- v_write(pty, lag, cp - lag + 1);
- lag = cp + 1;
- }
- if (lag != end)
- v_write(pty, lag, end - lag);
-
- XtFree(client_data);
- XtFree(value);
- }
-
-
- void
- HandleInsertSelection(w, event, params, num_params)
- Widget w;
- XEvent *event; /* assumed to be XButtonEvent* */
- String *params; /* selections in precedence order */
- Cardinal *num_params;
- {
- if (SendMousePosition(w, event)) return;
- _GetSelection(w, event->xbutton.time, params, *num_params);
- }
-
-
- static void
- SetSelectUnit(buttonDownTime, defaultUnit)
- unsigned long buttonDownTime;
- SelectUnit defaultUnit;
- {
- /* Do arithmetic as integers, but compare as unsigned solves clock wraparound */
- if ((long unsigned)((long int)buttonDownTime - lastButtonUpTime)
- > term->screen.multiClickTime) {
- numberOfClicks = 1;
- selectUnit = defaultUnit;
- } else {
- ++numberOfClicks;
- selectUnit = ((selectUnit + 1) % NSELECTUNITS);
- }
- }
-
- static void do_select_start (w, event, startrow, startcol)
- Widget w;
- XEvent *event; /* must be XButtonEvent* */
- int startrow, startcol;
- {
- if (SendMousePosition(w, event)) return;
- SetSelectUnit(event->xbutton.time, SELECTCHAR);
- replyToEmacs = FALSE;
- StartSelect(startrow, startcol);
- }
-
- /* ARGSUSED */
- void
- HandleSelectStart(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XButtonEvent* */
- String *params; /* unused */
- Cardinal *num_params; /* unused */
- {
- register TScreen *screen = &((XtermWidget)w)->screen;
- int startrow, startcol;
-
- firstValidRow = 0;
- lastValidRow = screen->max_row;
- PointToRowCol(event->xbutton.y, event->xbutton.x, &startrow, &startcol);
- do_select_start (w, event, startrow, startcol);
- }
-
-
- /* ARGSUSED */
- void
- HandleKeyboardSelectStart(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XButtonEvent* */
- String *params; /* unused */
- Cardinal *num_params; /* unused */
- {
- register TScreen *screen = &((XtermWidget)w)->screen;
-
- do_select_start (w, event, screen->cursor_row, screen->cursor_col);
- }
-
-
- static void
- TrackDown(event)
- register XButtonEvent *event;
- {
- int startrow, startcol;
-
- SetSelectUnit(event->time, SELECTCHAR);
- if (numberOfClicks > 1 ) {
- PointToRowCol(event->y, event->x, &startrow, &startcol);
- replyToEmacs = TRUE;
- StartSelect(startrow, startcol);
- } else {
- waitingForTrackInfo = 1;
- EditorButton(event);
- }
- }
-
-
- #define boundsCheck(x) if (x < 0) \
- x = 0; \
- else if (x >= screen->max_row) \
- x = screen->max_row;
-
- TrackMouse(func, startrow, startcol, firstrow, lastrow)
- int func, startrow, startcol, firstrow, lastrow;
- {
- TScreen *screen = &term->screen;
-
- if (!waitingForTrackInfo) { /* Timed out, so ignore */
- return;
- }
- waitingForTrackInfo = 0;
- if (func == 0) return;
- boundsCheck (startrow)
- boundsCheck (firstrow)
- boundsCheck (lastrow)
- firstValidRow = firstrow;
- lastValidRow = lastrow;
- replyToEmacs = TRUE;
- StartSelect(startrow, startcol);
- }
-
- static void
- StartSelect(startrow, startcol)
- int startrow, startcol;
- {
- TScreen *screen = &term->screen;
-
- if (screen->cursor_state)
- HideCursor ();
- if (numberOfClicks == 1) {
- /* set start of selection */
- rawRow = startrow;
- rawCol = startcol;
-
- } /* else use old values in rawRow, Col */
-
- saveStartRRow = startERow = rawRow;
- saveStartRCol = startECol = rawCol;
- saveEndRRow = endERow = rawRow;
- saveEndRCol = endECol = rawCol;
- if (Coordinate(startrow, startcol) < Coordinate(rawRow, rawCol)) {
- eventMode = LEFTEXTENSION;
- startERow = startrow;
- startECol = startcol;
- } else {
- eventMode = RIGHTEXTENSION;
- endERow = startrow;
- endECol = startcol;
- }
- ComputeSelect(startERow, startECol, endERow, endECol, False);
-
- }
-
- static void
- EndExtend(w, event, params, num_params, use_cursor_loc)
- Widget w;
- XEvent *event; /* must be XButtonEvent */
- String *params; /* selections */
- Cardinal num_params;
- Bool use_cursor_loc;
- {
- int row, col;
- TScreen *screen = &term->screen;
- char line[9];
-
- if (use_cursor_loc) {
- row = screen->cursor_row;
- col = screen->cursor_col;
- } else {
- PointToRowCol(event->xbutton.y, event->xbutton.x, &row, &col);
- }
- ExtendExtend (row, col);
- lastButtonUpTime = event->xbutton.time;
- if (startSRow != endSRow || startSCol != endSCol) {
- if (replyToEmacs) {
- if (rawRow == startSRow && rawCol == startSCol
- && row == endSRow && col == endSCol) {
- /* Use short-form emacs select */
- strcpy(line, "\033[t");
- line[3] = ' ' + endSCol + 1;
- line[4] = ' ' + endSRow + 1;
- v_write(screen->respond, line, 5);
- } else {
- /* long-form, specify everything */
- strcpy(line, "\033[T");
- line[3] = ' ' + startSCol + 1;
- line[4] = ' ' + startSRow + 1;
- line[5] = ' ' + endSCol + 1;
- line[6] = ' ' + endSRow + 1;
- line[7] = ' ' + col + 1;
- line[8] = ' ' + row + 1;
- v_write(screen->respond, line, 9);
- }
- TrackText(0, 0, 0, 0);
- }
- }
- SelectSet(w, event, params, num_params);
- eventMode = NORMAL;
- }
-
- void
- HandleSelectSet(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- SelectSet (w, event, params, *num_params);
- }
-
- static void SaltTextAway();
-
- /* ARGSUSED */
- static void
- SelectSet (w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal num_params;
- {
- /* Only do select stuff if non-null select */
- if (startSRow != endSRow || startSCol != endSCol) {
- SaltTextAway(startSRow, startSCol, endSRow, endSCol,
- params, num_params);
- } else
- DisownSelection(term);
- }
-
- #define Abs(x) ((x) < 0 ? -(x) : (x))
-
- /* ARGSUSED */
- static void do_start_extend (w, event, params, num_params, use_cursor_loc)
- Widget w;
- XEvent *event; /* must be XButtonEvent* */
- String *params; /* unused */
- Cardinal *num_params; /* unused */
- Bool use_cursor_loc;
- {
- TScreen *screen = &((XtermWidget)w)->screen;
- int row, col, coord;
-
- if (SendMousePosition(w, event)) return;
- firstValidRow = 0;
- lastValidRow = screen->max_row;
- SetSelectUnit(event->xbutton.time, selectUnit);
- replyToEmacs = FALSE;
-
- if (numberOfClicks == 1) {
- /* Save existing selection so we can reestablish it if the guy
- extends past the other end of the selection */
- saveStartRRow = startERow = startRRow;
- saveStartRCol = startECol = startRCol;
- saveEndRRow = endERow = endRRow;
- saveEndRCol = endECol = endRCol;
- } else {
- /* He just needed the selection mode changed, use old values. */
- startERow = startRRow = saveStartRRow;
- startECol = startRCol = saveStartRCol;
- endERow = endRRow = saveEndRRow;
- endECol = endRCol = saveEndRCol;
-
- }
- if (use_cursor_loc) {
- row = screen->cursor_row;
- col = screen->cursor_col;
- } else {
- PointToRowCol(event->xbutton.y, event->xbutton.x, &row, &col);
- }
- coord = Coordinate(row, col);
-
- if (Abs(coord - Coordinate(startSRow, startSCol))
- < Abs(coord - Coordinate(endSRow, endSCol))
- || coord < Coordinate(startSRow, startSCol)) {
- /* point is close to left side of selection */
- eventMode = LEFTEXTENSION;
- startERow = row;
- startECol = col;
- } else {
- /* point is close to left side of selection */
- eventMode = RIGHTEXTENSION;
- endERow = row;
- endECol = col;
- }
- ComputeSelect(startERow, startECol, endERow, endECol, True);
- }
-
- static void
- ExtendExtend (row, col)
- int row, col;
- {
- int coord = Coordinate(row, col);
-
- if (eventMode == LEFTEXTENSION
- && (coord + (selectUnit!=SELECTCHAR)) > Coordinate(endSRow, endSCol)) {
- /* Whoops, he's changed his mind. Do RIGHTEXTENSION */
- eventMode = RIGHTEXTENSION;
- startERow = saveStartRRow;
- startECol = saveStartRCol;
- } else if (eventMode == RIGHTEXTENSION
- && coord < Coordinate(startSRow, startSCol)) {
- /* Whoops, he's changed his mind. Do LEFTEXTENSION */
- eventMode = LEFTEXTENSION;
- endERow = saveEndRRow;
- endECol = saveEndRCol;
- }
- if (eventMode == LEFTEXTENSION) {
- startERow = row;
- startECol = col;
- } else {
- endERow = row;
- endECol = col;
- }
- ComputeSelect(startERow, startECol, endERow, endECol, False);
- }
-
-
- void HandleStartExtend(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XButtonEvent* */
- String *params; /* unused */
- Cardinal *num_params; /* unused */
- {
- do_start_extend (w, event, params, num_params, False);
- }
-
- void HandleKeyboardStartExtend(w, event, params, num_params)
- Widget w;
- XEvent *event; /* must be XButtonEvent* */
- String *params; /* unused */
- Cardinal *num_params; /* unused */
- {
- do_start_extend (w, event, params, num_params, True);
- }
-
-
-
-
-
- ScrollSelection(screen, amount)
- register TScreen* screen;
- register int amount;
- {
- register int minrow = -screen->savedlines;
-
- /* Sent by scrollbar stuff, so amount never takes selection out of
- saved text */
-
- /* XXX - the preceeding is false; cat /etc/termcap (or anything
- larger than the number of saved lines plus the screen height) and then
- hit extend select */
-
- startRRow += amount; endRRow += amount;
- startSRow += amount; endSRow += amount;
- rawRow += amount;
- screen->startHRow += amount;
- screen->endHRow += amount;
-
- if (startRRow < minrow) {
- startRRow = minrow;
- startRCol = 0;
- }
- if (endRRow < minrow) {
- endRRow = minrow;
- endRCol = 0;
- }
- if (startSRow < minrow) {
- startSRow = minrow;
- startSCol = 0;
- }
- if (endSRow < minrow) {
- endSRow = minrow;
- endSCol = 0;
- }
- if (rawRow < minrow) {
- rawRow = minrow;
- rawCol = 0;
- }
- if (screen->startHRow < minrow) {
- screen->startHRow = minrow;
- screen->startHCol = 0;
- }
- if (screen->endHRow < minrow) {
- screen->endHRow = minrow;
- screen->endHCol = 0;
- }
- screen->startHCoord = Coordinate (screen->startHRow, screen->startHCol);
- screen->endHCoord = Coordinate (screen->endHRow, screen->endHCol);
- }
-
-
- /*ARGSUSED*/
- ResizeSelection (screen, rows, cols)
- TScreen *screen;
- int rows, cols;
- {
- rows--; /* decr to get 0-max */
- cols--;
-
- if (startRRow > rows) startRRow = rows;
- if (startSRow > rows) startSRow = rows;
- if (endRRow > rows) endRRow = rows;
- if (endSRow > rows) endSRow = rows;
- if (rawRow > rows) rawRow = rows;
-
- if (startRCol > cols) startRCol = cols;
- if (startSCol > cols) startSCol = cols;
- if (endRCol > cols) endRCol = cols;
- if (endSCol > cols) endSCol = cols;
- if (rawCol > cols) rawCol = cols;
- }
-
- static void
- PointToRowCol(y, x, r, c)
- register int y, x;
- int *r, *c;
- /* Convert pixel coordinates to character coordinates.
- Rows are clipped between firstValidRow and lastValidRow.
- Columns are clipped between to be 0 or greater, but are not clipped to some
- maximum value. */
- {
- register TScreen *screen = &term->screen;
- register row, col;
-
- row = (y - screen->border) / FontHeight(screen);
- if(row < firstValidRow)
- row = firstValidRow;
- else if(row > lastValidRow)
- row = lastValidRow;
- col = (x - screen->border - screen->scrollbar) / FontWidth(screen);
- if(col < 0)
- col = 0;
- else if(col > screen->max_col+1) {
- col = screen->max_col+1;
- }
- *r = row;
- *c = col;
- }
-
- static int
- LastTextCol(row)
- register int row;
- {
- register TScreen *screen = &term->screen;
- register int i;
- register Char *ch;
-
- for ( i = screen->max_col,
- ch = screen->buf[2 * (row + screen->topline) + 1] + i ;
- i >= 0 && !(*ch & CHARDRAWN) ;
- ch--, i--)
- ;
- return(i);
- }
-
- /*
- ** double click table for cut and paste in 8 bits
- **
- ** This table is divided in four parts :
- **
- ** - control characters [0,0x1f] U [0x80,0x9f]
- ** - separators [0x20,0x3f] U [0xa0,0xb9]
- ** - binding characters [0x40,0x7f] U [0xc0,0xff]
- ** - execeptions
- */
- static int charClass[256] = {
- /* NUL SOH STX ETX EOT ENQ ACK BEL */
- 32, 1, 1, 1, 1, 1, 1, 1,
- /* BS HT NL VT NP CR SO SI */
- 1, 32, 1, 1, 1, 1, 1, 1,
- /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
- 1, 1, 1, 1, 1, 1, 1, 1,
- /* CAN EM SUB ESC FS GS RS US */
- 1, 1, 1, 1, 1, 1, 1, 1,
- /* SP ! " # $ % & ' */
- 32, 33, 34, 35, 36, 37, 38, 39,
- /* ( ) * + , - . / */
- 40, 41, 42, 43, 44, 45, 46, 47,
- /* 0 1 2 3 4 5 6 7 */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* 8 9 : ; < = > ? */
- 48, 48, 58, 59, 60, 61, 62, 63,
- /* @ A B C D E F G */
- 64, 48, 48, 48, 48, 48, 48, 48,
- /* H I J K L M N O */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* P Q R S T U V W */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* X Y Z [ \ ] ^ _ */
- 48, 48, 48, 91, 92, 93, 94, 48,
- /* ` a b c d e f g */
- 96, 48, 48, 48, 48, 48, 48, 48,
- /* h i j k l m n o */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* p q r s t u v w */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* x y z { | } ~ DEL */
- 48, 48, 48, 123, 124, 125, 126, 1,
- /* x80 x81 x82 x83 IND NEL SSA ESA */
- 1, 1, 1, 1, 1, 1, 1, 1,
- /* HTS HTJ VTS PLD PLU RI SS2 SS3 */
- 1, 1, 1, 1, 1, 1, 1, 1,
- /* DCS PU1 PU2 STS CCH MW SPA EPA */
- 1, 1, 1, 1, 1, 1, 1, 1,
- /* x98 x99 x9A CSI ST OSC PM APC */
- 1, 1, 1, 1, 1, 1, 1, 1,
- /* - i c/ L ox Y- | So */
- 160, 161, 162, 163, 164, 165, 166, 167,
- /* .. c0 ip << _ R0 - */
- 168, 169, 170, 171, 172, 173, 174, 175,
- /* o +- 2 3 ' u q| . */
- 176, 177, 178, 179, 180, 181, 182, 183,
- /* , 1 2 >> 1/4 1/2 3/4 ? */
- 184, 185, 186, 187, 188, 189, 190, 191,
- /* A` A' A^ A~ A: Ao AE C, */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* E` E' E^ E: I` I' I^ I: */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* D- N~ O` O' O^ O~ O: X */
- 48, 48, 48, 48, 48, 48, 48, 216,
- /* O/ U` U' U^ U: Y' P B */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* a` a' a^ a~ a: ao ae c, */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* e` e' e^ e: i` i' i^ i: */
- 48, 48, 48, 48, 48, 48, 48, 48,
- /* d n~ o` o' o^ o~ o: -: */
- 48, 48, 48, 48, 48, 48, 48, 248,
- /* o/ u` u' u^ u: y' P y: */
- 48, 48, 48, 48, 48, 48, 48, 48};
-
- int SetCharacterClassRange (low, high, value)
- register int low, high; /* in range of [0..255] */
- register int value; /* arbitrary */
- {
-
- if (low < 0 || high > 255 || high < low) return (-1);
-
- for (; low <= high; low++) charClass[low] = value;
-
- return (0);
- }
-
- /*
- * sets startSRow startSCol endSRow endSCol
- * ensuring that they have legal values
- */
-
- static void
- ComputeSelect(startRow, startCol, endRow, endCol, extend)
- int startRow, startCol, endRow, endCol;
- Bool extend;
- {
- register TScreen *screen = &term->screen;
- register Char *ptr;
- register int length;
- register int class;
- int osc = startSCol;
-
- if (Coordinate(startRow, startCol) <= Coordinate(endRow, endCol)) {
- startSRow = startRRow = startRow;
- startSCol = startRCol = startCol;
- endSRow = endRRow = endRow;
- endSCol = endRCol = endCol;
- } else { /* Swap them */
- startSRow = startRRow = endRow;
- startSCol = startRCol = endCol;
- endSRow = endRRow = startRow;
- endSCol = endRCol = startCol;
- }
-
- switch (selectUnit) {
- case SELECTCHAR :
- if (startSCol > (LastTextCol(startSRow) + 1)) {
- startSCol = 0;
- startSRow++;
- }
- if (endSCol > (LastTextCol(endSRow) + 1)) {
- endSCol = 0;
- endSRow++;
- }
- break;
- case SELECTWORD :
- if (startSCol > (LastTextCol(startSRow) + 1)) {
- startSCol = 0;
- startSRow++;
- } else {
- ptr = screen->buf[2*(startSRow+screen->topline)]
- + startSCol;
- class = charClass[*ptr];
- do {
- --startSCol;
- --ptr;
- } while (startSCol >= 0
- && charClass[*ptr] == class);
- ++startSCol;
- }
- if (endSCol > (LastTextCol(endSRow) + 1)) {
- endSCol = 0;
- endSRow++;
- } else {
- length = LastTextCol(endSRow);
- ptr = screen->buf[2*(endSRow+screen->topline)]
- + endSCol;
- class = charClass[*ptr];
- do {
- ++endSCol;
- ++ptr;
- } while (endSCol <= length
- && charClass[*ptr] == class);
- /* Word select selects if pointing to any char
- in "word", especially in that it includes
- the last character in a word. So no --endSCol
- and do special eol handling */
- if (endSCol > length+1) {
- endSCol = 0;
- ++endSRow;
- }
- }
- break;
- case SELECTLINE :
- if (term->screen.cutToBeginningOfLine) {
- startSCol = 0;
- } else if (!extend) {
- startSCol = osc;
- }
- if (term->screen.cutNewline) {
- endSCol = 0;
- ++endSRow;
- } else {
- endSCol = LastTextCol(endSRow) + 1;
- }
- break;
- }
-
- TrackText(startSRow, startSCol, endSRow, endSCol);
- return;
- }
-
-
- TrackText(frow, fcol, trow, tcol)
- register int frow, fcol, trow, tcol;
- /* Guaranteed (frow, fcol) <= (trow, tcol) */
- {
- register int from, to;
- register TScreen *screen = &term->screen;
- int old_startrow, old_startcol, old_endrow, old_endcol;
-
- old_startrow = screen->startHRow;
- old_startcol = screen->startHCol;
- old_endrow = screen->endHRow;
- old_endcol = screen->endHCol;
- if (frow == old_startrow && fcol == old_startcol &&
- trow == old_endrow && tcol == old_endcol) return;
- screen->startHRow = frow;
- screen->startHCol = fcol;
- screen->endHRow = trow;
- screen->endHCol = tcol;
- from = Coordinate(frow, fcol);
- to = Coordinate(trow, tcol);
- if (to <= screen->startHCoord || from > screen->endHCoord) {
- /* No overlap whatsoever between old and new hilite */
- ReHiliteText(old_startrow, old_startcol, old_endrow, old_endcol);
- ReHiliteText(frow, fcol, trow, tcol);
- } else {
- if (from < screen->startHCoord) {
- /* Extend left end */
- ReHiliteText(frow, fcol, old_startrow, old_startcol);
- } else if (from > screen->startHCoord) {
- /* Shorten left end */
- ReHiliteText(old_startrow, old_startcol, frow, fcol);
- }
- if (to > screen->endHCoord) {
- /* Extend right end */
- ReHiliteText(old_endrow, old_endcol, trow, tcol);
- } else if (to < screen->endHCoord) {
- /* Shorten right end */
- ReHiliteText(trow, tcol, old_endrow, old_endcol);
- }
- }
- screen->startHCoord = from;
- screen->endHCoord = to;
- }
-
- static void
- ReHiliteText(frow, fcol, trow, tcol)
- register int frow, fcol, trow, tcol;
- /* Guaranteed that (frow, fcol) <= (trow, tcol) */
- {
- register TScreen *screen = &term->screen;
- register int i;
-
- if (frow < 0)
- frow = fcol = 0;
- else if (frow > screen->max_row)
- return; /* nothing to do, since trow >= frow */
-
- if (trow < 0)
- return; /* nothing to do, since frow <= trow */
- else if (trow > screen->max_row) {
- trow = screen->max_row;
- tcol = screen->max_col+1;
- }
- if (frow == trow && fcol == tcol)
- return;
-
- if(frow != trow) { /* do multiple rows */
- if((i = screen->max_col - fcol + 1) > 0) { /* first row */
- ScrnRefresh(screen, frow, fcol, 1, i, True);
- }
- if((i = trow - frow - 1) > 0) { /* middle rows*/
- ScrnRefresh(screen, frow+1, 0,i, screen->max_col+1, True);
- }
- if(tcol > 0 && trow <= screen->max_row) { /* last row */
- ScrnRefresh(screen, trow, 0, 1, tcol, True);
- }
- } else { /* do single row */
- ScrnRefresh(screen, frow, fcol, 1, tcol - fcol, True);
- }
- }
-
- static _OwnSelection();
-
- static void
- SaltTextAway(crow, ccol, row, col, params, num_params)
- /*register*/ int crow, ccol, row, col;
- String *params; /* selections */
- Cardinal num_params;
- /* Guaranteed that (crow, ccol) <= (row, col), and that both points are valid
- (may have row = screen->max_row+1, col = 0) */
- {
- register TScreen *screen = &term->screen;
- register int i, j = 0;
- int eol;
- char *line, *lp;
-
- if (crow == row && ccol > col) {
- int tmp = ccol;
- ccol = col;
- col = tmp;
- }
-
- --col;
- /* first we need to know how long the string is before we can save it*/
-
- if ( row == crow ) j = Length(screen, crow, ccol, col);
- else { /* two cases, cut is on same line, cut spans multiple lines */
- j += Length(screen, crow, ccol, screen->max_col) + 1;
- for(i = crow + 1; i < row; i++)
- j += Length(screen, i, 0, screen->max_col) + 1;
- if (col >= 0)
- j += Length(screen, row, 0, col);
- }
-
- /* now get some memory to save it in */
-
- if (screen->selection_size <= j) {
- if((line = malloc((unsigned) j + 1)) == (char *)NULL)
- SysError(ERROR_BMALLOC2);
- XtFree(screen->selection);
- screen->selection = line;
- screen->selection_size = j + 1;
- } else line = screen->selection;
- if (!line || j < 0) return;
-
- line[j] = '\0'; /* make sure it is null terminated */
- lp = line; /* lp points to where to save the text */
- if ( row == crow ) lp = SaveText(screen, row, ccol, col, lp, &eol);
- else {
- lp = SaveText(screen, crow, ccol, screen->max_col, lp, &eol);
- if (eol)
- *lp ++ = '\n'; /* put in newline at end of line */
- for(i = crow +1; i < row; i++) {
- lp = SaveText(screen, i, 0, screen->max_col, lp, &eol);
- if (eol)
- *lp ++ = '\n';
- }
- if (col >= 0)
- lp = SaveText(screen, row, 0, col, lp, &eol);
- }
- *lp = '\0'; /* make sure we have end marked */
-
- screen->selection_length = (lp - line);
- _OwnSelection(term, params, num_params);
- }
-
- static Boolean ConvertSelection(w, selection, target,
- type, value, length, format)
- Widget w;
- Atom *selection, *target, *type;
- XtPointer *value;
- unsigned long *length;
- int *format;
- {
- Display* d = XtDisplay(w);
- XtermWidget xterm = (XtermWidget)w;
-
- if (xterm->screen.selection == NULL) return False; /* can this happen? */
-
- if (*target == XA_TARGETS(d)) {
- Atom* targetP;
- Atom* std_targets;
- unsigned long std_length;
- XmuConvertStandardSelection(
- w, xterm->screen.selection_time, selection,
- target, type, (caddr_t*)&std_targets, &std_length, format
- );
- *length = std_length + 5;
- *value = (XtPointer)XtMalloc(sizeof(Atom)*(*length));
- targetP = *(Atom**)value;
- *targetP++ = XA_STRING;
- *targetP++ = XA_TEXT(d);
- *targetP++ = XA_COMPOUND_TEXT(d);
- *targetP++ = XA_LENGTH(d);
- *targetP++ = XA_LIST_LENGTH(d);
- bcopy((char*)std_targets, (char*)targetP, sizeof(Atom)*std_length);
- XtFree((char*)std_targets);
- *type = XA_ATOM;
- *format = 32;
- return True;
- }
-
- if (*target == XA_STRING ||
- *target == XA_TEXT(d) ||
- *target == XA_COMPOUND_TEXT(d)) {
- if (*target == XA_COMPOUND_TEXT(d))
- *type = *target;
- else
- *type = XA_STRING;
- *value = xterm->screen.selection;
- *length = xterm->screen.selection_length;
- *format = 8;
- return True;
- }
- if (*target == XA_LIST_LENGTH(d)) {
- *value = XtMalloc(4);
- if (sizeof(long) == 4)
- *(long*)*value = 1;
- else {
- long temp = 1;
- bcopy( ((char*)&temp)+sizeof(long)-4, (char*)*value, 4);
- }
- *type = XA_INTEGER;
- *length = 1;
- *format = 32;
- return True;
- }
- if (*target == XA_LENGTH(d)) {
- *value = XtMalloc(4);
- if (sizeof(long) == 4)
- *(long*)*value = xterm->screen.selection_length;
- else {
- long temp = xterm->screen.selection_length;
- bcopy( ((char*)&temp)+sizeof(long)-4, (char*)*value, 4);
- }
- *type = XA_INTEGER;
- *length = 1;
- *format = 32;
- return True;
- }
- if (XmuConvertStandardSelection(w, xterm->screen.selection_time, selection,
- target, type,
- (caddr_t *)value, length, format))
- return True;
-
- /* else */
- return False;
-
- }
-
-
- static void LoseSelection(w, selection)
- Widget w;
- Atom *selection;
- {
- register TScreen* screen = &((XtermWidget)w)->screen;
- register Atom* atomP;
- int i;
- for (i = 0, atomP = screen->selection_atoms;
- i < screen->selection_count; i++, atomP++)
- {
- if (*selection == *atomP) *atomP = (Atom)0;
- switch (*atomP) {
- case XA_CUT_BUFFER0:
- case XA_CUT_BUFFER1:
- case XA_CUT_BUFFER2:
- case XA_CUT_BUFFER3:
- case XA_CUT_BUFFER4:
- case XA_CUT_BUFFER5:
- case XA_CUT_BUFFER6:
- case XA_CUT_BUFFER7: *atomP = (Atom)0;
- }
- }
-
- for (i = screen->selection_count; i; i--) {
- if (screen->selection_atoms[i-1] != 0) break;
- }
- screen->selection_count = i;
-
- for (i = 0, atomP = screen->selection_atoms;
- i < screen->selection_count; i++, atomP++)
- {
- if (*atomP == (Atom)0) {
- *atomP = screen->selection_atoms[--screen->selection_count];
- }
- }
-
- if (screen->selection_count == 0)
- TrackText(0, 0, 0, 0);
- }
-
-
- /* ARGSUSED */
- static void SelectionDone(w, selection, target)
- Widget w;
- Atom *selection, *target;
- {
- /* empty proc so Intrinsics know we want to keep storage */
- }
-
-
- static /* void */ _OwnSelection(termw, selections, count)
- register XtermWidget termw;
- String *selections;
- Cardinal count;
- {
- Atom* atoms = termw->screen.selection_atoms;
- int i;
- Boolean have_selection = False;
-
- if (termw->screen.selection_length < 0) return;
-
- if (count > termw->screen.sel_atoms_size) {
- XtFree((char*)atoms);
- atoms = (Atom*)XtMalloc(count*sizeof(Atom));
- termw->screen.selection_atoms = atoms;
- termw->screen.sel_atoms_size = count;
- }
- XmuInternStrings( XtDisplay((Widget)termw), selections, count, atoms );
- for (i = 0; i < count; i++) {
- int cutbuffer;
- switch (atoms[i]) {
- case XA_CUT_BUFFER0: cutbuffer = 0; break;
- case XA_CUT_BUFFER1: cutbuffer = 1; break;
- case XA_CUT_BUFFER2: cutbuffer = 2; break;
- case XA_CUT_BUFFER3: cutbuffer = 3; break;
- case XA_CUT_BUFFER4: cutbuffer = 4; break;
- case XA_CUT_BUFFER5: cutbuffer = 5; break;
- case XA_CUT_BUFFER6: cutbuffer = 6; break;
- case XA_CUT_BUFFER7: cutbuffer = 7; break;
- default: cutbuffer = -1;
- }
- if (cutbuffer >= 0)
- if ( termw->screen.selection_length >
- 4*XMaxRequestSize(XtDisplay((Widget)termw))-32)
- fprintf(stderr,
- "%s: selection too big (%d bytes), not storing in CUT_BUFFER%d\n",
- xterm_name, termw->screen.selection_length, cutbuffer);
- else
- XStoreBuffer( XtDisplay((Widget)termw), termw->screen.selection,
- termw->screen.selection_length, cutbuffer );
- else if (!replyToEmacs) {
- have_selection |=
- XtOwnSelection( (Widget)termw, atoms[i],
- termw->screen.selection_time,
- ConvertSelection, LoseSelection, SelectionDone );
- }
- }
- if (!replyToEmacs)
- termw->screen.selection_count = count;
- if (!have_selection)
- TrackText(0, 0, 0, 0);
- }
-
- /* void */
- DisownSelection(termw)
- register XtermWidget termw;
- {
- Atom* atoms = termw->screen.selection_atoms;
- Cardinal count = termw->screen.selection_count;
- int i;
-
- for (i = 0; i < count; i++) {
- int cutbuffer;
- switch (atoms[i]) {
- case XA_CUT_BUFFER0: cutbuffer = 0; break;
- case XA_CUT_BUFFER1: cutbuffer = 1; break;
- case XA_CUT_BUFFER2: cutbuffer = 2; break;
- case XA_CUT_BUFFER3: cutbuffer = 3; break;
- case XA_CUT_BUFFER4: cutbuffer = 4; break;
- case XA_CUT_BUFFER5: cutbuffer = 5; break;
- case XA_CUT_BUFFER6: cutbuffer = 6; break;
- case XA_CUT_BUFFER7: cutbuffer = 7; break;
- default: cutbuffer = -1;
- }
- if (cutbuffer < 0)
- XtDisownSelection( (Widget)termw, atoms[i],
- termw->screen.selection_time );
- }
- termw->screen.selection_count = 0;
- termw->screen.startHRow = termw->screen.startHCol = 0;
- termw->screen.endHRow = termw->screen.endHCol = 0;
- }
-
-
- /* returns number of chars in line from scol to ecol out */
- /* ARGSUSED */
- static int
- Length(screen, row, scol, ecol)
- register int row, scol, ecol;
- register TScreen *screen;
- {
- register int lastcol = LastTextCol(row);
-
- if (ecol > lastcol)
- ecol = lastcol;
- return (ecol - scol + 1);
- }
-
- /* copies text into line, preallocated */
- static char *
- SaveText(screen, row, scol, ecol, lp, eol)
- int row;
- int scol, ecol;
- TScreen *screen;
- register char *lp; /* pointer to where to put the text */
- int *eol;
- {
- register int i = 0;
- register Char *ch = screen->buf[2 * (row + screen->topline)];
- Char attr;
- register int c;
-
- *eol = 0;
- i = Length(screen, row, scol, ecol);
- ecol = scol + i;
- if (*eol == 0) {
- if(ScrnGetAttributes(screen, row + screen->topline, 0, &attr, 1) == 1) {
- *eol = (attr & LINEWRAPPED) ? 0 : 1;
- } else {
- /* If we can't get the attributes, assume no wrap */
- /* CANTHAPPEN */
- (void)fprintf(stderr, "%s: no attributes for %d, %d\n",
- xterm_name, row, ecol - 1);
- *eol = 1;
- }
- }
- for (i = scol; i < ecol; i++) {
- c = ch[i];
- if (c == 0)
- c = ' ';
- else if(c < ' ') {
- if(c == '\036')
- c = '#'; /* char on screen is pound sterling */
- else
- c += 0x5f; /* char is from DEC drawing set */
- } else if(c == 0x7f)
- c = 0x5f;
- *lp++ = c;
- }
- return(lp);
- }
-
- static void
- EditorButton(event)
- register XButtonEvent *event;
- {
- register TScreen *screen = &term->screen;
- int pty = screen->respond;
- char line[6];
- register unsigned row, col;
- int button;
-
- button = event->button - 1;
-
- row = (event->y - screen->border)
- / FontHeight(screen);
- col = (event->x - screen->border - screen->scrollbar)
- / FontWidth(screen);
- (void) strcpy(line, "\033[M");
- if (screen->send_mouse_pos == 1) {
- line[3] = ' ' + button;
- } else {
- line[3] = ' ' + (KeyState(event->state) << 2) +
- ((event->type == ButtonPress)? button:3);
- }
- line[4] = ' ' + col + 1;
- line[5] = ' ' + row + 1;
- v_write(pty, line, 6);
- }
-
-
- /*ARGSUSED*/
- void HandleGINInput (w, event, param_list, nparamsp)
- Widget w;
- XEvent *event;
- String *param_list;
- Cardinal *nparamsp;
- {
- if (term->screen.TekGIN && *nparamsp == 1) {
- int c = param_list[0][0];
- switch (c) {
- case 'l': case 'm': case 'r':
- case 'L': case 'M': case 'R':
- break;
- default:
- Bell (); /* let them know they goofed */
- c = 'l'; /* provide a default */
- }
- TekEnqMouse (c | 0x80);
- TekGINoff();
- } else {
- Bell ();
- }
- }
-
-
- /* ARGSUSED */
- void HandleSecure(w, event, params, param_count)
- Widget w;
- XEvent *event; /* unused */
- String *params; /* [0] = volume */
- Cardinal *param_count; /* 0 or 1 */
- {
- Time time = CurrentTime;
-
- if ((event->xany.type == KeyPress) ||
- (event->xany.type == KeyRelease))
- time = event->xkey.time;
- else if ((event->xany.type == ButtonPress) ||
- (event->xany.type == ButtonRelease))
- time = event->xbutton.time;
- DoSecureKeyboard (time);
- }
-