On Fri, Dec 02, 2016 at 02:33:43PM +0100, Bill Allombert wrote:
> On the other hand, if you write a patch so that consolation does the
> same as gpm, I would be happy to apply it.

Here you go; the first commit talks to the kernel, using current gpm
defaults.  The second commit allows configuring this by the user, defaulting
to xfce4-terminal's setting.  It is debatable which one is "right" -- turns
out every GUI terminal I looked at uses a different set.

Even those who do allow configuring the set, though, don't allow altering
non-ASCII, and I think for a good reason: only a rare user would want to go
through deciding which of Unicode characters should be included.  The kernel
allows setting only printables between U+00A0..U+00FF anyway.


I've also attached a debugging aid, a kernel patch that printks the LUT
table as it is being loaded.


Meow!
-- 
The bill declaring Jesus as the King of Poland fails to specify whether
the addition is at the top or end of the list of kings.  What should the
historians do?
>From 3eca506f989ab934ef9bafeb6e9238ff89006eab Mon Sep 17 00:00:00 2001
From: Adam Borowski <[email protected]>
Date: Sat, 3 Dec 2016 09:00:46 +0100
Subject: [PATCH 1/2] Set "word chars" to gpm's default, hard-coded.

This means alphanumerics, latin-1 letters, _, and, unlike kernel's
default, also -./
---
 src/consolation.h |  1 +
 src/input.c       |  2 ++
 src/selection.c   | 26 ++++++++++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/src/consolation.h b/src/consolation.h
index 052a1a0..cf74711 100644
--- a/src/consolation.h
+++ b/src/consolation.h
@@ -29,6 +29,7 @@ void select_word(int x, int y);
 void select_line(int x, int y);
 void paste(void);
 void scroll(int sc);
+void set_lut(void);
 
 /* action.c */
 
diff --git a/src/input.c b/src/input.c
index 74b271a..846d585 100644
--- a/src/input.c
+++ b/src/input.c
@@ -227,6 +227,8 @@ event_main(void)
   if (!li)
     return 1;
 
+  set_lut();
+
   mainloop(li);
 
   libinput_unref(li);
diff --git a/src/selection.c b/src/selection.c
index cdebb64..912dd0b 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -20,6 +20,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <linux/tiocl.h>
+#include <stdint.h>
 
 #include "consolation.h"
 
@@ -108,3 +109,28 @@ void scroll(int sc)
     perror("scroll: TIOCLINUX");
   close(fd);
 }
+
+void set_lut(void)
+{
+  int fd;
+  struct {
+    char subcode;
+    char padding[3];
+    uint32_t lut[8];
+  } l = { TIOCL_SELLOADLUT, 0, 0, 0,
+    0x00000000, /* control chars     */
+    0x03FFE000, /* digits and "-./"  */
+    0x87FFFFFE, /* uppercase and '_' */
+    0x07FFFFFE, /* lowercase         */
+    0x00000000,
+    0x00000000,
+    0xFF7FFFFF, /* latin-1 accented letters, not multiplication sign */
+    0xFF7FFFFF  /* latin-1 accented letters, not division sign */
+  }; /* all of Unicode above U+00FF is considered "word" chars, even
+        frames and the likes */
+
+  fd = open("/dev/tty0",O_RDWR);
+  if(ioctl(fd, TIOCLINUX, &l)<0)
+    perror("set_lut: TIOCLINUX");
+  close(fd);
+}
-- 
2.10.2

>From e0459edc5f02984de0338d085a46c4060bbea5b7 Mon Sep 17 00:00:00 2001
From: Adam Borowski <[email protected]>
Date: Sat, 3 Dec 2016 09:46:11 +0100
Subject: [PATCH 2/2] Allow setting --word-chars.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

There's intentionally no way to change non-ASCII ones; this is on par with
most GUI terminals.  In theory, we could allow altering U+00A0..U+00FF, but
it'd probably be too confusing for most users.

Non-ASCII are hard-coded to:
U+00A0..U+00BF, U+00D7, U+00F7: not word-chars:
 ¡¢£¤¥¦§ ¨©ª«¬-®¯ °±²³´µ¶· ¸¹º»¼½¾¿ × ÷
U+00C0..U+00FE except U+00D7, U+00F7: word-chars:
ÀÁÂÃÄÅÆÇ ÈÉÊËÌÍÎÏ ÐÑÒÓÔÕÖ  ØÙÚÛÜÝÞß àáâãäåæç èéêëìíîï ðñòóôõö  øùúûüýþÿ

Anything U+00FF..U+FFFF is hard-coded to be word-chars in the kernel, with
no possibility of altering by userspace.  This includes even line-drawing
which we really would like to exclude.

The kernel doesn't support Unicode above Plane 0 at all -- I know how much
people miss U+1F4A9 (💩) but with only 256/512 characters vgacon can possibly
support, that'd be a waste of effort.
---
 src/consolation.h |  2 +-
 src/input.c       |  2 +-
 src/selection.c   | 24 +++++++++++++++++++++++-
 src/shared.c      | 11 +++++++++++
 src/shared.h      |  1 +
 5 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/src/consolation.h b/src/consolation.h
