1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* genmap.c |
3 | * originally written by: Kirk Reiser. |
4 | * |
5 | ** Copyright (C) 2002 Kirk Reiser. |
6 | * Copyright (C) 2003 David Borowski. |
7 | */ |
8 | |
9 | #include <stdlib.h> |
10 | #include <stdio.h> |
11 | #include <libgen.h> |
12 | #include <string.h> |
13 | #include <linux/version.h> |
14 | #include <ctype.h> |
15 | #include "utils.h" |
16 | |
17 | struct st_key_init { |
18 | char *name; |
19 | int value, shift; |
20 | }; |
21 | |
22 | static unsigned char key_data[MAXKEYVAL][16], *kp; |
23 | |
24 | #include "mapdata.h" |
25 | |
26 | static const char delims[] = "\t\n " ; |
27 | static char *cp; |
28 | static int map_ver = 119; /* an arbitrary number so speakup can check */ |
29 | static int shift_table[17]; |
30 | static int max_states = 1, flags; |
31 | /* flags reserved for later, maybe for individual console maps */ |
32 | |
33 | static int get_shift_value(int state) |
34 | { |
35 | int i; |
36 | |
37 | for (i = 0; shift_table[i] != state; i++) { |
38 | if (shift_table[i] == -1) { |
39 | if (i >= 16) |
40 | oops(msg: "too many shift states" , NULL); |
41 | shift_table[i] = state; |
42 | max_states = i+1; |
43 | break; |
44 | } |
45 | } |
46 | return i; |
47 | } |
48 | |
49 | int |
50 | main(int argc, char *argv[]) |
51 | { |
52 | int value, shift_state, i, spk_val = 0, lock_val = 0; |
53 | int max_key_used = 0, num_keys_used = 0; |
54 | struct st_key *this; |
55 | struct st_key_init *p_init; |
56 | char buffer[256]; |
57 | |
58 | bzero(s: key_table, n: sizeof(key_table)); |
59 | bzero(s: key_data, n: sizeof(key_data)); |
60 | |
61 | shift_table[0] = 0; |
62 | for (i = 1; i <= 16; i++) |
63 | shift_table[i] = -1; |
64 | |
65 | if (argc < 2) { |
66 | fputs(s: "usage: genmap filename\n" , stderr); |
67 | exit(status: 1); |
68 | } |
69 | |
70 | for (p_init = init_key_data; p_init->name[0] != '.'; p_init++) |
71 | add_key(name: p_init->name, value: p_init->value, shift: p_init->shift); |
72 | |
73 | open_input(NULL, name: argv[1]); |
74 | while (fgets(s: buffer, n: sizeof(buffer), stream: infile)) { |
75 | lc++; |
76 | value = shift_state = 0; |
77 | |
78 | cp = strtok(s: buffer, delim: delims); |
79 | if (*cp == '#') |
80 | continue; |
81 | |
82 | while (cp) { |
83 | if (*cp == '=') |
84 | break; |
85 | this = find_key(name: cp); |
86 | if (this == NULL) |
87 | oops(msg: "unknown key/modifier" , info: cp); |
88 | if (this->shift == is_shift) { |
89 | if (value) |
90 | oops(msg: "modifiers must come first" , info: cp); |
91 | shift_state += this->value; |
92 | } else if (this->shift == is_input) |
93 | value = this->value; |
94 | else |
95 | oops(msg: "bad modifier or key" , info: cp); |
96 | cp = strtok(s: 0, delim: delims); |
97 | } |
98 | if (!cp) |
99 | oops(msg: "no = found" , NULL); |
100 | |
101 | cp = strtok(s: 0, delim: delims); |
102 | if (!cp) |
103 | oops(msg: "no speakup function after =" , NULL); |
104 | |
105 | this = find_key(name: cp); |
106 | if (this == NULL || this->shift != is_spk) |
107 | oops(msg: "invalid speakup function" , info: cp); |
108 | |
109 | i = get_shift_value(state: shift_state); |
110 | if (key_data[value][i]) { |
111 | while (--cp > buffer) |
112 | if (!*cp) |
113 | *cp = ' '; |
114 | oops(msg: "two functions on same key combination" , info: cp); |
115 | } |
116 | key_data[value][i] = (char)this->value; |
117 | if (value > max_key_used) |
118 | max_key_used = value; |
119 | } |
120 | fclose(stream: infile); |
121 | |
122 | this = find_key(name: "spk_key" ); |
123 | if (this) |
124 | spk_val = this->value; |
125 | |
126 | this = find_key(name: "spk_lock" ); |
127 | if (this) |
128 | lock_val = this->value; |
129 | |
130 | for (lc = 1; lc <= max_key_used; lc++) { |
131 | kp = key_data[lc]; |
132 | if (!memcmp(s1: key_data[0], s2: kp, n: 16)) |
133 | continue; |
134 | num_keys_used++; |
135 | for (i = 0; i < max_states; i++) { |
136 | if (kp[i] != spk_val && kp[i] != lock_val) |
137 | continue; |
138 | shift_state = shift_table[i]; |
139 | if (shift_state&16) |
140 | continue; |
141 | shift_state = get_shift_value(state: shift_state+16); |
142 | kp[shift_state] = kp[i]; |
143 | /* fill in so we can process the key up, as spk bit will be set */ |
144 | } |
145 | } |
146 | |
147 | printf(format: "\t%d, %d, %d,\n\t" , map_ver, num_keys_used, max_states); |
148 | for (i = 0; i < max_states; i++) |
149 | printf(format: "%d, " , shift_table[i]); |
150 | printf(format: "%d," , flags); |
151 | for (lc = 1; lc <= max_key_used; lc++) { |
152 | kp = key_data[lc]; |
153 | if (!memcmp(s1: key_data[0], s2: kp, n: 16)) |
154 | continue; |
155 | printf(format: "\n\t%d," , lc); |
156 | for (i = 0; i < max_states; i++) |
157 | printf(format: " %d," , (unsigned int)kp[i]); |
158 | } |
159 | printf(format: "\n\t0, %d\n" , map_ver); |
160 | |
161 | exit(status: 0); |
162 | } |
163 | |