/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */ #define is_space_on_vt(c) ((c) == ' ')
/* FIXME: all this needs locking */ staticstruct vc_selection { struct mutex lock; struct vc_data *cons; /* must not be deallocated */ char *buffer; unsignedint buf_len; volatileint start; /* cleared by clear_selection */ int end;
} vc_sel = {
.lock = __MUTEX_INITIALIZER(vc_sel.lock),
.start = -1,
};
/* clear_selection, highlight and highlight_pointer can be called
from interrupt (via scrollback/front) */
/* set reverse video on characters s-e of console with selection. */ staticinlinevoid highlight(constint s, constint e)
{
invert_screen(vc_sel.cons, s, e-s+2, true);
}
/* use complementary color to show the pointer */ staticinlinevoid highlight_pointer(constint where)
{
complement_pos(vc_sel.cons, where);
}
static u32
sel_pos(int n, bool unicode)
{ if (unicode) return screen_glyph_unicode(vc_sel.cons, n / 2); return inverse_translate(vc_sel.cons, screen_glyph(vc_sel.cons, n), false);
}
/* does screen address p correspond to character at LH/RH edge of screen? */ staticinlineint atedge(constint p, int size_row)
{ return (!(p % size_row) || !((p + 2) % size_row));
}
/* Allocate a new buffer before freeing the old one ... */ /* chars can take up to 4 bytes with unicode */
bp = kmalloc_array((vc_sel.end - vc_sel.start) / 2 + 1, unicode ? 4 : 1,
GFP_KERNEL | __GFP_NOWARN); if (!bp) {
printk(KERN_WARNING "selection: kmalloc() failed\n");
clear_selection(); return -ENOMEM;
}
kfree(vc_sel.buffer);
vc_sel.buffer = bp;
obp = bp; for (i = vc_sel.start; i <= vc_sel.end; i += 2) {
u32 c = sel_pos(i, unicode); if (unicode)
bp += store_utf8(c, bp); else
*bp++ = c; if (!is_space_on_vt(c))
obp = bp; if (!((i + 2) % vc->vc_size_row)) { /* strip trailing blanks from line and add newline,
unless non-space at end of line. */ if (obp != bp) {
bp = obp;
*bp++ = '\r';
}
obp = bp;
}
}
vc_sel.buf_len = bp - vc_sel.buffer;
return0;
}
staticint vc_do_selection(struct vc_data *vc, unsignedshort mode, int ps, int pe)
{ int new_sel_start, new_sel_end, spc; bool unicode = vt_do_kdgkbmode(fg_console) == K_UNICODE;
/* select to end of line if on trailing space */ if (new_sel_end > new_sel_start &&
!atedge(new_sel_end, vc->vc_size_row) &&
is_space_on_vt(sel_pos(new_sel_end, unicode))) { for (pe = new_sel_end + 2; ; pe += 2) if (!is_space_on_vt(sel_pos(pe, unicode)) ||
atedge(pe, vc->vc_size_row)) break; if (is_space_on_vt(sel_pos(pe, unicode)))
new_sel_end = pe;
} if (vc_sel.start == -1) /* no current selection */
highlight(new_sel_start, new_sel_end); elseif (new_sel_start == vc_sel.start)
{ if (new_sel_end == vc_sel.end) /* no action required */ return0; elseif (new_sel_end > vc_sel.end) /* extend to right */
highlight(vc_sel.end + 2, new_sel_end); else/* contract from right */
highlight(new_sel_end + 2, vc_sel.end);
} elseif (new_sel_end == vc_sel.end)
{ if (new_sel_start < vc_sel.start) /* extend to left */
highlight(new_sel_start, vc_sel.start - 2); else/* contract from left */
highlight(vc_sel.start, new_sel_start - 2);
} else/* some other case; start selection from scratch */
{
clear_selection();
highlight(new_sel_start, new_sel_end);
}
vc_sel.start = new_sel_start;
vc_sel.end = new_sel_end;
/* Insert the contents of the selection buffer into the *queueofthettyassociatedwiththecurrentconsole. *Invokedbyioctl(). * *Locking:calledwithoutlocks.Callstheldiscwronglywith *unsafemethods,
*/ int paste_selection(struct tty_struct *tty)
{ struct vc_data *vc = tty->driver_data; int pasted = 0;
size_t count; struct tty_ldisc *ld;
DECLARE_WAITQUEUE(wait, current); int ret = 0;
bool bp = vc->vc_bracketed_paste; staticconstchar bracketed_paste_start[] = "\033[200~"; staticconstchar bracketed_paste_end[] = "\033[201~"; constchar *bps = bp ? bracketed_paste_start : NULL; constchar *bpe = bp ? bracketed_paste_end : NULL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.