aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/xterm/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/xterm/button.c')
-rw-r--r--nx-X11/programs/xterm/button.c3284
1 files changed, 0 insertions, 3284 deletions
diff --git a/nx-X11/programs/xterm/button.c b/nx-X11/programs/xterm/button.c
deleted file mode 100644
index d8d0b32b3..000000000
--- a/nx-X11/programs/xterm/button.c
+++ /dev/null
@@ -1,3284 +0,0 @@
-/* $XTermId: button.c,v 1.197 2005/11/03 13:17:27 tom Exp $ */
-
-/* $Xorg: button.c,v 1.3 2000/08/17 19:55:08 cpqbld Exp $ */
-/*
- * Copyright 1999-2004,2005 by Thomas E. Dickey
- *
- * All Rights Reserved
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the
- * sale, use or other dealings in this Software without prior written
- * authorization.
- *
- *
- * 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.
- */
-/* $XFree86: xc/programs/xterm/button.c,v 3.82 2005/11/03 13:17:27 dickey Exp $ */
-
-/*
-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 <xterm.h>
-
-#include <stdio.h>
-
-#include <X11/Xatom.h>
-#include <X11/Xmu/Atoms.h>
-#include <X11/Xmu/StdSel.h>
-
-#include <xutf8.h>
-
-#include <data.h>
-#include <error.h>
-#include <menu.h>
-#include <xcharmouse.h>
-#include <charclass.h>
-
-#if OPT_WIDE_CHARS
-#include <wcwidth.h>
-#else
-#define CharacterClass(value) \
- charClass[value & ((sizeof(charClass)/sizeof(charClass[0]))-1)]
-#endif
-
-#define XTERM_CELL(row,col) getXtermCell(screen, row + screen->topline, col)
-#define XTERM_CELL_C1(row,col) getXtermCellComb1(screen, row + screen->topline, col)
-#define XTERM_CELL_C2(row,col) getXtermCellComb2(screen, row + screen->topline, col)
-
- /*
- * We reserve shift modifier for cut/paste operations. In principle we
- * can pass through control and meta modifiers, but in practice, the
- * popup menu uses control, and the window manager is likely to use meta,
- * so those events are not delivered to SendMousePosition.
- */
-#define OurModifiers (ShiftMask | ControlMask | Mod1Mask)
-#define AllModifiers (ShiftMask | LockMask | ControlMask | Mod1Mask | \
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)
-
-#define KeyModifiers (event->xbutton.state & OurModifiers)
-
-#define KeyState(x) (((x) & (ShiftMask|ControlMask)) + (((x) & Mod1Mask) ? 2 : 0))
- /* adds together the bits:
- shift key -> 1
- meta key -> 2
- control key -> 4 */
-
-#define Coordinate(r,c) ((r) * MaxCols(&(term->screen)) + (c))
-
-#if OPT_DEC_LOCATOR
-static ANSI reply;
-#endif
-
-/* 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;
-
-/* Saved value of WORD selection for LINE processing to restore to */
-static int saveStartWRow, saveStartWCol;
-
-/* Multi-click handling */
-static int numberOfClicks = 0;
-static Time lastButtonUpTime = 0;
-
-#if OPT_READLINE
-static Time lastButtonDownTime = 0;
-static int ExtendingSelection = 0;
-static Time lastButton3UpTime = 0;
-static Time lastButton3DoubleDownTime = 0;
-static int lastButton3row, lastButton3col; /* At the release time */
-#endif /* OPT_READLINE */
-
-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;
-
-static Char *SaveText(TScreen * screen, int row, int scol, int ecol, Char *
- lp, int *eol);
-static int Length(TScreen * screen, int row, int scol, int ecol);
-static void ComputeSelect(int startRow, int startCol, int endRow, int
- endCol, Bool extend);
-static void EditorButton(XButtonEvent * event);
-static void EndExtend(Widget w, XEvent * event, String * params, Cardinal
- num_params, Bool use_cursor_loc);
-static void ExtendExtend(int row, int col);
-static void PointToRowCol(int y, int x, int *r, int *c);
-static void ReHiliteText(int frow, int fcol, int trow, int tcol);
-static void SaltTextAway(int crow, int ccol, int row, int col, String *
- params, Cardinal num_params);
-static void SelectSet(Widget w, XEvent * event, String * params, Cardinal num_params);
-static void SelectionReceived PROTO_XT_SEL_CB_ARGS;
-static void StartSelect(int startrow, int startcol);
-static void TrackDown(XButtonEvent * event);
-static void _OwnSelection(XtermWidget termw, String * selections, Cardinal count);
-static void do_select_end(Widget w, XEvent * event, String * params,
- Cardinal *num_params, Bool use_cursor_loc);
-
-Bool
-SendMousePosition(Widget w, XEvent * event)
-{
- TScreen *screen;
-
- if (!IsXtermWidget(w))
- return False;
-
- screen = &((XtermWidget) w)->screen;
-
- /* If send_mouse_pos mode isn't on, we shouldn't be here */
- if (screen->send_mouse_pos == MOUSE_OFF)
- return False;
-
-#if OPT_DEC_LOCATOR
- if (screen->send_mouse_pos == DEC_LOCATOR) {
- return (SendLocatorPosition(w, event));
- }
-#endif /* OPT_DEC_LOCATOR */
-
- /* Make sure the event is an appropriate type */
- if ((screen->send_mouse_pos != BTN_EVENT_MOUSE)
- && (screen->send_mouse_pos != ANY_EVENT_MOUSE)
- && event->type != ButtonPress
- && event->type != ButtonRelease)
- return False;
-
- switch (screen->send_mouse_pos) {
- case X10_MOUSE: /* X10 compatibility sequences */
-
- if (KeyModifiers == 0) {
- if (event->type == ButtonPress)
- EditorButton((XButtonEvent *) event);
- return True;
- }
- return False;
-
- case VT200_HIGHLIGHT_MOUSE: /* DEC vt200 hilite tracking */
- if (event->type == ButtonPress &&
- KeyModifiers == 0 &&
- event->xbutton.button == Button1) {
- TrackDown((XButtonEvent *) event);
- return True;
- }
- if (KeyModifiers == 0 || KeyModifiers == ControlMask) {
- EditorButton((XButtonEvent *) event);
- return True;
- }
- return False;
-
- case VT200_MOUSE: /* DEC vt200 compatible */
-
- /* xterm extension for motion reporting. June 1998 */
- /* EditorButton() will distinguish between the modes */
- case BTN_EVENT_MOUSE:
- case ANY_EVENT_MOUSE:
- if (KeyModifiers == 0 || KeyModifiers == ControlMask) {
- EditorButton((XButtonEvent *) event);
- return True;
- }
- return False;
-
- default:
- return False;
- }
-}
-
-#if OPT_DEC_LOCATOR
-
-#define LocatorCoords( row, col, x, y, oor ) \
- if( screen->locator_pixels ) { \
- (oor)=False; (row) = (y)+1; (col) = (x)+1; \
- /* Limit to screen dimensions */ \
- if ((row) < 1) (row) = 1,(oor)=True; \
- else if ((row) > screen->border*2+Height(screen)) \
- (row) = screen->border*2+Height(screen),(oor)=True; \
- if ((col) < 1) (col) = 1,(oor)=True; \
- else if ((col) > OriginX(screen)*2+Width(screen)) \
- (col) = OriginX(screen)*2+Width(screen),(oor)=True; \
- } else { \
- (oor)=False; \
- /* Compute character position of mouse pointer */ \
- (row) = ((y) - screen->border) / FontHeight(screen); \
- (col) = ((x) - OriginX(screen)) / FontWidth(screen); \
- /* Limit to screen dimensions */ \
- if ((row) < 0) (row) = 0,(oor)=True; \
- else if ((row) > screen->max_row) \
- (row) = screen->max_row,(oor)=True; \
- if ((col) < 0) (col) = 0,(oor)=True; \
- else if ((col) > screen->max_col) \
- (col) = screen->max_col,(oor)=True; \
- (row)++; (col)++; \
- }
-
-Bool
-SendLocatorPosition(Widget w, XEvent * event)
-{
- TScreen *screen = &((XtermWidget) w)->screen;
- int row, col;
- Bool oor;
- int button;
- int state;
-
- /* Make sure the event is an appropriate type */
- if ((event->type != ButtonPress &&
- event->type != ButtonRelease &&
- !screen->loc_filter) ||
- (KeyModifiers != 0 && KeyModifiers != ControlMask))
- return (False);
-
- if ((event->type == ButtonPress &&
- !(screen->locator_events & LOC_BTNS_DN)) ||
- (event->type == ButtonRelease &&
- !(screen->locator_events & LOC_BTNS_UP)))
- return (True);
-
- if (event->type == MotionNotify) {
- CheckLocatorPosition(w, event);
- return (True);
- }
-
- /* get button # */
- button = event->xbutton.button - 1;
-
- LocatorCoords(row, col, event->xbutton.x, event->xbutton.y, oor);
-
- /*
- * DECterm mouse:
- *
- * ESCAPE '[' event ; mask ; row ; column '&' 'w'
- */
- reply.a_type = CSI;
-
- if (oor) {
- reply.a_nparam = 1;
- reply.a_param[0] = 0; /* Event - 0 = locator unavailable */
- reply.a_inters = '&';
- reply.a_final = 'w';
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
- return (True);
- }
-
- /*
- * event:
- * 1 no buttons
- * 2 left button down
- * 3 left button up
- * 4 middle button down
- * 5 middle button up
- * 6 right button down
- * 7 right button up
- * 8 M4 down
- * 9 M4 up
- */
- reply.a_nparam = 4;
- switch (event->type) {
- case ButtonPress:
- reply.a_param[0] = 2 + (button << 1);
- break;
- case ButtonRelease:
- reply.a_param[0] = 3 + (button << 1);
- break;
- default:
- return (True);
- }
- /*
- * mask:
- * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
- * M4 down left down middle down right down
- *
- * Notice that Button1 (left) and Button3 (right) are swapped in the mask.
- * Also, mask should be the state after the button press/release,
- * X provides the state not including the button press/release.
- */
- state = (event->xbutton.state
- & (Button1Mask | Button2Mask | Button3Mask | Button4Mask)) >> 8;
- state ^= 1 << button; /* update mask to "after" state */
- state = (state & ~(4 | 1)) | ((state & 1) ? 4 : 0) | ((state & 4) ? 1 : 0); /* swap Button1 & Button3 */
-
- reply.a_param[1] = state;
- reply.a_param[2] = row;
- reply.a_param[3] = col;
- reply.a_inters = '&';
- reply.a_final = 'w';
-
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
-
- /*
- * DECterm turns the Locator off if a button is pressed while a filter rectangle
- * is active. This might be a bug, but I don't know, so I'll emulate it anyways.
- */
- if (screen->loc_filter) {
- screen->send_mouse_pos = MOUSE_OFF;
- screen->loc_filter = False;
- screen->locator_events = 0;
- MotionOff(screen, term);
- }
-
- return (True);
-}
-
-/*
- * mask:
- * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
- * M4 down left down middle down right down
- *
- * Button1 (left) and Button3 (right) are swapped in the mask relative to X.
- */
-#define ButtonState(state, mask) \
-{ (state) = ((mask) & (Button1Mask | Button2Mask | Button3Mask | Button4Mask)) >> 8; \
- /* swap Button1 & Button3 */ \
- (state) = ((state) & ~(4|1)) | (((state)&1)?4:0) | (((state)&4)?1:0); \
-}
-
-void
-GetLocatorPosition(XtermWidget w)
-{
- TScreen *screen = &w->screen;
- Window root, child;
- int rx, ry, x, y;
- unsigned int mask;
- int row = 0, col = 0;
- Bool oor = False;
- Bool ret = False;
- int state;
-
- /*
- * DECterm turns the Locator off if the position is requested while a filter rectangle
- * is active. This might be a bug, but I don't know, so I'll emulate it anyways.
- */
- if (screen->loc_filter) {
- screen->send_mouse_pos = MOUSE_OFF;
- screen->loc_filter = False;
- screen->locator_events = 0;
- MotionOff(screen, term);
- }
-
- reply.a_type = CSI;
-
- if (screen->send_mouse_pos == DEC_LOCATOR) {
- ret = XQueryPointer(screen->display, VWindow(screen), &root,
- &child, &rx, &ry, &x, &y, &mask);
- if (ret) {
- LocatorCoords(row, col, x, y, oor);
- }
- }
- if (ret == False || oor) {
- reply.a_nparam = 1;
- reply.a_param[0] = 0; /* Event - 0 = locator unavailable */
- reply.a_inters = '&';
- reply.a_final = 'w';
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
- return;
- }
-
- ButtonState(state, mask);
-
- reply.a_nparam = 4;
- reply.a_param[0] = 1; /* Event - 1 = response to locator request */
- reply.a_param[1] = state;
- reply.a_param[2] = row;
- reply.a_param[3] = col;
- reply.a_inters = '&';
- reply.a_final = 'w';
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
-}
-
-void
-InitLocatorFilter(XtermWidget w)
-{
- TScreen *screen = &w->screen;
- Window root, child;
- int rx, ry, x, y;
- unsigned int mask;
- int row = 0, col = 0;
- Bool oor = 0;
- Bool ret;
- int state;
-
- ret = XQueryPointer(screen->display, VWindow(screen),
- &root, &child, &rx, &ry, &x, &y, &mask);
- if (ret) {
- LocatorCoords(row, col, x, y, oor);
- }
- if (ret == False || oor) {
- /* Locator is unavailable */
-
- if (screen->loc_filter_top != LOC_FILTER_POS ||
- screen->loc_filter_left != LOC_FILTER_POS ||
- screen->loc_filter_bottom != LOC_FILTER_POS ||
- screen->loc_filter_right != LOC_FILTER_POS) {
- /*
- * If any explicit coordinates were received,
- * report immediately with no coordinates.
- */
- reply.a_type = CSI;
- reply.a_nparam = 1;
- reply.a_param[0] = 0; /* Event - 0 = locator unavailable */
- reply.a_inters = '&';
- reply.a_final = 'w';
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
- } else {
- /*
- * No explicit coordinates were received, and the pointer is
- * unavailable. Report when the pointer re-enters the window.
- */
- screen->loc_filter = True;
- MotionOn(screen, term);
- }
- return;
- }
-
- /*
- * Adjust rectangle coordinates:
- * 1. Replace "LOC_FILTER_POS" with current coordinates
- * 2. Limit coordinates to screen size
- * 3. make sure top and left are less than bottom and right, resp.
- */
- if (screen->locator_pixels) {
- rx = OriginX(screen) * 2 + Width(screen);
- ry = screen->border * 2 + Height(screen);
- } else {
- rx = screen->max_col;
- ry = screen->max_row;
- }
-
-#define Adjust( coord, def, max ) \
- if( (coord) == LOC_FILTER_POS ) (coord) = (def); \
- else if ((coord) < 1) (coord) = 1; \
- else if ((coord) > (max)) (coord) = (max)
-
- Adjust(screen->loc_filter_top, row, ry);
- Adjust(screen->loc_filter_left, col, rx);
- Adjust(screen->loc_filter_bottom, row, ry);
- Adjust(screen->loc_filter_right, col, rx);
-
- if (screen->loc_filter_top > screen->loc_filter_bottom) {
- ry = screen->loc_filter_top;
- screen->loc_filter_top = screen->loc_filter_bottom;
- screen->loc_filter_bottom = ry;
- }
-
- if (screen->loc_filter_left > screen->loc_filter_right) {
- rx = screen->loc_filter_left;
- screen->loc_filter_left = screen->loc_filter_right;
- screen->loc_filter_right = rx;
- }
-
- if ((col < screen->loc_filter_left) ||
- (col > screen->loc_filter_right) ||
- (row < screen->loc_filter_top) ||
- (row > screen->loc_filter_bottom)) {
- /* Pointer is already outside the rectangle - report immediately */
- ButtonState(state, mask);
-
- reply.a_type = CSI;
- reply.a_nparam = 4;
- reply.a_param[0] = 10; /* Event - 10 = locator outside filter */
- reply.a_param[1] = state;
- reply.a_param[2] = row;
- reply.a_param[3] = col;
- reply.a_inters = '&';
- reply.a_final = 'w';
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
- return;
- }
-
- /*
- * Rectangle is set up. Allow pointer tracking
- * to detect if the mouse leaves the rectangle.
- */
- screen->loc_filter = True;
- MotionOn(screen, term);
-}
-
-void
-CheckLocatorPosition(Widget w, XEvent * event)
-{
- TScreen *screen = &((XtermWidget) w)->screen;
- int row, col;
- Bool oor;
- int state;
-
- LocatorCoords(row, col, event->xbutton.x, event->xbutton.y, oor);
-
- /*
- * Send report if the pointer left the filter rectangle, if
- * the pointer left the window, or if the filter rectangle
- * had no coordinates and the pointer re-entered the window.
- */
- if (oor || (screen->loc_filter_top == LOC_FILTER_POS) ||
- (col < screen->loc_filter_left) ||
- (col > screen->loc_filter_right) ||
- (row < screen->loc_filter_top) ||
- (row > screen->loc_filter_bottom)) {
- /* Filter triggered - disable it */
- screen->loc_filter = False;
- MotionOff(screen, term);
-
- reply.a_type = CSI;
- if (oor) {
- reply.a_nparam = 1;
- reply.a_param[0] = 0; /* Event - 0 = locator unavailable */
- } else {
- ButtonState(state, event->xbutton.state);
-
- reply.a_nparam = 4;
- reply.a_param[0] = 10; /* Event - 10 = locator outside filter */
- reply.a_param[1] = state;
- reply.a_param[2] = row;
- reply.a_param[3] = col;
- }
-
- reply.a_inters = '&';
- reply.a_final = 'w';
- unparseseq(&reply, screen->respond);
-
- if (screen->locator_reset) {
- MotionOff(screen, term);
- screen->send_mouse_pos = MOUSE_OFF;
- }
- }
-}
-#endif /* OPT_DEC_LOCATOR */
-
-#if OPT_READLINE
-static int
-isClick1_clean(XEvent * event)
-{
- TScreen *screen = &term->screen;
- int delta;
-
- if (!(event->type == ButtonPress || event->type == ButtonRelease)
- /* Disable on Shift-Click-1, including the application-mouse modes */
- || (KeyModifiers & ShiftMask)
- || (screen->send_mouse_pos != MOUSE_OFF) /* Kinda duplicate... */
- ||ExtendingSelection) /* Was moved */
- return 0;
- if (event->type != ButtonRelease)
- return 0;
- if (lastButtonDownTime == (Time) 0) /* first time or once in a blue moon */
- delta = term->screen.multiClickTime + 1;
- else if (event->xbutton.time > lastButtonDownTime) /* most of the time */
- delta = event->xbutton.time - lastButtonDownTime;
- else /* time has rolled over since lastButtonUpTime */
- delta = (((Time) ~ 0) - lastButtonDownTime) + event->xbutton.time;
- return delta <= term->screen.multiClickTime;
-}
-
-static int
-isDoubleClick3(XEvent * event)
-{
- int delta;
-
- if (event->type != ButtonRelease
- || (KeyModifiers & ShiftMask)
- || event->xbutton.button != Button3) {
- lastButton3UpTime = 0; /* Disable the cached info */
- return 0;
- }
- /* Process Btn3Release. */
- if (lastButton3DoubleDownTime == (Time) 0) /* No previous click
- or once in a blue moon */
- delta = term->screen.multiClickTime + 1;
- else if (event->xbutton.time > lastButton3DoubleDownTime) /* most of the time */
- delta = event->xbutton.time - lastButton3DoubleDownTime;
- else /* time has rolled over since lastButton3DoubleDownTime */
- delta = (((Time) ~ 0) - lastButton3DoubleDownTime) + event->xbutton.time;
- if (delta <= term->screen.multiClickTime) {
- /* Double click */
- int row, col;
-
- /* Cannot check ExtendingSelection, since mouse-3 always sets it */
- PointToRowCol(event->xbutton.y, event->xbutton.x, &row, &col);
- if (row == lastButton3row && col == lastButton3col) {
- lastButton3DoubleDownTime = 0; /* Disable the third click */
- return 1;
- }
- }
- /* Not a double click, memorize for future check. */
- lastButton3UpTime = event->xbutton.time;
- PointToRowCol(event->xbutton.y, event->xbutton.x,
- &lastButton3row, &lastButton3col);
- return 0;
-}
-
-static int
-CheckSecondPress3(XEvent * event)
-{
- int delta, row, col;
-
- if (event->type != ButtonPress
- || (KeyModifiers & ShiftMask)
- || event->xbutton.button != Button3) {
- lastButton3DoubleDownTime = 0; /* Disable the cached info */
- return 0;
- }
- /* Process Btn3Press. */
- if (lastButton3UpTime == (Time) 0) /* No previous click
- or once in a blue moon */
- delta = term->screen.multiClickTime + 1;
- else if (event->xbutton.time > lastButton3UpTime) /* most of the time */
- delta = event->xbutton.time - lastButton3UpTime;
- else /* time has rolled over since lastButton3UpTime */
- delta = (((Time) ~ 0) - lastButton3UpTime) + event->xbutton.time;
- if (delta <= term->screen.multiClickTime) {
- PointToRowCol(event->xbutton.y, event->xbutton.x, &row, &col);
- if (row == lastButton3row && col == lastButton3col) {
- /* A candidate for a double-click */
- lastButton3DoubleDownTime = event->xbutton.time;
- PointToRowCol(event->xbutton.y, event->xbutton.x,
- &lastButton3row, &lastButton3col);
- return 1;
- }
- lastButton3UpTime = 0; /* Disable the info about the previous click */
- }
- /* Either too long, or moved, disable. */
- lastButton3DoubleDownTime = 0;
- return 0;
-}
-
-static int
-rowOnCurrentLine(int line, int *deltap) /* must be XButtonEvent */
-{
- TScreen *screen = &term->screen;
- int l1, l2;
-
- *deltap = 0;
- if (line == screen->cur_row)
- return 1;
-
- if (line < screen->cur_row)
- l1 = line, l2 = screen->cur_row;
- else
- l2 = line, l1 = screen->cur_row;
- l1--;
- while (++l1 < l2)
- if (!ScrnTstWrapped(screen, l1))
- return 0;
- /* Everything is on one "wrapped line" now */
- *deltap = line - screen->cur_row;
- return 1;
-}
-
-static int
-eventRow(XEvent * event) /* must be XButtonEvent */
-{
- TScreen *screen = &term->screen;
-
- return (event->xbutton.y - screen->border) / FontHeight(screen);
-}
-
-static int
-eventColBetween(XEvent * event) /* must be XButtonEvent */
-{
- TScreen *screen = &term->screen;
-
- /* Correct by half a width - we are acting on a boundary, not on a cell. */
- return ((event->xbutton.x - OriginX(screen) + (FontWidth(screen) - 1) / 2)
- / FontWidth(screen));
-}
-
-static int
-ReadLineMovePoint(int col, int ldelta)
-{
- TScreen *screen = &term->screen;
- Char line[6];
- unsigned count = 0;
-
- col += ldelta * MaxCols(screen) - screen->cur_col;
- if (col == 0)
- return 0;
- if (screen->control_eight_bits) {
- line[count++] = CSI;
- } else {
- line[count++] = ESC;
- line[count++] = '['; /* XXX maybe sometimes O is better? */
- }
- line[count++] = (col > 0 ? 'C' : 'D');
- if (col < 0)
- col = -col;
- while (col--)
- v_write(screen->respond, line, 3);
- return 1;
-}
-
-static int
-ReadLineDelete(int r1, int c1, int r2, int c2)
-{
- TScreen *screen = &term->screen;
- int del;
-
- del = c2 - c1 + (r2 - r1) * MaxCols(screen);
- if (del <= 0) /* Just in case... */
- return 0;
- while (del--)
- v_write(screen->respond, (Char *) "\177", 1);
- return 1;
-}
-#endif /* OPT_READLINE */
-
-/* ^XM-G<line+' '><col+' '> */
-void
-DiredButton(Widget w GCC_UNUSED,
- XEvent * event, /* must be XButtonEvent */
- String * params GCC_UNUSED, /* selections */
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen = &term->screen;
- Char Line[6];
- unsigned line, col;
-
- if (event->type == ButtonPress || event->type == ButtonRelease) {
- line = (event->xbutton.y - screen->border) / FontHeight(screen);
- col = (event->xbutton.x - OriginX(screen)) / FontWidth(screen);
- Line[0] = CONTROL('X');
- Line[1] = ESC;
- Line[2] = 'G';
- Line[3] = ' ' + col;
- Line[4] = ' ' + line;
- v_write(screen->respond, Line, 5);
- }
-}
-
-#if OPT_READLINE
-void
-ReadLineButton(Widget w GCC_UNUSED,
- XEvent * event, /* must be XButtonEvent */
- String * params GCC_UNUSED, /* selections */
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen = &term->screen;
- Char Line[6];
- int line, col, ldelta = 0;
-
- if (!(event->type == ButtonPress || event->type == ButtonRelease)
- || (screen->send_mouse_pos != MOUSE_OFF) || ExtendingSelection)
- goto finish;
- if (event->type == ButtonRelease) {
- int delta;
-
- if (lastButtonDownTime == (Time) 0) /* first time and once in a blue moon */
- delta = screen->multiClickTime + 1;
- else if (event->xbutton.time > lastButtonDownTime) /* most of the time */
- delta = event->xbutton.time - lastButtonDownTime;
- else /* time has rolled over since lastButtonUpTime */
- delta = (((Time) ~ 0) - lastButtonDownTime) + event->xbutton.time;
- if (delta > screen->multiClickTime)
- goto finish; /* All this work for this... */
- }
- line = (event->xbutton.y - screen->border) / FontHeight(screen);
- if (line != screen->cur_row) {
- int l1, l2;
-
- if (line < screen->cur_row)
- l1 = line, l2 = screen->cur_row;
- else
- l2 = line, l1 = screen->cur_row;
- l1--;
- while (++l1 < l2)
- if (!ScrnTstWrapped(screen, l1))
- goto finish;
- /* Everything is on one "wrapped line" now */
- ldelta = line - screen->cur_row;
- }
- /* Correct by half a width - we are acting on a boundary, not on a cell. */
- col = (event->xbutton.x - OriginX(screen) + (FontWidth(screen) - 1) / 2)
- / FontWidth(screen) - screen->cur_col + ldelta * MaxCols(screen);
- if (col == 0)
- goto finish;
- Line[0] = ESC;
- /* XXX: sometimes it is better to send '['? */
- Line[1] = 'O';
- Line[2] = (col > 0 ? 'C' : 'D');
- if (col < 0)
- col = -col;
- while (col--)
- v_write(screen->respond, Line, 3);
- finish:
- if (event->type == ButtonRelease)
- do_select_end(w, event, params, num_params, False);
-}
-#endif /* OPT_READLINE */
-
-/* repeats <ESC>n or <ESC>p */
-void
-ViButton(Widget w GCC_UNUSED,
- XEvent * event, /* must be XButtonEvent */
- String * params GCC_UNUSED, /* selections */
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen = &term->screen;
- int pty = screen->respond;
- Char Line[6];
- int line;
-
- if (event->type == ButtonPress || event->type == ButtonRelease) {
-
- line = screen->cur_row -
- ((event->xbutton.y - screen->border) / FontHeight(screen));
- if (line != 0) {
- Line[0] = ESC; /* force an exit from insert-mode */
- v_write(pty, Line, 1);
-
- if (line < 0) {
- line = -line;
- Line[0] = CONTROL('n');
- } else {
- Line[0] = CONTROL('p');
- }
- while (--line >= 0)
- v_write(pty, Line, 1);
- }
- }
-}
-
-/*
- * This function handles button-motion events
- */
-/*ARGSUSED*/
-void
-HandleSelectExtend(Widget w,
- XEvent * event, /* must be XMotionEvent */
- String * params GCC_UNUSED,
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen;
- int row, col;
-
- if (!IsXtermWidget(w))
- return;
-
- screen = &((XtermWidget) w)->screen;
- screen->selection_time = event->xmotion.time;
- switch (eventMode) {
- /* If not in one of the DEC mouse-reporting modes */
- case LEFTEXTENSION:
- case RIGHTEXTENSION:
- PointToRowCol(event->xmotion.y, event->xmotion.x,
- &row, &col);
- ExtendExtend(row, col);
- break;
-
- /* If in motion reporting mode, send mouse position to
- character process as a key sequence \E[M... */
- case NORMAL:
- /* will get here if send_mouse_pos != MOUSE_OFF */
- if (screen->send_mouse_pos == BTN_EVENT_MOUSE
- || screen->send_mouse_pos == ANY_EVENT_MOUSE) {
- (void) SendMousePosition(w, event);
- }
- break;
- }
-}
-
-void
-HandleKeyboardSelectExtend(Widget w,
- XEvent * event GCC_UNUSED, /* must be XButtonEvent */
- String * params GCC_UNUSED,
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen;
-
- if (!IsXtermWidget(w))
- return;
-
- screen = &((XtermWidget) w)->screen;
- ExtendExtend(screen->cursor_row, screen->cursor_col);
-}
-
-static void
-do_select_end(Widget w,
- XEvent * event, /* must be XButtonEvent */
- String * params, /* selections */
- Cardinal *num_params,
- Bool use_cursor_loc)
-{
-#if OPT_READLINE
- int ldelta1, ldelta2;
- TScreen *screen = &term->screen;
-#endif
-
- if (!IsXtermWidget(w)) {
- return;
- }
-
- ((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);
-#if OPT_READLINE
- if (isClick1_clean(event)
- && SCREEN_FLAG(screen, click1_moves)
- && rowOnCurrentLine(eventRow(event), &ldelta1)) {
- ReadLineMovePoint(eventColBetween(event), ldelta1);
- }
- if (isDoubleClick3(event)
- && SCREEN_FLAG(screen, dclick3_deletes)
- && rowOnCurrentLine(startSRow, &ldelta1)
- && rowOnCurrentLine(endSRow, &ldelta2)) {
- ReadLineMovePoint(endSCol, ldelta2);
- ReadLineDelete(startSRow, startSCol, endSRow, endSCol);
- }
-#endif /* OPT_READLINE */
- break;
- }
-}
-
-void
-HandleSelectEnd(Widget w,
- XEvent * event, /* must be XButtonEvent */
- String * params, /* selections */
- Cardinal *num_params)
-{
- do_select_end(w, event, params, num_params, False);
-}
-
-void
-HandleKeyboardSelectEnd(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;
- Atom *targets;
- Time time;
-};
-
-/* convert a UTF-8 string to Latin-1, replacing non Latin-1 characters
- * by `#'. */
-
-#if OPT_WIDE_CHARS
-static Char *
-UTF8toLatin1(Char * s, unsigned len, unsigned long *result)
-{
- static Char *buffer;
- static size_t used;
-
- Char *p = s;
- Char *q;
-
- if (used == 0) {
- buffer = (Char *) XtMalloc(used = len);
- } else if (len > used) {
- buffer = (Char *) XtRealloc((char *) buffer, used = len);
- }
- q = buffer;
-
- /* We're assuming that the xterm widget never contains Unicode
- control characters. */
-
- while (p < s + len) {
- if ((*p & 0x80) == 0) {
- *q++ = *p++;
- } else if ((*p & 0x7C) == 0x40 && p < s + len - 1) {
- *q++ = ((*p & 0x03) << 6) | (p[1] & 0x3F);
- p += 2;
- } else if ((*p & 0x60) == 0x40) {
- *q++ = '#';
- p += 2;
- } else if ((*p & 0x50) == 0x40) {
- *q++ = '#';
- p += 3;
- } else { /* this cannot happen */
- *q++ = '#';
- p++;
- }
- }
- *result = q - buffer;
- return buffer;
-}
-#endif /* OPT_WIDE_CHARS */
-
-static Atom *
-_SelectionTargets(Widget w)
-{
- static Atom *eightBitSelectionTargets = NULL;
- TScreen *screen;
- int n;
-
- if (!IsXtermWidget(w))
- return NULL;
-
- screen = &((XtermWidget) w)->screen;
-
-#if OPT_WIDE_CHARS
- if (screen->wide_chars) {
- static Atom *utf8SelectionTargets = NULL;
-
- if (utf8SelectionTargets == NULL) {
- utf8SelectionTargets = (Atom *) XtMalloc(5 * sizeof(Atom));
- if (utf8SelectionTargets == NULL) {
- TRACE(("Couldn't allocate utf8SelectionTargets\n"));
- return NULL;
- }
- n = 0;
- utf8SelectionTargets[n++] = XA_UTF8_STRING(XtDisplay(w));
-#ifdef X_HAVE_UTF8_STRING
- if (screen->i18nSelections) {
- utf8SelectionTargets[n++] = XA_TEXT(XtDisplay(w));
- utf8SelectionTargets[n++] = XA_COMPOUND_TEXT(XtDisplay(w));
- }
-#endif
- utf8SelectionTargets[n++] = XA_STRING;
- utf8SelectionTargets[n] = None;
- }
- return utf8SelectionTargets;
- }
-#endif
-
- /* not screen->wide_chars */
- if (eightBitSelectionTargets == NULL) {
- eightBitSelectionTargets = (Atom *) XtMalloc(5 * sizeof(Atom));
- if (eightBitSelectionTargets == NULL) {
- TRACE(("Couldn't allocate eightBitSelectionTargets\n"));
- return NULL;
- }
- n = 0;
-#ifdef X_HAVE_UTF8_STRING
- eightBitSelectionTargets[n++] = XA_UTF8_STRING(XtDisplay(w));
-#endif
- if (screen->i18nSelections) {
- eightBitSelectionTargets[n++] = XA_TEXT(XtDisplay(w));
- eightBitSelectionTargets[n++] = XA_COMPOUND_TEXT(XtDisplay(w));
- }
- eightBitSelectionTargets[n++] = XA_STRING;
- eightBitSelectionTargets[n] = None;
- }
- return eightBitSelectionTargets;
-}
-
-/*
- * Lookup the cut-buffer number, which will be in the range 0-7.
- * If it is not a cut-buffer, it is the primary selection (-1).
- */
-static int
-CutBuffer(unsigned code)
-{
- int cutbuffer;
- switch (code) {
- 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;
- break;
- }
- return cutbuffer;
-}
-
-#define ResetPaste64() term->screen.base64_paste = 0
-
-#if !OPT_PASTE64
-static
-#endif
-void
-xtermGetSelection(Widget w,
- Time ev_time,
- String * params, /* selections in precedence order */
- Cardinal num_params,
- Atom * targets)
-{
- Atom selection;
- int cutbuffer;
- Atom target;
-
- if (!IsXtermWidget(w))
- return;
-
-#if OPT_TRACE
- TRACE(("xtermGetSelection\n"));
- if (num_params > 0) {
- Cardinal n;
- for (n = 0; n < num_params; ++n) {
- TRACE(("param[%d]:%s\n", n, params[n]));
- }
- }
-#endif
-
- XmuInternStrings(XtDisplay(w), params, (Cardinal) 1, &selection);
- cutbuffer = CutBuffer(selection);
- TRACE(("Cutbuffer: %d, target: %lu\n", cutbuffer,
- targets ? (unsigned long) targets[0] : 0));
- if (cutbuffer >= 0) {
- int inbytes;
- unsigned long nbytes;
- int fmt8 = 8;
- Atom type = XA_STRING;
- char *line;
-
- /* 'line' is freed in SelectionReceived */
- line = XFetchBuffer(XtDisplay(w), &inbytes, cutbuffer);
- nbytes = (unsigned long) inbytes;
-
- if (nbytes > 0)
- SelectionReceived(w, NULL, &selection, &type, (XtPointer) line,
- &nbytes, &fmt8);
- else if (num_params > 1)
- xtermGetSelection(w, ev_time, params + 1, num_params - 1, NULL);
-#if OPT_PASTE64
- else
- ResetPaste64();
-#endif
- return;
- } else {
- struct _SelectionList *list;
-
- if (targets == NULL || targets[0] == None) {
- targets = _SelectionTargets(w);
- }
-
- if (targets != 0) {
- target = targets[0];
-
- if (targets[1] == None) { /* last target in list */
- params++;
- num_params--;
- targets = _SelectionTargets(w);
- } else {
- targets = &(targets[1]);
- }
-
- if (num_params) {
- /* 'list' is freed in SelectionReceived */
- list = XtNew(struct _SelectionList);
- if (list != 0) {
- list->params = params;
- list->count = num_params;
- list->targets = targets;
- list->time = ev_time;
- }
- } else {
- list = NULL;
- }
-
- XtGetSelectionValue(w, selection,
- target,
- SelectionReceived,
- (XtPointer) list, ev_time);
- }
- }
-}
-
-#if OPT_TRACE && OPT_WIDE_CHARS
-static void
-GettingSelection(Display * dpy, Atom type, Char * line, unsigned long len)
-{
- Char *cp;
- char *name;
-
- name = XGetAtomName(dpy, type);
-
- TRACE(("Getting %s (%ld)\n", name, (long int) type));
- for (cp = line; cp < line + len; cp++) {
- TRACE(("[%d:%lu]", cp + 1 - line, len));
- if (isprint(*cp)) {
- TRACE(("%c\n", *cp));
- } else {
- TRACE(("\\x%02x\n", *cp));
- }
- }
-}
-#else
-#define GettingSelection(dpy,type,line,len) /* nothing */
-#endif
-
-#ifdef VMS
-# define tty_vwrite(pty,lag,l) tt_write(lag,l)
-#else /* !( VMS ) */
-# define tty_vwrite(pty,lag,l) v_write(pty,lag,l)
-#endif /* defined VMS */
-
-#if OPT_PASTE64
-/* Return base64 code character given 6-bit number */
-static const char base64_code[] = "\
-ABCDEFGHIJKLMNOPQRSTUVWXYZ\
-abcdefghijklmnopqrstuvwxyz\
-0123456789+/";
-static void
-base64_flush(TScreen * screen)
-{
- Char x;
- switch (screen->base64_count) {
- case 0:
- break;
- case 2:
- x = base64_code[screen->base64_accu << 4];
- tty_vwrite(screen->respond, &x, 1);
- break;
- case 4:
- x = base64_code[screen->base64_accu << 2];
- tty_vwrite(screen->respond, &x, 1);
- break;
- }
- if (screen->base64_pad & 3)
- tty_vwrite(screen->respond,
- (Char *) "===",
- 4 - (screen->base64_pad & 3));
- screen->base64_count = 0;
- screen->base64_accu = 0;
- screen->base64_pad = 0;
-}
-#endif /* OPT_PASTE64 */
-
-static void
-_qWriteSelectionData(TScreen * screen, Char * lag, unsigned length)
-{
-#if OPT_PASTE64
- if (screen->base64_paste) {
- /* Send data as base64 */
- Char *p = lag;
- Char buf[64];
- unsigned x = 0;
- while (length--) {
- switch (screen->base64_count) {
- case 0:
- buf[x++] = base64_code[*p >> 2];
- screen->base64_accu = (*p & 0x3);
- screen->base64_count = 2;
- ++p;
- break;
- case 2:
- buf[x++] = base64_code[(screen->base64_accu << 4) + (*p >> 4)];
- screen->base64_accu = (*p & 0xF);
- screen->base64_count = 4;
- ++p;
- break;
- case 4:
- buf[x++] = base64_code[(screen->base64_accu << 2) + (*p >> 6)];
- buf[x++] = base64_code[*p & 0x3F];
- screen->base64_accu = 0;
- screen->base64_count = 0;
- ++p;
- break;
- }
- if (x >= 63) {
- /* Write 63 or 64 characters */
- screen->base64_pad += x;
- tty_vwrite(screen->respond, buf, x);
- x = 0;
- }
- }
- if (x != 0) {
- screen->base64_pad += x;
- tty_vwrite(screen->respond, buf, x);
- }
- } else
-#endif /* OPT_PASTE64 */
-#if OPT_READLINE
- if (SCREEN_FLAG(screen, paste_quotes)) {
- while (length--) {
- tty_vwrite(screen->respond, (Char *) "\026", 1); /* Control-V */
- tty_vwrite(screen->respond, lag++, 1);
- }
- } else
-#endif
- tty_vwrite(screen->respond, lag, length);
-}
-
-static void
-_WriteSelectionData(TScreen * screen, Char * line, int length)
-{
- /* 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. */
-
- Char *lag, *end;
-
- /* in the VMS version, if tt_pasting isn't set to True then qio
- reads aren't blocked and an infinite loop is entered, where the
- pasted text shows up as new input, goes in again, shows up
- again, ad nauseum. */
-#ifdef VMS
- tt_pasting = True;
-#endif
-
- end = &line[length];
- lag = line;
-
-#if OPT_PASTE64
- if (screen->base64_paste) {
- _qWriteSelectionData(screen, lag, (unsigned) (end - lag));
- base64_flush(screen);
- } else
-#endif
- {
- if (!SCREEN_FLAG(screen, paste_literal_nl)) {
- Char *cp;
- for (cp = line; cp != end; cp++) {
- if (*cp == '\n') {
- *cp = '\r';
- _qWriteSelectionData(screen, lag, (unsigned) (cp - lag + 1));
- lag = cp + 1;
- }
- }
- }
-
- if (lag != end) {
- _qWriteSelectionData(screen, lag, (unsigned) (end - lag));
- }
- }
-#ifdef VMS
- tt_pasting = False;
- tt_start_read(); /* reenable reads or a character may be lost */
-#endif
-}
-
-#if OPT_READLINE
-static void
-_WriteKey(TScreen * screen, Char * in)
-{
- Char line[16];
- unsigned count = 0;
- unsigned length = strlen((char *) in);
-
- if (screen->control_eight_bits) {
- line[count++] = CSI;
- } else {
- line[count++] = ESC;
- line[count++] = '[';
- }
- while (length--)
- line[count++] = *in++;
- line[count++] = '~';
- tty_vwrite(screen->respond, line, count);
-}
-#endif /* OPT_READLINE */
-
-/* SelectionReceived: stuff received selection text into pty */
-
-/* ARGSUSED */
-static void
-SelectionReceived(Widget w,
- XtPointer client_data,
- Atom * selection GCC_UNUSED,
- Atom * type,
- XtPointer value,
- unsigned long *length,
- int *format GCC_UNUSED)
-{
- char **text_list = NULL;
- int text_list_count;
- XTextProperty text_prop;
- TScreen *screen;
- Display *dpy;
-#if OPT_TRACE && OPT_WIDE_CHARS
- Char *line = (Char *) value;
-#endif
-
- if (!IsXtermWidget(w))
- return;
- screen = &((XtermWidget) w)->screen;
- dpy = XtDisplay(w);
-
- if (*type == 0 /*XT_CONVERT_FAIL */
- || *length == 0
- || value == NULL)
- goto fail;
-
- text_prop.value = (unsigned char *) value;
- text_prop.encoding = *type;
- text_prop.format = *format;
- text_prop.nitems = *length;
-
-#if OPT_WIDE_CHARS
- if (screen->wide_chars) {
- if (*type == XA_UTF8_STRING(XtDisplay(w)) ||
- *type == XA_STRING ||
- *type == XA_COMPOUND_TEXT(XtDisplay(w))) {
- GettingSelection(dpy, *type, line, *length);
- if (Xutf8TextPropertyToTextList(dpy, &text_prop,
- &text_list,
- &text_list_count) < 0) {
- TRACE(("Conversion failed\n"));
- text_list = NULL;
- }
- }
- } else
-#endif /* OPT_WIDE_CHARS */
- {
- /* Convert the selection to locale's multibyte encoding. */
-
- /* There's no need to special-case UTF8_STRING. If Xlib
- doesn't know about it, we didn't request it. If a broken
- selection holder sends it anyhow, the conversion function
- will fail. */
-
- if (*type == XA_UTF8_STRING(XtDisplay(w)) ||
- *type == XA_STRING ||
- *type == XA_COMPOUND_TEXT(XtDisplay(w))) {
- Status rc;
- GettingSelection(dpy, *type, line, *length);
- if (*type == XA_STRING && screen->brokenSelections) {
- rc = XTextPropertyToStringList(&text_prop,
- &text_list, &text_list_count);
- } else {
- rc = XmbTextPropertyToTextList(dpy, &text_prop,
- &text_list,
- &text_list_count);
- }
- if (rc < 0) {
- TRACE(("Conversion failed\n"));
- text_list = NULL;
- }
- }
- }
-
- if (text_list != NULL && text_list_count != 0) {
- int i;
-
-#if OPT_PASTE64
- if (screen->base64_paste) {
- ;
- } else
-#endif
-#if OPT_READLINE
- if (SCREEN_FLAG(screen, paste_brackets)) {
- _WriteKey(screen, (Char *) "200");
- }
-#endif
- for (i = 0; i < text_list_count; i++) {
- int len = strlen(text_list[i]);
- _WriteSelectionData(screen, (Char *) text_list[i], len);
- }
-#if OPT_PASTE64
- if (screen->base64_paste) {
- ResetPaste64();
- } else
-#endif
-#if OPT_READLINE
- if (SCREEN_FLAG(screen, paste_brackets)) {
- _WriteKey(screen, (Char *) "201");
- }
-#endif
- XFreeStringList(text_list);
- } else
- goto fail;
-
- XtFree((char *) client_data);
- XtFree((char *) value);
-
- return;
-
- fail:
- if (client_data != 0) {
- struct _SelectionList *list = (struct _SelectionList *) client_data;
- xtermGetSelection(w, list->time,
- list->params, list->count, list->targets);
- XtFree((char *) client_data);
-#if OPT_PASTE64
- } else {
- ResetPaste64();
-#endif
- }
- return;
-}
-
-void
-HandleInsertSelection(Widget w,
- XEvent * event, /* assumed to be XButtonEvent* */
- String * params, /* selections in precedence order */
- Cardinal *num_params)
-{
-#if OPT_READLINE
- int ldelta;
- TScreen *screen = &((XtermWidget) w)->screen;
-#endif
-
- if (SendMousePosition(w, event))
- return;
-
-#if OPT_READLINE
- if ((event->type == ButtonPress || event->type == ButtonRelease)
- /* Disable on Shift-mouse, including the application-mouse modes */
- && !(KeyModifiers & ShiftMask)
- && (screen->send_mouse_pos == MOUSE_OFF)
- && SCREEN_FLAG(screen, paste_moves)
- && rowOnCurrentLine(eventRow(event), &ldelta))
- ReadLineMovePoint(eventColBetween(event), ldelta);
-#endif /* OPT_READLINE */
-
- xtermGetSelection(w, event->xbutton.time, params, *num_params, NULL);
-}
-
-static SelectUnit
-EvalSelectUnit(Time buttonDownTime, SelectUnit defaultUnit)
-{
- int delta;
-
- if (lastButtonUpTime == (Time) 0) /* first time and once in a blue moon */
- delta = term->screen.multiClickTime + 1;
- else if (buttonDownTime > lastButtonUpTime) /* most of the time */
- delta = buttonDownTime - lastButtonUpTime;
- else /* time has rolled over since lastButtonUpTime */
- delta = (((Time) ~ 0) - lastButtonUpTime) + buttonDownTime;
-
- if (delta > term->screen.multiClickTime) {
- numberOfClicks = 1;
- return defaultUnit;
- } else {
- ++numberOfClicks;
- return ((selectUnit + 1) % NSELECTUNITS);
- }
-}
-
-static void
-do_select_start(Widget w,
- XEvent * event, /* must be XButtonEvent* */
- int startrow,
- int startcol)
-{
- if (SendMousePosition(w, event))
- return;
- selectUnit = EvalSelectUnit(event->xbutton.time, SELECTCHAR);
- replyToEmacs = False;
-
-#if OPT_READLINE
- lastButtonDownTime = event->xbutton.time;
-#endif
-
- StartSelect(startrow, startcol);
-}
-
-/* ARGSUSED */
-void
-HandleSelectStart(Widget w,
- XEvent * event, /* must be XButtonEvent* */
- String * params GCC_UNUSED,
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen;
- int startrow, startcol;
-
- if (!IsXtermWidget(w))
- return;
-
- screen = &((XtermWidget) w)->screen;
- firstValidRow = 0;
- lastValidRow = screen->max_row;
- PointToRowCol(event->xbutton.y, event->xbutton.x, &startrow, &startcol);
-
-#if OPT_READLINE
- ExtendingSelection = 0;
-#endif
-
- do_select_start(w, event, startrow, startcol);
-}
-
-/* ARGSUSED */
-void
-HandleKeyboardSelectStart(Widget w,
- XEvent * event, /* must be XButtonEvent* */
- String * params GCC_UNUSED,
- Cardinal *num_params GCC_UNUSED)
-{
- TScreen *screen;
-
- if (!IsXtermWidget(w))
- return;
-
- screen = &((XtermWidget) w)->screen;
- do_select_start(w, event, screen->cursor_row, screen->cursor_col);
-}
-
-static void
-TrackDown(XButtonEvent * event)
-{
- int startrow, startcol;
-
- selectUnit = EvalSelectUnit(event->time, SELECTCHAR);
- if (numberOfClicks > 1) {
- PointToRowCol(event->y, event->x, &startrow, &startcol);
- replyToEmacs = True;
- StartSelect(startrow, startcol);
- } else {
- waitingForTrackInfo = True;
- EditorButton((XButtonEvent *) event);
- }
-}
-
-#define boundsCheck(x) if (x < 0) \
- x = 0; \
- else if (x >= screen->max_row) \
- x = screen->max_row
-
-void
-TrackMouse(int func, int startrow, int startcol, int firstrow, int lastrow)
-{
- TScreen *screen = &term->screen;
-
- if (!waitingForTrackInfo) { /* Timed out, so ignore */
- return;
- }
- waitingForTrackInfo = False;
- if (func == 0)
- return;
- boundsCheck(startrow);
- boundsCheck(firstrow);
- boundsCheck(lastrow);
- firstValidRow = firstrow;
- lastValidRow = lastrow;
- replyToEmacs = True;
- StartSelect(startrow, startcol);
-}
-
-static void
-StartSelect(int startrow, int startcol)
-{
- TScreen *screen = &term->screen;
-
- TRACE(("StartSelect row=%d, col=%d\n", startrow, startcol));
- 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(Widget w,
- XEvent * event, /* must be XButtonEvent */
- String * params, /* selections */
- Cardinal num_params,
- Bool use_cursor_loc)
-{
- int row, col;
- unsigned count;
- 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) {
- count = 0;
- if (screen->control_eight_bits) {
- line[count++] = CSI;
- } else {
- line[count++] = ESC;
- line[count++] = '[';
- }
- if (rawRow == startSRow && rawCol == startSCol
- && row == endSRow && col == endSCol) {
- /* Use short-form emacs select */
- line[count++] = 't';
- line[count++] = ' ' + endSCol + 1;
- line[count++] = ' ' + endSRow + 1;
- } else {
- /* long-form, specify everything */
- line[count++] = 'T';
- line[count++] = ' ' + startSCol + 1;
- line[count++] = ' ' + startSRow + 1;
- line[count++] = ' ' + endSCol + 1;
- line[count++] = ' ' + endSRow + 1;
- line[count++] = ' ' + col + 1;
- line[count++] = ' ' + row + 1;
- }
- v_write(screen->respond, line, count);
- TrackText(0, 0, 0, 0);
- }
- }
- SelectSet(w, event, params, num_params);
- eventMode = NORMAL;
-}
-
-void
-HandleSelectSet(Widget w,
- XEvent * event,
- String * params,
- Cardinal *num_params)
-{
- SelectSet(w, event, params, *num_params);
-}
-
-/* ARGSUSED */
-static void
-SelectSet(Widget w GCC_UNUSED,
- XEvent * event GCC_UNUSED,
- String * params,
- Cardinal num_params)
-{
- TRACE(("SelectSet\n"));
- /* 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(Widget w,
- XEvent * event, /* must be XButtonEvent* */
- String * params GCC_UNUSED,
- Cardinal *num_params GCC_UNUSED,
- Bool use_cursor_loc)
-{
- TScreen *screen;
- int row, col, coord;
-
- if (!IsXtermWidget(w))
- return;
-
- screen = &((XtermWidget) w)->screen;
- if (SendMousePosition(w, event))
- return;
- firstValidRow = 0;
- lastValidRow = screen->max_row;
-#if OPT_READLINE
- if ((KeyModifiers & ShiftMask)
- || event->xbutton.button != Button3
- || !(SCREEN_FLAG(screen, dclick3_deletes)))
-#endif
- selectUnit = EvalSelectUnit(event->xbutton.time, selectUnit);
- replyToEmacs = False;
-
-#if OPT_READLINE
- CheckSecondPress3(event);
-#endif
-
- if (numberOfClicks == 1
- || (SCREEN_FLAG(screen, dclick3_deletes) /* Dclick special */
- &&!(KeyModifiers & ShiftMask))) {
- /* 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);
-
-#if OPT_READLINE
- if (startSRow != endSRow || startSCol != endSCol)
- ExtendingSelection = 1;
-#endif
-}
-
-static void
-ExtendExtend(int row, int col)
-{
- int coord = Coordinate(row, col);
-
- TRACE(("ExtendExtend row=%d, col=%d\n", 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);
-
-#if OPT_READLINE
- if (startSRow != endSRow || startSCol != endSCol)
- ExtendingSelection = 1;
-#endif
-}
-
-void
-HandleStartExtend(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(Widget w,
- XEvent * event, /* must be XButtonEvent* */
- String * params, /* unused */
- Cardinal *num_params) /* unused */
-{
- do_start_extend(w, event, params, num_params, True);
-}
-
-void
-ScrollSelection(TScreen * screen, int amount, Bool always)
-{
- int minrow = -screen->savedlines - screen->topline;
- int maxrow = screen->max_row - screen->topline;
- int maxcol = screen->max_col;
-
-#define scroll_update_one(row, col) \
- row += amount; \
- if (row < minrow) { \
- row = minrow; \
- col = 0; \
- } \
- if (row > maxrow) { \
- row = maxrow; \
- col = maxcol; \
- }
-
- scroll_update_one(startRRow, startRCol);
- scroll_update_one(endRRow, endRCol);
- scroll_update_one(startSRow, startSCol);
- scroll_update_one(endSRow, endSCol);
-
- scroll_update_one(rawRow, rawCol);
-
- /*
- * If we are told to scroll the selection but it lies outside the scrolling
- * margins, then that could cause the selection to move (bad). It is not
- * simple to fix, because this function is called both for the scrollbar
- * actions as well as application scrolling. The 'always' flag is set in
- * the former case. The rest of the logic handles the latter.
- */
- if (ScrnHaveSelection(screen)) {
- int adjust;
-
- adjust = screen->startHRow + screen->topline;
- if (always
- || !ScrnHaveLineMargins(screen)
- || ScrnIsLineInMargins(screen, adjust)) {
- scroll_update_one(screen->startHRow, screen->startHCol);
- }
- adjust = screen->endHRow + screen->topline;
- if (always
- || !ScrnHaveLineMargins(screen)
- || ScrnIsLineInMargins(screen, adjust)) {
- scroll_update_one(screen->endHRow, screen->endHCol);
- }
- }
-
- screen->startHCoord = Coordinate(screen->startHRow, screen->startHCol);
- screen->endHCoord = Coordinate(screen->endHRow, screen->endHCol);
-}
-
-/*ARGSUSED*/
-void
-ResizeSelection(TScreen * screen GCC_UNUSED, int rows, int 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;
-}
-
-#if OPT_WIDE_CHARS
-Bool
-iswide(int i)
-{
- return (i == HIDDEN_CHAR) || (my_wcwidth(i) == 2);
-}
-
-#define isWideCell(row, col) iswide((int)XTERM_CELL(row, col))
-#endif
-
-static void
-PointToRowCol(int y,
- int x,
- int *r,
- int *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. */
-{
- TScreen *screen = &term->screen;
- int row, col;
-
- row = (y - screen->border) / FontHeight(screen);
- if (row < firstValidRow)
- row = firstValidRow;
- else if (row > lastValidRow)
- row = lastValidRow;
- col = (x - OriginX(screen)) / FontWidth(screen);
- if (col < 0)
- col = 0;
- else if (col > MaxCols(screen)) {
- col = MaxCols(screen);
- }
-#if OPT_WIDE_CHARS
- /*
- * If we got a click on the right half of a doublewidth character,
- * pretend it happened on the left half.
- */
- if (col > 0
- && isWideCell(row, col - 1)
- && (XTERM_CELL(row, col) == HIDDEN_CHAR)) {
- col -= 1;
- }
-#endif
- *r = row;
- *c = col;
-}
-
-static int
-LastTextCol(int row)
-{
- TScreen *screen = &term->screen;
- int i;
- Char *ch;
-
- if ((row += screen->topline) + screen->savedlines >= 0) {
- for (i = screen->max_col,
- ch = SCRN_BUF_ATTRS(screen, row) + i;
- i >= 0 && !(*ch & CHARDRAWN);
- ch--, i--) ;
-#if OPT_DEC_CHRSET
- if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, row)[0])) {
- i *= 2;
- }
-#endif
- } else {
- i = -1;
- }
- return (i);
-}
-
-#if !OPT_WIDE_CHARS
-/*
-** 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]
-** - exceptions
-*/
-/* *INDENT-OFF* */
-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, 215,
-/* 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, 247,
-/* o/ u` u' u^ u: y' P y: */
- 48, 48, 48, 48, 48, 48, 48, 48};
-/* *INDENT-ON* */
-
-int
-SetCharacterClassRange(int low, /* in range of [0..255] */
- int high,
- int value) /* arbitrary */
-{
-
- if (low < 0 || high > 255 || high < low)
- return (-1);
-
- for (; low <= high; low++)
- charClass[low] = value;
-
- return (0);
-}
-#endif
-
-#if OPT_WIDE_CHARS
-static int
-class_of(TScreen * screen, int row, int col)
-{
- int value;
-#if OPT_DEC_CHRSET
- if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, row + screen->topline)[0])) {
- col /= 2;
- }
-#endif
- value = XTERM_CELL(row, col);
- if_OPT_WIDE_CHARS(screen, {
- return CharacterClass(value);
- });
- return CharacterClass(value);
-}
-#define ClassSelects(screen, row, col, cclass) \
- (class_of(screen, row, col) == cclass \
- || XTERM_CELL(row, col) == HIDDEN_CHAR)
-#else
-#define class_of(screen,row,col) charClass[XTERM_CELL(row, col)]
-#define ClassSelects(screen, row, col, cclass) \
- (class_of(screen,row, col) == cclass)
-#endif
-
-/*
- * sets startSRow startSCol endSRow endSCol
- * ensuring that they have legal values
- */
-static void
-ComputeSelect(int startRow,
- int startCol,
- int endRow,
- int endCol,
- Bool extend)
-{
- TScreen *screen = &term->screen;
- int length;
- int cclass;
-
- TRACE(("ComputeSelect(startRow=%d, startCol=%d, endRow=%d, endCol=%d, %sextend)\n",
- startRow, startCol, endRow, endCol, extend ? "" : "no"));
-
-#if OPT_WIDE_CHARS
- if (startCol > 1
- && isWideCell(startRow, startCol - 1)
- && XTERM_CELL(startRow, startCol - 0) == HIDDEN_CHAR) {
- fprintf(stderr, "Adjusting start. Changing downwards from %i.\n", startCol);
- startCol -= 1;
- if (endCol == (startCol + 1))
- endCol--;
- }
-
- if (endCol > 1
- && isWideCell(endRow, endCol - 1)
- && XTERM_CELL(endRow, endCol) == HIDDEN_CHAR) {
- endCol += 1;
- }
-#endif
-
- 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 {
- cclass = class_of(screen, startSRow, startSCol);
- do {
- --startSCol;
- if (startSCol < 0
- && ScrnTstWrapped(screen, startSRow - 1)) {
- --startSRow;
- startSCol = LastTextCol(startSRow);
- }
- } while (startSCol >= 0
- && ClassSelects(screen, startSRow, startSCol, cclass));
- ++startSCol;
- }
-
-#if OPT_WIDE_CHARS
- if (startSCol && XTERM_CELL(startSRow, startSCol) == HIDDEN_CHAR)
- startSCol++;
-#endif
-
- if (endSCol > (LastTextCol(endSRow) + 1)) {
- endSCol = 0;
- endSRow++;
- } else {
- length = LastTextCol(endSRow);
- cclass = class_of(screen, endSRow, endSCol);
- do {
- ++endSCol;
- if (endSCol > length
- && ScrnTstWrapped(screen, endSRow)) {
- endSCol = 0;
- ++endSRow;
- length = LastTextCol(endSRow);
- }
- } while (endSCol <= length
- && ClassSelects(screen, endSRow, endSCol, cclass));
- /* 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;
- }
- }
-
-#if OPT_WIDE_CHARS
- if (endSCol && XTERM_CELL(endSRow, endSCol) == HIDDEN_CHAR)
- endSCol++;
-#endif
-
- saveStartWRow = startSRow;
- saveStartWCol = startSCol;
- break;
- case SELECTLINE:
- while (ScrnTstWrapped(screen, endSRow)) {
- ++endSRow;
- }
- if (term->screen.cutToBeginningOfLine
- || startSRow < saveStartWRow) {
- startSCol = 0;
- while (ScrnTstWrapped(screen, startSRow - 1)) {
- --startSRow;
- }
- } else if (!extend) {
- if ((startRow < saveStartWRow)
- || (startRow == saveStartWRow
- && startCol < saveStartWCol)) {
- startSCol = 0;
- while (ScrnTstWrapped(screen, startSRow - 1)) {
- --startSRow;
- }
- } else {
- startSRow = saveStartWRow;
- startSCol = saveStartWCol;
- }
- }
- if (term->screen.cutNewline) {
- endSCol = 0;
- ++endSRow;
- } else {
- endSCol = LastTextCol(endSRow) + 1;
- }
- break;
- }
-
- /* check boundaries */
- ScrollSelection(screen, 0, False);
-
- TrackText(startSRow, startSCol, endSRow, endSCol);
- return;
-}
-
-void
-TrackText(int frow,
- int fcol,
- int trow,
- int tcol)
- /* Guaranteed (frow, fcol) <= (trow, tcol) */
-{
- int from, to;
- TScreen *screen = &term->screen;
- int old_startrow, old_startcol, old_endrow, old_endcol;
-
- TRACE(("TrackText(frow=%d, fcol=%d, trow=%d, tcol=%d)\n",
- frow, fcol, trow, tcol));
-
- 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(int frow,
- int fcol,
- int trow,
- int tcol)
- /* Guaranteed that (frow, fcol) <= (trow, tcol) */
-{
- TScreen *screen = &term->screen;
- int i;
-
- TRACE(("ReHiliteText from %d.%d to %d.%d\n", frow, fcol, trow, tcol));
-
- 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 = MaxCols(screen);
- }
- 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, MaxCols(screen), 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 void
-SaltTextAway(int crow, int ccol, int row, int 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) */
-{
- TScreen *screen = &term->screen;
- int i, j = 0;
- int eol;
- Char *line;
- Char *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);
- }
-
- /* UTF-8 may require more space */
- if_OPT_WIDE_CHARS(screen, {
- j *= 4;
- });
-
- /* now get some memory to save it in */
-
- if (screen->selection_size <= j) {
- if ((line = (Char *) malloc((unsigned) j + 1)) == 0)
- SysError(ERROR_BMALLOC2);
- XtFree((char *) screen->selection_data);
- screen->selection_data = line;
- screen->selection_size = j + 1;
- } else {
- line = screen->selection_data;
- }
-
- if ((line == 0)
- || (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 */
-
- TRACE(("Salted TEXT:%d:%.*s\n", lp - line, lp - line, line));
- screen->selection_length = (lp - line);
- _OwnSelection(term, params, num_params);
-}
-
-#if OPT_PASTE64
-void
-ClearSelectionBuffer()
-{
- TScreen *screen = &term->screen;
- screen->selection_length = 0;
- screen->base64_count = 0;
-}
-
-static void
-AppendStrToSelectionBuffer(Char * text, int len)
-{
- TScreen *screen = &term->screen;
- if (len != 0) {
- int j = screen->selection_length + len; /* New length */
- int k = j + (j >> 2) + 80; /* New size if we grow buffer: grow by ~50% */
- if (j + 1 >= screen->selection_size) {
- if (!screen->selection_length) {
- /* New buffer */
- Char *line;
- if ((line = (Char *) malloc((unsigned) k)) == 0)
- SysError(ERROR_BMALLOC2);
- XtFree((char *) screen->selection_data);
- screen->selection_data = line;
- } else {
- /* Realloc buffer */
- screen->selection_data = (Char *)
- realloc(screen->selection_data,
- (unsigned) k);
- if (screen->selection_data == 0)
- SysError(ERROR_BMALLOC2);
- }
- screen->selection_size = k;
- }
- memcpy(screen->selection_data + screen->selection_length, text, len);
- screen->selection_length += len;
- screen->selection_data[screen->selection_length] = 0;
- }
-}
-
-void
-AppendToSelectionBuffer(TScreen * screen, unsigned c)
-{
- int six;
- Char ch;
-
- /* Decode base64 character */
- if (c >= 'A' && c <= 'Z')
- six = c - 'A';
- else if (c >= 'a' && c <= 'z')
- six = c - 'a' + 26;
- else if (c >= '0' && c <= '9')
- six = c - '0' + 52;
- else if (c == '+')
- six = 62;
- else if (c == '/')
- six = 63;
- else
- return;
-
- /* Accumulate bytes */
- switch (screen->base64_count) {
- case 0:
- screen->base64_accu = six;
- screen->base64_count = 6;
- break;
-
- case 2:
- ch = (screen->base64_accu << 6) + six;
- screen->base64_count = 0;
- AppendStrToSelectionBuffer(&ch, 1);
- break;
-
- case 4:
- ch = (screen->base64_accu << 4) + (six >> 2);
- screen->base64_accu = (six & 0x3);
- screen->base64_count = 2;
- AppendStrToSelectionBuffer(&ch, 1);
- break;
-
- case 6:
- ch = (screen->base64_accu << 2) + (six >> 4);
- screen->base64_accu = (six & 0xF);
- screen->base64_count = 4;
- AppendStrToSelectionBuffer(&ch, 1);
- break;
- }
-}
-
-void
-CompleteSelection(char **args, Cardinal len)
-{
- term->screen.base64_count = 0;
- term->screen.base64_accu = 0;
- _OwnSelection(term, args, len);
-}
-#endif /* OPT_PASTE64 */
-
-static Bool
-_ConvertSelectionHelper(Widget w,
- Atom * type, XtPointer *value,
- unsigned long *length, int *format,
- int (*conversion_function) (Display *,
- char **, int,
- XICCEncodingStyle,
- XTextProperty *),
- XICCEncodingStyle conversion_style)
-{
- Display *d = XtDisplay(w);
- TScreen *screen;
- XTextProperty textprop;
-
- if (!IsXtermWidget(w))
- return False;
-
- screen = &((XtermWidget) w)->screen;
-
- if (conversion_function(d, (char **) &screen->selection_data, 1,
- conversion_style,
- &textprop) < Success)
- return False;
- *value = (XtPointer) textprop.value;
- *length = textprop.nitems;
- *type = textprop.encoding;
- *format = textprop.format;
- return True;
-}
-
-static Boolean
-ConvertSelection(Widget w,
- Atom * selection,
- Atom * target,
- Atom * type,
- XtPointer *value,
- unsigned long *length,
- int *format)
-{
- Display *d = XtDisplay(w);
- TScreen *screen;
- Bool result = False;
-
- if (!IsXtermWidget(w))
- return False;
-
- screen = &((XtermWidget) w)->screen;
-
- if (screen->selection_data == NULL)
- return False; /* can this happen? */
-
- if (*target == XA_TARGETS(d)) {
- Atom *targetP;
- Atom *std_targets;
- XPointer std_return = 0;
- unsigned long std_length;
- if (XmuConvertStandardSelection(w, screen->selection_time, selection,
- target, type, &std_return,
- &std_length, format)) {
- std_targets = (Atom *) (std_return);
- *length = std_length + 6;
- targetP = (Atom *) XtMalloc(sizeof(Atom) * (*length));
- *value = (XtPointer) targetP;
- *targetP++ = XA_STRING;
- *targetP++ = XA_TEXT(d);
-#ifdef X_HAVE_UTF8_STRING
- *targetP++ = XA_COMPOUND_TEXT(d);
- *targetP++ = XA_UTF8_STRING(d);
-#else
- *targetP = XA_COMPOUND_TEXT(d);
- if_OPT_WIDE_CHARS(screen, {
- *targetP = XA_UTF8_STRING(d);
- });
- targetP++;
-#endif
- *targetP++ = XA_LENGTH(d);
- *targetP++ = XA_LIST_LENGTH(d);
- memcpy(targetP, std_targets, sizeof(Atom) * std_length);
- XtFree((char *) std_targets);
- *type = XA_ATOM;
- *format = 32;
- result = True;
- }
- }
-#if OPT_WIDE_CHARS
- else if (screen->wide_chars && *target == XA_STRING) {
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- Xutf8TextListToTextProperty,
- XStringStyle);
- } else if (screen->wide_chars && *target == XA_UTF8_STRING(d)) {
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- Xutf8TextListToTextProperty,
- XUTF8StringStyle);
- } else if (screen->wide_chars && *target == XA_TEXT(d)) {
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- Xutf8TextListToTextProperty,
- XStdICCTextStyle);
- } else if (screen->wide_chars && *target == XA_COMPOUND_TEXT(d)) {
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- Xutf8TextListToTextProperty,
- XCompoundTextStyle);
- }
-#endif
-
- else if (*target == XA_STRING) { /* not wide_chars */
- /* We can only reach this point if the selection requestor
- requested STRING before any of TEXT, COMPOUND_TEXT or
- UTF8_STRING. We therefore assume that the requestor is not
- properly internationalised, and dump raw eight-bit data
- with no conversion into the selection. Yes, this breaks
- the ICCCM in non-Latin-1 locales. */
- *type = XA_STRING;
- *value = (XtPointer) screen->selection_data;
- *length = screen->selection_length;
- *format = 8;
- result = True;
- } else if (*target == XA_TEXT(d)) { /* not wide_chars */
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- XmbTextListToTextProperty,
- XStdICCTextStyle);
- } else if (*target == XA_COMPOUND_TEXT(d)) { /* not wide_chars */
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- XmbTextListToTextProperty,
- XCompoundTextStyle);
- }
-#ifdef X_HAVE_UTF8_STRING
- else if (*target == XA_UTF8_STRING(d)) { /* not wide_chars */
- result =
- _ConvertSelectionHelper(w,
- type, value, length, format,
- XmbTextListToTextProperty,
- XUTF8StringStyle);
- }
-#endif
- else if (*target == XA_LIST_LENGTH(d)) {
- *value = XtMalloc(4);
- if (sizeof(long) == 4)
- *(long *) *value = 1;
- else {
- long temp = 1;
- memcpy((char *) *value, ((char *) &temp) + sizeof(long) - 4, 4);
- }
- *type = XA_INTEGER;
- *length = 1;
- *format = 32;
- result = True;
- } else if (*target == XA_LENGTH(d)) {
- /* This value is wrong if we have UTF-8 text */
- *value = XtMalloc(4);
- if (sizeof(long) == 4) {
- *(long *) *value = screen->selection_length;
- } else {
- long temp = screen->selection_length;
- memcpy((char *) *value, ((char *) &temp) + sizeof(long) - 4, 4);
- }
- *type = XA_INTEGER;
- *length = 1;
- *format = 32;
- result = True;
- } else if (XmuConvertStandardSelection(w,
- screen->selection_time, selection,
- target, type, (XPointer *) value,
- length, format)) {
- result = True;
- }
-
- /* else */
- return result;
-}
-
-static void
-LoseSelection(Widget w, Atom * selection)
-{
- TScreen *screen;
- Atom *atomP;
- Cardinal i;
-
- if (!IsXtermWidget(w))
- return;
-
- screen = &((XtermWidget) w)->screen;
- for (i = 0, atomP = screen->selection_atoms;
- i < screen->selection_count; i++, atomP++) {
- if (*selection == *atomP)
- *atomP = (Atom) 0;
- if (CutBuffer(*atomP) >= 0) {
- *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(Widget w GCC_UNUSED,
- Atom * selection GCC_UNUSED,
- Atom * target GCC_UNUSED)
-{
- /* empty proc so Intrinsics know we want to keep storage */
-}
-
-static void
-_OwnSelection(XtermWidget termw,
- String * selections,
- Cardinal count)
-{
- Atom *atoms = termw->screen.selection_atoms;
- Cardinal i;
- Bool 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 = CutBuffer(atoms[i]);
- 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 {
- /* This used to just use the UTF-8 data, which was totally
- * broken as not even the corresponding paste code in Xterm
- * understood this! So now it converts to Latin1 first.
- * Robert Brady, 2000-09-05
- */
- unsigned long length = termw->screen.selection_length;
- Char *data = termw->screen.selection_data;
- if_OPT_WIDE_CHARS((&(termw->screen)), {
- data = UTF8toLatin1(data, length, &length);
- });
- TRACE(("XStoreBuffer(%d)\n", cutbuffer));
- XStoreBuffer(XtDisplay((Widget) termw),
- (char *) data,
- (int) 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);
-}
-
-static void
-ResetSelectionState(TScreen * screen)
-{
- screen->selection_count = 0;
- screen->startHRow = screen->startHCol = 0;
- screen->endHRow = screen->endHCol = 0;
-}
-
-void
-DisownSelection(XtermWidget termw)
-{
- TScreen *screen = &(termw->screen);
- Atom *atoms = screen->selection_atoms;
- Cardinal count = screen->selection_count;
- Cardinal i;
-
- TRACE(("DisownSelection count %d, start %d.%d, end %d.%d\n",
- count,
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol));
-
- for (i = 0; i < count; i++) {
- int cutbuffer = CutBuffer(atoms[i]);
- if (cutbuffer < 0) {
- XtDisownSelection((Widget) termw, atoms[i],
- screen->selection_time);
- }
- }
- /*
- * If none of the callbacks via XtDisownSelection() reset highlighting
- * do it now.
- */
- if (ScrnHaveSelection(screen)) {
- /* save data which will be reset */
- int start_row = screen->startHRow;
- int start_col = screen->startHCol;
- int end_row = screen->endHRow;
- int end_col = screen->endHCol;
-
- ResetSelectionState(screen);
- ReHiliteText(start_row, start_col, end_row, end_col);
- } else {
- ResetSelectionState(screen);
- }
-}
-
-/* returns number of chars in line from scol to ecol out */
-/* ARGSUSED */
-static int
-Length(TScreen * screen GCC_UNUSED,
- int row,
- int scol,
- int ecol)
-{
- int lastcol = LastTextCol(row);
-
- if (ecol > lastcol)
- ecol = lastcol;
- return (ecol - scol + 1);
-}
-
-/* copies text into line, preallocated */
-static Char *
-SaveText(TScreen * screen,
- int row,
- int scol,
- int ecol,
- Char * lp, /* pointer to where to put the text */
- int *eol)
-{
- int i = 0;
- unsigned c;
- Char *result = lp;
-#if OPT_WIDE_CHARS
- int previous = 0;
- unsigned c_1 = 0, c_2 = 0;
-#endif
-
- i = Length(screen, row, scol, ecol);
- ecol = scol + i;
-#if OPT_DEC_CHRSET
- if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, row + screen->topline)[0])) {
- scol = (scol + 0) / 2;
- ecol = (ecol + 1) / 2;
- }
-#endif
- *eol = !ScrnTstWrapped(screen, row);
- for (i = scol; i < ecol; i++) {
- c = E2A(XTERM_CELL(row, i));
-#if OPT_WIDE_CHARS
- if (screen->utf8_mode != uFalse) {
- c_1 = E2A(XTERM_CELL_C1(row, i));
- c_2 = E2A(XTERM_CELL_C2(row, i));
- }
-
- /* We want to strip out every occurrence of HIDDEN_CHAR AFTER a
- * wide character.
- */
- if (c == HIDDEN_CHAR && iswide(previous)) {
- previous = c;
- /* Combining characters attached to double-width characters
- are in memory attached to the HIDDEN_CHAR */
- if (c_1) {
- lp = convertToUTF8(lp, c_1);
- if (c_2)
- lp = convertToUTF8(lp, c_2);
- }
- continue;
- }
- previous = c;
- if (screen->utf8_mode != uFalse) {
- lp = convertToUTF8(lp, (c != 0) ? c : ' ');
- if (c_1) {
- lp = convertToUTF8(lp, c_1);
- if (c_2)
- lp = convertToUTF8(lp, c_2);
- }
- } else
-#endif
- {
- if (c == 0) {
- c = E2A(' ');
- } else if (c < E2A(' ')) {
- if (c == XPOUND)
- c = 0x23; /* char on screen is pound sterling */
- else
- c += 0x5f; /* char is from DEC drawing set */
- } else if (c == 0x7f) {
- c = 0x5f;
- }
- *lp++ = A2E(c);
- }
- if (c != E2A(' '))
- result = lp;
- }
-
- /*
- * If requested, trim trailing blanks from selected lines. Do not do this
- * if the line is wrapped.
- */
- if (!*eol || !screen->trim_selection)
- result = lp;
-
- return (result);
-}
-
-/* 32 + following 7-bit word:
-
- 1:0 Button no: 0, 1, 2. 3=release.
- 2 shift
- 3 meta
- 4 ctrl
- 5 set for motion notify
- 6 set for wheel
-*/
-
-/* Position: 32 - 255. */
-
-static int
-BtnCode(XButtonEvent * event, int button)
-{
- int result = 32 + (KeyState(event->state) << 2);
-
- if (button < 0 || button > 5) {
- result += 3;
- } else {
- if (button > 3)
- result += (64 - 4);
- if (event->type == MotionNotify)
- result += 32;
- result += button;
- }
- return result;
-}
-
-#define MOUSE_LIMIT (255 - 32)
-
-static void
-EditorButton(XButtonEvent * event)
-{
- TScreen *screen = &term->screen;
- int pty = screen->respond;
- Char line[6];
- int row, col;
- int button;
- unsigned count = 0;
-
- /* If button event, get button # adjusted for DEC compatibility */
- button = event->button - 1;
- if (button >= 3)
- button++;
-
- /* Compute character position of mouse pointer */
- row = (event->y - screen->border) / FontHeight(screen);
- col = (event->x - OriginX(screen)) / FontWidth(screen);
-
- /* Limit to screen dimensions */
- if (row < 0)
- row = 0;
- else if (row > screen->max_row)
- row = screen->max_row;
- else if (row > MOUSE_LIMIT)
- row = MOUSE_LIMIT;
-
- if (col < 0)
- col = 0;
- else if (col > screen->max_col)
- col = screen->max_col;
- else if (col > MOUSE_LIMIT)
- col = MOUSE_LIMIT;
-
- /* Build key sequence starting with \E[M */
- if (screen->control_eight_bits) {
- line[count++] = CSI;
- } else {
- line[count++] = ESC;
- line[count++] = '[';
- }
- line[count++] = 'M';
-
- /* Add event code to key sequence */
- if (screen->send_mouse_pos == X10_MOUSE) {
- line[count++] = ' ' + button;
- } else {
- /* Button-Motion events */
- switch (event->type) {
- case ButtonPress:
- line[count++] = BtnCode(event, screen->mouse_button = button);
- break;
- case ButtonRelease:
- /*
- * Wheel mouse interface generates release-events for buttons
- * 4 and 5, coded here as 3 and 4 respectively. We change the
- * release for buttons 1..3 to a -1.
- */
- if (button < 3)
- button = -1;
- line[count++] = BtnCode(event, screen->mouse_button = button);
- break;
- case MotionNotify:
- /* BTN_EVENT_MOUSE and ANY_EVENT_MOUSE modes send motion
- * events only if character cell has changed.
- */
- if ((row == screen->mouse_row)
- && (col == screen->mouse_col))
- return;
- line[count++] = BtnCode(event, screen->mouse_button);
- break;
- default:
- return;
- }
- }
-
- screen->mouse_row = row;
- screen->mouse_col = col;
-
- /* Add pointer position to key sequence */
- line[count++] = ' ' + col + 1;
- line[count++] = ' ' + row + 1;
-
- TRACE(("mouse at %d,%d button+mask = %#x\n", row, col,
- (screen->control_eight_bits) ? line[2] : line[3]));
-
- /* Transmit key sequence to process running under xterm */
- v_write(pty, line, count);
-}
-
-/*ARGSUSED*/
-#if OPT_TEK4014
-void
-HandleGINInput(Widget w GCC_UNUSED,
- XEvent * event GCC_UNUSED,
- 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(XkbBI_MinorError, 0); /* let them know they goofed */
- c = 'l'; /* provide a default */
- }
- TekEnqMouse(c | 0x80);
- TekGINoff();
- } else {
- Bell(XkbBI_MinorError, 0);
- }
-}
-#endif /* OPT_TEK4014 */
-
-/* ARGSUSED */
-void
-HandleSecure(Widget w GCC_UNUSED,
- XEvent * event, /* unused */
- String * params GCC_UNUSED, /* [0] = volume */
- Cardinal *param_count GCC_UNUSED) /* 0 or 1 */
-{
- Time ev_time = CurrentTime;
-
- if ((event->xany.type == KeyPress) ||
- (event->xany.type == KeyRelease))
- ev_time = event->xkey.time;
- else if ((event->xany.type == ButtonPress) ||
- (event->xany.type == ButtonRelease))
- ev_time = event->xbutton.time;
- DoSecureKeyboard(ev_time);
-}