static void key_states_scan_key(const char *key, KEY_REC *rec) { GSList *tmp, *out; if (strcmp(rec->info->id, "key") == 0) return; out = g_slist_append(NULL, g_string_new(NULL)); if (expand_key(key, &out)) { for (tmp = out; tmp != NULL; tmp = tmp->next) { GString *str = tmp->data; if (str->str[1] == '-' || str->str[1] == '\0') used_keys[(int)(unsigned char)str->str[0]] = 1; g_tree_insert(key_states, g_strdup(str->str), rec); } } expand_out_free(out); }
static int expand_combo(const char *start, const char *end, GSList **out, int *limit) { KEY_REC *rec; KEYINFO_REC *info; GSList *tmp, *tmp2, *list, *copy, *newout; char *str, *p; if ((*limit)-- < 0) { return FALSE; } if (start == end) { /* single key */ expand_out_char(*out, *start); return TRUE; } info = key_info_find("key"); if (info == NULL) return FALSE; /* get list of all key combos that generate the named combo.. */ list = NULL; str = g_strndup(start, (int) (end-start)+1); for (tmp = info->keys; tmp != NULL; tmp = tmp->next) { KEY_REC *rec = tmp->data; if (g_strcmp0(rec->data, str) == 0) list = g_slist_append(list, rec); } if (list == NULL) { /* unknown keycombo - add it as-is, maybe the GUI will feed it to us as such */ for (p = str; *p != '\0'; p++) expand_out_char(*out, *p); g_free(str); return TRUE; } g_free(str); if (list->next == NULL) { /* only one way to generate the combo, good */ rec = list->data; g_slist_free(list); return expand_key(rec->key, out, limit); } /* multiple ways to generate the combo - we'll need to include all of them in output */ newout = NULL; for (tmp = list->next; tmp != NULL; tmp = tmp->next) { KEY_REC *rec = tmp->data; copy = NULL; for (tmp2 = *out; tmp2 != NULL; tmp2 = tmp2->next) { GString *str = tmp2->data; copy = g_slist_append(copy, g_string_new(str->str)); } if (!expand_key(rec->key, ©, limit)) { if (*limit < 0) { return FALSE; } /* illegal key combo, remove from list */ expand_out_free(copy); } else { newout = g_slist_concat(newout, copy); } } rec = list->data; g_slist_free(list); if (!expand_key(rec->key, out, limit)) { if (*limit < 0) { return FALSE; } /* illegal key combo, remove from list */ expand_out_free(*out); } *out = g_slist_concat(*out, newout); return *out != NULL; }