kamil The patch below is how I've fixed it on my machine.
diff -urN a/wsmoused/selection.c b/wsmoused/selection.c
--- a/wsmoused/selection.c 2007-05-27 15:05:00.000000000 +0000
+++ b/wsmoused/selection.c 2020-10-21 06:17:38.666544347 +0000
@@ -144,6 +144,7 @@
static void selarea_start(void);
static void selarea_end(void);
static void selarea_calculate(void);
+static void selarea_getrowcol(size_t, size_t*, size_t*);
static void selarea_hide(void);
static void selarea_show(void);
static void selarea_paste(void);
@@ -624,14 +625,29 @@
/* ---------------------------------------------------------------------- */
+/* Turns selection absolute position in the screen buffer back into
+ row, col co-ordinates */
+static void
+selarea_getrowcol(size_t pos, size_t* row, size_t* col)
+{
+ size_t xres = Selmouse.sm_max_x + 1;
+
+ *row = pos / xres;
+ *col = pos - (*row * xres);
+}
+
+/* ---------------------------------------------------------------------- */
+
/* Hides the highlighted region, returning it to normal colors. */
static void
selarea_hide(void)
{
- size_t i;
+ size_t i, row, col;
- for (i = Selarea.sa_startoff; i <= Selarea.sa_endoff; i++)
- char_invert(0, i);
+ for (i = Selarea.sa_startoff; i <= Selarea.sa_endoff; i++) {
+ selarea_getrowcol(i, &row, &col);
+ char_invert(row, col);
+ }
}
/* ---------------------------------------------------------------------- */
@@ -640,11 +656,13 @@
static void
selarea_show(void)
{
- size_t i;
+ size_t i, row, col;
selarea_calculate();
- for (i = Selarea.sa_startoff; i <= Selarea.sa_endoff; i++)
- char_invert(0, i);
+ for (i = Selarea.sa_startoff; i <= Selarea.sa_endoff; i++) {
+ selarea_getrowcol(i, &row, &col);
+ char_invert(row, col);
+ }
}
/* ---------------------------------------------------------------------- */
diff -urN a/wsmoused/wsmoused.c b/wsmoused/wsmoused.c
--- a/wsmoused/wsmoused.c 2011-05-31 03:37:02.000000000 +0000
+++ b/wsmoused/wsmoused.c 2020-10-21 06:17:38.666544347 +0000
@@ -71,7 +71,7 @@
static int X_Console = -1;
static int X_Console_Delay = 5;
-#ifdef WSMOUSED_SELECTION_MODE
+#ifdef WSMOUSED_ACTION_MODE
extern struct mode_bootstrap Action_Mode;
#endif
#ifdef WSMOUSED_SELECTION_MODE
All I can say it that the old code should never have worked. That it did for 15+ years tells me that the kernel has now been fixed to do ioctl(WSDISPLAYIO_GETWSCHAR);
as the man-page documents.
The patch is a quick fix. It still retains the subtle infelicities of the original:
- Backgrounds on cells with bold/blink attrs. are not re-set correctly after the mouse cursor moves over them.
- Selection highlight is removed as soon as selection is complete. It would be better to retain it until the paste happens.
- Forward selection highlighting is slightly visually non-intuitive. Is the last char. in the highlighted region included in the selection, or, not?
- Single-char. selections are also non-intuitive.
- Backward selected text does not exactly correspond to the highlighted text. The selected text is back by a column relative to the highlighted section.
- Selection of large areas is very slow.
I'll try to fix most of these problems over the weekend when I have the time (and if none of the official NetBSD devs. have done it by then). The last item, #6, will need a new kernel ioctl
for efficient selections. Something like: ioctl(fd, WSDISPLAYIO_GETSELECTION, struct selection*)
where struct selection
contains start and end row, col fields and a buffer pointer.
Doing the equivalent of ioctl(GETWSCHAR)
for every cell is very slow on the Linux framebuffer also. It is slow even in an xterm
running inside accelerated X on Linux. I should know. I wrote a similar screen-scraper some time ago on Linux and found this out the hard way: I didn't want to handle \a
, \b
, '\t, '\r', '\n
, '\v`, ANSI-Esc sequences, ...The result was a darn slow program.