in speakup/keyhelp.c [49:98]
static void build_key_data(void)
{
u_char *kp, counters[MAXFUNCS], ch, ch1;
u_short *p_key, key;
int i, offset = 1;
nstates = (int)(state_tbl[-1]);
memset(counters, 0, sizeof(counters));
memset(key_offsets, 0, sizeof(key_offsets));
kp = state_tbl + nstates + 1;
while (*kp++) {
/* count occurrences of each function */
for (i = 0; i < nstates; i++, kp++) {
if (!*kp)
continue;
if ((state_tbl[i] & 16) != 0 && *kp == SPK_KEY)
continue;
counters[*kp]++;
}
}
for (i = 0; i < MAXFUNCS; i++) {
if (counters[i] == 0)
continue;
key_offsets[i] = offset;
offset += (counters[i] + 1);
if (offset >= MAXKEYS)
break;
}
/* leave counters set so high keycodes come first.
* this is done so num pad and other extended keys maps are spoken before
* the alpha with speakup type mapping.
*/
kp = state_tbl + nstates + 1;
while ((ch = *kp++)) {
for (i = 0; i < nstates; i++) {
ch1 = *kp++;
if (!ch1)
continue;
if ((state_tbl[i] & 16) != 0 && ch1 == SPK_KEY)
continue;
key = (state_tbl[i] << 8) + ch;
counters[ch1]--;
offset = key_offsets[ch1];
if (!offset)
continue;
p_key = key_data + offset + counters[ch1];
*p_key = key;
}
}
}