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