tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

cons(9): char mapping



For at least userconf, are added means to define a char mapping for
the console during startup (the userconf char to char mapping command
will be "kmap", key 'k'; and a series of instructions, assembled by
config(1), will be proceeded during userconf_init() before
userconf_bootinfo(), allowing one to add a pseudo keyboard mapping
in the kernel config for early interaction).

Attached is the diff.

Comments?
-- 
        Thierry Laronde <tlaronde +AT+ kergis +dot+ com>
                     http://www.kergis.com/
                    http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C
diff --git a/share/man/man9/cons.9 b/share/man/man9/cons.9
index 42db38b25d5b..af96362d8f32 100644
--- a/share/man/man9/cons.9
+++ b/share/man/man9/cons.9
@@ -24,11 +24,13 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 8, 2010
+.Dd November 16, 2023
 .Dt CONS 9
 .Os
 .Sh NAME
 .Nm cnbell ,
+.Nm cncmap ,
+.Nm cncmapreset ,
 .Nm cnflush ,
 .Nm cngetc ,
 .Nm cngetsn ,
@@ -41,6 +43,10 @@
 .Ft void
 .Fn cnbell "u_int pitch" "u_int period" "u_int volume"
 .Ft void
+.Fn cncmap "u_char from" "u_char to"
+.Ft void
+.Fn cncmapreset "void"
+.Ft void
 .Fn cnflush "void"
 .Ft int
 .Fn cngetc "void"
@@ -80,10 +86,17 @@ milliseconds at given
 Note that the
 .Fa volume
 value is ignored commonly.
+.It Fn cncmap
+Maps a char to another char. The mapping is only used inside
+.Fn cngetc
+and the facility exists to allow a kind of keyboard mapping during
+startup interaction. The nul char is never mapped.
+.It Fn cncmapreset
+Resets the char mapping to the identity mapping.
 .It Fn cnflush
 Waits for all pending output to finish.
 .It Fn cngetc
-Poll (busy wait) for an input and return the input key.
+Poll (busy wait) for an input and return the mapped input key.
 Returns 0 if there is no console input device.
 .Fn cnpollc
 .Em must
@@ -154,6 +167,7 @@ cnpollc(0);
 .Xr pckbd 4 ,
 .Xr pcppi 4 ,
 .Xr tty 4 ,
+.Xr userconf 4 ,
 .Xr wscons 4 ,
 .Xr wskbd 4 ,
 .Xr printf 9 ,
diff --git a/sys/dev/cons.c b/sys/dev/cons.c
index f3a2387fbceb..cc8db394b339 100644
--- a/sys/dev/cons.c
+++ b/sys/dev/cons.c
@@ -95,6 +95,8 @@ struct	tty *volatile constty;	/* virtual console output device */
 struct	consdev *cn_tab;	/* physical console device info */
 struct	vnode *cn_devvp[2];	/* vnode for underlying device. */
 
+static unsigned char cn_cmap[UCHAR_MAX+1];	/* char mapping for cngetc() */
+
 void
 cn_set_tab(struct consdev *tab)
 {
@@ -109,6 +111,15 @@ cn_set_tab(struct consdev *tab)
 	 * cn_tab updates.
 	 */
 	cn_tab = tab;
+
+	/*
+	 * Char mapping is only done in cngetc() i.e. in kernel
+	 * startup when the console is not a tty. Assuming here that
+	 * if there were more than one console, there would be a
+	 * different terminal, that is a different keyboard attached
+	 * to the console so a different mapping.
+	 */
+	cncmapreset();
 }
 
 int
@@ -315,6 +326,29 @@ cnkqfilter(dev_t dev, struct knote *kn)
 	return error;
 }
 
+void
+cncmapreset(void)
+{
+	unsigned char c;
+
+	/* Consistency, a keyboard is supposed attached to a cons */
+	if (cn_tab == NULL)
+		return;
+
+	for (c = 0; c <= UCHAR_MAX; c++)
+		cn_cmap[c] = c;
+}
+
+void
+cncmap(unsigned char from, unsigned char to)
+{
+	if (cn_tab == NULL)
+		return;
+
+	if (from)	/* Nul is never mapped */
+		cn_cmap[from] = to;
+}
+
 int
 cngetc(void)
 {
@@ -325,7 +359,9 @@ cngetc(void)
 		const int rv = (*cn_tab->cn_getc)(cn_tab->cn_dev);
 		if (rv >= 0) {
 			splx(s);
-			return rv;
+			/* Nul is never mapped */
+			return (rv && rv <= UCHAR_MAX)?
+				(int) cn_cmap[(unsigned char)rv] : rv;
 		}
 		docritpollhooks();
 	}
diff --git a/sys/dev/cons.h b/sys/dev/cons.h
index 9fed7cb0eb00..aba8def6a743 100644
--- a/sys/dev/cons.h
+++ b/sys/dev/cons.h
@@ -79,6 +79,8 @@ extern	struct consdev *cn_tab;
 void	cn_set_tab(struct consdev *);
 
 void	cninit(void);
+void	cncmapreset(void);
+void	cncmap(unsigned char, unsigned char);
 int	cngetc(void);
 int	cngetsn(char *, int);
 void	cnputc(int);


Home | Main Index | Thread Index | Old Index