xref: /openbsd-src/sbin/wsconsctl/util.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: util.c,v 1.6 2001/07/06 21:52:34 mickey Exp $ */
2 /*	$NetBSD: util.c,v 1.8 2000/03/14 08:11:53 sato Exp $ */
3 
4 /*-
5  * Copyright (c) 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Juergen Hannken-Illjes.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include <sys/time.h>
41 #include <dev/wscons/wsconsio.h>
42 #include <dev/wscons/wsksymdef.h>
43 #include <err.h>
44 #include <string.h>
45 #include <stdio.h>
46 #include <unistd.h>
47 #include "wsconsctl.h"
48 
49 #define TABLEN(t)		(sizeof(t)/sizeof(t[0]))
50 
51 extern struct wskbd_map_data kbmap;	/* from keyboard.c */
52 extern struct wskbd_map_data newkbmap;	/* from map_parse.y */
53 
54 struct nameint {
55 	int value;
56 	char *name;
57 };
58 
59 static const struct nameint kbtype_tab[] = {
60 	{ WSKBD_TYPE_LK201,	"lk201" },
61 	{ WSKBD_TYPE_LK401,	"lk401" },
62 	{ WSKBD_TYPE_PC_XT,	"pc-xt" },
63 	{ WSKBD_TYPE_PC_AT,	"pc-at" },
64 	{ WSKBD_TYPE_USB,	"usb" },
65 	{ WSKBD_TYPE_HPC_KBD,	"hpc-kbd" },
66 	{ WSKBD_TYPE_HPC_BTN,	"hpc-btn" },
67 	{ WSKBD_TYPE_ADB,	"adb" },
68 };
69 
70 static const struct nameint mstype_tab[] = {
71 	{ WSMOUSE_TYPE_VSXXX,	"dec-tc" },
72 	{ WSMOUSE_TYPE_PS2,	"ps2" },
73 	{ WSMOUSE_TYPE_USB,	"usb" },
74 	{ WSMOUSE_TYPE_LMS,	"lms" },
75 	{ WSMOUSE_TYPE_MMS,	"mms" },
76 	{ WSMOUSE_TYPE_TPANEL,	"touch-pannel" },
77 	{ WSMOUSE_TYPE_NEXT,	"NeXT" },
78 	{ WSMOUSE_TYPE_ARCHIMEDES, "archimedes" }
79 };
80 
81 static const struct nameint dpytype_tab[] = {
82 	{ WSDISPLAY_TYPE_UNKNOWN,	"unknown" },
83 	{ WSDISPLAY_TYPE_PM_MONO,	"dec-pm-mono" },
84 	{ WSDISPLAY_TYPE_PM_COLOR,	"dec-pm-color" },
85 	{ WSDISPLAY_TYPE_CFB,		"dec-cfb" },
86 	{ WSDISPLAY_TYPE_XCFB,		"dec-xcfb" },
87 	{ WSDISPLAY_TYPE_MFB,		"dec-mfb" },
88 	{ WSDISPLAY_TYPE_SFB,		"dec-sfb" },
89 	{ WSDISPLAY_TYPE_ISAVGA,	"vga-isa" },
90 	{ WSDISPLAY_TYPE_PCIVGA,	"vga-pci" },
91 	{ WSDISPLAY_TYPE_TGA,		"dec-tga-pci" },
92 	{ WSDISPLAY_TYPE_SFBP,		"dec-sfb+" },
93 	{ WSDISPLAY_TYPE_PCIMISC,	"generic-pci" },
94 	{ WSDISPLAY_TYPE_NEXTMONO,	"next-mono" },
95 	{ WSDISPLAY_TYPE_PX,		"dex-px" },
96 	{ WSDISPLAY_TYPE_PXG,		"dex-pxg" },
97 	{ WSDISPLAY_TYPE_TX,		"dex-tx" },
98 	{ WSDISPLAY_TYPE_HPCFB,		"generic-hpc" },
99 	{ WSDISPLAY_TYPE_VIDC,		"arm-vidc" },
100 	{ WSDISPLAY_TYPE_SPX,		"dec-spx" },
101 	{ WSDISPLAY_TYPE_GPX,		"dec-gpx" },
102 	{ WSDISPLAY_TYPE_LCG,		"dec-lcg" },
103 	{ WSDISPLAY_TYPE_VAX_MONO,	"dec-mono" },
104 	{ WSDISPLAY_TYPE_SB_P9100,	"p9100" },
105 	{ WSDISPLAY_TYPE_EGA,		"ega" },
106 	{ WSDISPLAY_TYPE_DCPVR,		"powervr" }
107 };
108 
109 static const struct nameint kbdenc_tab[] = {
110 	KB_ENCTAB
111 };
112 
113 static const struct nameint kbdvar_tab[] = {
114 	KB_VARTAB
115 };
116 
117 char *int2name __P((int, int, const struct nameint *, int));
118 int name2int __P((char *, const struct nameint *, int));
119 void print_kmap __P((struct wskbd_map_data *));
120 
121 struct field *
122 field_by_name(field_tab, name)
123 	struct field *field_tab;
124 	char *name;
125 {
126 	const char *p = strchr(name, '.');
127 
128 	if (!p++)
129 		errx(1, "%s: illigale variable name", name);
130 
131 	for (; field_tab->name; field_tab++)
132 		if (strcmp(field_tab->name, p) == 0)
133 			return (field_tab);
134 
135 	errx(1, "%s: not found", name);
136 }
137 
138 struct field *
139 field_by_value(field_tab, addr)
140 	struct field *field_tab;
141 	void *addr;
142 {
143 	for (; field_tab->name; field_tab++)
144 		if (field_tab->valp == addr)
145 			return (field_tab);
146 
147 	errx(1, "internal error: field_by_value: not found");
148 }
149 
150 char *
151 int2name(val, uflag, tab, len)
152 	int val, uflag, len;
153 	const struct nameint *tab;
154 {
155 	static char tmp[20];
156 	int i;
157 
158 	for (i = 0; i < len; i++)
159 		if (tab[i].value == val)
160 			return(tab[i].name);
161 
162 	if (uflag) {
163 		snprintf(tmp, sizeof(tmp), "unknown_%d", val);
164 		return(tmp);
165 	} else
166 		return(NULL);
167 }
168 
169 int
170 name2int(val, tab, len)
171 	char *val;
172 	const struct nameint *tab;
173 	int len;
174 {
175 	int i;
176 
177 	for (i = 0; i < len; i++)
178 		if (strcmp(tab[i].name, val) == 0)
179 			return(tab[i].value);
180 	return(-1);
181 }
182 
183 void
184 pr_field(pre, f, sep)
185 	const char *pre;
186 	struct field *f;
187 	const char *sep;
188 {
189 	char *p;
190 	u_int flags;
191 	int i;
192 
193 	if (sep)
194 		printf("%s.%s%s", pre, f->name, sep);
195 
196 	switch (f->format) {
197 	case FMT_UINT:
198 		printf("%u", *((u_int *) f->valp));
199 		break;
200 	case FMT_BOOL:
201 		printf("%s", *((u_int *) f->valp)? "on" : "off");
202 		break;
203 	case FMT_KBDTYPE:
204 		p = int2name(*((u_int *) f->valp), 1,
205 			     kbtype_tab, TABLEN(kbtype_tab));
206 		printf("%s", p);
207 		break;
208 	case FMT_MSTYPE:
209 		p = int2name(*((u_int *) f->valp), 1,
210 			     mstype_tab, TABLEN(mstype_tab));
211 		printf("%s", p);
212 		break;
213 	case FMT_DPYTYPE:
214 		p = int2name(*((u_int *) f->valp), 1,
215 			     dpytype_tab, TABLEN(dpytype_tab));
216 		printf("%s", p);
217 		break;
218 	case FMT_KBDENC:
219 		p = int2name(KB_ENCODING(*((u_int *) f->valp)), 1,
220 			     kbdenc_tab, TABLEN(kbdenc_tab));
221 		printf("%s", p);
222 
223 		flags = KB_VARIANT(*((u_int *) f->valp));
224 		for (i = 0; i < 32; i++) {
225 			if (!(flags & (1 << i)))
226 				continue;
227 			p = int2name(flags & (1 << i), 1,
228 				     kbdvar_tab, TABLEN(kbdvar_tab));
229 			printf(".%s", p);
230 		}
231 		break;
232 	case FMT_KBMAP:
233 		print_kmap((struct wskbd_map_data *) f->valp);
234 		break;
235 	default:
236 		errx(1, "internal error: pr_field: no format %d", f->format);
237 		break;
238 	}
239 
240 	printf("\n");
241 }
242 
243 void
244 rd_field(f, val, merge)
245 	struct field *f;
246 	char *val;
247 	int merge;
248 {
249 	int i;
250 	u_int u;
251 	char *p;
252 	struct wscons_keymap *mp;
253 
254 	switch (f->format) {
255 	case FMT_UINT:
256 		if (sscanf(val, "%u", &u) != 1)
257 			errx(1, "%s: not a number", val);
258 		if (merge)
259 			*((u_int *) f->valp) += u;
260 		else
261 			*((u_int *) f->valp) = u;
262 		break;
263 	case FMT_BOOL:
264 		if (*val != 'o' || (val[1] != 'n' &&
265 		    (val[1] != 'f' || val[2] != 'f')))
266 			errx(1, "%s: invalid value (on/off)", val);
267 		*((u_int *) f->valp) = val[1] == 'n'? 1 : 0;
268 		break;
269 	case FMT_KBDENC:
270 		p = strchr(val, '.');
271 		if (p != NULL)
272 			*p++ = '\0';
273 
274 		i = name2int(val, kbdenc_tab, TABLEN(kbdenc_tab));
275 		if (i == -1)
276 			errx(1, "%s: not a valid encoding", val);
277 		*((u_int *) f->valp) = i;
278 
279 		while (p) {
280 			val = p;
281 			p = strchr(p, '.');
282 			if (p != NULL)
283 				*p++ = '\0';
284 			i = name2int(val, kbdvar_tab, TABLEN(kbdvar_tab));
285 			if (i == -1)
286 				errx(1, "%s: not a valid variant", val);
287 			*((u_int *) f->valp) |= i;
288 		}
289 		break;
290 	case FMT_KBMAP:
291 		if (! merge)
292 			kbmap.maplen = 0;
293 		map_scan_setinput(val);
294 		yyparse();
295 		if (merge) {
296 			if (newkbmap.maplen < kbmap.maplen)
297 				newkbmap.maplen = kbmap.maplen;
298 			for (i = 0; i < kbmap.maplen; i++) {
299 				mp = newkbmap.map + i;
300 				if (mp->command == KS_voidSymbol &&
301 				    mp->group1[0] == KS_voidSymbol &&
302 				    mp->group1[1] == KS_voidSymbol &&
303 				    mp->group2[0] == KS_voidSymbol &&
304 				    mp->group2[1] == KS_voidSymbol)
305 					*mp = kbmap.map[i];
306 			}
307 		}
308 		kbmap.maplen = newkbmap.maplen;
309 		bcopy(newkbmap.map, kbmap.map,
310 		      kbmap.maplen*sizeof(struct wscons_keymap));
311 		break;
312 	default:
313 		errx(1, "internal error: rd_field: no format %d", f->format);
314 		break;
315 	}
316 }
317 
318 void
319 print_kmap(map)
320 	struct wskbd_map_data *map;
321 {
322 	int i;
323 	struct wscons_keymap *mp;
324 
325 	for (i = 0; i < map->maplen; i++) {
326 		mp = map->map + i;
327 
328 		if (mp->command == KS_voidSymbol &&
329 		    mp->group1[0] == KS_voidSymbol &&
330 		    mp->group1[1] == KS_voidSymbol &&
331 		    mp->group2[0] == KS_voidSymbol &&
332 		    mp->group2[1] == KS_voidSymbol)
333 			continue;
334 		printf("\n");
335 		printf("keycode %u =", i);
336 		if (mp->command != KS_voidSymbol)
337 			printf(" %s", ksym2name(mp->command));
338 		printf(" %s", ksym2name(mp->group1[0]));
339 		if (mp->group1[0] != mp->group1[1] ||
340 		    mp->group1[0] != mp->group2[0] ||
341 		    mp->group1[0] != mp->group2[1]) {
342 			printf(" %s", ksym2name(mp->group1[1]));
343 			if (mp->group1[0] != mp->group2[0] ||
344 			    mp->group1[1] != mp->group2[1]) {
345 				printf(" %s", ksym2name(mp->group2[0]));
346 				printf(" %s", ksym2name(mp->group2[1]));
347 			}
348 		}
349 	}
350 }
351