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