index cf74711..18e7a15 100644
--- a/src/consolation.h
+++ b/src/consolation.h
@@ -29,7 +29,7 @@ void select_word(int x, int y);
 void select_line(int x, int y);
 void paste(void);
 void scroll(int sc);
-void set_lut(void);
+void set_lut(const char *word_chars);
 
 /* action.c */
 
diff --git a/src/input.c b/src/input.c
index 846d585..766f569 100644
--- a/src/input.c
+++ b/src/input.c
@@ -227,7 +227,7 @@ event_main(void)
   if (!li)
     return 1;
 
-  set_lut();
+  set_lut(context.options.word_chars);
 
   mainloop(li);
 
diff --git a/src/selection.c b/src/selection.c
index 912dd0b..29dba14 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -110,7 +110,12 @@ void scroll(int sc)
   close(fd);
 }
 
-void set_lut(void)
+static int goodchar(char x)
+{
+  return x >= 0x20 && x < 0x7f;
+}
+
+void set_lut(const char *def)
 {
   int fd;
   struct {
@@ -129,6 +134,23 @@ void set_lut(void)
   }; /* all of Unicode above U+00FF is considered "word" chars, even
         frames and the likes */
 
+  /* we allow changing only U+0020..U+7E */
+  l.lut[1] = l.lut[2] = l.lut[3] = 0;
+
+  while (*def) {
+    char c = *def++;
+    if (!goodchar(c))
+      continue;
+    if (*def == '-' && goodchar(def[1])) {
+      ++def;
+      for (; c <= *def; ++c)
+        l.lut[c >> 5] |= 1 << (uint32_t)(c & 31);
+      ++def;
+    }
+    else
+      l.lut[c >> 5] |= 1 << (uint32_t)(c & 31);
+  }
+
   fd = open("/dev/tty0",O_RDWR);
   if(ioctl(fd, TIOCLINUX, &l)<0)
     perror("set_lut: TIOCLINUX");
diff --git a/src/shared.c b/src/shared.c
index 9acbf76..578a69d 100644
--- a/src/shared.c
+++ b/src/shared.c
@@ -65,6 +65,7 @@ enum options {
 	OPT_SCROLL_BUTTON,
 	OPT_SPEED,
 	OPT_PROFILE,
+	OPT_WORD_CHARS,
 	OPT_VERSION
 };
 
@@ -84,6 +85,7 @@ tools_usage()
 	       "--udev <seat>.... Use udev device discovery (default).\n"
 	       "		  Specifying a seat ID is optional.\n"
 	       "--device /path/to/device .... open the given device only\n"
+	       "--word-chars '-A-Za-z0-9,./?%&#:_=+@~' (ASCII only)\n"
 	       "\n"
 	       "Features:\n"
 	       "--enable-tap\n"
@@ -145,6 +147,7 @@ tools_init_context(struct tools_context *context)
 	options->seat = "seat0";
 	options->speed = 0.0;
 	options->profile = LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+	options->word_chars = "-A-Za-z0-9,./?%&#:_=+@~";
 }
 
 int
@@ -181,6 +184,7 @@ tools_parse_args(int argc, char **argv, struct tools_context *context)
 			{ "set-scroll-button", 1, 0, OPT_SCROLL_BUTTON },
 			{ "set-profile", 1, 0, OPT_PROFILE },
 			{ "speed", 1, 0, OPT_SPEED },
+			{ "word-chars", 1, 0, OPT_WORD_CHARS },
 			{ 0, 0, 0, 0}
 		};
 
@@ -333,6 +337,13 @@ tools_parse_args(int argc, char **argv, struct tools_context *context)
 				return 1;
 			}
 			break;
+		case OPT_WORD_CHARS:
+			if (!optarg) {
+				tools_usage();
+				return 1;
+			}
+			options->word_chars = optarg;
+			break;
 		default:
 			tools_usage();
 			return 1;
diff --git a/src/shared.h b/src/shared.h
index d18fcbb..9b6ee93 100644
--- a/src/shared.h
+++ b/src/shared.h
@@ -52,6 +52,7 @@ struct tools_options {
 	double speed;
 	int dwt;
 	enum libinput_config_accel_profile profile;
+	const char *word_chars;
 };
 
 struct tools_context {
-- 
2.10.2

>From f2c654d35bc90365e049440dd9243258f61e973d Mon Sep 17 00:00:00 2001
From: Adam Borowski <[email protected]>
Date: Sat, 3 Dec 2016 04:51:36 +0100
Subject: [PATCH] vt: printk LUT table as it is being loaded

---
 drivers/tty/vt/selection.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index 368ce18..8e67386 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -106,10 +106,13 @@ static inline int inword(const u16 c) {
  */
 int sel_loadlut(char __user *p)
 {
+	int i;
 	u32 tmplut[8];
 	if (copy_from_user(tmplut, (u32 __user *)(p+4), 32))
 		return -EFAULT;
 	memcpy(inwordLut, tmplut, 32);
+	for (i=0; i<ARRAY_SIZE(inwordLut); ++i)
+		printk("LUT %d/8: %08x\n", i, inwordLut[i]);
 	return 0;
 }
 
-- 
2.10.2

Reply via email to