Index | Thread | Search

From:
Jiri Navratil <jiri@navratil.cz>
Subject:
patch for Czech (cz) console keyboard
To:
tech@openbsd.org
Cc:
jiri@navratil.cz
Date:
Mon, 27 Jul 2026 12:59:35 +0200

Download raw body.

Thread
Hi tech@,

I have

hw.product=Raspberry Pi 400 Rev 1.0
hw.machine=arm64
hw.model=ARM Cortex-A72 r0p3

and I'm using OpenBSD -current

$ uname -m -p -r -s -v
OpenBSD 8.0 GENERIC.MP#0 arm64 aarch64

on tty (not with X). There is not yet Czech QWERTZ keyboard.

I prepared enclosed patch for adding it.

--- sys/dev/wscons/wsksymdef.h
+++ sys/dev/wscons/wsksymdef.h
@@ -376,6 +376,8 @@
 #define KS_L2_Nacute		0x0143
 #define KS_L2_nacute		0x0144
 #define KS_L2_Ncaron		0x0147
+#define KS_L2_ncaron		0x0148
+#define KS_EuroSign		0x20ac
 #define KS_L2_Odoubleacute	0x0150
 #define KS_L2_odoubleacute	0x0151
 #define KS_L2_Racute		0x0154
@@ -741,6 +743,7 @@
 #define KB_LV			0x1b00
 #define KB_IS			0x1c00
 #define KB_EE			0x1d00
+#define KB_CZ			0x1e00
 
 #define KB_NODEAD		0x00000001 /* disable dead accents */
 #define KB_DECLK		0x00000002 /* DEC LKnnn layout */
@@ -782,7 +785,8 @@
 	{ KB_CF,	"cf" }, \
 	{ KB_LV,	"lv" }, \
 	{ KB_IS,	"is" }, \
-	{ KB_EE,	"ee" }
+	{ KB_EE,	"ee" }, \
+	{ KB_CZ,	"cz" }
 
 #define KB_VARTAB \
 	{ KB_NODEAD,	"nodead" }, \
--- sys/dev/pckbc/wskbdmap_mfii.c
+++ sys/dev/pckbc/wskbdmap_mfii.c
@@ -1110,6 +1110,57 @@
     KC(41),  KS_L2_caron,	KS_asciitilde,
 };
 
