1 1.34 mlelstv /* $NetBSD: util.c,v 1.34 2024/10/20 08:46:02 mlelstv Exp $ */ 2 1.1 hannken 3 1.1 hannken /*- 4 1.31 khorben * Copyright (c) 1998, 2006, 2012 The NetBSD Foundation, Inc. 5 1.1 hannken * All rights reserved. 6 1.1 hannken * 7 1.1 hannken * This code is derived from software contributed to The NetBSD Foundation 8 1.24 jmmv * by Juergen Hannken-Illjes and Julio M. Merino Vidal. 9 1.1 hannken * 10 1.1 hannken * Redistribution and use in source and binary forms, with or without 11 1.1 hannken * modification, are permitted provided that the following conditions 12 1.1 hannken * are met: 13 1.1 hannken * 1. Redistributions of source code must retain the above copyright 14 1.1 hannken * notice, this list of conditions and the following disclaimer. 15 1.1 hannken * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 hannken * notice, this list of conditions and the following disclaimer in the 17 1.1 hannken * documentation and/or other materials provided with the distribution. 18 1.1 hannken * 19 1.1 hannken * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 hannken * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 hannken * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 hannken * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 hannken * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 hannken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 hannken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 hannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 hannken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 hannken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 hannken * POSSIBILITY OF SUCH DAMAGE. 30 1.1 hannken */ 31 1.1 hannken 32 1.1 hannken #include <sys/time.h> 33 1.25 jmmv 34 1.1 hannken #include <dev/wscons/wsconsio.h> 35 1.1 hannken #include <dev/wscons/wsksymdef.h> 36 1.33 mlelstv #include <dev/videomode/videomode.h> 37 1.33 mlelstv #include <dev/videomode/edidreg.h> 38 1.33 mlelstv #include <dev/videomode/edidvar.h> 39 1.24 jmmv 40 1.1 hannken #include <err.h> 41 1.24 jmmv #include <errno.h> 42 1.24 jmmv #include <limits.h> 43 1.24 jmmv #include <stdio.h> 44 1.24 jmmv #include <stdlib.h> 45 1.1 hannken #include <string.h> 46 1.1 hannken #include <unistd.h> 47 1.24 jmmv 48 1.1 hannken #include "wsconsctl.h" 49 1.1 hannken 50 1.1 hannken #define TABLEN(t) (sizeof(t)/sizeof(t[0])) 51 1.1 hannken 52 1.1 hannken extern struct wskbd_map_data kbmap; /* from keyboard.c */ 53 1.1 hannken extern struct wskbd_map_data newkbmap; /* from map_parse.y */ 54 1.1 hannken 55 1.1 hannken struct nameint { 56 1.1 hannken int value; 57 1.23 christos const char *name; 58 1.1 hannken }; 59 1.1 hannken 60 1.1 hannken static struct nameint kbtype_tab[] = { 61 1.9 ad { WSKBD_TYPE_LK201, "lk201" }, 62 1.9 ad { WSKBD_TYPE_LK401, "lk401" }, 63 1.9 ad { WSKBD_TYPE_PC_XT, "pc-xt" }, 64 1.9 ad { WSKBD_TYPE_PC_AT, "pc-at" }, 65 1.9 ad { WSKBD_TYPE_USB, "usb" }, 66 1.9 ad { WSKBD_TYPE_HPC_KBD, "hpc-kbd" }, 67 1.9 ad { WSKBD_TYPE_HPC_BTN, "hpc-btn" }, 68 1.9 ad { WSKBD_TYPE_ARCHIMEDES, "archimedes" }, 69 1.9 ad { WSKBD_TYPE_RISCPC, "riscpc" }, 70 1.10 gmcgarry { WSKBD_TYPE_ADB, "adb" }, 71 1.10 gmcgarry { WSKBD_TYPE_HIL, "hil" }, 72 1.12 jandberg { WSKBD_TYPE_AMIGA, "amiga" }, 73 1.15 itohy { WSKBD_TYPE_MAPLE, "maple" }, 74 1.16 thomas { WSKBD_TYPE_ATARI, "atari" }, 75 1.17 heas { WSKBD_TYPE_SUN, "sun" }, 76 1.17 heas { WSKBD_TYPE_SUN5, "sun-type5" }, 77 1.22 joff { WSKBD_TYPE_SGI, "sgi" }, 78 1.22 joff { WSKBD_TYPE_MATRIXKP, "matrix-keypad" }, 79 1.26 gdamore { WSKBD_TYPE_BLUETOOTH, "bluetooth" }, 80 1.1 hannken }; 81 1.1 hannken 82 1.1 hannken static struct nameint mstype_tab[] = { 83 1.9 ad { WSMOUSE_TYPE_VSXXX, "dec-tc" }, 84 1.9 ad { WSMOUSE_TYPE_PS2, "ps2" }, 85 1.9 ad { WSMOUSE_TYPE_USB, "usb" }, 86 1.9 ad { WSMOUSE_TYPE_LMS, "logitech-bus" }, 87 1.9 ad { WSMOUSE_TYPE_MMS, "ms-inport" }, 88 1.9 ad { WSMOUSE_TYPE_TPANEL, "touch-panel" }, 89 1.9 ad { WSMOUSE_TYPE_NEXT, "next" }, 90 1.9 ad { WSMOUSE_TYPE_ARCHIMEDES, "archimedes" }, 91 1.10 gmcgarry { WSMOUSE_TYPE_HIL, "hil" }, 92 1.12 jandberg { WSMOUSE_TYPE_AMIGA, "amiga" }, 93 1.13 ad { WSMOUSE_TYPE_MAXINE, "dec-maxine" }, 94 1.15 itohy { WSMOUSE_TYPE_MAPLE, "maple" }, 95 1.26 gdamore { WSMOUSE_TYPE_BLUETOOTH, "bluetooth" }, 96 1.1 hannken }; 97 1.1 hannken 98 1.1 hannken static struct nameint dpytype_tab[] = { 99 1.3 augustss { WSDISPLAY_TYPE_UNKNOWN, "unknown" }, 100 1.7 ad { WSDISPLAY_TYPE_PM_MONO, "dec-pm-mono" }, 101 1.7 ad { WSDISPLAY_TYPE_PM_COLOR, "dec-pm-color" }, 102 1.1 hannken { WSDISPLAY_TYPE_CFB, "dec-cfb" }, 103 1.7 ad { WSDISPLAY_TYPE_XCFB, "dec-xcfb" }, 104 1.1 hannken { WSDISPLAY_TYPE_MFB, "dec-mfb" }, 105 1.1 hannken { WSDISPLAY_TYPE_SFB, "dec-sfb" }, 106 1.1 hannken { WSDISPLAY_TYPE_ISAVGA, "vga-isa" }, 107 1.1 hannken { WSDISPLAY_TYPE_PCIVGA, "vga-pci" }, 108 1.1 hannken { WSDISPLAY_TYPE_TGA, "dec-tga-pci" }, 109 1.1 hannken { WSDISPLAY_TYPE_SFBP, "dec-sfb+" }, 110 1.1 hannken { WSDISPLAY_TYPE_PCIMISC, "generic-pci" }, 111 1.7 ad { WSDISPLAY_TYPE_NEXTMONO, "next-mono" }, 112 1.11 ad { WSDISPLAY_TYPE_PX, "dec-px" }, 113 1.11 ad { WSDISPLAY_TYPE_PXG, "dec-pxg" }, 114 1.11 ad { WSDISPLAY_TYPE_TX, "dec-tx" }, 115 1.7 ad { WSDISPLAY_TYPE_HPCFB, "generic-hpc" }, 116 1.9 ad { WSDISPLAY_TYPE_VIDC, "arm-vidc" }, 117 1.9 ad { WSDISPLAY_TYPE_SPX, "dec-spx" }, 118 1.9 ad { WSDISPLAY_TYPE_GPX, "dec-gpx" }, 119 1.9 ad { WSDISPLAY_TYPE_LCG, "dec-lcg" }, 120 1.9 ad { WSDISPLAY_TYPE_VAX_MONO, "dec-vax-mono" }, 121 1.9 ad { WSDISPLAY_TYPE_SB_P9100, "sparcbook-p9100" }, 122 1.9 ad { WSDISPLAY_TYPE_EGA, "ega" }, 123 1.9 ad { WSDISPLAY_TYPE_DCPVR, "dreamcast-pvr" }, 124 1.29 pooka { WSDISPLAY_TYPE_GBOX, "hp-gator" }, 125 1.10 gmcgarry { WSDISPLAY_TYPE_TOPCAT, "hp-topcat" }, 126 1.29 pooka { WSDISPLAY_TYPE_RBOX, "hp-renaissance" }, 127 1.10 gmcgarry { WSDISPLAY_TYPE_CATSEYE, "hp-catseye" }, 128 1.29 pooka { WSDISPLAY_TYPE_DVBOX, "hp-davinci" }, 129 1.29 pooka { WSDISPLAY_TYPE_TVRX, "hp-tiger" }, 130 1.10 gmcgarry { WSDISPLAY_TYPE_HYPERION, "hp-hyperion" }, 131 1.12 jandberg { WSDISPLAY_TYPE_AMIGACC, "amiga-cc" }, 132 1.18 heas { WSDISPLAY_TYPE_SUN24, "sun24" }, 133 1.18 heas { WSDISPLAY_TYPE_NEWPORT, "sgi-newport" }, 134 1.18 heas { WSDISPLAY_TYPE_GR2, "sgi-gr2" }, 135 1.18 heas { WSDISPLAY_TYPE_SUNCG12, "suncg12" }, 136 1.18 heas { WSDISPLAY_TYPE_SUNCG14, "suncg14" }, 137 1.18 heas { WSDISPLAY_TYPE_SUNTCX, "suntcx" }, 138 1.18 heas { WSDISPLAY_TYPE_SUNFFB, "sunffb" }, 139 1.34 mlelstv { WSDISPLAY_TYPE_STI, "hp-sti" }, 140 1.34 mlelstv { WSDISPLAY_TYPE_HDLCD, "hd44780" }, 141 1.34 mlelstv { WSDISPLAY_TYPE_VESA, "vesa" }, 142 1.34 mlelstv { WSDISPLAY_TYPE_XILFB, "xilinx" }, 143 1.34 mlelstv { WSDISPLAY_TYPE_LIGHT, "sgi-light" }, 144 1.34 mlelstv { WSDISPLAY_TYPE_GENFB, "genfb" }, 145 1.34 mlelstv { WSDISPLAY_TYPE_CRIME, "sgi-o2" }, 146 1.34 mlelstv { WSDISPLAY_TYPE_PXALCD, "pxa" }, 147 1.34 mlelstv { WSDISPLAY_TYPE_AG10, "fujitsu-ag10" }, 148 1.34 mlelstv { WSDISPLAY_TYPE_DL, "displaylink" }, 149 1.34 mlelstv { WSDISPLAY_TYPE_XVR1000, "sun-xvr1000" }, 150 1.34 mlelstv { WSDISPLAY_TYPE_LUNA, "omron-luna" }, 151 1.34 mlelstv { WSDISPLAY_TYPE_GRF, "grf" }, 152 1.34 mlelstv { WSDISPLAY_TYPE_VNC, "vnc" }, 153 1.34 mlelstv { WSDISPLAY_TYPE_VALKYRIE, "apple-valkyrie" }, 154 1.34 mlelstv { WSDISPLAY_TYPE_IMXIPU, "imx-ipu" }, 155 1.34 mlelstv { WSDISPLAY_TYPE_VC4, "videocore4" }, 156 1.34 mlelstv { WSDISPLAY_TYPE_OMAP3, "omap3530" }, 157 1.34 mlelstv { WSDISPLAY_TYPE_WINDERMERE, "windermere" }, 158 1.34 mlelstv { WSDISPLAY_TYPE_CLPS711X, "clps-711x" }, 159 1.34 mlelstv { WSDISPLAY_TYPE_ALLWINNER, "allwinner" }, 160 1.34 mlelstv { WSDISPLAY_TYPE_MGX, "ssb-mgx" }, 161 1.34 mlelstv { WSDISPLAY_TYPE_MESON, "amlogc-meson" }, 162 1.34 mlelstv { WSDISPLAY_TYPE_TEGRA, "nvidia-tegra" }, 163 1.34 mlelstv { WSDISPLAY_TYPE_PLATINUM, "platinum" }, 164 1.34 mlelstv { WSDISPLAY_TYPE_PLFB, "primcell-pl11x" }, 165 1.34 mlelstv { WSDISPLAY_TYPE_SSDFB, "ssdfb" }, 166 1.34 mlelstv { WSDISPLAY_TYPE_VC6, "videocore6" }, 167 1.1 hannken }; 168 1.1 hannken 169 1.1 hannken static struct nameint kbdenc_tab[] = { 170 1.5 drochner KB_ENCTAB 171 1.5 drochner }; 172 1.5 drochner 173 1.5 drochner static struct nameint kbdvar_tab[] = { 174 1.5 drochner KB_VARTAB 175 1.1 hannken }; 176 1.1 hannken 177 1.19 jmmv static struct nameint color_tab[] = { 178 1.19 jmmv { WSCOL_UNSUPPORTED, "unsupported" }, 179 1.19 jmmv { WSCOL_BLACK, "black" }, 180 1.19 jmmv { WSCOL_RED, "red" }, 181 1.19 jmmv { WSCOL_GREEN, "green" }, 182 1.19 jmmv { WSCOL_BROWN, "brown" }, 183 1.19 jmmv { WSCOL_BLUE, "blue" }, 184 1.19 jmmv { WSCOL_MAGENTA, "magenta" }, 185 1.19 jmmv { WSCOL_CYAN, "cyan" }, 186 1.19 jmmv { WSCOL_WHITE, "white" }, 187 1.19 jmmv }; 188 1.19 jmmv 189 1.19 jmmv static struct nameint attr_tab[] = { 190 1.19 jmmv { WSATTR_NONE, "none" }, 191 1.19 jmmv { WSATTR_REVERSE, "reverse" }, 192 1.19 jmmv { WSATTR_HILIT, "hilit" }, 193 1.19 jmmv { WSATTR_BLINK, "blink" }, 194 1.19 jmmv { WSATTR_UNDERLINE, "underline" }, 195 1.19 jmmv { WSATTR_WSCOLORS, "color" }, 196 1.19 jmmv }; 197 1.19 jmmv 198 1.1 hannken static struct field *field_tab; 199 1.1 hannken static int field_tab_len; 200 1.1 hannken 201 1.23 christos static const char *int2name(int, int, struct nameint *, int); 202 1.21 xtraeme static int name2int(char *, struct nameint *, int); 203 1.21 xtraeme static void print_kmap(struct wskbd_map_data *); 204 1.24 jmmv static unsigned int rd_bitfield(const char *); 205 1.24 jmmv static void pr_bitfield(unsigned int); 206 1.1 hannken 207 1.1 hannken void 208 1.21 xtraeme field_setup(struct field *ftab, int len) 209 1.1 hannken { 210 1.25 jmmv 211 1.1 hannken field_tab = ftab; 212 1.1 hannken field_tab_len = len; 213 1.1 hannken } 214 1.1 hannken 215 1.1 hannken struct field * 216 1.21 xtraeme field_by_name(char *name) 217 1.1 hannken { 218 1.1 hannken int i; 219 1.1 hannken 220 1.1 hannken for (i = 0; i < field_tab_len; i++) 221 1.1 hannken if (strcmp(field_tab[i].name, name) == 0) 222 1.25 jmmv return field_tab + i; 223 1.1 hannken 224 1.25 jmmv errx(EXIT_FAILURE, "%s: not found", name); 225 1.1 hannken } 226 1.1 hannken 227 1.1 hannken struct field * 228 1.21 xtraeme field_by_value(void *addr) 229 1.1 hannken { 230 1.1 hannken int i; 231 1.1 hannken 232 1.1 hannken for (i = 0; i < field_tab_len; i++) 233 1.1 hannken if (field_tab[i].valp == addr) 234 1.25 jmmv return field_tab + i; 235 1.1 hannken 236 1.25 jmmv errx(EXIT_FAILURE, "internal error: field_by_value: not found"); 237 1.1 hannken } 238 1.1 hannken 239 1.20 jmmv void 240 1.21 xtraeme field_disable_by_value(void *addr) 241 1.20 jmmv { 242 1.20 jmmv struct field *f; 243 1.20 jmmv 244 1.20 jmmv f = field_by_value(addr); 245 1.20 jmmv f->flags |= FLG_DISABLED; 246 1.20 jmmv } 247 1.20 jmmv 248 1.23 christos static const char * 249 1.21 xtraeme int2name(int val, int uflag, struct nameint *tab, int len) 250 1.1 hannken { 251 1.1 hannken static char tmp[20]; 252 1.1 hannken int i; 253 1.1 hannken 254 1.1 hannken for (i = 0; i < len; i++) 255 1.1 hannken if (tab[i].value == val) 256 1.25 jmmv return tab[i].name; 257 1.1 hannken 258 1.1 hannken if (uflag) { 259 1.25 jmmv (void)snprintf(tmp, sizeof(tmp), "unknown_%d", val); 260 1.25 jmmv return tmp; 261 1.1 hannken } else 262 1.25 jmmv return NULL; 263 1.1 hannken } 264 1.1 hannken 265 1.1 hannken static int 266 1.21 xtraeme name2int(char *val, struct nameint *tab, int len) 267 1.1 hannken { 268 1.1 hannken int i; 269 1.1 hannken 270 1.1 hannken for (i = 0; i < len; i++) 271 1.1 hannken if (strcmp(tab[i].name, val) == 0) 272 1.25 jmmv return tab[i].value; 273 1.25 jmmv return -1; 274 1.1 hannken } 275 1.1 hannken 276 1.1 hannken void 277 1.23 christos pr_field(struct field *f, const char *sep) 278 1.1 hannken { 279 1.23 christos const char *p; 280 1.25 jmmv unsigned int flags; 281 1.19 jmmv int first, i, mask; 282 1.33 mlelstv struct wsdisplayio_edid_info *info; 283 1.33 mlelstv struct edid_info edid; 284 1.1 hannken 285 1.1 hannken if (sep) 286 1.25 jmmv (void)printf("%s%s", f->name, sep); 287 1.1 hannken 288 1.1 hannken switch (f->format) { 289 1.1 hannken case FMT_UINT: 290 1.25 jmmv (void)printf("%u", *((unsigned int *) f->valp)); 291 1.1 hannken break; 292 1.31 khorben case FMT_INT: 293 1.31 khorben (void)printf("%d", *((int *) f->valp)); 294 1.31 khorben break; 295 1.14 hannken case FMT_STRING: 296 1.25 jmmv (void)printf("\"%s\"", *((char **) f->valp)); 297 1.14 hannken break; 298 1.24 jmmv case FMT_BITFIELD: 299 1.24 jmmv pr_bitfield(*((unsigned int *) f->valp)); 300 1.24 jmmv break; 301 1.1 hannken case FMT_KBDTYPE: 302 1.25 jmmv p = int2name(*((unsigned int *) f->valp), 1, 303 1.25 jmmv kbtype_tab, TABLEN(kbtype_tab)); 304 1.25 jmmv (void)printf("%s", p); 305 1.1 hannken break; 306 1.1 hannken case FMT_MSTYPE: 307 1.25 jmmv p = int2name(*((unsigned int *) f->valp), 1, 308 1.25 jmmv mstype_tab, TABLEN(mstype_tab)); 309 1.25 jmmv (void)printf("%s", p); 310 1.1 hannken break; 311 1.1 hannken case FMT_DPYTYPE: 312 1.25 jmmv p = int2name(*((unsigned int *) f->valp), 1, 313 1.25 jmmv dpytype_tab, TABLEN(dpytype_tab)); 314 1.25 jmmv (void)printf("%s", p); 315 1.1 hannken break; 316 1.1 hannken case FMT_KBDENC: 317 1.25 jmmv p = int2name(KB_ENCODING(*((unsigned int *) f->valp)), 1, 318 1.25 jmmv kbdenc_tab, TABLEN(kbdenc_tab)); 319 1.25 jmmv (void)printf("%s", p); 320 1.1 hannken 321 1.25 jmmv flags = KB_VARIANT(*((unsigned int *) f->valp)); 322 1.5 drochner for (i = 0; i < 32; i++) { 323 1.5 drochner if (!(flags & (1 << i))) 324 1.5 drochner continue; 325 1.5 drochner p = int2name(flags & (1 << i), 1, 326 1.25 jmmv kbdvar_tab, TABLEN(kbdvar_tab)); 327 1.25 jmmv (void)printf(".%s", p); 328 1.5 drochner } 329 1.1 hannken break; 330 1.1 hannken case FMT_KBMAP: 331 1.1 hannken print_kmap((struct wskbd_map_data *) f->valp); 332 1.1 hannken break; 333 1.19 jmmv case FMT_COLOR: 334 1.25 jmmv p = int2name(*((unsigned int *) f->valp), 1, 335 1.25 jmmv color_tab, TABLEN(color_tab)); 336 1.25 jmmv (void)printf("%s", p); 337 1.19 jmmv break; 338 1.19 jmmv case FMT_ATTRS: 339 1.19 jmmv mask = 0x10; 340 1.19 jmmv first = 1; 341 1.19 jmmv while (mask > 0) { 342 1.25 jmmv if (*((unsigned int *) f->valp) & mask) { 343 1.25 jmmv p = int2name(*((unsigned int *) f->valp) & mask, 344 1.25 jmmv 1, attr_tab, TABLEN(attr_tab)); 345 1.25 jmmv (void)printf("%s%s", first ? "" : ",", p); 346 1.19 jmmv first = 0; 347 1.19 jmmv } 348 1.19 jmmv mask >>= 1; 349 1.19 jmmv } 350 1.19 jmmv if (first) 351 1.25 jmmv (void)printf("none"); 352 1.19 jmmv break; 353 1.33 mlelstv case FMT_EDID: 354 1.33 mlelstv info = (struct wsdisplayio_edid_info *)f->valp; 355 1.33 mlelstv if (edid_parse(info->edid_data, &edid)) 356 1.33 mlelstv (void)printf("invalid"); 357 1.33 mlelstv else { 358 1.33 mlelstv (void)printf("\n"); 359 1.33 mlelstv edid_print(&edid); 360 1.33 mlelstv } 361 1.33 mlelstv break; 362 1.1 hannken default: 363 1.25 jmmv errx(EXIT_FAILURE, "internal error: pr_field: no format %d", 364 1.25 jmmv f->format); 365 1.1 hannken break; 366 1.1 hannken } 367 1.1 hannken 368 1.25 jmmv (void)printf("\n"); 369 1.1 hannken } 370 1.1 hannken 371 1.24 jmmv static void 372 1.24 jmmv pr_bitfield(unsigned int f) 373 1.24 jmmv { 374 1.24 jmmv 375 1.24 jmmv if (f == 0) 376 1.25 jmmv (void)printf("none"); 377 1.24 jmmv else { 378 1.28 lukem unsigned int i; 379 1.28 lukem int first, mask; 380 1.24 jmmv 381 1.24 jmmv for (i = 0, first = 1, mask = 1; i < sizeof(f) * 8; i++) { 382 1.24 jmmv if (f & mask) { 383 1.28 lukem (void)printf("%s%u", first ? "" : " ", i); 384 1.24 jmmv first = 0; 385 1.24 jmmv } 386 1.24 jmmv mask = mask << 1; 387 1.24 jmmv } 388 1.24 jmmv } 389 1.24 jmmv } 390 1.24 jmmv 391 1.1 hannken void 392 1.21 xtraeme rd_field(struct field *f, char *val, int merge) 393 1.1 hannken { 394 1.1 hannken int i; 395 1.25 jmmv unsigned int u; 396 1.1 hannken char *p; 397 1.1 hannken struct wscons_keymap *mp; 398 1.1 hannken 399 1.1 hannken switch (f->format) { 400 1.1 hannken case FMT_UINT: 401 1.1 hannken if (sscanf(val, "%u", &u) != 1) 402 1.25 jmmv errx(EXIT_FAILURE, "%s: not a number", val); 403 1.1 hannken if (merge) 404 1.25 jmmv *((unsigned int *) f->valp) += u; 405 1.1 hannken else 406 1.25 jmmv *((unsigned int *) f->valp) = u; 407 1.14 hannken break; 408 1.31 khorben case FMT_INT: 409 1.31 khorben if (sscanf(val, "%d", &i) != 1) 410 1.31 khorben errx(EXIT_FAILURE, "%s: not a number", val); 411 1.31 khorben if (merge) 412 1.31 khorben *((int *) f->valp) += i; 413 1.31 khorben else 414 1.31 khorben *((int *) f->valp) = i; 415 1.31 khorben break; 416 1.14 hannken case FMT_STRING: 417 1.14 hannken if ((*((char **) f->valp) = strdup(val)) == NULL) 418 1.25 jmmv err(EXIT_FAILURE, "strdup"); 419 1.1 hannken break; 420 1.24 jmmv case FMT_BITFIELD: 421 1.24 jmmv *((unsigned int *) f->valp) = rd_bitfield(val); 422 1.24 jmmv break; 423 1.1 hannken case FMT_KBDENC: 424 1.1 hannken p = strchr(val, '.'); 425 1.1 hannken if (p != NULL) 426 1.1 hannken *p++ = '\0'; 427 1.1 hannken 428 1.1 hannken i = name2int(val, kbdenc_tab, TABLEN(kbdenc_tab)); 429 1.1 hannken if (i == -1) 430 1.25 jmmv errx(EXIT_FAILURE, "%s: not a valid encoding", val); 431 1.25 jmmv *((unsigned int *) f->valp) = i; 432 1.1 hannken 433 1.5 drochner while (p) { 434 1.5 drochner val = p; 435 1.5 drochner p = strchr(p, '.'); 436 1.5 drochner if (p != NULL) 437 1.5 drochner *p++ = '\0'; 438 1.5 drochner i = name2int(val, kbdvar_tab, TABLEN(kbdvar_tab)); 439 1.5 drochner if (i == -1) 440 1.25 jmmv errx(EXIT_FAILURE, "%s: not a valid variant", 441 1.25 jmmv val); 442 1.25 jmmv *((unsigned int *) f->valp) |= i; 443 1.5 drochner } 444 1.1 hannken break; 445 1.1 hannken case FMT_KBMAP: 446 1.1 hannken if (! merge) 447 1.1 hannken kbmap.maplen = 0; 448 1.1 hannken map_scan_setinput(val); 449 1.1 hannken yyparse(); 450 1.1 hannken if (merge) { 451 1.1 hannken if (newkbmap.maplen < kbmap.maplen) 452 1.1 hannken newkbmap.maplen = kbmap.maplen; 453 1.28 lukem for (u = 0; u < kbmap.maplen; u++) { 454 1.28 lukem mp = newkbmap.map + u; 455 1.1 hannken if (mp->command == KS_voidSymbol && 456 1.1 hannken mp->group1[0] == KS_voidSymbol && 457 1.1 hannken mp->group1[1] == KS_voidSymbol && 458 1.1 hannken mp->group2[0] == KS_voidSymbol && 459 1.1 hannken mp->group2[1] == KS_voidSymbol) 460 1.28 lukem *mp = kbmap.map[u]; 461 1.1 hannken } 462 1.1 hannken } 463 1.1 hannken kbmap.maplen = newkbmap.maplen; 464 1.32 mlelstv memcpy(kbmap.map, newkbmap.map, 465 1.25 jmmv kbmap.maplen * sizeof(struct wscons_keymap)); 466 1.1 hannken break; 467 1.19 jmmv case FMT_COLOR: 468 1.19 jmmv i = name2int(val, color_tab, TABLEN(color_tab)); 469 1.19 jmmv if (i == -1) 470 1.25 jmmv errx(EXIT_FAILURE, "%s: not a valid color", val); 471 1.25 jmmv *((unsigned int *) f->valp) = i; 472 1.19 jmmv break; 473 1.19 jmmv case FMT_ATTRS: 474 1.19 jmmv p = val; 475 1.19 jmmv while (p) { 476 1.19 jmmv val = p; 477 1.19 jmmv p = strchr(p, ','); 478 1.19 jmmv if (p != NULL) 479 1.19 jmmv *p++ = '\0'; 480 1.19 jmmv i = name2int(val, attr_tab, TABLEN(attr_tab)); 481 1.19 jmmv if (i == -1) 482 1.25 jmmv errx(EXIT_FAILURE, "%s: not a valid attribute", 483 1.25 jmmv val); 484 1.25 jmmv *((unsigned int *) f->valp) |= i; 485 1.19 jmmv } 486 1.19 jmmv break; 487 1.1 hannken default: 488 1.25 jmmv errx(EXIT_FAILURE, "internal error: rd_field: no format %d", 489 1.25 jmmv f->format); 490 1.1 hannken break; 491 1.1 hannken } 492 1.1 hannken } 493 1.1 hannken 494 1.24 jmmv static unsigned int 495 1.24 jmmv rd_bitfield(const char *str) 496 1.24 jmmv { 497 1.24 jmmv const char *ptr; 498 1.24 jmmv char *ep; 499 1.24 jmmv long lval; 500 1.24 jmmv unsigned int result; 501 1.24 jmmv 502 1.24 jmmv ep = NULL; 503 1.24 jmmv ptr = str; 504 1.24 jmmv result = 0; 505 1.24 jmmv while (*ptr != '\0') { 506 1.24 jmmv errno = 0; 507 1.24 jmmv lval = strtol(ptr, &ep, 10); 508 1.24 jmmv if (*ep != '\0' && *ep != ' ') 509 1.25 jmmv errx(EXIT_FAILURE, "%s: not a valid number list", str); 510 1.24 jmmv if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) 511 1.25 jmmv errx(EXIT_FAILURE, "%s: not a valid number list", str); 512 1.28 lukem if (lval >= (long)sizeof(result) * 8) 513 1.25 jmmv errx(EXIT_FAILURE, "%ld: number out of range", lval); 514 1.24 jmmv result |= (1 << lval); 515 1.24 jmmv 516 1.24 jmmv ptr = ep; 517 1.24 jmmv while (*ptr == ' ') 518 1.24 jmmv ptr++; 519 1.24 jmmv } 520 1.24 jmmv 521 1.24 jmmv return result; 522 1.24 jmmv } 523 1.24 jmmv 524 1.1 hannken static void 525 1.21 xtraeme print_kmap(struct wskbd_map_data *map) 526 1.1 hannken { 527 1.28 lukem unsigned int i; 528 1.1 hannken struct wscons_keymap *mp; 529 1.1 hannken 530 1.1 hannken for (i = 0; i < map->maplen; i++) { 531 1.1 hannken mp = map->map + i; 532 1.1 hannken 533 1.1 hannken if (mp->command == KS_voidSymbol && 534 1.1 hannken mp->group1[0] == KS_voidSymbol && 535 1.1 hannken mp->group1[1] == KS_voidSymbol && 536 1.1 hannken mp->group2[0] == KS_voidSymbol && 537 1.1 hannken mp->group2[1] == KS_voidSymbol) 538 1.1 hannken continue; 539 1.25 jmmv (void)printf("\n"); 540 1.25 jmmv (void)printf("keycode %u =", i); 541 1.1 hannken if (mp->command != KS_voidSymbol) 542 1.25 jmmv (void)printf(" %s", ksym2name(mp->command)); 543 1.25 jmmv (void)printf(" %s", ksym2name(mp->group1[0])); 544 1.1 hannken if (mp->group1[0] != mp->group1[1] || 545 1.1 hannken mp->group1[0] != mp->group2[0] || 546 1.1 hannken mp->group1[0] != mp->group2[1]) { 547 1.25 jmmv (void)printf(" %s", ksym2name(mp->group1[1])); 548 1.1 hannken if (mp->group1[0] != mp->group2[0] || 549 1.1 hannken mp->group1[1] != mp->group2[1]) { 550 1.25 jmmv (void)printf(" %s", ksym2name(mp->group2[0])); 551 1.25 jmmv (void)printf(" %s", ksym2name(mp->group2[1])); 552 1.1 hannken } 553 1.1 hannken } 554 1.1 hannken } 555 1.1 hannken } 556 1.33 mlelstv 557