This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Code generation bug in 2.95.2


Hi,

I am using gcc 2.95.2 on Solaris for Intel. The offending source is
from xterm 152. Attached is the C source, and the assembler output.

Have a look at the assembler output and search for "call 0" (zero).

The C source logic is as follows.

	ptr_to_function = NULL;
#if ... false_condition
	ptr_to_function = valid_ptr;
#endif
	if (ptr_to_function) {
		(*ptr_to_function)(... args ...);
	}

All #if ... are false, given the specific ./configure stuff.

gcc does generate the test "if (ptr_to_function) { ...". It does not
seem to realize, that the pointer is NULL.

But within the "if" statement it does not generate a call to a pointer
to function, here it realizes that the pointer must be NULL.

So it generates the false assembler statement "call 0".

The error message is "Assembler: illegal pc-relative relocation".

This happens with -O[0-3]*, it does not happen w/o -O.

The optimizer logic seems to be broken, because it does not skip the
whole test, and the "if", which can never be true.

The code generator seems to be broken, because it generates an
illegal assembler directive.

Kind regards		Ruediger Schuetz
/* $Xorg: button.c,v 1.3 2000/08/17 19:55:08 cpqbld Exp $ */
/*
 * Copyright 1999-2000 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.55 2001/01/17 23:46:34 dawes 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 <data.h>
#include <error.h>
#include <menu.h>
#include <xcharmouse.h>

#if OPT_WIDE_CHARS
#include <charclass.h>
#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) * (term->screen.max_col+1) + (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;
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);

Boolean 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)++;					\
    }

#define	MotionOff( s, t ) {						\
	    (s)->event_mask |= ButtonMotionMask;			\
	    (s)->event_mask &= ~PointerMotionMask;			\
	    XSelectInput(XtDisplay((t)), XtWindow((t)), (s)->event_mask); }

#define	MotionOn( s, t ) {						\
	    (s)->event_mask &= ~ButtonMotionMask;			\
	    (s)->event_mask |= PointerMotionMask;			\
	    XSelectInput(XtDisplay((t)), XtWindow((t)), (s)->event_mask); }

Boolean
SendLocatorPosition(Widget w, XEvent* event)
{
    TScreen	*screen = &((XtermWidget)w)->screen;
    int		row, col;
    Boolean	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;
    Boolean		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;
    Boolean		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;
    Boolean		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 */

void
DiredButton(
	Widget w GCC_UNUSED,
	XEvent *event,			/* must be XButtonEvent */
	String *params GCC_UNUSED,	/* selections */
	Cardinal *num_params GCC_UNUSED)
{	/* ^XM-G<line+' '><col+' '> */
    register TScreen *screen = &term->screen;
    Char Line[ 6 ];
    register 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 );
    }
}

void
ViButton(
	Widget w GCC_UNUSED,
	XEvent *event,			/* must be XButtonEvent */
	String *params GCC_UNUSED,	/* selections */
	Cardinal *num_params GCC_UNUSED)
{	/* ^XM-G<line+' '><col+' '> */
    register TScreen *screen = &term->screen;
    int pty = screen->respond;
    Char Line[ 6 ];
    register 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)
{
	register 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 )
			    SendMousePosition(w,event);
			break;
	}
}

static void do_select_end (
	Widget w,
	XEvent *event,		/* must be XButtonEvent */
	String *params,		/* selections */
	Cardinal *num_params,
	Bool use_cursor_loc)
{
	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);
		    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);
}

#ifndef X_HAVE_UTF8_STRING
static Atom XA_UTF8_STRING(Display *dpy)
{
    static AtomPtr p = NULL;

    if(p == NULL)
	p = XmuMakeAtom("UTF8_STRING");
    return XmuInternAtom(dpy, p);
}
#endif

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, int 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 > (int) 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;
}

/* Convert a Latin-1 string to UTF-8 */

static Char *
Latin1toUTF8(Char *s, int len, int *len_return)
{
    Char *p = s;
    Char *t;
    Char *q;

    t = XtMalloc(2 * len);
    if (t == 0) {
	TRACE(("Couldn't allocate target string\n"));
	return 0;
    }
    q = t;

    while (p < s + len) {
	if ((*p & 0x80) == 0) {
	    *q++ = *p++;
	} else {
	    *q++ = 0xC0 | ((*p >> 6) & 0x3);
	    *q++ = 0x80 | (*p & 0x3F);
	    p++;
	}
    }

    *len_return = q - t;
    return t;
}

/* Eliminate all control characters from a UTF-8 string, doing
   something reasonable with PS and LS */

static Char*
filterUTF8(Char *s, int len, int *len_return)
{
    Char *p=s;
    Char *t;
    Char *q;
    unsigned codepoint;
    int size;

    t = XtMalloc(len);
    if (t == 0) {
	TRACE(("Couldn't allocate target string\n"));
	return 0;
    }
    q = t;

    while (p < (s + len) && q < (t + len)) {
	if ((*p & 0x80) == 0) {
	    codepoint = *p & 0x7F;
	    size = 1;
	} else if ((*p & 0x60) == 0x40 && p < s + len - 1) {
	    codepoint = ((p[0] & 0x1F) << 6) | (p[1] & 0x3F);
	    size = 2;
	} else if ((*p & 0x70) == 0x60 && p < s + len - 2) {
	    codepoint = ((p[0] & 0x0F) << 12)
		      | ((p[1] & 0x3F) << 6)
		      | (p[2] & 0x3F);
	    size = 3;
	} else if ((*p & 0x78) == 0x70 && p < s + len - 3) {
	    p += 4;		/* eliminate surrogates */
	    continue;
	} else if ((*p & 0x7C) == 0x78 && p < s + len - 4) {
	    p += 5;
	    continue;
	} else if ((*p & 0x7E) == 0x7C && p < s + len - 5) {
	    p += 6;
	    continue;
	} else {		/* wrong UTF-8?  Silently discard. */
	    p++;
	    continue;
	}

	if(codepoint == 0x2028) {
	    /* line separator -- replace by NL*/
	    p += size;
	    *q++ = 0x0A;
	} else if (codepoint == 0x2029) {
	    /* paragraph separator -- replace by NL NL */
	    p += size;
	    *q++ = 0x0A;
	    if (q < t + len)
		*q++ = 0x0A;
	} else if (codepoint >= 0x202A && codepoint <= 0x202E) {
	    /* ignore Unicode control characters; surrogates have already
	       been eliminated */
	    p += size;
	} else {
	    /* just copy the UTF-8 */
	  while (size--)
	    *q++ = *p++;
	}
    }
    *len_return = q - t;
    return t;
}
#endif /* OPT_WIDE_CHARS */

#if OPT_WIDE_CHARS
static Status
XTextPropertyToStringListUnchecked(XTextProperty *tp,
				   char ***list_return,
				   int *count_return)
{
    char **list;			/* return value */
    int nelements;			/* return value */
    register char *cp;			/* temp variable */
    char *start;			/* start of thing to copy */
    int i, j;				/* iterator variables */
    int datalen = (int) tp->nitems;	/* for convenience */

    if (datalen == 0) {
	*list_return = NULL;
	*count_return = 0;
	return True;
    }

    /*
     * walk the list to figure out how many elements there are
     */
    nelements = 1;			/* since null-separated */
    for (cp = (char *) tp->value, i = datalen; i > 0; cp++, i--) {
	if (*cp == '\0') nelements++;
    }

    /*
     * allocate list and duplicate
     */
    list = (char **) XtMalloc (nelements * sizeof (char *));
    if (!list) return False;

    start = (char *) XtMalloc ((datalen + 1) * sizeof (char));	/* for <NUL> */
    if (!start) {
	XtFree ((char *) list);
	return False;
    }

    /*
     * copy data
     */
    memcpy (start, (char *) tp->value, tp->nitems);
    start[datalen] = '\0';

    /*
     * walk down list setting value
     */
    for (cp = start, i = datalen + 1, j = 0; i > 0; cp++, i--) {
	if (*cp == '\0') {
	    list[j] = start;
	    start = (cp + 1);
	    j++;
	}
    }

    /*
     * append final null pointer and then return data
     */
    *list_return = list;
    *count_return = nelements;
    return True;
}
#endif

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)); n++;
#if OPT_USE_UTF8_API
	    if (screen->i18nSelections) {
		utf8SelectionTargets[n] = XA_TEXT(XtDisplay(w)); n++;
		utf8SelectionTargets[n] = XA_COMPOUND_TEXT(XtDisplay(w)); n++;
	    }
#endif
	    utf8SelectionTargets[n] = XA_STRING; n++;
	    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;
	if (screen->i18nSelections) {
	    eightBitSelectionTargets[n] = XA_TEXT(XtDisplay(w)); n++;
	    eightBitSelectionTargets[n] = XA_COMPOUND_TEXT(XtDisplay(w)); n++;
	}
#if OPT_USE_UTF8_API
	eightBitSelectionTargets[n] = XA_UTF8_STRING(XtDisplay(w)); n++;
#endif
	eightBitSelectionTargets[n] = XA_STRING; n++;
	eightBitSelectionTargets[n] = None;
    }
    return eightBitSelectionTargets;
}

static void _GetSelection(
	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;

    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;
    }
    TRACE(("Cutbuffer: %d, target: %lu\n", cutbuffer,
	   (unsigned long)targets[0]));
    if (cutbuffer >= 0) {
	int inbytes;
	unsigned long nbytes;
	int fmt8 = 8;
	Atom type = XA_STRING;
	char *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)
	    _GetSelection(w, ev_time, params+1, num_params-1, NULL);
	return;
    } else {
	struct _SelectionList* list;

	if (targets == NULL || targets[0] == None) {
	    targets = _SelectionTargets(w);
	}

	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 = XtNew(struct _SelectionList);
	    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(char *tag, Char *line, int len)
{
    Char *cp;

    Trace("Getting %s\n", tag);
    for (cp = line; cp < line + len; cp++)
	Trace("%c\n", *cp);
}
#else
#define GettingSelection(tag,line,len) /* nothing */
#endif

#ifndef VMS
static void
_WriteSelectionData(int pty, 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. */

    register Char *lag, *cp, *end;

    end = &line[length];
    lag = line;
    for (cp = line; cp != end; cp++) {
	if (*cp == '\n') {
	    *cp = '\r';
	    v_write(pty, lag, cp - lag + 1);
	    lag = cp + 1;
	}
    }
    if (lag != end) {
	v_write(pty, lag, end - lag);
    }
}

#else  /* VMS */

static void
_WriteSelectionData(int pty, Char *line, int length)
{
    /* 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. */

    register Char *lag, *cp, *end;

    tt_pasting = TRUE;

    end = &line[length];
    lag = line;
    for (cp = line; cp != end; cp++) {
	if (*cp == '\n') {
	    *cp = '\r';
	    tt_write(lag, cp - lag + 1);
	    lag = cp + 1;
	}
    }
    if (lag != end) {
	tt_write(lag, end - lag);
    }

    tt_pasting = FALSE;
    tt_start_read();  /* reenable reads or a character may be lost */
}
#endif /* VMS */

/* 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;
    Char *(*conversion_function)(Char*, int, int*) = NULL;
    int text_list_count;
    XTextProperty text_prop;
    TScreen *screen;
    Display *dpy;

    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 = 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))) {
	    GettingSelection("UTF8_STRING", line, *length);
	    if(XTextPropertyToStringListUnchecked(&text_prop, &text_list,
						  &text_list_count) < 0) {
		TRACE(("Conversion failed\n"));
		text_list = NULL;
	    }
	    conversion_function = filterUTF8;
	}
#if OPT_USE_UTF8_API
	if (*type == XA_COMPOUND_TEXT(XtDisplay(w))) {
	    GettingSelection("COMPOUND_TEXT", line, *length);
	    if(Xutf8TextPropertyToTextList(dpy, &text_prop,
					   &text_list,
					   &text_list_count) < 0) {
		TRACE(("Conversion failed\n"));
		text_list = NULL;
	    }
	}
#endif
	if (*type == XA_STRING) {
	    GettingSelection("STRING", line, *length);
	    if(XTextPropertyToStringList(&text_prop, &text_list,
					 &text_list_count) < 0) {
		TRACE(("Conversion failed\n"));
		text_list = NULL;
	    }
	    conversion_function = Latin1toUTF8;
	}
    } else
#endif /* OPT_WIDE_CHARS */
    {
	if(*type == XA_COMPOUND_TEXT(XtDisplay(w))) {
	    GettingSelection("COMPOUND_TEXT", line, *length);
	    if(XmbTextPropertyToTextList(dpy, &text_prop,
					 &text_list,
					 &text_list_count) < 0) {
		TRACE(("Conversion failed\n"));
		text_list = NULL;
	    }
	}
    }
#if OPT_USE_UTF8_API
	if(*type == XA_UTF8_STRING(XtDisplay(w))) {
	    GettingSelection("UTF8_STRING", line, *length);
	    if(Xutf8TextPropertyToTextList(dpy, &text_prop,
					   &text_list,
					   &text_list_count) < 0) {
		TRACE(("Conversion failed\n"));
		text_list = NULL;
	    }
	}
#endif
	if(*type == XA_STRING) {
	    Status rc;
	    GettingSelection("STRING", line, *length);
	    if(screen->i18nSelections) {
		rc = XmbTextPropertyToTextList(dpy,
					       &text_prop,
					       &text_list, &text_list_count);
	    } else {
		rc = XTextPropertyToStringList(&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;
	for(i = 0; i < text_list_count; i++) {
	    Char *t = (Char *)text_list[i];
	    int len = strlen(text_list[i]);
	    if(conversion_function) {
		if ((t = conversion_function(t, len, &len)) != 0) {
		    _WriteSelectionData(((XtermWidget)w)->screen.respond, t, len);
		    XtFree((char *)t);
		}
	    } else {
		_WriteSelectionData(((XtermWidget)w)->screen.respond, t, len);
	    }
	}
	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;
	_GetSelection(w, list->time,
		      list->params, list->count, list->targets);
	XtFree((char *)client_data);
    }
    return;
}


void
HandleInsertSelection(
	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, 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;
	StartSelect(startrow, startcol);
}

/* ARGSUSED */
void
HandleSelectStart(
	Widget w,
	XEvent *event,			/* must be XButtonEvent* */
	String *params GCC_UNUSED,
	Cardinal *num_params GCC_UNUSED)
{
	register 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);
	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)
{
	register TScreen *screen;

	if (!IsXtermWidget(w))
		return;

	screen = &((XtermWidget)w)->screen;
	do_select_start (w, event, screen->cursor_row, screen->cursor_col);
}


static void
TrackDown(register 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 = 1;
		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 = 0;
	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, 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)
{
	/* 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;
	selectUnit = EvalSelectUnit(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 (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);
}


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(register TScreen* screen, register int amount)
{
    register int minrow = -screen->savedlines - screen->topline;
    register int maxrow = screen->max_row - screen->topline;
    register 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);

    scroll_update_one(screen->startHRow, screen->startHCol);
    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
int iswide(int i)
{
    return (i == HIDDEN_CHAR) || (my_wcwidth(i) == 2);
}
#endif

static void
PointToRowCol(
    register int y,
    register 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. */
{
	register TScreen *screen = &term->screen;
	register 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 > screen->max_col+1) {
		col = screen->max_col+1;
	}
#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
	 && iswide(XTERM_CELL(row, col-1))
	 && (XTERM_CELL(row, col) == HIDDEN_CHAR)) {
		col -= 1;
	}
#endif
	*r = row;
	*c = col;
}

