key-string.c revision 1.5
1/* $OpenBSD: key-string.c,v 1.5 2009/07/26 21:42:08 nicm Exp $ */
2
3/*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20
21#include <string.h>
22
23#include "tmux.h"
24
25int	key_string_search_table(const char *);
26
27struct {
28	const char *string;
29	int	 key;
30} key_string_table[] = {
31	/* Function keys. */
32	{ "F1",		KEYC_F1 },
33	{ "F2",		KEYC_F2 },
34	{ "F3",		KEYC_F3 },
35	{ "F4",		KEYC_F4 },
36	{ "F5",		KEYC_F5 },
37	{ "F6",		KEYC_F6 },
38	{ "F7",		KEYC_F7 },
39	{ "F8",		KEYC_F8 },
40	{ "F9",		KEYC_F9 },
41	{ "F10",	KEYC_F10 },
42	{ "F11",	KEYC_F11 },
43	{ "F12",	KEYC_F12 },
44	{ "F13",	KEYC_F13 },
45	{ "F14",	KEYC_F14 },
46	{ "F15",	KEYC_F15 },
47	{ "F16",	KEYC_F16 },
48	{ "F17",	KEYC_F17 },
49	{ "F18",	KEYC_F18 },
50	{ "F19",	KEYC_F19 },
51	{ "F20",	KEYC_F20 },
52	{ "IC",		KEYC_IC },
53	{ "DC",		KEYC_DC },
54	{ "Home",	KEYC_HOME },
55	{ "End",	KEYC_END },
56	{ "NPage",	KEYC_NPAGE },
57	{ "PPage",	KEYC_PPAGE },
58	{ "Tab",	'\011' },
59	{ "BTab",	KEYC_BTAB },
60	{ "BSpace",	KEYC_BSPACE },
61
62	/* Arrow keys. */
63	{ "Up",		KEYC_UP },
64	{ "Down",	KEYC_DOWN },
65	{ "Left",	KEYC_LEFT },
66	{ "Right",	KEYC_RIGHT },
67
68	/* Numeric keypad. */
69	{ "KP/", 	KEYC_KP0_1 },
70	{ "KP*",	KEYC_KP0_2 },
71	{ "KP-",	KEYC_KP0_3 },
72	{ "KP7",	KEYC_KP1_0 },
73	{ "KP8",	KEYC_KP1_1 },
74	{ "KP9",	KEYC_KP1_2 },
75	{ "KP+",	KEYC_KP1_3 },
76	{ "KP4",	KEYC_KP2_0 },
77	{ "KP5",	KEYC_KP2_1 },
78	{ "KP6",	KEYC_KP2_2 },
79	{ "KP1",	KEYC_KP3_0 },
80	{ "KP2",	KEYC_KP3_1 },
81	{ "KP3",	KEYC_KP3_2 },
82	{ "KPEnter",	KEYC_KP3_3 },
83	{ "KP0",	KEYC_KP4_0 },
84	{ "KP.",	KEYC_KP4_2 },
85};
86
87int
88key_string_search_table(const char *string)
89{
90	u_int	i;
91
92	for (i = 0; i < nitems(key_string_table); i++) {
93		if (strcasecmp(string, key_string_table[i].string) == 0)
94			return (key_string_table[i].key);
95	}
96	return (KEYC_NONE);
97}
98
99int
100key_string_lookup_string(const char *string)
101{
102	int	      	 key;
103	const u_char	*ptr;
104
105	if (string[0] == '\0')
106		return (KEYC_NONE);
107	if (string[1] == '\0')
108		return (string[0]);
109
110	ptr = NULL;
111	if ((string[0] == 'C' || string[0] == 'c') && string[1] == '-')
112		ptr = string + 2;
113	else if (string[0] == '^')
114		ptr = string + 1;
115	if (ptr != NULL) {
116		if (ptr[0] == '\0')
117			return (KEYC_NONE);
118		if (ptr[1] == '\0') {
119			if (ptr[0] == 32)
120				return (0);
121			if (ptr[0] >= 64 && ptr[0] <= 95)
122				return (ptr[0] - 64);
123			if (ptr[0] >= 97 && ptr[0] <= 122)
124				return (ptr[0] - 96);
125			return (KEYC_NONE);
126		}
127		key = key_string_search_table(ptr);
128		if (key != KEYC_NONE)
129			return (key | KEYC_CTRL);
130		return (KEYC_NONE);
131	}
132
133	if ((string[0] == 'M' || string[0] == 'm') && string[1] == '-') {
134		ptr = string + 2;
135		if (ptr[0] == '\0')
136			return (KEYC_NONE);
137		if (ptr[1] == '\0') {
138			if (ptr[0] < 32 || ptr[0] > 127)
139				return (KEYC_NONE);
140			return (ptr[0] | KEYC_ESCAPE);
141		}
142		key = key_string_lookup_string(ptr);
143		if (key != KEYC_NONE)
144			return (key | KEYC_ESCAPE);
145		return (KEYC_NONE);
146	}
147
148	return (key_string_search_table(string));
149}
150
151const char *
152key_string_lookup_key(int key)
153{
154	static char tmp[24], tmp2[24];
155	const char *s;
156	u_int	    i;
157
158	if (key == 127)
159		return (NULL);
160
161	if (key & KEYC_ESCAPE) {
162		if ((s = key_string_lookup_key(key & ~KEYC_ESCAPE)) == NULL)
163			return (NULL);
164		xsnprintf(tmp2, sizeof tmp2, "M-%s", s);
165		return (tmp2);
166	}
167	if (key & KEYC_CTRL) {
168		if ((s = key_string_lookup_key(key & ~KEYC_CTRL)) == NULL)
169			return (NULL);
170		xsnprintf(tmp2, sizeof tmp2, "C-%s", s);
171		return (tmp2);
172	}
173	if (key & KEYC_SHIFT) {
174		if ((s = key_string_lookup_key(key & ~KEYC_SHIFT)) == NULL)
175			return (NULL);
176		xsnprintf(tmp2, sizeof tmp2, "S-%s", s);
177		return (tmp2);
178	}
179
180	if (key >= 32 && key <= 255) {
181		tmp[0] = key;
182		tmp[1] = '\0';
183		return (tmp);
184	}
185
186	if (key >= 0 && key <= 32) {
187		if (key == 0 || key > 26)
188			xsnprintf(tmp, sizeof tmp, "C-%c", 64 + key);
189		else
190			xsnprintf(tmp, sizeof tmp, "C-%c", 96 + key);
191		return (tmp);
192	}
193
194	for (i = 0; i < nitems(key_string_table); i++) {
195		if (key == key_string_table[i].key)
196			return (key_string_table[i].string);
197	}
198	return (NULL);
199}
200