static void sel_drag(pos selpoint) { term.selected = true; if (!term.sel_rect) { /* * For normal selection, we set (sel_start,sel_end) to * (selpoint,sel_anchor) in some order. */ if (poslt(selpoint, term.sel_anchor)) { term.sel_start = selpoint; term.sel_end = term.sel_anchor; } else { term.sel_start = term.sel_anchor; term.sel_end = selpoint; } incpos(term.sel_end); sel_spread(); } 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.sel_start.x = min(term.sel_anchor.x, selpoint.x); term.sel_end.x = 1 + max(term.sel_anchor.x, selpoint.x); term.sel_start.y = min(term.sel_anchor.y, selpoint.y); term.sel_end.y = max(term.sel_anchor.y, selpoint.y); } }
void term_mouse (Mouse_Button b, Mouse_Action a, int x, int y) { unsigned long *selpoint; if (y<0) y = 0; if (y>=rows) y = rows-1; if (x<0) { if (y > 0) { x = cols-1; y--; } else x = 0; } if (x>=cols) x = cols-1; selpoint = disptop + y * (cols+1) + x; if (b == MB_SELECT && a == MA_CLICK) { deselect(); selstate = ABOUT_TO; selanchor = selpoint; selmode = SM_CHAR; } else if (b == MB_SELECT && (a == MA_2CLK || a == MA_3CLK)) { deselect(); selmode = (a == MA_2CLK ? SM_WORD : SM_LINE); selstate = DRAGGING; selstart = selanchor = selpoint; selend = selstart + 1; sel_spread(); } else if ((b == MB_SELECT && a == MA_DRAG) || (b == MB_EXTEND && a != MA_RELEASE)) { if (selstate == ABOUT_TO && selanchor == selpoint) return; if (b == MB_EXTEND && a != MA_DRAG && selstate == SELECTED) { if (selpoint-selstart < (selend-selstart)/2) selanchor = selend - 1; else selanchor = selstart; selstate = DRAGGING; } if (selstate != ABOUT_TO && selstate != DRAGGING) selanchor = selpoint; selstate = DRAGGING; if (selpoint < selanchor) { selstart = selpoint; selend = selanchor + 1; } else { selstart = selanchor; selend = selpoint + 1; } sel_spread(); } else if ((b == MB_SELECT || b == MB_EXTEND) && a == MA_RELEASE) { if (selstate == DRAGGING) { /* * We've completed a selection. We now transfer the * data to the clipboard. */ unsigned char *p = selspace; unsigned long *q = selstart; while (q < selend) { int nl = FALSE; unsigned long *lineend = q - (q-text) % (cols+1) + cols; unsigned long *nlpos = lineend; if (!(*nlpos & ATTR_WRAPPED)) { while ((nlpos[-1] & CHAR_MASK) == 0x20 && nlpos > q) nlpos--; if (nlpos < selend) nl = TRUE; } while (q < nlpos && q < selend) *p++ = (unsigned char) (*q++ & CHAR_MASK); if (nl) { int i; for (i=0; i<sizeof(sel_nl); i++) *p++ = sel_nl[i]; } q = lineend + 1; /* start of next line */ } write_clip (selspace, p - selspace); selstate = SELECTED; } else selstate = NO_SELECTION; } else if (b == MB_PASTE && (a==MA_CLICK || a==MA_2CLK || a==MA_3CLK)) { char *data; int len; get_clip((void **) &data, &len); if (data) { char *p, *q; p = q = data; while (p < data+len) { while (p < data+len && !(p <= data+len-sizeof(sel_nl) && !memcmp(p, sel_nl, sizeof(sel_nl)))) p++; { int i; unsigned char c; for(i=0;i<p-q;i++) { c=xlat_kbd2tty(q[i]); ldisc->send(&c,1); } } if (p <= data+len-sizeof(sel_nl) && !memcmp(p, sel_nl, sizeof(sel_nl))) { ldisc->send ("\r", 1); p += sizeof(sel_nl); } q = p; } } get_clip(NULL, NULL); } term_update(); }