+static const keysym_t pckbd_keydesc_cz[] = {
+/*  pos      normal		shifted		altgr */
+    KC(41),  KS_semicolon,	KS_dead_abovering, KS_grave,
+    KC(2),   KS_plus,		KS_1,		KS_exclam,
+    KC(3),   KS_L2_ecaron,	KS_2,		KS_at,
+    KC(4),   KS_L2_scaron,	KS_3,		KS_numbersign,
+    KC(5),   KS_L2_ccaron,	KS_4,		KS_dollar,
+    KC(6),   KS_L2_rcaron,	KS_5,		KS_percent,
+    KC(7),   KS_L2_zcaron,	KS_6,		KS_asciicircum,
+    KC(8),   KS_yacute,	KS_7,		KS_ampersand,
+    KC(9),   KS_aacute,	KS_8,		KS_asterisk,
+    KC(10),  KS_iacute,	KS_9,		KS_braceleft,
+    KC(11),  KS_eacute,	KS_0,		KS_braceright,
+    KC(12),  KS_equal,		KS_percent,	KS_backslash,
+    KC(13),  KS_dead_acute,	KS_dead_caron,	KS_dead_diaeresis,
+    KC(16),  KS_q,		KS_Q,		KS_backslash,
+    KC(17),  KS_w,		KS_W,		KS_bar,
+    KC(18),  KS_e,		KS_E,		KS_EuroSign,
+    KC(19),  KS_r,		KS_R,
+    KC(20),  KS_t,		KS_T,
+    KC(21),  KS_z,		KS_Z,
+    KC(22),  KS_u,		KS_U,
+    KC(23),  KS_i,		KS_I,
+    KC(24),  KS_o,		KS_O,
+    KC(25),  KS_p,		KS_P,
+    KC(26),  KS_uacute,	KS_slash,	KS_bracketleft,
+    KC(27),  KS_parenright,	KS_parenleft,	KS_bracketright,
+    KC(30),  KS_a,		KS_A,		KS_asciitilde,
+    KC(31),  KS_s,		KS_S,		KS_L2_dstroke,
+    KC(32),  KS_d,		KS_D,		KS_L2_Dstroke,
+    KC(33),  KS_f,		KS_F,		KS_bracketleft,
+    KC(34),  KS_g,		KS_G,		KS_bracketright,
+    KC(35),  KS_h,		KS_H,		KS_grave,
+    KC(36),  KS_j,		KS_J,		KS_apostrophe,
+    KC(37),  KS_k,		KS_K,		KS_L2_lstroke,
+    KC(38),  KS_l,		KS_L,		KS_L2_Lstroke,
+    KC(39),  KS_L2_uring,	KS_quotedbl,	KS_dollar,
+    KC(40),  KS_section,	KS_exclam,	KS_apostrophe,
+    KC(44),  KS_y,		KS_Y,		KS_degree,
+    KC(45),  KS_x,		KS_X,		KS_numbersign,
+    KC(46),  KS_c,		KS_C,		KS_ampersand,
+    KC(47),  KS_v,		KS_V,		KS_at,
+    KC(48),  KS_b,		KS_B,		KS_braceleft,
+    KC(49),  KS_n,		KS_N,		KS_braceright,
+    KC(50),  KS_m,		KS_M,		KS_asciicircum,
+    KC(51),  KS_comma,		KS_question,	KS_less,
+    KC(52),  KS_period,	KS_colon,	KS_greater,
+    KC(53),  KS_minus,		KS_underscore,	KS_asterisk,
+    KC(184), KS_Mode_switch,	KS_Multi_key,
+};
+
 #endif	/* WSKBD_NO_INTL_LAYOUTS */
 
 #define KBD_MAP(name, base, map) \
@@ -1171,6 +1222,7 @@
 	KBD_MAP(KB_IS | KB_NODEAD,	KB_IS, 	pckbd_keydesc_is_nodead),
 	KBD_MAP(KB_EE,			KB_US,	pckbd_keydesc_ee),
 	KBD_MAP(KB_EE | KB_NODEAD,	KB_EE,	pckbd_keydesc_ee_nodead),
+	KBD_MAP(KB_CZ,			KB_US,	pckbd_keydesc_cz),
 #endif	/* WSKBD_NO_INTL_LAYOUTS */
 	{0, 0, 0, 0}
 };
--- sys/dev/wscons/wskbdutil.c
+++ sys/dev/wscons/wskbdutil.c
@@ -174,7 +174,21 @@
 	{ { KS_dead_caron,		KS_S },			KS_L2_Scaron },
 	{ { KS_dead_caron,		KS_Z },			KS_L2_Zcaron },
 	{ { KS_dead_caron,		KS_s },			KS_L2_scaron },
-	{ { KS_dead_caron,		KS_z },			KS_L2_zcaron }
+	{ { KS_dead_caron,		KS_z },			KS_L2_zcaron },
+	{ { KS_dead_caron,		KS_C },			KS_L2_Ccaron },
+	{ { KS_dead_caron,		KS_c },			KS_L2_ccaron },
+	{ { KS_dead_caron,		KS_D },			KS_L2_Dcaron },
+	{ { KS_dead_caron,		KS_d },			KS_L2_dcaron },
+	{ { KS_dead_caron,		KS_E },			KS_L2_Ecaron },
+	{ { KS_dead_caron,		KS_e },			KS_L2_ecaron },
+	{ { KS_dead_caron,		KS_N },			KS_L2_Ncaron },
+	{ { KS_dead_caron,		KS_n },			KS_L2_ncaron },
+	{ { KS_dead_caron,		KS_R },			KS_L2_Rcaron },
+	{ { KS_dead_caron,		KS_r },			KS_L2_rcaron },
+	{ { KS_dead_caron,		KS_T },			KS_L2_Tcaron },
+	{ { KS_dead_caron,		KS_t },			KS_L2_tcaron },
+	{ { KS_dead_abovering,		KS_U },			KS_L2_Uring },
+	{ { KS_dead_abovering,		KS_u },			KS_L2_uring }
 };
 
 #define COMPOSE_SIZE	nitems(compose_tab)
