/* copy a word under the mouse pointer */ static void mouse_cut_word(scr_stat *scp) { int start; int end; int sol; int eol; int c; int j; int len; /* * Because we don't have locale information in the kernel, * we only distinguish space char and non-space chars. Punctuation * chars, symbols and other regular chars are all treated alike * unless user specified SC_CUT_SEPCHARS in his kernel config file. */ if (scp->status & MOUSE_VISIBLE) { sol = rounddown(scp->mouse_pos, scp->xsize); eol = sol + scp->xsize; c = sc_vtb_getc(&scp->vtb, scp->mouse_pos); if (IS_SEP_CHAR(c)) { /* blank space */ for (j = scp->mouse_pos; j >= sol; --j) { c = sc_vtb_getc(&scp->vtb, j); if (!IS_SEP_CHAR(c)) break; } start = ++j; for (j = scp->mouse_pos; j < eol; ++j) { c = sc_vtb_getc(&scp->vtb, j); if (!IS_SEP_CHAR(c)) break; } end = j - 1; } else { /* non-space word */ for (j = scp->mouse_pos; j >= sol; --j) { c = sc_vtb_getc(&scp->vtb, j); if (IS_SEP_CHAR(c)) break; } start = ++j; for (j = scp->mouse_pos; j < eol; ++j) { c = sc_vtb_getc(&scp->vtb, j); if (IS_SEP_CHAR(c)) break; } end = j - 1; } /* copy the found word */ mouse_do_cut(scp, start, end); len = strlen(cut_buffer); if (cut_buffer[len - 1] == '\r') cut_buffer[len - 1] = '\0'; } }
/* copy a line under the mouse pointer */ static void mouse_cut_line(scr_stat *scp) { int i; int j; if (scp->status & MOUSE_VISIBLE) { /* remove the current cut mark */ crit_enter(); if (scp->mouse_cut_start <= scp->mouse_cut_end) { mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); } else if (scp->mouse_cut_end >= 0) { mark_for_update(scp, scp->mouse_cut_end); mark_for_update(scp, scp->mouse_cut_start); } /* mark the entire line */ scp->mouse_cut_start = (scp->mouse_pos / scp->xsize) * scp->xsize; scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1; mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); crit_exit(); /* copy the line into the cut buffer */ for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j) cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j); cut_buffer[i++] = '\r'; cut_buffer[i] = '\0'; scp->status |= MOUSE_CUTTING; } }
/* a mouse button is pressed, start cut operation */ static void mouse_cut_start(scr_stat *scp) { int i; int s; if (scp->status & MOUSE_VISIBLE) { sc_remove_all_cutmarkings(scp->sc); if ((scp->mouse_pos == scp->mouse_cut_start) && (scp->mouse_pos == scp->mouse_cut_end)) { cut_buffer[0] = '\0'; return; } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) { /* if the pointer is on trailing blank chars, mark towards eol */ i = skip_spc_left(scp, scp->mouse_pos) + 1; s = spltty(); scp->mouse_cut_start = rounddown(scp->mouse_pos, scp->xsize) + i; scp->mouse_cut_end = (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1; splx(s); cut_buffer[0] = '\r'; } else { s = spltty(); scp->mouse_cut_start = scp->mouse_pos; scp->mouse_cut_end = scp->mouse_cut_start; splx(s); cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start); } cut_buffer[1] = '\0'; scp->status |= MOUSE_CUTTING; mark_all(scp); /* this is probably overkill XXX */ } }
static void mouse_do_cut(scr_stat *scp, int from, int to) { int blank; int i; int leadspaces; int p; int s; for (p = from, i = blank = leadspaces = 0; p <= to; ++p) { cut_buffer[i] = sc_vtb_getc(&scp->vtb, p); /* Be prepared that sc_vtb_getc() can return '\0' */ if (cut_buffer[i] == '\0') cut_buffer[i] = ' '; #ifdef SC_CUT_SPACES2TABS if (leadspaces != -1) { if (IS_SPACE_CHAR(cut_buffer[i])) { leadspaces++; /* Check that we are at tabstop position */ if ((p % scp->xsize) % 8 == 7) { i -= leadspaces - 1; cut_buffer[i] = '\t'; leadspaces = 0; } } else { leadspaces = -1; } } #endif /* SC_CUT_SPACES2TABS */ /* remember the position of the last non-space char */ if (!IS_BLANK_CHAR(cut_buffer[i])) blank = i + 1; /* the first space after the last non-space */ ++i; /* trim trailing blank when crossing lines */ if ((p % scp->xsize) == (scp->xsize - 1)) { cut_buffer[blank++] = '\r'; i = blank; leadspaces = 0; } } cut_buffer[i] = '\0'; /* remove the current marking */ s = spltty(); if (scp->mouse_cut_start <= scp->mouse_cut_end) { mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); } else if (scp->mouse_cut_end >= 0) { mark_for_update(scp, scp->mouse_cut_end); mark_for_update(scp, scp->mouse_cut_start); } /* mark the new region */ scp->mouse_cut_start = from; scp->mouse_cut_end = to; mark_for_update(scp, from); mark_for_update(scp, to); splx(s); }
/* skip spaces to left */ static int skip_spc_left(scr_stat *scp, int p) { int c; int i; for (i = p-- % scp->xsize - 1; i >= 0; --i) { c = sc_vtb_getc(&scp->vtb, p); if (!IS_SPACE_CHAR(c)) break; --p; } return i; }
/* skip spaces to right */ static int skip_spc_right(scr_stat *scp, int p) { int c; int i; for (i = p % scp->xsize; i < scp->xsize; ++i) { c = sc_vtb_getc(&scp->vtb, p); if (!IS_SPACE_CHAR(c)) break; ++p; } return i; }
/* copy marked region to the cut buffer */ static void mouse_cut(scr_stat *scp) { int start; int end; int from; int to; int c; int p; int s; int i; start = scp->mouse_cut_start; end = scp->mouse_cut_end; if (scp->mouse_pos >= start) { from = start; to = end = scp->mouse_pos; } else { from = end = scp->mouse_pos; to = start - 1; } p = to; for (i = p % scp->xsize; i < scp->xsize; ++i) { c = sc_vtb_getc(&scp->vtb, p); if (!IS_SPACE_CHAR(c)) break; ++p; } /* if there is nothing but blank chars, trim them, but mark towards eol */ if (i == scp->xsize) { if (end >= start) to = end = p - 1; else to = start = p; } mouse_do_cut(scp, from, to); s = spltty(); scp->mouse_cut_start = start; scp->mouse_cut_end = end; splx(s); }
/* a mouse button is pressed, start cut operation */ static void mouse_cut_start(scr_stat *scp) { int i; int j; if (scp->status & MOUSE_VISIBLE) { i = scp->mouse_cut_start; j = scp->mouse_cut_end; sc_remove_all_cutmarkings(scp->sc); if (scp->mouse_pos == i && i == j) { cut_buffer[0] = '\0'; } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) { /* if the pointer is on trailing blank chars, mark towards eol */ i = skip_spc_left(scp, scp->mouse_pos) + 1; crit_enter(); scp->mouse_cut_start = (scp->mouse_pos / scp->xsize) * scp->xsize + i; scp->mouse_cut_end = (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1; crit_exit(); cut_buffer[0] = '\r'; cut_buffer[1] = '\0'; scp->status |= MOUSE_CUTTING; } else { crit_enter(); scp->mouse_cut_start = scp->mouse_pos; scp->mouse_cut_end = scp->mouse_cut_start; crit_exit(); cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start); cut_buffer[1] = '\0'; scp->status |= MOUSE_CUTTING; } mark_all(scp); /* this is probably overkill XXX */ } }
/* copy a word under the mouse pointer */ static void mouse_cut_word(scr_stat *scp) { int start; int end; int sol; int eol; int c; int i; int j; /* * Because we don't have locale information in the kernel, * we only distinguish space char and non-space chars. Punctuation * chars, symbols and other regular chars are all treated alike. */ if (scp->status & MOUSE_VISIBLE) { /* remove the current cut mark */ crit_enter(); if (scp->mouse_cut_start <= scp->mouse_cut_end) { mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); } else if (scp->mouse_cut_end >= 0) { mark_for_update(scp, scp->mouse_cut_end); mark_for_update(scp, scp->mouse_cut_start); } scp->mouse_cut_start = scp->xsize*scp->ysize; scp->mouse_cut_end = -1; crit_exit(); sol = (scp->mouse_pos / scp->xsize) * scp->xsize; eol = sol + scp->xsize; c = sc_vtb_getc(&scp->vtb, scp->mouse_pos); if (IS_SPACE_CHAR(c)) { /* blank space */ for (j = scp->mouse_pos; j >= sol; --j) { c = sc_vtb_getc(&scp->vtb, j); if (!IS_SPACE_CHAR(c)) break; } start = ++j; for (j = scp->mouse_pos; j < eol; ++j) { c = sc_vtb_getc(&scp->vtb, j); if (!IS_SPACE_CHAR(c)) break; } end = j - 1; } else { /* non-space word */ for (j = scp->mouse_pos; j >= sol; --j) { c = sc_vtb_getc(&scp->vtb, j); if (IS_SPACE_CHAR(c)) break; } start = ++j; for (j = scp->mouse_pos; j < eol; ++j) { c = sc_vtb_getc(&scp->vtb, j); if (IS_SPACE_CHAR(c)) break; } end = j - 1; } /* copy the found word */ for (i = 0, j = start; j <= end; ++j) cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j); cut_buffer[i] = '\0'; scp->status |= MOUSE_CUTTING; /* mark the region */ crit_enter(); scp->mouse_cut_start = start; scp->mouse_cut_end = end; mark_for_update(scp, start); mark_for_update(scp, end); crit_exit(); } }
/* copy marked region to the cut buffer */ static void mouse_cut(scr_stat *scp) { int start; int end; int from; int to; int blank; int c; int p; int i; start = scp->mouse_cut_start; if (scp->mouse_pos >= start) { from = start; to = end = scp->mouse_pos; } else { from = end = scp->mouse_pos; to = start - 1; } for (p = from, i = blank = 0; p <= to; ++p) { cut_buffer[i] = sc_vtb_getc(&scp->vtb, p); /* remember the position of the last non-space char */ if (!IS_SPACE_CHAR(cut_buffer[i++])) blank = i; /* the first space after the last non-space */ /* trim trailing blank when crossing lines */ if ((p % scp->xsize) == (scp->xsize - 1)) { cut_buffer[blank] = '\r'; i = blank + 1; } } cut_buffer[i] = '\0'; /* scan towards the end of the last line */ --p; for (i = p % scp->xsize; i < scp->xsize; ++i) { c = sc_vtb_getc(&scp->vtb, p); if (!IS_SPACE_CHAR(c)) break; ++p; } /* if there is nothing but blank chars, trim them, but mark towards eol */ if (i >= scp->xsize) { if (end >= start) to = end = p - 1; else to = start = p; cut_buffer[blank++] = '\r'; cut_buffer[blank] = '\0'; } /* remove the current marking */ crit_enter(); if (scp->mouse_cut_start <= scp->mouse_cut_end) { mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); } else if (scp->mouse_cut_end >= 0) { mark_for_update(scp, scp->mouse_cut_end); mark_for_update(scp, scp->mouse_cut_start); } /* mark the new region */ scp->mouse_cut_start = start; scp->mouse_cut_end = end; mark_for_update(scp, from); mark_for_update(scp, to); crit_exit(); }