Example #1
0
/* Expand key code - returns TRUE if successful. */
static int expand_key(const char *key, GSList **out)
{
	GSList *tmp;
	const char *start;
	int last_hyphen;

	/* meta-^W^Gf -> ^[-^W-^G-f */
        start = NULL; last_hyphen = TRUE;
	for (; *key != '\0'; key++) {
		if (start != NULL) {
			if (i_isalnum(*key) || *key == '_') {
                                /* key combo continues */
				continue;
			}

			if (!expand_combo(start, key-1, out))
                                return FALSE;
			expand_out_char(*out, '-');
                        start = NULL;
		}

		if (*key == '-') {
			if (last_hyphen) {
                                expand_out_char(*out, '-');
                                expand_out_char(*out, '-');
			}
			last_hyphen = !last_hyphen;
		} else if (*key == '^') {
                        /* ctrl-code */
			if (key[1] != '\0')
				key++;

			expand_out_char(*out, '^');
			expand_out_char(*out, *key);
			expand_out_char(*out, '-');
                        last_hyphen = FALSE; /* optional */
		} else if (last_hyphen && i_isalnum(*key) && !i_isdigit(*key)) {
                        /* possibly beginning of keycombo */
			start = key;
                        last_hyphen = FALSE;
		} else {
			expand_out_char(*out, *key);
			expand_out_char(*out, '-');
                        last_hyphen = FALSE; /* optional */
		}
	}

	if (start != NULL)
		return expand_combo(start, key-1, out);

	for (tmp = *out; tmp != NULL; tmp = tmp->next) {
		GString *str = tmp->data;

		g_string_truncate(str, str->len-1);
	}

        return TRUE;
}
Example #2
0
File: keyboard.c Project: ahf/irssi
/* Expand key code - returns TRUE if successful. */
static int expand_key(const char *key, GSList **out, int *limit)
{
	GSList *tmp;
	const char *start;
	int last_hyphen;

	if ((*limit)-- < 0) {
		return FALSE;
	}

	/* meta-^W^Gf -> ^[-^W-^G-f */
        start = NULL; last_hyphen = TRUE;
	for (; *key != '\0'; key++) {
		if (start != NULL) {
			if (i_isalnum(*key) || *key == '_') {
                                /* key combo continues */
				continue;
			}

			if (!expand_combo(start, key-1, out, limit))
                                return FALSE;
			expand_out_char(*out, '-');
                        start = NULL;
		}

		if (*key == '-') {
			if (last_hyphen) {
                                expand_out_char(*out, '-');
                                expand_out_char(*out, '-');
			}
			last_hyphen = !last_hyphen;
		} else if (*key == '^') {
			expand_out_char(*out, '^');

                        /* ctrl-code */
			if (key[1] != '\0' && key[1] != '-') {
				key++;
				expand_out_char(*out, *key);
			}
			else {
				/* escaped syntax for ^, see gui-readline.c */
				expand_out_char(*out, '-');
			}

			expand_out_char(*out, '-');
                        last_hyphen = FALSE; /* optional */
		} else if (last_hyphen && i_isalpha(*key)) {
                        /* possibly beginning of keycombo */
			start = key;
                        last_hyphen = FALSE;
		} else if (g_utf8_validate(key, -1, NULL)) {
			/* Assume we are looking at the start of a
			 * multibyte sequence we will receive as-is,
			 * so add it to the list as-is.
			 */
			const char *p, *end = g_utf8_next_char(key);
			for (p = key; p != end; p++)
				expand_out_char(*out, *p);
			expand_out_char(*out, '-');
			/* The for loop skips past the remaining character.
			 * Nasty, I know...
			 */
			key = end - 1;
			last_hyphen = FALSE;
		} else {
			expand_out_char(*out, *key);
			expand_out_char(*out, '-');
                        last_hyphen = FALSE; /* optional */
		}
	}

	if (start != NULL)
		return expand_combo(start, key-1, out, limit);

	for (tmp = *out; tmp != NULL; tmp = tmp->next) {
		GString *str = tmp->data;

		g_string_truncate(str, str->len-1);
	}

        return TRUE;
}
Example #3
0
File: keyboard.c Project: ahf/irssi
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, &copy, 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;
}