static int is_down = 0;  switch (b) { case MBT_LEFT: encstate = 0x20;	        break; case MBT_MIDDLE: encstate = 0x21; break; case MBT_RIGHT: encstate = 0x22; break; case MBT_WHEEL_UP: encstate = 0x60; break; case MBT_WHEEL_DOWN: encstate = 0x61; break; default: break;
if (term->ldisc) {  switch (b) { case MBT_LEFT: encstate = 0x20;	        break; case MBT_MIDDLE: encstate = 0x21; break; case MBT_RIGHT: encstate = 0x22; break; case MBT_WHEEL_UP: encstate = 0x60; break; case MBT_WHEEL_DOWN: encstate = 0x61; break; default: break;	        } switch (a) { case MA_DRAG: if (term->xterm_mouse == 1) return; encstate += 0x20; break; case MA_RELEASE: encstate = 0x23; term->mouse_is_down = 0; break; case MA_CLICK: if (term->mouse_is_down == b) return; term->mouse_is_down = b; break; default: break;	        } if (shift) encstate += 0x04; if (ctrl) encstate += 0x10; r = y + 33; c = x + 33;  sprintf(abuf, "\033[M%c%c%c", encstate, c, r); ldisc_send(term->ldisc, abuf, 6, 0);
void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y,		int shift, int ctrl, int alt){    pos selpoint;    unsigned long *ldata;    int raw_mouse = (term->xterm_mouse &&		     !cfg.no_mouse_rep &&		     !(cfg.mouse_override && shift));    int default_seltype;    if (y < 0) {	y = 0;	if (a == MA_DRAG && !raw_mouse)	    term_scroll(term, 0, -1);    }    if (y >= term->rows) {	y = term->rows - 1;	if (a == MA_DRAG && !raw_mouse)	    term_scroll(term, 0, +1);    }    if (x < 0) {	if (y > 0) {	    x = term->cols - 1;	    y--;	} else	    x = 0;    }    if (x >= term->cols)	x = term->cols - 1;    selpoint.y = y + term->disptop;    selpoint.x = x;    ldata = lineptr(selpoint.y);    if ((ldata[term->cols] & LATTR_MODE) != LATTR_NORM)	selpoint.x /= 2;    if (raw_mouse) {	int encstate = 0, r, c;	char abuf[16];	static int is_down = 0;	switch (b) {	  case MBT_LEFT:	    encstate = 0x20;	       /* left button down */	    break;	  case MBT_MIDDLE:	    encstate = 0x21;	    break;	  case MBT_RIGHT:	    encstate = 0x22;	    break;	  case MBT_WHEEL_UP:	    encstate = 0x60;	    break;	  case MBT_WHEEL_DOWN:	    encstate = 0x61;	    break;	  default: break;	       /* placate gcc warning about enum use */	}	switch (a) {	  case MA_DRAG:	    if (term->xterm_mouse == 1)		return;	    encstate += 0x20;	    break;	  case MA_RELEASE:	    encstate = 0x23;	    is_down = 0;	    break;	  case MA_CLICK:	    if (is_down == b)		return;	    is_down = b;	    break;	  default: break;	       /* placate gcc warning about enum use */	}	if (shift)	    encstate += 0x04;	if (ctrl)	    encstate += 0x10;	r = y + 33;	c = x + 33;	sprintf(abuf, "\033[M%c%c%c", encstate, c, r);	ldisc_send(abuf, 6, 0);	return;    }    b = translate_button(b);    /*     * Set the selection type (rectangular or normal) at the start     * of a selection attempt, from the state of Alt.     */    if (!alt ^ !cfg.rect_select)	default_seltype = RECTANGULAR;    else	default_seltype = LEXICOGRAPHIC;	    if (term->selstate == NO_SELECTION) {	term->seltype = default_seltype;    }    if (b == MBT_SELECT && a == MA_CLICK) {	deselect(term);	term->selstate = ABOUT_TO;	term->seltype = default_seltype;	term->selanchor = selpoint;	term->selmode = SM_CHAR;    } else if (b == MBT_SELECT && (a == MA_2CLK || a == MA_3CLK)) {	deselect(term);	term->selmode = (a == MA_2CLK ? SM_WORD : SM_LINE);	term->selstate = DRAGGING;	term->selstart = term->selanchor = selpoint;	term->selend = term->selstart;	incpos(term->selend);	sel_spread(term);    } else if ((b == MBT_SELECT && a == MA_DRAG) ||	       (b == MBT_EXTEND && a != MA_RELEASE)) {	if (term->selstate == ABOUT_TO && poseq(term->selanchor, selpoint))	    return;	if (b == MBT_EXTEND && a != MA_DRAG && term->selstate == SELECTED) {	    if (term->seltype == LEXICOGRAPHIC) {		/*		 * For normal selection, we extend by moving		 * whichever end of the current selection is closer		 * to the mouse.		 */		if (posdiff(selpoint, term->selstart) <		    posdiff(term->selend, term->selstart) / 2) {		    term->selanchor = term->selend;		    decpos(term->selanchor);		} else {		    term->selanchor = term->selstart;		}	    } else {		/*		 * For rectangular selection, we have a choice of		 * _four_ places to put selanchor and selpoint: the		 * four corners of the selection.		 */		if (2*selpoint.x < term->selstart.x + term->selend.x)		    term->selanchor.x = term->selend.x-1;		else		    term->selanchor.x = term->selstart.x;		if (2*selpoint.y < term->selstart.y + term->selend.y)		    term->selanchor.y = term->selend.y;		else		    term->selanchor.y = term->selstart.y;	    }	    term->selstate = DRAGGING;	}	if (term->selstate != ABOUT_TO && term->selstate != DRAGGING)	    term->selanchor = selpoint;	term->selstate = DRAGGING;	if (term->seltype == LEXICOGRAPHIC) {	    /*	     * For normal selection, we set (selstart,selend) to	     * (selpoint,selanchor) in some order.	     */	    if (poslt(selpoint, term->selanchor)) {		term->selstart = selpoint;		term->selend = term->selanchor;		incpos(term->selend);	    } else {		term->selstart = term->selanchor;		term->selend = selpoint;		incpos(term->selend);	    }	} else {	    /*	     * For rectangular selection, we may need to	     * interchange x and y coordinates (if the user has	     * dragged in the -x and +y directions, or vice versa).	     */	    term->selstart.x = min(term->selanchor.x, selpoint.x);	    term->selend.x = 1+max(term->selanchor.x, selpoint.x);	    term->selstart.y = min(term->selanchor.y, selpoint.y);	    term->selend.y =   max(term->selanchor.y, selpoint.y);	}	sel_spread(term);    } else if ((b == MBT_SELECT || b == MBT_EXTEND) && a == MA_RELEASE) {	if (term->selstate == DRAGGING) {	    /*	     * We've completed a selection. We now transfer the	     * data to the clipboard.	     */	    clipme(term, term->selstart, term->selend,		   (term->seltype == RECTANGULAR));	    term->selstate = SELECTED;	} else	    term->selstate = NO_SELECTION;    } else if (b == MBT_PASTE	       && (a == MA_CLICK#if MULTICLICK_ONLY_EVENT		   || a == MA_2CLK || a == MA_3CLK#endif		   )) {	request_paste();    }    term_update(term);}