aboutsummaryrefslogtreecommitdiff
path: root/ht/gen-keysyms-new.sh
blob: 388d946a7a521476daec7954a307e229beab2d1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/sh
gofmt <<EOF | sed 's, *//$,,'
// Code generated by running "go generate" in janouch.name/haven. DO NOT EDIT.

package $GOPACKAGE

import (
	"strings"
	"janouch.name/haven/nexgb/xproto"
)

$(curl --silent --show-error \
	https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h \
	https://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h \
| perl -lne '
	next unless /^\#define\s+
		(XF86)?(XK_)([a-zA-Z_0-9]+)\s+
		0x([0-9a-fA-F]+)\s*
		(?:\/\*\s*(.*?)\s*\*\/)?\s*
	$/x;

	my ($name, $ident, $hex, $comment) =
		(($1 // "") . $3,  ($1 // "") . $2 . $3, lc $4, ($5 // ""));

	# They are already somewhat sorted in the source file.
	push @a, { hex => $hex, ident => $ident, comment => $comment };

	$nametokeysym{$name} = $ident;

	# All but the first name listed should be considered deprecated.
	$keysymtoname{$ident} = $name unless exists $seen{$hex};
	$seen{$hex}++;

	# TODO: Try stringer, see
	# https://eli.thegreenplace.net/2021/a-comprehensive-guide-to-go-generate/
	END {
		print "const (";
		print "$_->{ident} = 0x$_->{hex} // $_->{comment}" for @a;
		print ")";

		# Very large tables, should be an on-demand package :(
		#
		# KeysymToName/NameToKeysym can also be compress/lzw (small code),
		# that may reduce string data to about 1/3.  It's still rather small
		# (27K -> 8K), I'm not sure where all those bytes come from.
		#
		# KeysymToName might be generated from NameToKeysym.
		# KeysymToName may just be an index into the ntk constant.
		#
		# Actually we may just include a $name => $hex table and screw
		# all else.  But the text still begs for compression and the numbers
		# for filtering and compression.
		#
		# Or actually []{$hex, $name}, stable sorted by $hex, and having
		# the $name be an index into a constant.  On construction we keep
		# a map so that only the first $hex occurrence receives a name.
		#
		# My biggest gripe is probably source code size that won't go down
		# because the constants are just so large (158K).

		my (@ktnK, @ktnV);
		for (sort keys %keysymtoname) {
			push @ktnK, $_;
			push @ktnV, $keysymtoname{$_};
		}
		print "var ktnKeys = []xproto.Keysym{${\join \", \", @ktnK}}";
		print "var ktnValues = \"${\join \" \", @ktnV}\"";

		my (@ntkK, @ntkV);
		for (sort keys %nametokeysym) {
			push @ntkK, $_;
			push @ntkV, $nametokeysym{$_};
		}
		print "var ntkKeys = \"${\join \" \", @ntkK}\"";
		print "var ntkValues = []xproto.Keysym{${\join \", \", @ntkV}}";
	}
')

// KeysymToName maps X11 keysym constants to their names.
var KeysymToName = map[xproto.Keysym]string{}

// NameToKeysym maps X11 keysym names to their constants.
var NameToKeysym = map[string]xproto.Keysym{}

func init() {
	x := strings.Split(ktnValues, " ")
	for i, keysym := range ktnKeys {
		KeysymToName[keysym] = x[i]
	}
	for i, name := range strings.Split(ntkKeys, " ") {
		NameToKeysym[name] = ntkValues[i]
	}
}
EOF