-/**
- * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
- * groups, and reduce to one group if all groups are identical anyway.
- */
-static void
-PrepareKeyDef(KeyInfo *keyi)
-{
- xkb_group_index_t i, lastGroup;
- unsigned int defined;
- xkb_level_index_t j, width;
- bool identical;
-
- defined = keyi->symsDefined | keyi->actsDefined | keyi->typesDefined;
- /* get highest group number */
- for (i = XkbNumKbdGroups - 1; i > 0; i--) {
- if (defined & (1 << i))
- break;
- }
- lastGroup = i;
-
- if (lastGroup == 0)
- return;
-
- /* If there are empty groups between non-empty ones fill them with data */
- /* from the first group. */
- /* We can make a wrong assumption here. But leaving gaps is worse. */
- for (i = lastGroup; i > 0; i--) {
- if (defined & (1 << i))
- continue;
- width = keyi->numLevels[0];
- if (keyi->typesDefined & 1) {
- for (j = 0; j < width; j++) {
- keyi->types[i] = keyi->types[0];
- }
- keyi->typesDefined |= 1 << i;
- }
- if ((keyi->actsDefined & 1) && !darray_empty(keyi->acts[0])) {
- darray_copy(keyi->acts[i], keyi->acts[0]);
- keyi->actsDefined |= 1 << i;
- }
- if ((keyi->symsDefined & 1) && !darray_empty(keyi->syms[0])) {
- darray_copy(keyi->syms[i], keyi->syms[0]);
- darray_copy(keyi->symsMapIndex[i], keyi->symsMapIndex[0]);
- darray_copy(keyi->symsMapNumEntries[i],
- keyi->symsMapNumEntries[0]);
- keyi->symsDefined |= 1 << i;
- }
- if (defined & 1) {
- keyi->numLevels[i] = keyi->numLevels[0];
- }
- }
- /* If all groups are completely identical remove them all */
- /* exept the first one. */
- identical = true;
- for (i = lastGroup; i > 0; i--) {
- if ((keyi->numLevels[i] != keyi->numLevels[0]) ||
- (keyi->types[i] != keyi->types[0])) {
- identical = false;
- break;
- }
- if (!darray_same(keyi->syms[i], keyi->syms[0]) &&
- (darray_empty(keyi->syms[i]) || darray_empty(keyi->syms[0]) ||
- darray_size(keyi->syms[i]) != darray_size(keyi->syms[0]) ||
- memcmp(darray_mem(keyi->syms[i], 0),
- darray_mem(keyi->syms[0], 0),
- sizeof(xkb_keysym_t) * darray_size(keyi->syms[0])))) {
- identical = false;
- break;
- }
- if (!darray_same(keyi->symsMapIndex[i], keyi->symsMapIndex[0]) &&
- (darray_empty(keyi->symsMapIndex[i]) ||
- darray_empty(keyi->symsMapIndex[0]) ||
- memcmp(darray_mem(keyi->symsMapIndex[i], 0),
- darray_mem(keyi->symsMapIndex[0], 0),
- keyi->numLevels[0] * sizeof(int)))) {
- identical = false;
- continue;
- }
- if (!darray_same(keyi->symsMapNumEntries[i],
- keyi->symsMapNumEntries[0]) &&
- (darray_empty(keyi->symsMapNumEntries[i]) ||
- darray_empty(keyi->symsMapNumEntries[0]) ||
- memcmp(darray_mem(keyi->symsMapNumEntries[i], 0),
- darray_mem(keyi->symsMapNumEntries[0], 0),
- keyi->numLevels[0] * sizeof(size_t)))) {
- identical = false;
- continue;
- }
- if (!darray_same(keyi->acts[i], keyi->acts[0]) &&
- (darray_empty(keyi->acts[i]) || darray_empty(keyi->acts[0]) ||
- memcmp(darray_mem(keyi->acts[i], 0),
- darray_mem(keyi->acts[0], 0),
- keyi->numLevels[0] * sizeof(union xkb_action)))) {
- identical = false;
- break;
- }
- }
- if (identical) {
- for (i = lastGroup; i > 0; i--) {
- keyi->numLevels[i] = 0;
- darray_free(keyi->syms[i]);
- darray_free(keyi->symsMapIndex[i]);
- darray_free(keyi->symsMapNumEntries[i]);
- darray_free(keyi->acts[i]);
- keyi->types[i] = 0;
- }
- keyi->symsDefined &= 1;
- keyi->actsDefined &= 1;
- keyi->typesDefined &= 1;
- }
-}
-
-/**
- * Copy the KeyInfo into the keyboard description.
- *
- * This function recurses.
- */