1 /* $NetBSD: util.c,v 1.27 2008/04/28 20:23:09 martin Exp $ */
4 * Copyright (c) 1998, 2006 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Juergen Hannken-Illjes and Julio M. Merino Vidal.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
34 #include <dev/wscons/wsconsio.h>
35 #include <dev/wscons/wsksymdef.h>
45 #include "wsconsctl.h"
47 #define TABLEN(t) (sizeof(t)/sizeof(t[0]))
49 extern struct wskbd_map_data kbmap
; /* from keyboard.c */
50 extern struct wskbd_map_data newkbmap
; /* from map_parse.y */
57 static struct nameint kbtype_tab
[] = {
58 { WSKBD_TYPE_LK201
, "lk201" },
59 { WSKBD_TYPE_LK401
, "lk401" },
60 { WSKBD_TYPE_PC_XT
, "pc-xt" },
61 { WSKBD_TYPE_PC_AT
, "pc-at" },
62 { WSKBD_TYPE_USB
, "usb" },
63 { WSKBD_TYPE_HPC_KBD
, "hpc-kbd" },
64 { WSKBD_TYPE_HPC_BTN
, "hpc-btn" },
65 { WSKBD_TYPE_ARCHIMEDES
, "archimedes" },
66 { WSKBD_TYPE_RISCPC
, "riscpc" },
67 { WSKBD_TYPE_ADB
, "adb" },
68 { WSKBD_TYPE_HIL
, "hil" },
69 { WSKBD_TYPE_AMIGA
, "amiga" },
70 { WSKBD_TYPE_MAPLE
, "maple" },
71 { WSKBD_TYPE_ATARI
, "atari" },
72 { WSKBD_TYPE_SUN
, "sun" },
73 { WSKBD_TYPE_SUN5
, "sun-type5" },
74 { WSKBD_TYPE_SGI
, "sgi" },
75 { WSKBD_TYPE_MATRIXKP
, "matrix-keypad" },
76 { WSKBD_TYPE_BLUETOOTH
, "bluetooth" },
79 static struct nameint mstype_tab
[] = {
80 { WSMOUSE_TYPE_VSXXX
, "dec-tc" },
81 { WSMOUSE_TYPE_PS2
, "ps2" },
82 { WSMOUSE_TYPE_USB
, "usb" },
83 { WSMOUSE_TYPE_LMS
, "logitech-bus" },
84 { WSMOUSE_TYPE_MMS
, "ms-inport" },
85 { WSMOUSE_TYPE_TPANEL
, "touch-panel" },
86 { WSMOUSE_TYPE_NEXT
, "next" },
87 { WSMOUSE_TYPE_ARCHIMEDES
, "archimedes" },
88 { WSMOUSE_TYPE_HIL
, "hil" },
89 { WSMOUSE_TYPE_AMIGA
, "amiga" },
90 { WSMOUSE_TYPE_MAXINE
, "dec-maxine" },
91 { WSMOUSE_TYPE_MAPLE
, "maple" },
92 { WSMOUSE_TYPE_BLUETOOTH
, "bluetooth" },
95 static struct nameint dpytype_tab
[] = {
96 { WSDISPLAY_TYPE_UNKNOWN
, "unknown" },
97 { WSDISPLAY_TYPE_PM_MONO
, "dec-pm-mono" },
98 { WSDISPLAY_TYPE_PM_COLOR
, "dec-pm-color" },
99 { WSDISPLAY_TYPE_CFB
, "dec-cfb" },
100 { WSDISPLAY_TYPE_XCFB
, "dec-xcfb" },
101 { WSDISPLAY_TYPE_MFB
, "dec-mfb" },
102 { WSDISPLAY_TYPE_SFB
, "dec-sfb" },
103 { WSDISPLAY_TYPE_ISAVGA
, "vga-isa" },
104 { WSDISPLAY_TYPE_PCIVGA
, "vga-pci" },
105 { WSDISPLAY_TYPE_TGA
, "dec-tga-pci" },
106 { WSDISPLAY_TYPE_SFBP
, "dec-sfb+" },
107 { WSDISPLAY_TYPE_PCIMISC
, "generic-pci" },
108 { WSDISPLAY_TYPE_NEXTMONO
, "next-mono" },
109 { WSDISPLAY_TYPE_PX
, "dec-px" },
110 { WSDISPLAY_TYPE_PXG
, "dec-pxg" },
111 { WSDISPLAY_TYPE_TX
, "dec-tx" },
112 { WSDISPLAY_TYPE_HPCFB
, "generic-hpc" },
113 { WSDISPLAY_TYPE_VIDC
, "arm-vidc" },
114 { WSDISPLAY_TYPE_SPX
, "dec-spx" },
115 { WSDISPLAY_TYPE_GPX
, "dec-gpx" },
116 { WSDISPLAY_TYPE_LCG
, "dec-lcg" },
117 { WSDISPLAY_TYPE_VAX_MONO
, "dec-vax-mono" },
118 { WSDISPLAY_TYPE_SB_P9100
, "sparcbook-p9100" },
119 { WSDISPLAY_TYPE_EGA
, "ega" },
120 { WSDISPLAY_TYPE_DCPVR
, "dreamcast-pvr" },
121 { WSDISPLAY_TYPE_GATOR
, "hp-gator" },
122 { WSDISPLAY_TYPE_TOPCAT
, "hp-topcat" },
123 { WSDISPLAY_TYPE_RENAISSANCE
, "hp-renaissance" },
124 { WSDISPLAY_TYPE_CATSEYE
, "hp-catseye" },
125 { WSDISPLAY_TYPE_DAVINCI
, "hp-davinci" },
126 { WSDISPLAY_TYPE_TIGER
, "hp-tiger" },
127 { WSDISPLAY_TYPE_HYPERION
, "hp-hyperion" },
128 { WSDISPLAY_TYPE_AMIGACC
, "amiga-cc" },
129 { WSDISPLAY_TYPE_SUN24
, "sun24" },
130 { WSDISPLAY_TYPE_NEWPORT
, "sgi-newport" },
131 { WSDISPLAY_TYPE_GR2
, "sgi-gr2" },
132 { WSDISPLAY_TYPE_SUNCG12
, "suncg12" },
133 { WSDISPLAY_TYPE_SUNCG14
, "suncg14" },
134 { WSDISPLAY_TYPE_SUNTCX
, "suntcx" },
135 { WSDISPLAY_TYPE_SUNFFB
, "sunffb" },
138 static struct nameint kbdenc_tab
[] = {
142 static struct nameint kbdvar_tab
[] = {
146 static struct nameint color_tab
[] = {
147 { WSCOL_UNSUPPORTED
, "unsupported" },
148 { WSCOL_BLACK
, "black" },
149 { WSCOL_RED
, "red" },
150 { WSCOL_GREEN
, "green" },
151 { WSCOL_BROWN
, "brown" },
152 { WSCOL_BLUE
, "blue" },
153 { WSCOL_MAGENTA
, "magenta" },
154 { WSCOL_CYAN
, "cyan" },
155 { WSCOL_WHITE
, "white" },
158 static struct nameint attr_tab
[] = {
159 { WSATTR_NONE
, "none" },
160 { WSATTR_REVERSE
, "reverse" },
161 { WSATTR_HILIT
, "hilit" },
162 { WSATTR_BLINK
, "blink" },
163 { WSATTR_UNDERLINE
, "underline" },
164 { WSATTR_WSCOLORS
, "color" },
167 static struct field
*field_tab
;
168 static int field_tab_len
;
170 static const char *int2name(int, int, struct nameint
*, int);
171 static int name2int(char *, struct nameint
*, int);
172 static void print_kmap(struct wskbd_map_data
*);
173 static unsigned int rd_bitfield(const char *);
174 static void pr_bitfield(unsigned int);
177 field_setup(struct field
*ftab
, int len
)
185 field_by_name(char *name
)
189 for (i
= 0; i
< field_tab_len
; i
++)
190 if (strcmp(field_tab
[i
].name
, name
) == 0)
191 return field_tab
+ i
;
193 errx(EXIT_FAILURE
, "%s: not found", name
);
197 field_by_value(void *addr
)
201 for (i
= 0; i
< field_tab_len
; i
++)
202 if (field_tab
[i
].valp
== addr
)
203 return field_tab
+ i
;
205 errx(EXIT_FAILURE
, "internal error: field_by_value: not found");
209 field_disable_by_value(void *addr
)
213 f
= field_by_value(addr
);
214 f
->flags
|= FLG_DISABLED
;
218 int2name(int val
, int uflag
, struct nameint
*tab
, int len
)
223 for (i
= 0; i
< len
; i
++)
224 if (tab
[i
].value
== val
)
228 (void)snprintf(tmp
, sizeof(tmp
), "unknown_%d", val
);
235 name2int(char *val
, struct nameint
*tab
, int len
)
239 for (i
= 0; i
< len
; i
++)
240 if (strcmp(tab
[i
].name
, val
) == 0)
246 pr_field(struct field
*f
, const char *sep
)
253 (void)printf("%s%s", f
->name
, sep
);
257 (void)printf("%u", *((unsigned int *) f
->valp
));
260 (void)printf("\"%s\"", *((char **) f
->valp
));
263 pr_bitfield(*((unsigned int *) f
->valp
));
266 p
= int2name(*((unsigned int *) f
->valp
), 1,
267 kbtype_tab
, TABLEN(kbtype_tab
));
268 (void)printf("%s", p
);
271 p
= int2name(*((unsigned int *) f
->valp
), 1,
272 mstype_tab
, TABLEN(mstype_tab
));
273 (void)printf("%s", p
);
276 p
= int2name(*((unsigned int *) f
->valp
), 1,
277 dpytype_tab
, TABLEN(dpytype_tab
));
278 (void)printf("%s", p
);
281 p
= int2name(KB_ENCODING(*((unsigned int *) f
->valp
)), 1,
282 kbdenc_tab
, TABLEN(kbdenc_tab
));
283 (void)printf("%s", p
);
285 flags
= KB_VARIANT(*((unsigned int *) f
->valp
));
286 for (i
= 0; i
< 32; i
++) {
287 if (!(flags
& (1 << i
)))
289 p
= int2name(flags
& (1 << i
), 1,
290 kbdvar_tab
, TABLEN(kbdvar_tab
));
291 (void)printf(".%s", p
);
295 print_kmap((struct wskbd_map_data
*) f
->valp
);
298 p
= int2name(*((unsigned int *) f
->valp
), 1,
299 color_tab
, TABLEN(color_tab
));
300 (void)printf("%s", p
);
306 if (*((unsigned int *) f
->valp
) & mask
) {
307 p
= int2name(*((unsigned int *) f
->valp
) & mask
,
308 1, attr_tab
, TABLEN(attr_tab
));
309 (void)printf("%s%s", first
? "" : ",", p
);
315 (void)printf("none");
318 errx(EXIT_FAILURE
, "internal error: pr_field: no format %d",
327 pr_bitfield(unsigned int f
)
331 (void)printf("none");
336 for (i
= 0, first
= 1, mask
= 1; i
< sizeof(f
) * 8; i
++) {
338 (void)printf("%s%u", first
? "" : " ", i
);
347 rd_field(struct field
*f
, char *val
, int merge
)
352 struct wscons_keymap
*mp
;
356 if (sscanf(val
, "%u", &u
) != 1)
357 errx(EXIT_FAILURE
, "%s: not a number", val
);
359 *((unsigned int *) f
->valp
) += u
;
361 *((unsigned int *) f
->valp
) = u
;
364 if ((*((char **) f
->valp
) = strdup(val
)) == NULL
)
365 err(EXIT_FAILURE
, "strdup");
368 *((unsigned int *) f
->valp
) = rd_bitfield(val
);
371 p
= strchr(val
, '.');
375 i
= name2int(val
, kbdenc_tab
, TABLEN(kbdenc_tab
));
377 errx(EXIT_FAILURE
, "%s: not a valid encoding", val
);
378 *((unsigned int *) f
->valp
) = i
;
385 i
= name2int(val
, kbdvar_tab
, TABLEN(kbdvar_tab
));
387 errx(EXIT_FAILURE
, "%s: not a valid variant",
389 *((unsigned int *) f
->valp
) |= i
;
395 map_scan_setinput(val
);
398 if (newkbmap
.maplen
< kbmap
.maplen
)
399 newkbmap
.maplen
= kbmap
.maplen
;
400 for (u
= 0; u
< kbmap
.maplen
; u
++) {
401 mp
= newkbmap
.map
+ u
;
402 if (mp
->command
== KS_voidSymbol
&&
403 mp
->group1
[0] == KS_voidSymbol
&&
404 mp
->group1
[1] == KS_voidSymbol
&&
405 mp
->group2
[0] == KS_voidSymbol
&&
406 mp
->group2
[1] == KS_voidSymbol
)
410 kbmap
.maplen
= newkbmap
.maplen
;
411 bcopy(newkbmap
.map
, kbmap
.map
,
412 kbmap
.maplen
* sizeof(struct wscons_keymap
));
415 i
= name2int(val
, color_tab
, TABLEN(color_tab
));
417 errx(EXIT_FAILURE
, "%s: not a valid color", val
);
418 *((unsigned int *) f
->valp
) = i
;
427 i
= name2int(val
, attr_tab
, TABLEN(attr_tab
));
429 errx(EXIT_FAILURE
, "%s: not a valid attribute",
431 *((unsigned int *) f
->valp
) |= i
;
435 errx(EXIT_FAILURE
, "internal error: rd_field: no format %d",
442 rd_bitfield(const char *str
)
452 while (*ptr
!= '\0') {
454 lval
= strtol(ptr
, &ep
, 10);
455 if (*ep
!= '\0' && *ep
!= ' ')
456 errx(EXIT_FAILURE
, "%s: not a valid number list", str
);
457 if (errno
== ERANGE
&& (lval
== LONG_MAX
|| lval
== LONG_MIN
))
458 errx(EXIT_FAILURE
, "%s: not a valid number list", str
);
459 if (lval
>= (long)sizeof(result
) * 8)
460 errx(EXIT_FAILURE
, "%ld: number out of range", lval
);
461 result
|= (1 << lval
);
472 print_kmap(struct wskbd_map_data
*map
)
475 struct wscons_keymap
*mp
;
477 for (i
= 0; i
< map
->maplen
; i
++) {
480 if (mp
->command
== KS_voidSymbol
&&
481 mp
->group1
[0] == KS_voidSymbol
&&
482 mp
->group1
[1] == KS_voidSymbol
&&
483 mp
->group2
[0] == KS_voidSymbol
&&
484 mp
->group2
[1] == KS_voidSymbol
)
487 (void)printf("keycode %u =", i
);
488 if (mp
->command
!= KS_voidSymbol
)
489 (void)printf(" %s", ksym2name(mp
->command
));
490 (void)printf(" %s", ksym2name(mp
->group1
[0]));
491 if (mp
->group1
[0] != mp
->group1
[1] ||
492 mp
->group1
[0] != mp
->group2
[0] ||
493 mp
->group1
[0] != mp
->group2
[1]) {
494 (void)printf(" %s", ksym2name(mp
->group1
[1]));
495 if (mp
->group1
[0] != mp
->group2
[0] ||
496 mp
->group1
[1] != mp
->group2
[1]) {
497 (void)printf(" %s", ksym2name(mp
->group2
[0]));
498 (void)printf(" %s", ksym2name(mp
->group2
[1]));