--- sys/dev/wscons/wsemul_subr.c
+++ sys/dev/wscons/wsemul_subr.c
@@ -559,6 +559,15 @@
 int
 wsemul_local_translate(u_int32_t unisym, kbd_t layout, u_char *out)
 {
+	/*
+	 * There is no Euro sign in the 8-bit encoding. Substitute
+	 * with a clearly-a-substitution placeholder.
+	 */
+	if (unisym == KS_EuroSign) {
+		*out = '?';
+		return (1);
+	}
+
 	switch (unisym >> 7) {
 	case 0x0080 >> 7:
 		switch (KB_ENCODING(layout)) {
@@ -613,6 +622,7 @@
 			break;
 		case KB_PL:
 		case KB_SI:
+		case KB_CZ:
 			if (unisym < 0x100 + nitems(unicode_to_latin2) &&
 			    unicode_to_latin2[unisym - 0x100] != 0)
 				unisym = unicode_to_latin2[unisym - 0x100];
@@ -624,6 +634,7 @@
 		switch (KB_ENCODING(layout)) {
 		case KB_PL:
 		case KB_SI:
+		case KB_CZ:
 			switch (unisym) {
 			case KS_L2_caron:
 				unisym = 0xb7;
--- share/man/man4/wskbd.4
+++ share/man/man4/wskbd.4
@@ -146,6 +146,7 @@
 .It Li br Ta Dv KB_BR Ta Brazilian with
 .Dq dead accents
 .It Li cf Ta Dv KB_CF Ta Canadian French
+.It Li cz Ta Dv KB_CZ Ta Czech
 .It Li dk Ta Dv KB_DK Ta Danish with
 .Dq dead accents
 .It Li nl Ta Dv KB_NL Ta Dutch
--- share/man/man4/pckbd.4
+++ share/man/man4/pckbd.4
@@ -69,6 +69,9 @@
 .It KB_CF
 .Pq cf
 Canadian French.
+.It KB_CZ
+.Pq cz
+Czech.
 .It KB_DE
 .Pq de
 German with
--- share/man/man4/ukbd.4
+++ share/man/man4/ukbd.4
@@ -96,6 +96,9 @@
 .It KB_CF
 .Pq cf
 Canadian French.
+.It KB_CZ
+.Pq cz
+Czech.
 .It KB_DE
 .Pq de
 German with

---

The ukbdmap.c is not included in the patch, as it's generated.
Font don't show some letters, but these are entered properly.

Here are steps I used:

sysupgrade -s -n
rm /home/_sysupgrade/x*
reboot

cd /usr/src
make clean
cvs -q up -C -Pd -A

patch -p0 < $HOME/add-cz-console-keyboard.patch

cd /usr/src/sys/dev/usb
awk -f makemap.awk ../pckbc/wskbdmap_mfii.c > ukbdmap.c

cd /usr/src && make includes

cd /usr/src/sys/arch/arm64/compile/GENERIC.MP
make obj && make config && make clean && make && make install
cd /usr/src/sbin/kbd && make clean && make && make install
cd /usr/src/sbin/wsconsctl && make clean && make && make install

cd /usr/src/share/man/man4
make install
makewhatis

reboot

---

I have in /etc/profile 
export LANG="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
export LC_COLLATE="cs_CZ.UTF-8"
export LC_MESSAGES="en_US.UTF-8"
export LC_MONETARY="cs_CZ.UTF-8"
export LC_NUMERIC="cs_CZ.UTF-8"
export LC_TIME="cs_CZ.UTF-8"
printf '\033%%G'

in /etc/wsconsctl.conf
keyboard.encoding=cz

I may switch between keyboards via
kbd us
kbd cz

I will appreciate if my patch will eventually get integrated.

Thank you for your work on OpenBSD.

PS: I'm not subscribed to the list.

Best regards,
Jiří Navrátil

-- 
Jiri Navratil, https://www.navratil.cz, +420 777 224 245