static int
LastTextCol(register int row)
{
	register TScreen *screen =  &term->screen;
	register int i;
	register 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
*/
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 (
    register int low,			/* in range of [0..255] */
    register int high,
    register 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)
{
    unsigned 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)
{
	register TScreen *screen = &term->screen;
	register int length;
	register int cclass;

#if OPT_WIDE_CHARS
	if (startCol > 1
	 && iswide(XTERM_CELL(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 (iswide(XTERM_CELL(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;
	}

	TrackText(startSRow, startSCol, endSRow, endSCol);
	return;
}

void
TrackText(
	register int frow,
	register int fcol,
	register int trow,
	register int 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(
    register int frow,
    register int fcol,
    register int trow,
    register int 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 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) */
{
    register TScreen *screen = &term->screen;
    register 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(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 = (Char *)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:%.*s\n", (char *)lp - line, line));
    screen->selection_length = ((char *)lp - line);
    _OwnSelection(term, params, num_params);
}

static Boolean
_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;


    *value = (XtPointer) screen->selection_data;
    if (conversion_function(d, (char**)value, 1,
			    conversion_style,
			    &textprop) < Success)
	return False;
    *value = (XtPointer) textprop.value;
    *length = textprop.nitems;
    *type = textprop.encoding;
    *format = 8;
    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;

    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;
	unsigned long std_length;
	XmuConvertStandardSelection(w, screen->selection_time, selection,
				    target, type, (XPointer *)&std_targets,
				    &std_length, format);
	*length = std_length + 6;
	targetP = (Atom*)XtMalloc(sizeof(Atom)*(*length));
	*value = (XtPointer) targetP;
	*targetP++ = XA_STRING;
	*targetP++ = XA_TEXT(d);
#if OPT_USE_UTF8_API
	*targetP++ = XA_COMPOUND_TEXT(d);
	*targetP++ = XA_UTF8_STRING(d);
#else  /* OPT_USE_UTF8_API */
	*targetP = XA_COMPOUND_TEXT(d);
	if_OPT_WIDE_CHARS(screen, {
	    *targetP = XA_UTF8_STRING(d);
	})
	targetP++;
#endif /* OPT_USE_UTF8_API */
	*targetP++ = XA_LENGTH(d);
	*targetP++ = XA_LIST_LENGTH(d);
	memcpy ( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
	XtFree((char*)std_targets);
	*type = XA_ATOM;
	*format = 32;
	return True;
    }


#if OPT_WIDE_CHARS
    /* Deal with XA_TEXT in the Unicode case */
    if (*target == XA_TEXT(d) && screen->wide_chars) {
#if OPT_USE_UTF8_API
	char *p;
	/* walk the string, searching for non ISO 8859-1 characters */
	for (p = screen->selection_data;
	     p < screen->selection_data+screen->selection_length;
	     p++) {
	    if ((*p & 0xC0) == 0xC0
		&& ((*p & 0x20) || (!(*p & 0x20) && (*p & 0x1C))))
		break;
	}
	if (p < screen->selection_data + screen->selection_length) {
	    /* non ISO 8859-1 character found -- return CTEXT */
	    *target = XA_COMPOUND_TEXT(d);
	} else {
	    /* none found -- return STRING */
	    *target = XA_STRING;
	}
#else /* OPT_USE_UTF8_API */
	*target = XA_STRING;
#endif /* OPT_USE_UTF8_API */
    }
#endif /* OPT_WIDE_CHARS */


#if OPT_WIDE_CHARS
    if (screen->wide_chars && *target == XA_STRING) {
	*value = UTF8toLatin1((Char*)screen->selection_data,
			      screen->selection_length, length);
	*type = XA_STRING;
	*format = 8;
	return True;
    }
    if (screen->wide_chars && *target == XA_UTF8_STRING(d)) {
	*type = XA_UTF8_STRING(d);
	*value = screen->selection_data;
	*length = screen->selection_length;
	*format = 8;
	return True;
    }
    if (screen->wide_chars && *target == XA_COMPOUND_TEXT(d)) {
#if OPT_USE_UTF8_API
	return
	    _ConvertSelectionHelper(w,
				    type, value, length, format,
				    Xutf8TextListToTextProperty,
				    XCompoundTextStyle);
#else
	return False;
#endif
    }
#endif

    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 = screen->selection_data;
	*length = screen->selection_length;
	*format = 8;
	return True;
    }

    if (*target == XA_TEXT(d)) { /* not wide_chars */
	return
	    _ConvertSelectionHelper(w,
				    type, value, length, format,
				    XmbTextListToTextProperty,
				    XStdICCTextStyle);
    }

    if (*target == XA_COMPOUND_TEXT(d)) { /* not wide_chars */
	return
	    _ConvertSelectionHelper(w,
				    type, value, length, format,
				    XmbTextListToTextProperty,
				    XCompoundTextStyle);
    }

    if (*target == XA_UTF8_STRING(d)) { /* not wide_chars */
#if OPT_USE_UTF8_API
	return
	    _ConvertSelectionHelper(w,
				    type, value, length, format,
				    XmbTextListToTextProperty,
				    XUTF8StringStyle);
#else
	return False;
#endif
    }

    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;
	return True;
    }

    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;
	return True;
    }

    if (XmuConvertStandardSelection(w, screen->selection_time, selection,
				    target, type, (XPointer *)value,
				    length, format))
	return True;

    /* else */
    return False;
}


static void
LoseSelection(Widget w, Atom *selection)
{
    register TScreen* screen;
    register 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;
	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(
	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(
	register XtermWidget termw,
	String *selections,
	Cardinal count)
{
    Atom* atoms = termw->screen.selection_atoms;
    Cardinal 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 {
		/* 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 = (Char *)termw->screen.selection_data;
		if_OPT_WIDE_CHARS((&(termw->screen)), {
		    data = UTF8toLatin1(data, length, &length);
		})
		XStoreBuffer( XtDisplay((Widget)termw),
			      (char *)data, 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(register XtermWidget termw)
{
    Atom* atoms = termw->screen.selection_atoms;
    Cardinal count = termw->screen.selection_count;
    Cardinal 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(
    register TScreen *screen GCC_UNUSED,
    register int row,
    register int scol,
    register int ecol)
{
	register 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,
    register 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) {
	    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) {
	    lp = convertToUTF8(lp, 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);
}

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(register XButtonEvent *event)
{
	TScreen *screen = &term->screen;
	int pty = screen->respond;
	Char line[6];
	int row, col;
	int button, 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);
}
	.file	"button.c"
	.version	"01.01"
gcc2_compiled.:
.data
	.align 4
	.type	 endRCol,@object
	.size	 endRCol,4
endRCol:
	.long 0
	.align 4
	.type	 endSCol,@object
	.size	 endSCol,4
endSCol:
	.long 0
	.align 4
	.type	 numberOfClicks,@object
	.size	 numberOfClicks,4
numberOfClicks:
	.long 0
	.align 4
	.type	 lastButtonUpTime,@object
	.size	 lastButtonUpTime,4
lastButtonUpTime:
	.long 0
.text
	.align 4
.globl SendMousePosition
	.type	 SendMousePosition,@function
SendMousePosition:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	movl 8(%ebp),%ecx
	movl 12(%ebp),%edx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%ecx)
	jne .L19
	addl $124,%ecx
	movzwl 492(%ecx),%eax
	testw %ax,%ax
	je .L19
	addw $-4,%ax
	cmpw $1,%ax
	jbe .L5
	movl (%edx),%eax
	cmpl $4,%eax
	je .L5
	cmpl $5,%eax
	jne .L19
.L5:
	movzwl 492(%ecx),%eax
	decl %eax
	cmpl $4,%eax
	ja .L19
	jmp *.L20(,%eax,4)
	.align 4
.section	.rodata
	.align 4
	.align 4
.L20:
	.long .L7
	.long .L16
	.long .L10
	.long .L16
	.long .L16
.text
	.align 4
.L7:
	testb $13,48(%edx)
	jne .L19
	cmpl $4,(%edx)
	jne .L24
	addl $-12,%esp
	pushl %edx
	call EditorButton
	jmp .L24
	.align 4
.L10:
	movl 48(%edx),%eax
	cmpl $4,(%edx)
	jne .L11
	testb $13,%al
	jne .L22
	cmpl $1,52(%edx)
	jne .L11
	addl $-12,%esp
	pushl %edx
	call TrackDown
.L24:
	movl $1,%eax
	jmp .L21
	.align 4
.L11:
	testb $13,%al
	je .L18
.L22:
	andl $13,%eax
	cmpl $4,%eax
	je .L18
	jmp .L19
	.align 4
.L16:
	movl 48(%edx),%eax
	andl $13,%eax
	je .L18
	cmpl $4,%eax
	jne .L17
.L18:
	addl $-12,%esp
	pushl %edx
	call EditorButton
	jmp .L24
	.align 4
.L17:
.L19:
	xorl %eax,%eax
.L21:
	leave
	ret
.Lfe1:
	.size	 SendMousePosition,.Lfe1-SendMousePosition
	.align 4
.globl DiredButton
	.type	 DiredButton,@function
DiredButton:
	pushl %ebp
	movl %esp,%ebp
	subl $44,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 12(%ebp),%ecx
	movl term,%eax
	movl %eax,-24(%ebp)
	movl %eax,%esi
	addl $124,%esi
	movl (%ecx),%eax
	addl $-4,%eax
	cmpl $1,%eax
	ja .L26
	movl 480(%esi),%ebx
	movl 36(%ecx),%edx
	subl %ebx,%edx
	movl %edx,-16(%ebp)
	movl 640(%esi),%edi
	movl %edi,-20(%ebp)
	movl %edx,%eax
	cltd
	idivl 24(%edi)
	movl %eax,-12(%ebp)
	movl 32(%ecx),%eax
	movl 20(%edi),%ecx
	movl -24(%ebp),%edi
	cmpb $0,1675(%edi)
	jne .L27
	movl -20(%ebp),%edx
	addl 36(%edx),%ebx
.L27:
	subl %ebx,%eax
	cltd
	idivl %ecx
	movb $24,-8(%ebp)
	movb $27,-7(%ebp)
	movb $71,-6(%ebp)
	addb $32,%al
	movb %al,-5(%ebp)
	movb -12(%ebp),%al
	addb $32,%al
	movb %al,-4(%ebp)
	addl $-4,%esp
	pushl $5
	leal -8(%ebp),%eax
	pushl %eax
	pushl 4(%esi)
	call v_write
.L26:
	leal -56(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe2:
	.size	 DiredButton,.Lfe2-DiredButton
	.align 4
.globl ViButton
	.type	 ViButton,@function
ViButton:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 12(%ebp),%ecx
	movl term,%ebx
	addl $124,%ebx
	movl 4(%ebx),%edi
	movl (%ecx),%eax
	addl $-4,%eax
	cmpl $1,%eax
	ja .L30
	movl 480(%ebx),%eax
	movl 36(%ecx),%ecx
	subl %eax,%ecx
	movl 640(%ebx),%esi
	movl %ecx,%eax
	cltd
	idivl 24(%esi)
	movl %eax,%esi
	movl 732(%ebx),%ebx
	subl %esi,%ebx
	movl %ebx,%esi
	testl %esi,%esi
	je .L30
	movb $27,-8(%ebp)
	addl $-4,%esp
	pushl $1
	leal -8(%ebp),%ebx
	pushl %ebx
	pushl %edi
	call v_write
	addl $16,%esp
	testl %esi,%esi
	jge .L32
	negl %esi
	movb $14,-8(%ebp)
	jmp .L33
	.align 4
.L32:
	movb $16,-8(%ebp)
.L33:
	decl %esi
	js .L30
	.align 4
.L36:
	addl $-4,%esp
	pushl $1
	pushl %ebx
	pushl %edi
	call v_write
	addl $16,%esp
	decl %esi
	jns .L36
.L30:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe3:
	.size	 ViButton,.Lfe3-ViButton
	.align 4
.globl HandleSelectExtend
	.type	 HandleSelectExtend,@function
HandleSelectExtend:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	pushl %ebx
	movl 8(%ebp),%ecx
	movl 12(%ebp),%ebx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%ecx)
	jne .L38
	leal 124(%ecx),%edx
	movl 28(%ebx),%eax
	movl %eax,1304(%edx)
	movl eventMode,%eax
	testl %eax,%eax
	je .L43
	cmpl $2,%eax
	ja .L38
	leal -4(%ebp),%eax
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	pushl 32(%ebx)
	pushl 36(%ebx)
	call PointToRowCol
	addl $-8,%esp
	pushl -4(%ebp)
	pushl -8(%ebp)
	call ExtendExtend
	jmp .L38
	.align 4
.L43:
	movzwl 492(%edx),%eax
	addw $-4,%ax
	cmpw $1,%ax
	ja .L38
	addl $-8,%esp
	pushl %ebx
	pushl %ecx
	call SendMousePosition
.L38:
	movl -24(%ebp),%ebx
	leave
	ret
.Lfe4:
	.size	 HandleSelectExtend,.Lfe4-HandleSelectExtend
	.align 4
	.type	 do_select_end,@function
do_select_end:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	movl 8(%ebp),%edx
	movl 12(%ebp),%ecx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%edx)
	jne .L47
	movl 28(%ecx),%eax
	movl %eax,1428(%edx)
	movl eventMode,%eax
	testl %eax,%eax
	jne .L50
	addl $-8,%esp
	pushl %ecx
	pushl %edx
	call SendMousePosition
	jmp .L47
	.align 4
.L50:
	cmpl $2,%eax
	ja .L47
	addl $-12,%esp
	pushl 24(%ebp)
	movl 20(%ebp),%eax
	pushl (%eax)
	pushl 16(%ebp)
	pushl %ecx
	pushl %edx
	call EndExtend
.L47:
	leave
	ret
.Lfe5:
	.size	 do_select_end,.Lfe5-do_select_end
	.align 4
.globl HandleSelectEnd
	.type	 HandleSelectEnd,@function
HandleSelectEnd:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	addl $-12,%esp
	pushl $0
	pushl 20(%ebp)
	pushl 16(%ebp)
	pushl 12(%ebp)
	pushl 8(%ebp)
	call do_select_end
	leave
	ret
.Lfe6:
	.size	 HandleSelectEnd,.Lfe6-HandleSelectEnd
	.align 4
.globl HandleKeyboardSelectEnd
	.type	 HandleKeyboardSelectEnd,@function
HandleKeyboardSelectEnd:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	addl $-12,%esp
	pushl $1
	pushl 20(%ebp)
	pushl 16(%ebp)
	pushl 12(%ebp)
	pushl 8(%ebp)
	call do_select_end
	leave
	ret
.Lfe7:
	.size	 HandleKeyboardSelectEnd,.Lfe7-HandleKeyboardSelectEnd
.data
	.align 4
	.type	 p.24,@object
	.size	 p.24,4
p.24:
	.long 0
.section	.rodata
.LC0:
	.string	"UTF8_STRING"
.text
	.align 4
	.type	 XA_UTF8_STRING,@function
XA_UTF8_STRING:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	cmpl $0,p.24
	jne .L58
	addl $-12,%esp
	pushl $.LC0
	call XmuMakeAtom
	movl %eax,p.24
	addl $16,%esp
.L58:
	addl $-8,%esp
	pushl p.24
	pushl 8(%ebp)
	call XmuInternAtom
	leave
	ret
.Lfe8:
	.size	 XA_UTF8_STRING,.Lfe8-XA_UTF8_STRING
.data
	.align 4
	.type	 eightBitSelectionTargets.28,@object
	.size	 eightBitSelectionTargets.28,4
eightBitSelectionTargets.28:
	.long 0
.text
	.align 4
	.type	 _SelectionTargets,@function
_SelectionTargets:
	pushl %ebp
	movl %esp,%ebp
	subl $16,%esp
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%ebx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%ebx)
	jne .L65
	leal 124(%ebx),%esi
	cmpl $0,eightBitSelectionTargets.28
	jne .L61
	addl $-12,%esp
	pushl $20
	call XtMalloc
	movl %eax,eightBitSelectionTargets.28
	addl $16,%esp
	testl %eax,%eax
	jne .L62
.L65:
	xorl %eax,%eax
	jmp .L64
	.align 4
.L62:
	xorl %edx,%edx
	cmpb $0,1288(%esi)
	je .L63
	addl $-8,%esp
	pushl _XA_TEXT
	movl 88(%ebx),%eax
	pushl 4(%eax)
	call XmuInternAtom
	movl %eax,%edx
	movl eightBitSelectionTargets.28,%eax
	movl %edx,(%eax)
	addl $-8,%esp
	pushl _XA_COMPOUND_TEXT
	movl 88(%ebx),%eax
	pushl 4(%eax)
	call XmuInternAtom
	movl %eax,%edx
	movl eightBitSelectionTargets.28,%eax
	movl %edx,4(%eax)
	movl $2,%edx
.L63:
	movl eightBitSelectionTargets.28,%eax
	movl $31,(%eax,%edx,4)
	movl $0,4(%eax,%edx,4)
.L61:
	movl eightBitSelectionTargets.28,%eax
.L64:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	leave
	ret
.Lfe9:
	.size	 _SelectionTargets,.Lfe9-_SelectionTargets
	.align 4
	.type	 _GetSelection,@function
_GetSelection:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 20(%ebp),%edi
	movl 24(%ebp),%esi
	movl xtermWidgetClass,%eax
	movl 8(%ebp),%edx
	cmpl %eax,4(%edx)
	jne .L66
	leal -4(%ebp),%ebx
	pushl %ebx
	pushl $1
	movl 16(%ebp),%eax
	pushl %eax
	movl 88(%edx),%eax
	pushl 4(%eax)
	call XmuInternStrings
	addl $16,%esp
	movl -4(%ebp),%eax
	addl $-9,%eax
	cmpl $7,%eax
	ja .L79
	jmp *.L78(,%eax,4)
	.align 4
.section	.rodata
	.align 4
	.align 4
.L78:
	.long .L69
	.long .L70
	.long .L71
	.long .L72
	.long .L73
	.long .L74
	.long .L75
	.long .L76
.text
	.align 4
.L69:
	xorl %eax,%eax
	jmp .L90
	.align 4
.L70:
	movl $1,%eax
	jmp .L90
	.align 4
.L71:
	movl $2,%eax
	jmp .L90
	.align 4
.L72:
	movl $3,%eax
	jmp .L90
	.align 4
.L73:
	movl $4,%eax
	jmp .L90
	.align 4
.L74:
	movl $5,%eax
	jmp .L90
	.align 4
.L75:
	movl $6,%eax
	jmp .L90
	.align 4
.L76:
	movl $7,%eax
.L90:
	movl $8,-12(%ebp)
	movl $31,-20(%ebp)
	addl $-4,%esp
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	movl 88(%edx),%eax
	pushl 4(%eax)
	call XFetchBuffer
	movl %eax,%edx
	movl -8(%ebp),%eax
	movl %eax,-16(%ebp)
	addl $16,%esp
	testl %eax,%eax
	je .L80
	addl $-4,%esp
	leal -12(%ebp),%eax
	pushl %eax
	leal -16(%ebp),%eax
	pushl %eax
	pushl %edx
	leal -20(%ebp),%eax
	pushl %eax
	pushl %ebx
	pushl $0
	movl 8(%ebp),%eax
	pushl %eax
	call SelectionReceived
	jmp .L66
	.align 4
.L80:
	cmpl $1,%edi
	jbe .L66
	addl $-12,%esp
	pushl $0
	leal -1(%edi),%eax
	pushl %eax
	movl 16(%ebp),%eax
	addl $4,%eax
	pushl %eax
	movl 12(%ebp),%edx
	pushl %edx
	movl 8(%ebp),%eax
	pushl %eax
	call _GetSelection
	jmp .L66
	.align 4
.L79:
	testl %esi,%esi
	je .L85
	cmpl $0,(%esi)
	jne .L84
.L85:
	addl $-12,%esp
	movl 8(%ebp),%edx
	pushl %edx
	call _SelectionTargets
	movl %eax,%esi
	addl $16,%esp
.L84:
	movl (%esi),%ebx
	cmpl $0,4(%esi)
	jne .L86
	addl $4,16(%ebp)
	decl %edi
	addl $-12,%esp
	movl 8(%ebp),%eax
	pushl %eax
	call _SelectionTargets
	movl %eax,%esi
	addl $16,%esp
	jmp .L87
	.align 4
.L86:
	addl $4,%esi
.L87:
	testl %edi,%edi
	je .L88
	addl $-12,%esp
	pushl $16
	call XtMalloc
	movl 16(%ebp),%edx
	movl %edx,(%eax)
	movl %edi,4(%eax)
	movl %esi,8(%eax)
	movl 12(%ebp),%edx
	movl %edx,12(%eax)
	addl $16,%esp
	jmp .L89
	.align 4
.L88:
	xorl %eax,%eax
.L89:
	addl $-8,%esp
	movl 12(%ebp),%edx
	pushl %edx
	pushl %eax
	pushl $SelectionReceived
	pushl %ebx
	pushl -4(%ebp)
	movl 8(%ebp),%eax
	pushl %eax
	call XtGetSelectionValue
.L66:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe10:
	.size	 _GetSelection,.Lfe10-_GetSelection
	.align 4
	.type	 _WriteSelectionData,@function
_WriteSelectionData:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%edi
	movl 12(%ebp),%eax
	movl %eax,%esi
	addl 16(%ebp),%esi
	movl %eax,%edx
	cmpl %esi,%edx
	je .L98
	.align 4
.L95:
	leal 1(%eax),%ebx
	cmpb $10,(%eax)
	jne .L94
	movb $13,(%eax)
	addl $-4,%esp
	subl %edx,%eax
	incl %eax
	pushl %eax
	pushl %edx
	pushl %edi
	call v_write
	movl %ebx,%edx
	addl $16,%esp
.L94:
	movl %ebx,%eax
	cmpl %esi,%eax
	jne .L95
	cmpl %esi,%edx
	je .L98
	addl $-4,%esp
	subl %edx,%esi
	pushl %esi
	pushl %edx
	pushl %edi
	call v_write
.L98:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe11:
	.size	 _WriteSelectionData,.Lfe11-_WriteSelectionData
	.align 4
	.type	 SelectionReceived,@function
SelectionReceived:
	pushl %ebp
	movl %esp,%ebp
	subl $44,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 20(%ebp),%esi
	movl $0,-24(%ebp)
	movl xtermWidgetClass,%eax
	movl 8(%ebp),%edx
	cmpl %eax,4(%edx)
	jne .L99
	addl $124,%edx
	movl %edx,-32(%ebp)
	movl 8(%ebp),%eax
	movl 88(%eax),%ebx
	movl 4(%ebx),%edi
	movl (%esi),%edx
	testl %edx,%edx
	je .L103
	movl 28(%ebp),%eax
	movl (%eax),%ecx
	testl %ecx,%ecx
	je .L103
	cmpl $0,24(%ebp)
	je .L103
	movl 24(%ebp),%eax
	movl %eax,-16(%ebp)
	movl %edx,-12(%ebp)
	movl 32(%ebp),%eax
	movl (%eax),%eax
	movl %eax,-8(%ebp)
	movl %ecx,-4(%ebp)
	addl $-8,%esp
	pushl _XA_COMPOUND_TEXT
	pushl 4(%ebx)
	call XmuInternAtom
	addl $16,%esp
	cmpl %eax,(%esi)
	jne .L104
	leal -20(%ebp),%eax
	pushl %eax
	leal -24(%ebp),%eax
	pushl %eax
	leal -16(%ebp),%eax
	pushl %eax
	pushl %edi
	call XmbTextPropertyToTextList
	addl $16,%esp
	testl %eax,%eax
	jge .L104
	movl $0,-24(%ebp)
.L104:
	cmpl $31,(%esi)
	jne .L106
	movl -32(%ebp),%edx
	cmpb $0,1288(%edx)
	je .L107
	leal -20(%ebp),%eax
	pushl %eax
	leal -24(%ebp),%eax
	pushl %eax
	leal -16(%ebp),%eax
	pushl %eax
	pushl %edi
	call XmbTextPropertyToTextList
	jmp .L121
	.align 4
.L107:
	addl $-4,%esp
	leal -20(%ebp),%eax
	pushl %eax
	leal -24(%ebp),%eax
	pushl %eax
	leal -16(%ebp),%eax
	pushl %eax
	call XTextPropertyToStringList
.L121:
	addl $16,%esp
	testl %eax,%eax
	jge .L106
	movl $0,-24(%ebp)
.L106:
	movl -24(%ebp),%eax
	testl %eax,%eax
	je .L103
	movl -20(%ebp),%edx
	testl %edx,%edx
	je .L103
	xorl %esi,%esi
	cmpl %edx,%esi
	jge .L112
	.align 4
.L114:
	movl -24(%ebp),%eax
	movl (%eax,%esi,4),%ebx
	movl %ebx,%edi
	movb $0,%al
	cld
	movl $-1,%ecx
	repnz
	scasb
	notl %ecx
	leal -1(%ecx),%edx
	movl %edx,-28(%ebp)
	xorl %eax,%eax
	testl %eax,%eax
	je .L115
	addl $-4,%esp
	leal -28(%ebp),%eax
	pushl %eax
	pushl %edx
	pushl %ebx
	call 0
	movl %eax,%ebx
	addl $16,%esp
	testl %ebx,%ebx
	je .L113
	addl $-4,%esp
	pushl -28(%ebp)
	pushl %ebx
	movl 8(%ebp),%edx
	pushl 128(%edx)
	call _WriteSelectionData
	addl $-12,%esp
	pushl %ebx
	call XtFree
	addl $32,%esp
	jmp .L113
	.align 4
.L115:
	addl $-4,%esp
	pushl %edx
	pushl %ebx
	movl 8(%ebp),%eax
	pushl 128(%eax)
	call _WriteSelectionData
	addl $16,%esp
.L113:
	incl %esi
	movl -24(%ebp),%eax
	cmpl -20(%ebp),%esi
	jl .L114
.L112:
	addl $-12,%esp
	pushl %eax
	call XFreeStringList
	addl $16,%esp
	addl $-12,%esp
	movl 12(%ebp),%edx
	pushl %edx
	call XtFree
	addl $-12,%esp
	movl 24(%ebp),%eax
	pushl %eax
	call XtFree
	jmp .L99
	.align 4
.L103:
	cmpl $0,12(%ebp)
	je .L99
	addl $-12,%esp
	movl 12(%ebp),%edx
	pushl 8(%edx)
	pushl 4(%edx)
	pushl (%edx)
	pushl 12(%edx)
	movl 8(%ebp),%eax
	pushl %eax
	call _GetSelection
	addl $32,%esp
	addl $-12,%esp
	movl 12(%ebp),%edx
	pushl %edx
	call XtFree
.L99:
	leal -56(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe12:
	.size	 SelectionReceived,.Lfe12-SelectionReceived
	.align 4
.globl HandleInsertSelection
	.type	 HandleInsertSelection,@function
HandleInsertSelection:
	pushl %ebp
	movl %esp,%ebp
	subl $16,%esp
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 12(%ebp),%ebx
	addl $-8,%esp
	pushl %ebx
	pushl %esi
	call SendMousePosition
	addl $16,%esp
	testb %al,%al
	jne .L122
	addl $-12,%esp
	pushl $0
	movl 20(%ebp),%eax
	pushl (%eax)
	pushl 16(%ebp)
	pushl 28(%ebx)
	pushl %esi
	call _GetSelection
.L122:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	leave
	ret
.Lfe13:
	.size	 HandleInsertSelection,.Lfe13-HandleInsertSelection
	.align 4
	.type	 EvalSelectUnit,@function
EvalSelectUnit:
	pushl %ebp
	movl %esp,%ebp
	movl 8(%ebp),%edx
	movl lastButtonUpTime,%eax
	testl %eax,%eax
	jne .L125
	movl term,%eax
	movl 1392(%eax),%edx
	incl %edx
	jmp .L126
	.align 4
.L125:
	cmpl %eax,%edx
	ja .L132
	decl %edx
.L132:
	subl %eax,%edx
	movl term,%eax
.L126:
	cmpl 1392(%eax),%edx
	jg .L129
	incl numberOfClicks
	movl selectUnit,%ecx
	incl %ecx
	movl $1431655766,%edx
	movl %edx,%eax
	imull %ecx
	movl %ecx,%eax
	sarl $31,%eax
	subl %eax,%edx
	leal (%edx,%edx,2),%eax
	subl %eax,%ecx
	movl %ecx,%eax
	jmp .L131
	.align 4
.L129:
	movl $1,numberOfClicks
	movl 12(%ebp),%eax
.L131:
	leave
	ret
.Lfe14:
	.size	 EvalSelectUnit,.Lfe14-EvalSelectUnit
	.align 4
	.type	 do_select_start,@function
do_select_start:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	pushl %ebx
	movl 12(%ebp),%ebx
	addl $-8,%esp
	pushl %ebx
	pushl 8(%ebp)
	call SendMousePosition
	addl $16,%esp
	testb %al,%al
	jne .L133
	addl $-8,%esp
	pushl $0
	pushl 28(%ebx)
	call EvalSelectUnit
	movl %eax,selectUnit
	movl $0,replyToEmacs
	addl $-8,%esp
	pushl 20(%ebp)
	pushl 16(%ebp)
	call StartSelect
.L133:
	movl -24(%ebp),%ebx
	leave
	ret
.Lfe15:
	.size	 do_select_start,.Lfe15-do_select_start
	.align 4
.globl HandleSelectStart
	.type	 HandleSelectStart,@function
HandleSelectStart:
	pushl %ebp
	movl %esp,%ebp
	subl $16,%esp
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 12(%ebp),%ebx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%esi)
	jne .L135
	movl $0,firstValidRow
	movl 864(%esi),%eax
	movl %eax,lastValidRow
	leal -4(%ebp),%eax
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	pushl 32(%ebx)
	pushl 36(%ebx)
	call PointToRowCol
	pushl -4(%ebp)
	pushl -8(%ebp)
	pushl %ebx
	pushl %esi
	call do_select_start
.L135:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	leave
	ret
.Lfe16:
	.size	 HandleSelectStart,.Lfe16-HandleSelectStart
	.align 4
.globl HandleKeyboardSelectStart
	.type	 HandleKeyboardSelectStart,@function
HandleKeyboardSelectStart:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	movl 8(%ebp),%edx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%edx)
	jne .L137
	leal 124(%edx),%eax
	pushl 720(%eax)
	pushl 724(%eax)
	pushl 12(%ebp)
	pushl %edx
	call do_select_start
.L137:
	leave
	ret
.Lfe17:
	.size	 HandleKeyboardSelectStart,.Lfe17-HandleKeyboardSelectStart
	.align 4
	.type	 TrackDown,@function
TrackDown:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	pushl %ebx
	movl 8(%ebp),%ebx
	addl $-8,%esp
	pushl $0
	pushl 28(%ebx)
	call EvalSelectUnit
	movl %eax,selectUnit
	addl $16,%esp
	cmpl $1,numberOfClicks
	jle .L140
	leal -4(%ebp),%eax
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	pushl 32(%ebx)
	pushl 36(%ebx)
	call PointToRowCol
	movl $1,replyToEmacs
	addl $-8,%esp
	pushl -4(%ebp)
	pushl -8(%ebp)
	call StartSelect
	jmp .L141
	.align 4
.L140:
	movl $1,waitingForTrackInfo
	addl $-12,%esp
	pushl %ebx
	call EditorButton
.L141:
	movl -24(%ebp),%ebx
	leave
	ret
.Lfe18:
	.size	 TrackDown,.Lfe18-TrackDown
	.align 4
.globl TrackMouse
	.type	 TrackMouse,@function
TrackMouse:
	pushl %ebp
	movl %esp,%ebp
	subl $16,%esp
	pushl %esi
	pushl %ebx
	movl 12(%ebp),%esi
	movl 20(%ebp),%edx
	movl 24(%ebp),%ecx
	movl term,%ebx
	addl $124,%ebx
	cmpl $0,waitingForTrackInfo
	je .L142
	movl $0,waitingForTrackInfo
	cmpl $0,8(%ebp)
	je .L142
	testl %esi,%esi
	jge .L145
	xorl %esi,%esi
	jmp .L146
	.align 4
.L145:
	movl 740(%ebx),%eax
	cmpl %eax,%esi
	jl .L146
	movl %eax,%esi
.L146:
	testl %edx,%edx
	jge .L148
	xorl %edx,%edx
	jmp .L149
	.align 4
.L148:
	movl 740(%ebx),%eax
	cmpl %eax,%edx
	jl .L149
	movl %eax,%edx
.L149:
	testl %ecx,%ecx
	jge .L151
	xorl %ecx,%ecx
	jmp .L152
	.align 4
.L151:
	movl 740(%ebx),%eax
	cmpl %eax,%ecx
	jl .L152
	movl %eax,%ecx
.L152:
	movl %edx,firstValidRow
	movl %ecx,lastValidRow
	movl $1,replyToEmacs
	addl $-8,%esp
	pushl 16(%ebp)
	pushl %esi
	call StartSelect
.L142:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	leave
	ret
.Lfe19:
	.size	 TrackMouse,.Lfe19-TrackMouse
	.align 4
	.type	 StartSelect,@function
StartSelect:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 12(%ebp),%edi
	movl term,%eax
	addl $124,%eax
	cmpl $0,696(%eax)
	je .L155
	call HideCursor
.L155:
	cmpl $1,numberOfClicks
	jne .L156
	movl %esi,rawRow
	movl %edi,rawCol
.L156:
	movl rawRow,%edx
	movl %edx,startERow
	movl %edx,saveStartRRow
	movl rawCol,%ecx
	movl %ecx,startECol
	movl %ecx,saveStartRCol
	movl %edx,endERow
	movl %edx,saveEndRRow
	movl %ecx,endECol
	movl %ecx,saveEndRCol
	movl term,%eax
	movl 860(%eax),%ebx
	incl %ebx
	movl %esi,%eax
	imull %ebx,%eax
	addl %edi,%eax
	imull %ebx,%edx
	addl %ecx,%edx
	cmpl %edx,%eax
	jge .L157
	movl $1,eventMode
	movl %esi,startERow
	movl %edi,startECol
	jmp .L158
	.align 4
.L157:
	movl $2,eventMode
	movl %esi,endERow
	movl %edi,endECol
.L158:
	addl $-12,%esp
	pushl $0
	pushl endECol
	pushl endERow
	pushl startECol
	pushl startERow
	call ComputeSelect
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe20:
	.size	 StartSelect,.Lfe20-StartSelect
	.align 4
	.type	 EndExtend,@function
EndExtend:
	pushl %ebp
	movl %esp,%ebp
	subl $32,%esp
	pushl %esi
	pushl %ebx
	movl 12(%ebp),%esi
	movl term,%ebx
	addl $124,%ebx
	cmpl $0,24(%ebp)
	je .L160
	movl 724(%ebx),%eax
	movl %eax,-20(%ebp)
	movl 720(%ebx),%eax
	movl %eax,-16(%ebp)
	jmp .L161
	.align 4
.L160:
	leal -16(%ebp),%eax
	pushl %eax
	leal -20(%ebp),%eax
	pushl %eax
	pushl 32(%esi)
	pushl 36(%esi)
	call PointToRowCol
	addl $16,%esp
.L161:
	addl $-8,%esp
	pushl -16(%ebp)
	pushl -20(%ebp)
	call ExtendExtend
	movl 28(%esi),%eax
	movl %eax,lastButtonUpTime
	movl endSRow,%eax
	addl $16,%esp
	cmpl %eax,startSRow
	jne .L163
	movl endSCol,%eax
	cmpl %eax,startSCol
	je .L162
.L163:
	cmpl $0,replyToEmacs
	je .L162
	cmpb $0,1346(%ebx)
	je .L165
	movb $155,-12(%ebp)
	movl $1,%edx
	jmp .L166
	.align 4
.L165:
	movb $27,-12(%ebp)
	movb $91,-11(%ebp)
	movl $2,%edx
.L166:
	movl startSRow,%eax
	cmpl %eax,rawRow
	jne .L167
	movl startSCol,%eax
	cmpl %eax,rawCol
	jne .L167
	movl endSRow,%eax
	cmpl %eax,-20(%ebp)
	jne .L167
	movl endSCol,%eax
	cmpl %eax,-16(%ebp)
	jne .L167
	leal -12(%ebp),%eax
	movb $116,(%edx,%eax)
	incl %edx
	movb endSCol,%cl
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	movb endSRow,%cl
	jmp .L169
	.align 4
.L167:
	leal -12(%ebp),%eax
	movb $84,(%edx,%eax)
	incl %edx
	movb startSCol,%cl
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	movb startSRow,%cl
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	movb endSCol,%cl
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	movb endSRow,%cl
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	movb -16(%ebp),%cl
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	movb -20(%ebp),%cl
.L169:
	addb $33,%cl
	movb %cl,(%edx,%eax)
	incl %edx
	addl $-4,%esp
	pushl %edx
	pushl %eax
	pushl 4(%ebx)
	call v_write
	pushl $0
	pushl $0
	pushl $0
	pushl $0
	call TrackText
	addl $32,%esp
.L162:
	pushl 20(%ebp)
	pushl 16(%ebp)
	pushl %esi
	pushl 8(%ebp)
	call SelectSet
	movl $0,eventMode
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	leave
	ret
.Lfe21:
	.size	 EndExtend,.Lfe21-EndExtend
	.align 4
.globl HandleSelectSet
	.type	 HandleSelectSet,@function
HandleSelectSet:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	movl 20(%ebp),%eax
	pushl (%eax)
	pushl 16(%ebp)
	pushl 12(%ebp)
	pushl 8(%ebp)
	call SelectSet
	leave
	ret
.Lfe22:
	.size	 HandleSelectSet,.Lfe22-HandleSelectSet
	.align 4
	.type	 SelectSet,@function
SelectSet:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	pushl %ebx
	movl startSRow,%ebx
	movl endSRow,%edx
	movl startSCol,%ecx
	movl endSCol,%eax
	cmpl %edx,%ebx
	jne .L173
	cmpl %eax,%ecx
	je .L172
.L173:
	addl $-8,%esp
	pushl 20(%ebp)
	pushl 16(%ebp)
	pushl %eax
	pushl %edx
	pushl %ecx
	pushl %ebx
	call SaltTextAway
	jmp .L174
	.align 4
.L172:
	addl $-12,%esp
	pushl term
	call DisownSelection
.L174:
	movl -24(%ebp),%ebx
	leave
	ret
.Lfe23:
	.size	 SelectSet,.Lfe23-SelectSet
	.align 4
	.type	 do_start_extend,@function
do_start_extend:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%edx
	movl 12(%ebp),%esi
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%edx)
	jne .L175
	leal 124(%edx),%ebx
	addl $-8,%esp
	pushl %esi
	pushl %edx
	call SendMousePosition
	addl $16,%esp
	testb %al,%al
	jne .L175
	movl $0,firstValidRow
	movl 740(%ebx),%eax
	movl %eax,lastValidRow
	addl $-8,%esp
	pushl selectUnit
	pushl 28(%esi)
	call EvalSelectUnit
	movl %eax,selectUnit
	movl $0,replyToEmacs
	addl $16,%esp
	cmpl $1,numberOfClicks
	jne .L178
	movl startRRow,%eax
	movl %eax,startERow
	movl %eax,saveStartRRow
	movl startRCol,%eax
	movl %eax,startECol
	movl %eax,saveStartRCol
	movl endRRow,%eax
	movl %eax,endERow
	movl %eax,saveEndRRow
	movl endRCol,%eax
	movl %eax,endECol
	movl %eax,saveEndRCol
	jmp .L179
	.align 4
.L178:
	movl saveStartRRow,%eax
	movl %eax,startRRow
	movl %eax,startERow
	movl saveStartRCol,%eax
	movl %eax,startRCol
	movl %eax,startECol
	movl saveEndRRow,%eax
	movl %eax,endRRow
	movl %eax,endERow
	movl saveEndRCol,%eax
	movl %eax,endRCol
	movl %eax,endECol
.L179:
	cmpl $0,24(%ebp)
	je .L180
	movl 724(%ebx),%eax
	movl %eax,-8(%ebp)
	movl 720(%ebx),%eax
	movl %eax,-4(%ebp)
	jmp .L181
	.align 4
.L180:
	leal -4(%ebp),%eax
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	pushl 32(%esi)
	pushl 36(%esi)
	call PointToRowCol
	addl $16,%esp
.L181:
	movl term,%eax
	movl 860(%eax),%ebx
	incl %ebx
	movl %ebx,%esi
	imull -8(%ebp),%esi
	addl -4(%ebp),%esi
	movl startSRow,%eax
	imull %ebx,%eax
	movl startSCol,%edx
	addl %edx,%eax
	movl %esi,%edi
	subl %eax,%edi
	movl term,%ecx
	movl %ecx,-12(%ebp)
	movl startSRow,%ecx
	movl %edx,-16(%ebp)
	jns .L184
	movl %eax,%edi
	subl %esi,%edi
.L184:
	movl endSRow,%eax
	imull %ebx,%eax
	addl endSCol,%eax
	movl %esi,%edx
	subl %eax,%edx
	js .L185
	cmpl %edx,%edi
	jl .L183
	jmp .L186
	.align 4
.L185:
	subl %esi,%eax
	cmpl %eax,%edi
	jl .L183
.L186:
	movl -12(%ebp),%edx
	movl 860(%edx),%eax
	incl %eax
	imull %ecx,%eax
	addl -16(%ebp),%eax
	cmpl %eax,%esi
	jge .L182
.L183:
	movl $1,eventMode
	movl -8(%ebp),%eax
	movl %eax,startERow
	movl -4(%ebp),%eax
	movl %eax,startECol
	jmp .L187
	.align 4
.L182:
	movl $2,eventMode
	movl -8(%ebp),%eax
	movl %eax,endERow
	movl -4(%ebp),%eax
	movl %eax,endECol
.L187:
	addl $-12,%esp
	pushl $1
	pushl endECol
	pushl endERow
	pushl startECol
	pushl startERow
	call ComputeSelect
.L175:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe24:
	.size	 do_start_extend,.Lfe24-do_start_extend
	.align 4
	.type	 ExtendExtend,@function
ExtendExtend:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 12(%ebp),%edi
	movl term,%edx
	movl 860(%edx),%ecx
	incl %ecx
	movl %esi,%eax
	imull %ecx,%eax
	leal (%edi,%eax),%ebx
	cmpl $1,eventMode
	jne .L189
	imull endSRow,%ecx
	addl endSCol,%ecx
	cmpl $0,selectUnit
	je .L190
	leal 1(%ebx),%eax
	cmpl %ecx,%eax
	jg .L191
	jmp .L189
	.align 4
.L190:
	cmpl %ecx,%ebx
	jle .L189
.L191:
	movl $2,eventMode
	movl saveStartRRow,%eax
	movl %eax,startERow
	movl saveStartRCol,%eax
	movl %eax,startECol
	jmp .L192
	.align 4
.L189:
	cmpl $2,eventMode
	jne .L192
	movl 860(%edx),%eax
	incl %eax
	imull startSRow,%eax
	addl startSCol,%eax
	cmpl %eax,%ebx
	jge .L192
	movl $1,eventMode
	movl saveEndRRow,%eax
	movl %eax,endERow
	movl saveEndRCol,%eax
	movl %eax,endECol
.L192:
	cmpl $1,eventMode
	jne .L194
	movl %esi,startERow
	movl %edi,startECol
	jmp .L195
	.align 4
.L194:
	movl %esi,endERow
	movl %edi,endECol
.L195:
	addl $-12,%esp
	pushl $0
	pushl endECol
	pushl endERow
	pushl startECol
	pushl startERow
	call ComputeSelect
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe25:
	.size	 ExtendExtend,.Lfe25-ExtendExtend
	.align 4
.globl HandleStartExtend
	.type	 HandleStartExtend,@function
HandleStartExtend:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	addl $-12,%esp
	pushl $0
	pushl 20(%ebp)
	pushl 16(%ebp)
	pushl 12(%ebp)
	pushl 8(%ebp)
	call do_start_extend
	leave
	ret
.Lfe26:
	.size	 HandleStartExtend,.Lfe26-HandleStartExtend
	.align 4
.globl HandleKeyboardStartExtend
	.type	 HandleKeyboardStartExtend,@function
HandleKeyboardStartExtend:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	addl $-12,%esp
	pushl $1
	pushl 20(%ebp)
	pushl 16(%ebp)
	pushl 12(%ebp)
	pushl 8(%ebp)
	call do_start_extend
	leave
	ret
.Lfe27:
	.size	 HandleKeyboardStartExtend,.Lfe27-HandleKeyboardStartExtend
	.align 4
.globl ScrollSelection
	.type	 ScrollSelection,@function
ScrollSelection:
	pushl %ebp
	movl %esp,%ebp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%ebx
	movl 12(%ebp),%edi
	movl 760(%ebx),%edx
	negl %edx
	movl 756(%ebx),%eax
	subl %eax,%edx
	movl 740(%ebx),%ecx
	subl %eax,%ecx
	movl 736(%ebx),%esi
	movl %edi,%eax
	addl startRRow,%eax
	movl %eax,startRRow
	cmpl %edx,%eax
	jge .L199
	movl %edx,startRRow
	movl $0,startRCol
.L199:
	cmpl %ecx,startRRow
	jle .L200
	movl %ecx,startRRow
	movl %esi,startRCol
.L200:
	movl %edi,%eax
	addl endRRow,%eax
	movl %eax,endRRow
	cmpl %edx,%eax
	jge .L201
	movl %edx,endRRow
	movl $0,endRCol
.L201:
	cmpl %ecx,endRRow
	jle .L202
	movl %ecx,endRRow
	movl %esi,endRCol
.L202:
	movl %edi,%eax
	addl startSRow,%eax
	movl %eax,startSRow
	cmpl %edx,%eax
	jge .L203
	movl %edx,startSRow
	movl $0,startSCol
.L203:
	cmpl %ecx,startSRow
	jle .L204
	movl %ecx,startSRow
	movl %esi,startSCol
.L204:
	movl %edi,%eax
	addl endSRow,%eax
	movl %eax,endSRow
	cmpl %edx,%eax
	jge .L205
	movl %edx,endSRow
	movl $0,endSCol
.L205:
	cmpl %ecx,endSRow
	jle .L206
	movl %ecx,endSRow
	movl %esi,endSCol
.L206:
	movl %edi,%eax
	addl rawRow,%eax
	movl %eax,rawRow
	cmpl %edx,%eax
	jge .L207
	movl %edx,rawRow
	movl $0,rawCol
.L207:
	cmpl %ecx,rawRow
	jle .L208
	movl %ecx,rawRow
	movl %esi,rawCol
.L208:
	movl %edi,%eax
	addl 1308(%ebx),%eax
	movl %eax,1308(%ebx)
	cmpl %edx,%eax
	jge .L209
	movl %edx,1308(%ebx)
	movl $0,1312(%ebx)
.L209:
	cmpl %ecx,1308(%ebx)
	jle .L210
	movl %ecx,1308(%ebx)
	movl %esi,1312(%ebx)
.L210:
	movl 1316(%ebx),%eax
	addl %edi,%eax
	movl %eax,1316(%ebx)
	cmpl %edx,%eax
	jge .L211
	movl %edx,1316(%ebx)
	movl $0,1320(%ebx)
.L211:
	cmpl %ecx,1316(%ebx)
	jle .L212
	movl %ecx,1316(%ebx)
	movl %esi,1320(%ebx)
.L212:
	movl term,%eax
	movl 860(%eax),%edx
	incl %edx
	imull 1308(%ebx),%edx
	addl 1312(%ebx),%edx
	movl %edx,1324(%ebx)
	movl 860(%eax),%eax
	incl %eax
	imull 1316(%ebx),%eax
	addl 1320(%ebx),%eax
	movl %eax,1328(%ebx)
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe28:
	.size	 ScrollSelection,.Lfe28-ScrollSelection
	.align 4
.globl ResizeSelection
	.type	 ResizeSelection,@function
ResizeSelection:
	pushl %ebp
	movl %esp,%ebp
	movl 12(%ebp),%eax
	decl %eax
	movl 16(%ebp),%edx
	decl %edx
	cmpl %eax,startRRow
	jle .L214
	movl %eax,startRRow
.L214:
	cmpl %eax,startSRow
	jle .L215
	movl %eax,startSRow
.L215:
	cmpl %eax,endRRow
	jle .L216
	movl %eax,endRRow
.L216:
	cmpl %eax,endSRow
	jle .L217
	movl %eax,endSRow
.L217:
	cmpl %eax,rawRow
	jle .L218
	movl %eax,rawRow
.L218:
	cmpl %edx,startRCol
	jle .L219
	movl %edx,startRCol
.L219:
	cmpl %edx,startSCol
	jle .L220
	movl %edx,startSCol
.L220:
	cmpl %edx,endRCol
	jle .L221
	movl %edx,endRCol
.L221:
	cmpl %edx,endSCol
	jle .L222
	movl %edx,endSCol
.L222:
	cmpl %edx,rawCol
	jle .L223
	movl %edx,rawCol
.L223:
	leave
	ret
.Lfe29:
	.size	 ResizeSelection,.Lfe29-ResizeSelection
	.align 4
	.type	 PointToRowCol,@function
PointToRowCol:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 12(%ebp),%ebx
	movl term,%esi
	addl $124,%esi
	movl 480(%esi),%eax
	movl 8(%ebp),%ecx
	subl %eax,%ecx
	movl 640(%esi),%edi
	movl %ecx,%eax
	cltd
	idivl 24(%edi)
	movl %eax,%edi
	movl firstValidRow,%eax
	movl term,%edx
	movl %edx,-4(%ebp)
	cmpl %eax,%edi
	jl .L233
	movl lastValidRow,%eax
	cmpl %eax,%edi
	jle .L226
.L233:
	movl %eax,%edi
.L226:
	movl 480(%esi),%eax
	movl 640(%esi),%edx
	movl %edx,-8(%ebp)
	movl 20(%edx),%ecx
	movl -4(%ebp),%edx
	cmpb $0,1675(%edx)
	jne .L228
	movl -8(%ebp),%edx
	addl 36(%edx),%eax
.L228:
	subl %eax,%ebx
	movl %ebx,%eax
	cltd
	idivl %ecx
	movl %eax,%ecx
	testl %ecx,%ecx
	jge .L230
	xorl %ecx,%ecx
	jmp .L231
	.align 4
.L230:
	movl 736(%esi),%eax
	incl %eax
	cmpl %eax,%ecx
	jle .L231
	movl %eax,%ecx
.L231:
	movl 16(%ebp),%eax
	movl %edi,(%eax)
	movl 20(%ebp),%eax
	movl %ecx,(%eax)
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe30:
	.size	 PointToRowCol,.Lfe30-PointToRowCol
	.align 4
	.type	 LastTextCol,@function
LastTextCol:
	pushl %ebp
	movl %esp,%ebp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl term,%edx
	leal 124(%edx),%ecx
	movl 756(%ecx),%esi
	addl 8(%ebp),%esi
	movl %esi,%eax
	addl 760(%ecx),%eax
	movl %edx,%edi
	js .L235
	movl 736(%ecx),%ebx
	movl %esi,%eax
	imull 1592(%edi),%eax
	movl 776(%ecx),%edx
	movl %ebx,%ecx
	addl 8(%edx,%eax,4),%ecx
	movl %edx,%eax
	testl %ebx,%ebx
	jl .L237
.L244:
	cmpb $0,(%ecx)
	jl .L237
	decl %ecx
	decl %ebx
	jns .L244
	.align 4
.L237:
	imull 1592(%edi),%esi
	movl 16(%eax,%esi,4),%eax
	movb (%eax),%al
	decb %al
	cmpb $2,%al
	ja .L243
	addl %ebx,%ebx
	jmp .L243
	.align 4
.L235:
	movl $-1,%ebx
.L243:
	movl %ebx,%eax
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe31:
	.size	 LastTextCol,.Lfe31-LastTextCol
.data
	.align 32
	.type	 charClass,@object
	.size	 charClass,1024
charClass:
	.long 32
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 32
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 32
	.long 33
	.long 34
	.long 35
	.long 36
	.long 37
	.long 38
	.long 39
	.long 40
	.long 41
	.long 42
	.long 43
	.long 44
	.long 45
	.long 46
	.long 47
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 58
	.long 59
	.long 60
	.long 61
	.long 62
	.long 63
	.long 64
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 91
	.long 92
	.long 93
	.long 94
	.long 48
	.long 96
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 123
	.long 124
	.long 125
	.long 126
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 1
	.long 160
	.long 161
	.long 162
	.long 163
	.long 164
	.long 165
	.long 166
	.long 167
	.long 168
	.long 169
	.long 170
	.long 171
	.long 172
	.long 173
	.long 174
	.long 175
	.long 176
	.long 177
	.long 178
	.long 179
	.long 180
	.long 181
	.long 182
	.long 183
	.long 184
	.long 185
	.long 186
	.long 187
	.long 188
	.long 189
	.long 190
	.long 191
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 216
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 248
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
	.long 48
.text
	.align 4
.globl SetCharacterClassRange
	.type	 SetCharacterClassRange,@function
SetCharacterClassRange:
	pushl %ebp
	movl %esp,%ebp
	pushl %ebx
	movl 8(%ebp),%eax
	movl 12(%ebp),%edx
	movl 16(%ebp),%ebx
	testl %eax,%eax
	jl .L247
	cmpl $255,%edx
	jg .L247
	cmpl %eax,%edx
	jge .L246
.L247:
	movl $-1,%eax
	jmp .L253
	.align 4
.L246:
	cmpl %edx,%eax
	jg .L249
	movl $charClass,%ecx
	.align 4
.L251:
	movl %ebx,(%ecx,%eax,4)
	incl %eax
	cmpl %edx,%eax
	jle .L251
.L249:
	xorl %eax,%eax
.L253:
	popl %ebx
	leave
	ret
.Lfe32:
	.size	 SetCharacterClassRange,.Lfe32-SetCharacterClassRange
	.align 4
	.type	 ComputeSelect,@function
ComputeSelect:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 16(%ebp),%ecx
	movl 20(%ebp),%ebx
	movl term,%eax
	leal 124(%eax),%esi
	movl 860(%eax),%edx
	incl %edx
	movl 8(%ebp),%eax
	imull %edx,%eax
	addl 12(%ebp),%eax
	imull %ecx,%edx
	addl %ebx,%edx
	cmpl %edx,%eax
	jg .L255
	movl 8(%ebp),%eax
	movl %eax,startRRow
	movl %eax,startSRow
	movl 12(%ebp),%edx
	movl %edx,startRCol
	movl %edx,startSCol
	movl %ecx,endRRow
	movl %ecx,endSRow
	movl %ebx,endRCol
	movl %ebx,endSCol
	jmp .L256
	.align 4
.L255:
	movl %ecx,startRRow
	movl %ecx,startSRow
	movl %ebx,startRCol
	movl %ebx,startSCol
	movl 8(%ebp),%ebx
	movl %ebx,endRRow
	movl %ebx,endSRow
	movl 12(%ebp),%eax
	movl %eax,endRCol
	movl %eax,endSCol
.L256:
	movl selectUnit,%eax
	cmpl $1,%eax
	je .L261
	jg .L305
	testl %eax,%eax
	je .L258
	jmp .L257
	.align 4
.L305:
	cmpl $2,%eax
	je .L281
	jmp .L257
	.align 4
.L258:
	addl $-12,%esp
	pushl startSRow
	call LastTextCol
	incl %eax
	addl $16,%esp
	cmpl %eax,startSCol
	jle .L259
	movl $0,startSCol
	incl startSRow
.L259:
	addl $-12,%esp
	pushl endSRow
	call LastTextCol
	incl %eax
	addl $16,%esp
	cmpl %eax,endSCol
	jle .L257
	jmp .L307
	.align 4
.L261:
	addl $-12,%esp
	pushl startSRow
	call LastTextCol
	incl %eax
	movl startSCol,%ecx
	addl $16,%esp
	cmpl %eax,%ecx
	jle .L262
	movl $0,startSCol
	incl startSRow
	jmp .L263
	.align 4
.L262:
	movl term,%edx
	movl 756(%esi),%eax
	addl startSRow,%eax
	imull 1592(%edx),%eax
	movl 776(%esi),%edx
	movl 4(%edx,%eax,4),%eax
	movzbl (%ecx,%eax),%edx
	movl $charClass,%eax
	movl (%eax,%edx,4),%edi
	jmp .L268
	.align 4
.L270:
	movl term,%edx
	movl 756(%esi),%eax
	addl startSRow,%eax
	imull 1592(%edx),%eax
	movl 776(%esi),%edx
	movl 4(%edx,%eax,4),%edx
	movl startSCol,%eax
	movzbl (%eax,%edx),%edx
	cmpl %edi,charClass(,%edx,4)
	jne .L265
.L268:
	decl startSCol
	jns .L270
	movl term,%eax
	movl 756(%esi),%edx
	decl %edx
	movl startSRow,%ecx
	addl %ecx,%edx
	imull 1592(%eax),%edx
	movl 776(%esi),%eax
	testb $1,(%eax,%edx,4)
	je .L266
	decl %ecx
	movl %ecx,startSRow
	addl $-12,%esp
	pushl startSRow
	call LastTextCol
	movl %eax,startSCol
	addl $16,%esp
.L266:
	movl startSCol,%eax
	testl %eax,%eax
	jge .L270
.L265:
	incl %eax
	movl %eax,startSCol
.L263:
	addl $-12,%esp
	pushl endSRow
	call LastTextCol
	incl %eax
	addl $16,%esp
	cmpl %eax,endSCol
	jg .L308
	addl $-12,%esp
	pushl endSRow
	call LastTextCol
	movl %eax,%ebx
	movl term,%edx
	movl 756(%esi),%eax
	addl endSRow,%eax
	imull 1592(%edx),%eax
	movl 776(%esi),%edx
	movl 4(%edx,%eax,4),%edx
	movl endSCol,%eax
	movzbl (%eax,%edx),%edx
	movl $charClass,%eax
	movl (%eax,%edx,4),%edi
	addl $16,%esp
	jmp .L277
	.align 4
.L279:
	movl term,%edx
	movl 756(%esi),%eax
	addl endSRow,%eax
	imull 1592(%edx),%eax
	movl 776(%esi),%edx
	movl 4(%edx,%eax,4),%edx
	movl endSCol,%eax
	movzbl (%eax,%edx),%eax
	cmpl %edi,charClass(,%eax,4)
	jne .L274
.L277:
	movl endSCol,%eax
	leal 1(%eax),%edx
	movl %edx,endSCol
	movl %edx,%eax
	cmpl %ebx,%eax
	jle .L279
	movl term,%eax
	movl endSRow,%ecx
	movl %ecx,%edx
	addl 756(%esi),%edx
	imull 1592(%eax),%edx
	movl 776(%esi),%eax
	testb $1,(%eax,%edx,4)
	je .L275
	movl $0,endSCol
	leal 1(%ecx),%ebx
	movl %ebx,endSRow
	addl $-12,%esp
	movl %ebx,%eax
	pushl %eax
	call LastTextCol
	movl %eax,%ebx
	addl $16,%esp
.L275:
	cmpl %ebx,endSCol
	jle .L279
.L274:
	leal 1(%ebx),%eax
	cmpl %eax,endSCol
	jle .L272
.L308:
	movl $0,endSCol
	incl endSRow
.L272:
	movl startSRow,%eax
	movl %eax,saveStartWRow
	movl startSCol,%eax
	movl %eax,saveStartWCol
	jmp .L257
	.align 4
.L281:
	movl term,%edx
	movl endSRow,%ecx
	movl 756(%esi),%edi
	leal (%edi,%ecx),%eax
	movl 1592(%edx),%edx
	imull %edx,%eax
	movl 776(%esi),%ebx
	testb $1,(%ebx,%eax,4)
	je .L283
	movl %edx,-4(%ebp)
	.align 4
.L284:
	leal 1(%ecx),%edx
	movl %edx,%ecx
	leal (%edi,%edx),%eax
	imull -4(%ebp),%eax
	testb $1,(%ebx,%eax,4)
	jne .L284
	movl %edx,endSRow
.L283:
	movl term,%ecx
	cmpb $0,1409(%ecx)
	jne .L287
	movl startSRow,%eax
	movl saveStartWRow,%edx
	cmpl %edx,%eax
	jge .L286
.L287:
	movl $0,startSCol
	movl 756(%esi),%edi
	decl %edi
	movl startSRow,%edx
	leal (%edi,%edx),%eax
	movl 1592(%ecx),%ebx
	imull %ebx,%eax
	movl 776(%esi),%ecx
	testb $1,(%ecx,%eax,4)
	je .L292
	movl %edi,%esi
	.align 4
.L290:
	decl %edx
	movl %edx,startSRow
	leal (%esi,%edx),%eax
	imull %ebx,%eax
	testb $1,(%ecx,%eax,4)
	jne .L290
	jmp .L292
	.align 4
.L286:
	cmpl $0,24(%ebp)
	jne .L292
	cmpl %edx,8(%ebp)
	jl .L295
	jne .L294
	movl 12(%ebp),%ebx
	cmpl saveStartWCol,%ebx
	jge .L294
.L295:
	movl $0,startSCol
	movl 756(%esi),%ebx
	decl %ebx
	addl %ebx,%eax
	movl 1592(%ecx),%ecx
	imull %ecx,%eax
	movl 776(%esi),%edx
	testb $1,(%edx,%eax,4)
	je .L292
	.align 4
.L298:
	decl startSRow
	movl %ebx,%eax
	addl startSRow,%eax
	imull %ecx,%eax
	testb $1,(%edx,%eax,4)
	jne .L298
	jmp .L292
	.align 4
.L294:
	movl %edx,startSRow
	movl saveStartWCol,%eax
	movl %eax,startSCol
.L292:
	movl term,%eax
	cmpb $0,1408(%eax)
	je .L301
.L307:
	movl $0,endSCol
	incl endSRow
	jmp .L257
	.align 4
.L301:
	addl $-12,%esp
	pushl endSRow
	call LastTextCol
	incl %eax
	movl %eax,endSCol
	addl $16,%esp
.L257:
	pushl endSCol
	pushl endSRow
	pushl startSCol
	pushl startSRow
	call TrackText
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe33:
	.size	 ComputeSelect,.Lfe33-ComputeSelect
	.align 4
.globl TrackText
	.type	 TrackText,@function
TrackText:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl term,%ebx
	addl $124,%ebx
	movl 1308(%ebx),%esi
	movl 1312(%ebx),%ecx
	movl 1316(%ebx),%eax
	movl %eax,-8(%ebp)
	movl 1320(%ebx),%edx
	movl %edx,-12(%ebp)
	cmpl %esi,8(%ebp)
	jne .L310
	cmpl %ecx,12(%ebp)
	jne .L310
	cmpl %eax,16(%ebp)
	jne .L310
	cmpl %edx,20(%ebp)
	je .L309
.L310:
	movl 8(%ebp),%eax
	movl %eax,1308(%ebx)
	movl 12(%ebp),%edx
	movl %edx,1312(%ebx)
	movl 16(%ebp),%eax
	movl %eax,1316(%ebx)
	movl 20(%ebp),%edx
	movl %edx,1320(%ebx)
	movl term,%eax
	movl 860(%eax),%edx
	incl %edx
	movl 8(%ebp),%eax
	imull %edx,%eax
	addl 12(%ebp),%eax
	movl %eax,-4(%ebp)
	imull 16(%ebp),%edx
	movl 20(%ebp),%eax
	leal (%eax,%edx),%edi
	movl 1324(%ebx),%eax
	cmpl %eax,%edi
	jle .L312
	movl -4(%ebp),%edx
	cmpl 1328(%ebx),%edx
	jle .L311
.L312:
	movl -12(%ebp),%eax
	pushl %eax
	movl -8(%ebp),%edx
	pushl %edx
	pushl %ecx
	pushl %esi
	call ReHiliteText
	movl 20(%ebp),%eax
	pushl %eax
	movl 16(%ebp),%edx
	pushl %edx
	movl 12(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	jmp .L320
	.align 4
.L311:
	cmpl %eax,-4(%ebp)
	jge .L314
	pushl %ecx
	pushl %esi
	movl 12(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	jmp .L321
	.align 4
.L314:
	cmpl %eax,-4(%ebp)
	jle .L315
	movl 12(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	pushl %ecx
	pushl %esi
.L321:
	call ReHiliteText
	addl $16,%esp
.L315:
	movl 1328(%ebx),%eax
	cmpl %eax,%edi
	jle .L317
	movl 20(%ebp),%eax
	pushl %eax
	movl 16(%ebp),%edx
	pushl %edx
	movl -12(%ebp),%eax
	pushl %eax
	movl -8(%ebp),%edx
.L320:
	pushl %edx
	call ReHiliteText
	jmp .L313
	.align 4
.L317:
	cmpl %eax,%edi
	jge .L313
	movl -12(%ebp),%eax
	pushl %eax
	movl -8(%ebp),%edx
	pushl %edx
	movl 20(%ebp),%eax
	pushl %eax
	movl 16(%ebp),%edx
	pushl %edx
	call ReHiliteText
.L313:
	movl -4(%ebp),%eax
	movl %eax,1324(%ebx)
	movl %edi,1328(%ebx)
.L309:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe34:
	.size	 TrackText,.Lfe34-TrackText
	.align 4
	.type	 ReHiliteText,@function
ReHiliteText:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 12(%ebp),%ecx
	movl 16(%ebp),%edi
	movl term,%ebx
	addl $124,%ebx
	testl %esi,%esi
	jge .L323
	xorl %ecx,%ecx
	xorl %esi,%esi
	jmp .L324
	.align 4
.L323:
	cmpl 740(%ebx),%esi
	jg .L322
.L324:
	testl %edi,%edi
	jl .L322
	movl 740(%ebx),%eax
	cmpl %eax,%edi
	jle .L327
	movl %eax,%edi
	movl 736(%ebx),%eax
	incl %eax
	movl %eax,20(%ebp)
.L327:
	cmpl %edi,%esi
	jne .L335
	cmpl 20(%ebp),%ecx
	je .L322
	jmp .L330
	.align 4
.L335:
	movl 736(%ebx),%eax
	subl %ecx,%eax
	leal 1(%eax),%edx
	testl %edx,%edx
	jle .L331
	addl $-8,%esp
	pushl $1
	pushl %edx
	pushl $1
	pushl %ecx
	pushl %esi
	pushl %ebx
	call ScrnRefresh
	addl $32,%esp
.L331:
	movl %edi,%eax
	subl %esi,%eax
	leal -1(%eax),%edx
	testl %edx,%edx
	jle .L332
	addl $-8,%esp
	pushl $1
	movl 736(%ebx),%eax
	incl %eax
	pushl %eax
	pushl %edx
	pushl $0
	leal 1(%esi),%eax
	pushl %eax
	pushl %ebx
	call ScrnRefresh
	addl $32,%esp
.L332:
	cmpl $0,20(%ebp)
	jle .L322
	cmpl 740(%ebx),%edi
	jg .L322
	addl $-8,%esp
	pushl $1
	movl 20(%ebp),%eax
	pushl %eax
	pushl $1
	pushl $0
	pushl %edi
	pushl %ebx
	call ScrnRefresh
	jmp .L322
	.align 4
.L330:
	addl $-8,%esp
	pushl $1
	subl %ecx,20(%ebp)
	movl 20(%ebp),%eax
	pushl %eax
	pushl $1
	pushl %ecx
	pushl %esi
	pushl %ebx
	call ScrnRefresh
.L322:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe35:
	.size	 ReHiliteText,.Lfe35-ReHiliteText
	.align 4
	.type	 SaltTextAway,@function
SaltTextAway:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl term,%esi
	addl $124,%esi
	movl 16(%ebp),%eax
	cmpl %eax,8(%ebp)
	jne .L337
	movl 20(%ebp),%edx
	cmpl %edx,12(%ebp)
	jle .L337
	movl 12(%ebp),%eax
	movl %edx,12(%ebp)
	movl %eax,20(%ebp)
.L337:
	decl 20(%ebp)
	movl 8(%ebp),%eax
	cmpl %eax,16(%ebp)
	jne .L338
	movl 20(%ebp),%edx
	pushl %edx
	movl 12(%ebp),%eax
	pushl %eax
	movl 16(%ebp),%edx
	pushl %edx
	pushl %esi
	call Length
	movl %eax,%edi
	jmp .L361
	.align 4
.L338:
	pushl 736(%esi)
	movl 12(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	pushl %esi
	call Length
	leal 1(%eax),%edi
	movl 8(%ebp),%ebx
	incl %ebx
	addl $16,%esp
	cmpl 16(%ebp),%ebx
	jge .L341
	.align 4
.L343:
	pushl 736(%esi)
	pushl $0
	pushl %ebx
	pushl %esi
	call Length
	leal 1(%eax,%edi),%edi
	addl $16,%esp
	incl %ebx
	cmpl 16(%ebp),%ebx
	jl .L343
.L341:
	cmpl $0,20(%ebp)
	jl .L339
	movl 20(%ebp),%eax
	pushl %eax
	pushl $0
	movl 16(%ebp),%edx
	pushl %edx
	pushl %esi
	call Length
	addl %eax,%edi
.L361:
	addl $16,%esp
.L339:
	cmpl %edi,1296(%esi)
	jg .L346
	addl $-12,%esp
	leal 1(%edi),%ebx
	pushl %ebx
	call malloc
	movl %eax,-8(%ebp)
	addl $16,%esp
	testl %eax,%eax
	jne .L347
	addl $-12,%esp
	pushl $71
	call SysError
	addl $16,%esp
.L347:
	addl $-12,%esp
	pushl 1292(%esi)
	call XtFree
	movl -8(%ebp),%eax
	movl %eax,1292(%esi)
	movl %ebx,1296(%esi)
	addl $16,%esp
	jmp .L348
	.align 4
.L346:
	movl 1292(%esi),%edx
	movl %edx,-8(%ebp)
.L348:
	cmpl $0,-8(%ebp)
	je .L336
	testl %edi,%edi
	jl .L336
	movl -8(%ebp),%eax
	movb $0,(%edi,%eax)
	movl 8(%ebp),%edx
	cmpl %edx,16(%ebp)
	jne .L351
	addl $-8,%esp
	leal -4(%ebp),%eax
	pushl %eax
	movl -8(%ebp),%eax
	pushl %eax
	movl 20(%ebp),%edx
	pushl %edx
	movl 12(%ebp),%eax
	pushl %eax
	movl 16(%ebp),%edx
	pushl %edx
	jmp .L362
	.align 4
.L351:
	addl $-8,%esp
	leal -4(%ebp),%ebx
	pushl %ebx
	movl -8(%ebp),%eax
	pushl %eax
	pushl 736(%esi)
	movl 12(%ebp),%edx
	pushl %edx
	movl 8(%ebp),%eax
	pushl %eax
	pushl %esi
	call SaveText
	addl $32,%esp
	movl %ebx,%edi
	cmpl $0,-4(%ebp)
	je .L353
	movb $10,(%eax)
	incl %eax
.L353:
	movl 8(%ebp),%ebx
	jmp .L356
	.align 4
.L357:
	addl $-8,%esp
	pushl %edi
	pushl %eax
	pushl 736(%esi)
	pushl $0
	pushl %ebx
	pushl %esi
	call SaveText
	addl $32,%esp
	cmpl $0,-4(%ebp)
	je .L356
	movb $10,(%eax)
	incl %eax
.L356:
	incl %ebx
	cmpl 16(%ebp),%ebx
	jl .L357
	cmpl $0,20(%ebp)
	jl .L352
	addl $-8,%esp
	pushl %edi
	pushl %eax
	movl 20(%ebp),%edx
	pushl %edx
	pushl $0
	movl 16(%ebp),%eax
	pushl %eax
.L362:
	pushl %esi
	call SaveText
	addl $32,%esp
.L352:
	movb $0,(%eax)
	subl -8(%ebp),%eax
	movl %eax,1300(%esi)
	addl $-4,%esp
	pushl 28(%ebp)
	pushl 24(%ebp)
	pushl term
	call _OwnSelection
.L336:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe36:
	.size	 SaltTextAway,.Lfe36-SaltTextAway
	.align 4
	.type	 _ConvertSelectionHelper,@function
_ConvertSelectionHelper:
	pushl %ebp
	movl %esp,%ebp
	subl $32,%esp
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%edx
	movl 16(%ebp),%ebx
	movl 28(%ebp),%esi
	movl 88(%edx),%eax
	movl 4(%eax),%ecx
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%edx)
	jne .L365
	movl 1416(%edx),%eax
	movl %eax,(%ebx)
	addl $-12,%esp
	leal -16(%ebp),%eax
	pushl %eax
	pushl 32(%ebp)
	pushl $1
	pushl %ebx
	pushl %ecx
	call *%esi
	testl %eax,%eax
	jl .L365
	movl -16(%ebp),%eax
	movl %eax,(%ebx)
	movl -4(%ebp),%edx
	movl 20(%ebp),%eax
	movl %edx,(%eax)
	movl -12(%ebp),%edx
	movl 12(%ebp),%eax
	movl %edx,(%eax)
	movl 24(%ebp),%eax
	movl $8,(%eax)
	movl $1,%eax
	jmp .L366
	.align 4
.L365:
	xorl %eax,%eax
.L366:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	leave
	ret
.Lfe37:
	.size	 _ConvertSelectionHelper,.Lfe37-_ConvertSelectionHelper
	.align 4
	.type	 ConvertSelection,@function
ConvertSelection:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 16(%ebp),%edi
	movl 8(%ebp),%edx
	movl 88(%edx),%eax
	movl 4(%eax),%esi
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%edx)
	jne .L383
	movl 8(%ebp),%ebx
	addl $124,%ebx
	cmpl $0,1292(%ebx)
	je .L383
	addl $-8,%esp
	pushl _XA_TARGETS
	pushl %esi
	call XmuInternAtom
	movl (%edi),%edx
	addl $16,%esp
	cmpl %eax,%edx
	jne .L370
	movl 32(%ebp),%eax
	pushl %eax
	leal -4(%ebp),%eax
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	movl 20(%ebp),%edx
	pushl %edx
	pushl %edi
	movl 12(%ebp),%eax
	pushl %eax
	pushl 1304(%ebx)
	movl 8(%ebp),%edx
	pushl %edx
	call XmuConvertStandardSelection
	movl -4(%ebp),%eax
	addl $6,%eax
	movl 28(%ebp),%edx
	movl %eax,(%edx)
	addl $32,%esp
	addl $-12,%esp
	sall $2,%eax
	pushl %eax
	call XtMalloc
	movl %eax,%ebx
	movl 24(%ebp),%eax
	movl %ebx,(%eax)
	movl $31,(%ebx)
	addl $4,%ebx
	addl $-8,%esp
	pushl _XA_TEXT
	pushl %esi
	call XmuInternAtom
	movl %eax,(%ebx)
	addl $4,%ebx
	addl $32,%esp
	addl $-8,%esp
	pushl _XA_COMPOUND_TEXT
	pushl %esi
	call XmuInternAtom
	movl %eax,(%ebx)
	addl $4,%ebx
	addl $-8,%esp
	pushl _XA_LENGTH
	pushl %esi
	call XmuInternAtom
	movl %eax,(%ebx)
	addl $4,%ebx
	addl $32,%esp
	addl $-8,%esp
	pushl _XA_LIST_LENGTH
	pushl %esi
	call XmuInternAtom
	movl %eax,(%ebx)
	addl $4,%ebx
	movl -4(%ebp),%eax
	sall $2,%eax
	addl $-4,%esp
	pushl %eax
	pushl -8(%ebp)
	pushl %ebx
	call memcpy
	addl $32,%esp
	addl $-12,%esp
	pushl -8(%ebp)
	call XtFree
	movl 20(%ebp),%edx
	movl $4,(%edx)
.L385:
	movl 32(%ebp),%eax
	movl $32,(%eax)
	jmp .L381
	.align 4
.L370:
	cmpl $31,%edx
	jne .L371
	movl 20(%ebp),%edx
	movl $31,(%edx)
	movl 1292(%ebx),%eax
	movl 24(%ebp),%edx
	movl %eax,(%edx)
	movl 1300(%ebx),%eax
	movl 28(%ebp),%edx
	movl %eax,(%edx)
	movl 32(%ebp),%eax
	movl $8,(%eax)
	jmp .L381
	.align 4
.L371:
	addl $-8,%esp
	pushl _XA_TEXT
	pushl %esi
	call XmuInternAtom
	addl $16,%esp
	cmpl %eax,(%edi)
	jne .L372
	addl $-4,%esp
	pushl $3
	pushl $XmbTextListToTextProperty
	movl 32(%ebp),%edx
	pushl %edx
	movl 28(%ebp),%eax
	pushl %eax
	movl 24(%ebp),%edx
	pushl %edx
	movl 20(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	jmp .L384
	.align 4
.L372:
	addl $-8,%esp
	pushl _XA_COMPOUND_TEXT
	pushl %esi
	call XmuInternAtom
	addl $16,%esp
	cmpl %eax,(%edi)
	jne .L373
	addl $-4,%esp
	pushl $1
	pushl $XmbTextListToTextProperty
	movl 32(%ebp),%eax
	pushl %eax
	movl 28(%ebp),%edx
	pushl %edx
	movl 24(%ebp),%eax
	pushl %eax
	movl 20(%ebp),%edx
	pushl %edx
	movl 8(%ebp),%eax
	pushl %eax
.L384:
	call _ConvertSelectionHelper
	movsbl %al,%eax
	jmp .L382
	.align 4
.L373:
	addl $-12,%esp
	pushl %esi
	call XA_UTF8_STRING
	addl $16,%esp
	cmpl %eax,(%edi)
	je .L383
	addl $-8,%esp
	pushl _XA_LIST_LENGTH
	pushl %esi
	call XmuInternAtom
	addl $16,%esp
	cmpl %eax,(%edi)
	jne .L375
	addl $-12,%esp
	pushl $4
	call XtMalloc
	movl 24(%ebp),%edx
	movl %eax,(%edx)
	movl $1,(%eax)
	movl 20(%ebp),%eax
	movl $19,(%eax)
	movl 28(%ebp),%edx
	movl $1,(%edx)
	jmp .L385
	.align 4
.L375:
	addl $-8,%esp
	pushl _XA_LENGTH
	pushl %esi
	call XmuInternAtom
	addl $16,%esp
	cmpl %eax,(%edi)
	jne .L378
	addl $-12,%esp
	pushl $4
	call XtMalloc
	movl %eax,%edx
	movl 24(%ebp),%eax
	movl %edx,(%eax)
	movl 1300(%ebx),%eax
	movl %eax,(%edx)
	movl 20(%ebp),%edx
	movl $19,(%edx)
	movl 28(%ebp),%eax
	movl $1,(%eax)
	movl 32(%ebp),%edx
	movl $32,(%edx)
	jmp .L381
	.align 4
.L378:
	movl 32(%ebp),%eax
	pushl %eax
	movl 28(%ebp),%edx
	pushl %edx
	movl 24(%ebp),%eax
	pushl %eax
	movl 20(%ebp),%edx
	pushl %edx
	pushl %edi
	movl 12(%ebp),%eax
	pushl %eax
	pushl 1304(%ebx)
	movl 8(%ebp),%edx
	pushl %edx
	call XmuConvertStandardSelection
	testb %al,%al
	jne .L381
.L383:
	xorl %eax,%eax
	jmp .L382
	.align 4
.L381:
	movl $1,%eax
.L382:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe38:
	.size	 ConvertSelection,.Lfe38-ConvertSelection
	.align 4
	.type	 LoseSelection,@function
LoseSelection:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%edx
	movl 12(%ebp),%edi
	movl xtermWidgetClass,%eax
	cmpl %eax,4(%edx)
	jne .L386
	leal 124(%edx),%ebx
	xorl %esi,%esi
	movl 1332(%ebx),%ecx
	cmpl 1340(%ebx),%esi
	jae .L389
	.align 4
.L391:
	movl (%ecx),%eax
	cmpl %eax,(%edi)
	jne .L392
	movl $0,(%ecx)
.L392:
	movl (%ecx),%eax
	cmpl $16,%eax
	ja .L390
	cmpl $9,%eax
	jb .L390
	movl $0,(%ecx)
.L390:
	incl %esi
	addl $4,%ecx
	cmpl 1340(%ebx),%esi
	jb .L391
.L389:
	movl 1340(%ebx),%esi
	testl %esi,%esi
	je .L406
	movl 1332(%ebx),%eax
	cmpl $0,-4(%eax,%esi,4)
	jne .L406
	.align 4
.L407:
	decl %esi
	jz .L406
	cmpl $0,-4(%eax,%esi,4)
	je .L407
.L406:
	movl %esi,1340(%ebx)
	xorl %esi,%esi
	movl 1332(%ebx),%ecx
	jmp .L418
	.align 4
.L414:
	cmpl $0,(%ecx)
	jne .L413
	leal -1(%edx),%eax
	movl %eax,1340(%ebx)
	movl 1332(%ebx),%eax
	movl -4(%eax,%edx,4),%eax
	movl %eax,(%ecx)
.L413:
	incl %esi
	addl $4,%ecx
.L418:
	movl 1340(%ebx),%edx
	cmpl %edx,%esi
	jb .L414
	cmpl $0,1340(%ebx)
	jne .L386
	pushl $0
	pushl $0
	pushl $0
	pushl $0
	call TrackText
.L386:
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe39:
	.size	 LoseSelection,.Lfe39-LoseSelection
	.align 4
	.type	 SelectionDone,@function
SelectionDone:
	pushl %ebp
	movl %esp,%ebp
	leave
	ret
.Lfe40:
	.size	 SelectionDone,.Lfe40-SelectionDone
.section	.rodata
	.align 32
.LC1:
	.string	"%s: selection too big (%d bytes), not storing in CUT_BUFFER%d\n"
.text
	.align 4
	.type	 _OwnSelection,@function
_OwnSelection:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 1456(%esi),%eax
	movl %eax,-4(%ebp)
	movb $0,-5(%ebp)
	cmpl $0,1424(%esi)
	jl .L420
	movl 16(%ebp),%edx
	cmpl 1460(%esi),%edx
	jbe .L422
	addl $-12,%esp
	pushl %eax
	call XtFree
	addl $-12,%esp
	movl 16(%ebp),%eax
	sall $2,%eax
	pushl %eax
	call XtMalloc
	movl %eax,-4(%ebp)
	movl %eax,1456(%esi)
	movl 16(%ebp),%eax
	movl %eax,1460(%esi)
	addl $32,%esp
.L422:
	movl -4(%ebp),%edx
	pushl %edx
	movl 16(%ebp),%eax
	pushl %eax
	pushl 12(%ebp)
	movl 88(%esi),%eax
	pushl 4(%eax)
	call XmuInternStrings
	xorl %edi,%edi
	addl $16,%esp
	cmpl 16(%ebp),%edi
	jae .L424
	.align 4
.L426:
	movl -4(%ebp),%edx
	movl (%edx,%edi,4),%eax
	leal -9(%eax),%edx
	cmpl $7,%edx
	ja .L438
	jmp *.L437(,%edx,4)
	.align 4
.section	.rodata
	.align 4
	.align 4
.L437:
	.long .L428
	.long .L429
	.long .L430
	.long .L431
	.long .L432
	.long .L433
	.long .L434
	.long .L435
.text
	.align 4
.L428:
	xorl %ebx,%ebx
	jmp .L446
	.align 4
.L429:
	movl $1,%ebx
	jmp .L446
	.align 4
.L430:
	movl $2,%ebx
	jmp .L446
	.align 4
.L431:
	movl $3,%ebx
	jmp .L446
	.align 4
.L432:
	movl $4,%ebx
	jmp .L446
	.align 4
.L433:
	movl $5,%ebx
	jmp .L446
	.align 4
.L434:
	movl $6,%ebx
	jmp .L446
	.align 4
.L435:
	movl $7,%ebx
.L446:
	addl $-12,%esp
	movl 88(%esi),%eax
	pushl 4(%eax)
	call XMaxRequestSize
	leal -32(,%eax,4),%eax
	movl 1424(%esi),%edx
	addl $16,%esp
	cmpl %eax,%edx
	jle .L439
	addl $-12,%esp
	pushl %ebx
	pushl %edx
	pushl xterm_name
	pushl $.LC1
	pushl $__iob+32
	call fprintf
	jmp .L447
	.align 4
.L439:
	pushl %ebx
	pushl %edx
	pushl 1416(%esi)
	movl 88(%esi),%eax
	pushl 4(%eax)
	call XStoreBuffer
	addl $16,%esp
	jmp .L425
	.align 4
.L438:
	cmpl $0,replyToEmacs
	jne .L425
	addl $-8,%esp
	pushl $SelectionDone
	pushl $LoseSelection
	pushl $ConvertSelection
	pushl 1428(%esi)
	pushl %eax
	pushl %esi
	call XtOwnSelection
	orb %al,-5(%ebp)
.L447:
	addl $32,%esp
.L425:
	incl %edi
	cmpl 16(%ebp),%edi
	jb .L426
.L424:
	cmpl $0,replyToEmacs
	jne .L444
	movl 16(%ebp),%eax
	movl %eax,1464(%esi)
.L444:
	cmpb $0,-5(%ebp)
	jne .L420
	pushl $0
	pushl $0
	pushl $0
	pushl $0
	call TrackText
.L420:
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe41:
	.size	 _OwnSelection,.Lfe41-_OwnSelection
	.align 4
.globl DisownSelection
	.type	 DisownSelection,@function
DisownSelection:
	pushl %ebp
	movl %esp,%ebp
	subl $12,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 8(%ebp),%esi
	movl 1456(%esi),%eax
	movl %eax,-4(%ebp)
	movl 1464(%esi),%edi
	xorl %ebx,%ebx
	cmpl %edi,%ebx
	jae .L450
	.align 4
.L452:
	movl -4(%ebp),%eax
	movl (%eax,%ebx,4),%edx
	leal -9(%edx),%eax
	cmpl $7,%eax
	jbe .L451
	addl $-4,%esp
	pushl 1428(%esi)
	pushl %edx
	pushl %esi
	call XtDisownSelection
	addl $16,%esp
.L451:
	incl %ebx
	cmpl %edi,%ebx
	jb .L452
.L450:
	movl $0,1464(%esi)
	movl $0,1436(%esi)
	movl $0,1432(%esi)
	movl $0,1444(%esi)
	movl $0,1440(%esi)
	leal -24(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe42:
	.size	 DisownSelection,.Lfe42-DisownSelection
	.align 4
	.type	 Length,@function
Length:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	pushl %ebx
	movl 20(%ebp),%ebx
	addl $-12,%esp
	pushl 12(%ebp)
	call LastTextCol
	cmpl %eax,%ebx
	jle .L467
	movl %eax,%ebx
.L467:
	subl 16(%ebp),%ebx
	leal 1(%ebx),%eax
	movl -24(%ebp),%ebx
	leave
	ret
.Lfe43:
	.size	 Length,.Lfe43-Length
	.align 4
	.type	 SaveText,@function
SaveText:
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 16(%ebp),%ebx
	movl 24(%ebp),%esi
	movl %esi,-4(%ebp)
	pushl 20(%ebp)
	pushl %ebx
	movl 12(%ebp),%eax
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	call Length
	movl %eax,%ecx
	leal (%ecx,%ebx),%edi
	movl term,%eax
	movl 12(%ebp),%ecx
	movl 8(%ebp),%edx
	addl 756(%edx),%ecx
	imull 1592(%eax),%ecx
	movl 776(%edx),%eax
	movl %eax,-8(%ebp)
	movl 16(%eax,%ecx,4),%eax
	movb (%eax),%al
	decb %al
	cmpb $2,%al
	ja .L469
	movl %ebx,%eax
	shrl $31,%eax
	addl %eax,%ebx
	sarl $1,%ebx
	leal 1(%edi),%edx
	movl %edx,%eax
	shrl $31,%eax
	leal (%eax,%edx),%edi
	sarl $1,%edi
.L469:
	movl -8(%ebp),%edx
	movl (%edx,%ecx,4),%eax
	xorb $1,%al
	andl $1,%eax
	movl 28(%ebp),%edx
	movl %eax,(%edx)
	movl %ebx,%ecx
	cmpl %edi,%ecx
	jge .L471
	.align 4
.L473:
	movl term,%edx
	movl 12(%ebp),%eax
	movl 8(%ebp),%ebx
	addl 756(%ebx),%eax
	imull 1592(%edx),%eax
	movl 776(%ebx),%edx
	movl 4(%edx,%eax,4),%eax
	movzbl (%ecx,%eax),%eax
	testl %eax,%eax
	jne .L474
	movl $32,%eax
	jmp .L475
	.align 4
.L474:
	cmpl $31,%eax
	ja .L476
	cmpl $30,%eax
	jne .L477
	movl $35,%eax
	jmp .L475
	.align 4
.L477:
	addl $95,%eax
	jmp .L475
	.align 4
.L476:
	cmpl $127,%eax
	jne .L475
	movl $95,%eax
.L475:
	movb %al,(%esi)
	incl %esi
	cmpl $32,%eax
	je .L472
	movl %esi,-4(%ebp)
.L472:
	incl %ecx
	cmpl %edi,%ecx
	jl .L473
.L471:
	movl 28(%ebp),%eax
	cmpl $0,(%eax)
	je .L484
	movl 8(%ebp),%edx
	cmpb $0,1287(%edx)
	jne .L483
.L484:
	movl %esi,-4(%ebp)
.L483:
	movl -4(%ebp),%eax
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe44:
	.size	 SaveText,.Lfe44-SaveText
	.align 4
	.type	 BtnCode,@function
BtnCode:
	pushl %ebp
	movl %esp,%ebp
	pushl %ebx
	movl 8(%ebp),%ebx
	movl 12(%ebp),%ecx
	movl 48(%ebx),%eax
	movl %eax,%edx
	andl $5,%edx
	testb $8,%al
	je .L486
	leal 2(%edx),%eax
	leal 32(,%eax,4),%eax
	jmp .L487
	.align 4
.L486:
	leal 0(,%edx,4),%eax
	addl $32,%eax
.L487:
	cmpl $5,%ecx
	jbe .L488
	addl $3,%eax
	jmp .L489
	.align 4
.L488:
	cmpl $3,%ecx
	jle .L490
	addl $60,%eax
.L490:
	cmpl $6,(%ebx)
	jne .L491
	addl $32,%eax
.L491:
	addl %ecx,%eax
.L489:
	popl %ebx
	leave
	ret
.Lfe45:
	.size	 BtnCode,.Lfe45-BtnCode
	.align 4
	.type	 EditorButton,@function
EditorButton:
	pushl %ebp
	movl %esp,%ebp
	subl $44,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl term,%eax
	movl %eax,-12(%ebp)
	movl %eax,%edi
	addl $124,%edi
	movl 4(%edi),%edx
	movl %edx,-16(%ebp)
	movl 8(%ebp),%esi
	movl 52(%esi),%eax
	leal -1(%eax),%edx
	movl %edx,-28(%ebp)
	cmpl $2,%edx
	jle .L493
	movl %eax,-28(%ebp)
.L493:
	movl 480(%edi),%ebx
	movl 8(%ebp),%esi
	movl 36(%esi),%ecx
	subl %ebx,%ecx
	movl 640(%edi),%eax
	movl %eax,-32(%ebp)
	movl %ecx,%eax
	movl -32(%ebp),%esi
	cltd
	idivl 24(%esi)
	movl %eax,-36(%ebp)
	movl %eax,-20(%ebp)
	movl 8(%ebp),%edx
	movl 32(%edx),%eax
	movl 20(%esi),%ecx
	movl -12(%ebp),%esi
	cmpb $0,1675(%esi)
	jne .L494
	movl -32(%ebp),%edx
	addl 36(%edx),%ebx
.L494:
	subl %ebx,%eax
	cltd
	idivl %ecx
	movl %eax,-24(%ebp)
	cmpl $0,-36(%ebp)
	jge .L496
	movl $0,-20(%ebp)
	jmp .L497
	.align 4
.L496:
	movl 740(%edi),%eax
	cmpl %eax,-36(%ebp)
	jle .L498
	movl %eax,-20(%ebp)
	jmp .L497
	.align 4
.L498:
	cmpl $223,-36(%ebp)
	jle .L497
	movl $223,-20(%ebp)
.L497:
	cmpl $0,-24(%ebp)
	jge .L501
	movl $0,-24(%ebp)
	jmp .L502
	.align 4
.L501:
	movl 736(%edi),%eax
	cmpl %eax,-24(%ebp)
	jle .L503
	movl %eax,-24(%ebp)
	jmp .L502
	.align 4
.L503:
	cmpl $223,-24(%ebp)
	jle .L502
	movl $223,-24(%ebp)
.L502:
	cmpb $0,1346(%edi)
	je .L506
	movb $155,-8(%ebp)
	movl $1,%ebx
	jmp .L519
	.align 4
.L506:
	movb $27,-8(%ebp)
	movb $91,-7(%ebp)
	movl $2,%ebx
.L519:
	leal -8(%ebp),%esi
	movb $77,(%ebx,%esi)
	incl %ebx
	cmpw $1,492(%edi)
	jne .L508
	movb -28(%ebp),%al
	addb $32,%al
	movb %al,(%ebx,%esi)
	incl %ebx
	jmp .L509
	.align 4
.L508:
	movl 8(%ebp),%edx
	movl (%edx),%eax
	cmpl $5,%eax
	je .L512
	jg .L518
	cmpl $4,%eax
	je .L511
	jmp .L492
	.align 4
.L518:
	cmpl $6,%eax
	je .L514
	jmp .L492
	.align 4
.L511:
	addl $-8,%esp
	movl -28(%ebp),%eax
	movl %eax,496(%edi)
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	jmp .L520
	.align 4
.L512:
	cmpl $2,-28(%ebp)
	jg .L513
	movl $-1,-28(%ebp)
.L513:
	addl $-8,%esp
	movl -28(%ebp),%eax
	movl %eax,496(%edi)
	pushl %eax
	movl 8(%ebp),%edx
	pushl %edx
	jmp .L520
	.align 4
.L514:
	movl -20(%ebp),%eax
	cmpl 500(%edi),%eax
	jne .L515
	movl -24(%ebp),%edx
	cmpl 504(%edi),%edx
	je .L492
.L515:
	addl $-8,%esp
	pushl 496(%edi)
	movl 8(%ebp),%eax
	pushl %eax
.L520:
	call BtnCode
	movb %al,(%ebx,%esi)
	incl %ebx
	addl $16,%esp
.L509:
	movl -20(%ebp),%edx
	movl %edx,500(%edi)
	movl -24(%ebp),%eax
	movl %eax,504(%edi)
	addb $33,%al
	movb %al,(%ebx,%esi)
	incl %ebx
	addb $33,%dl
	movb %dl,(%ebx,%esi)
	incl %ebx
	addl $-4,%esp
	pushl %ebx
	pushl %esi
	movl -16(%ebp),%edx
	pushl %edx
	call v_write
.L492:
	leal -56(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
.Lfe46:
	.size	 EditorButton,.Lfe46-EditorButton
	.align 4
.globl HandleGINInput
	.type	 HandleGINInput,@function
HandleGINInput:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	movl term,%eax
	cmpl $0,1384(%eax)
	je .L522
	movl 20(%ebp),%eax
	cmpl $1,(%eax)
	jne .L522
	movl 16(%ebp),%eax
	movl (%eax),%eax
	movsbl (%eax),%eax
	leal -76(%eax),%edx
	cmpl $38,%edx
	ja .L530
	jmp *.L531(,%edx,4)
	.align 4
.section	.rodata
	.align 4
	.align 4
.L531:
	.long .L523
	.long .L523
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L523
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L523
	.long .L523
	.long .L530
	.long .L530
	.long .L530
	.long .L530
	.long .L523
.text
	.align 4
.L530:
	addl $-8,%esp
	pushl $0
	pushl $1
	call Bell
	movl $108,%eax
	addl $16,%esp
.L523:
	addl $-12,%esp
	orb $128,%al
	pushl %eax
	call TekEnqMouse
	call TekGINoff
	jmp .L532
	.align 4
.L522:
	addl $-8,%esp
	pushl $0
	pushl $1
	call Bell
.L532:
	leave
	ret
.Lfe47:
	.size	 HandleGINInput,.Lfe47-HandleGINInput
	.align 4
.globl HandleSecure
	.type	 HandleSecure,@function
HandleSecure:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	pushl %ebx
	movl 12(%ebp),%ecx
	xorl %ebx,%ebx
	movl (%ecx),%edx
	leal -2(%edx),%eax
	cmpl $1,%eax
	jbe .L537
	leal -4(%edx),%eax
	cmpl $1,%eax
	ja .L535
.L537:
	movl 28(%ecx),%ebx
.L535:
	addl $-12,%esp
	pushl %ebx
	call DoSecureKeyboard
	movl -24(%ebp),%ebx
	leave
	ret
.Lfe48:
	.size	 HandleSecure,.Lfe48-HandleSecure
	.local	rawRow
	.comm	rawRow,4,4
	.local	rawCol
	.comm	rawCol,4,4
	.local	startRRow
	.comm	startRRow,4,4
	.local	startRCol
	.comm	startRCol,4,4
	.local	endRRow
	.comm	endRRow,4,4
	.local	startSRow
	.comm	startSRow,4,4
	.local	startSCol
	.comm	startSCol,4,4
	.local	endSRow
	.comm	endSRow,4,4
	.local	firstValidRow
	.comm	firstValidRow,4,4
	.local	lastValidRow
	.comm	lastValidRow,4,4
	.local	startERow
	.comm	startERow,4,4
	.local	startECol
	.comm	startECol,4,4
	.local	endERow
	.comm	endERow,4,4
	.local	endECol
	.comm	endECol,4,4
	.local	saveStartRRow
	.comm	saveStartRRow,4,4
	.local	saveStartRCol
	.comm	saveStartRCol,4,4
	.local	saveEndRRow
	.comm	saveEndRRow,4,4
	.local	saveEndRCol
	.comm	saveEndRCol,4,4
	.local	saveStartWRow
	.comm	saveStartWRow,4,4
	.local	saveStartWCol
	.comm	saveStartWCol,4,4
	.local	selectUnit
	.comm	selectUnit,4,4
	.local	replyToEmacs
	.comm	replyToEmacs,4,4
	.ident	"GCC: (GNU) 2.95.2 19991024 (release)"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]