kbd_wscons.c revision 1.1
1/* $OpenBSD: kbd_wscons.c,v 1.1 2001/03/08 08:00:16 maja Exp $ */ 2 3/* 4 * Copyright (c) 2001 Mats O Jansson. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Mats O Jansson. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <err.h> 33#include <errno.h> 34#include <kvm.h> 35#include <fcntl.h> 36#include <limits.h> 37#include <nlist.h> 38#include <stdio.h> 39#include <sys/ioctl.h> 40#include <sys/time.h> 41#include <dev/wscons/wsconsio.h> 42#include <dev/wscons/wsksymdef.h> 43 44#define NUM_KBD 10 45 46#define SA_PCKBD 0 47#define SA_UKBD 1 48#define SA_AKBD 2 49 50struct nlist nl[] = { 51 { "_pckbd_keydesctab" }, 52 { "_ukbd_keydesctab" }, 53 { "_akbd_keydesctab" }, 54 { NULL }, 55}; 56 57char *kbtype_tab[] = { 58 "pc-xt/pc-at", 59 "usb", 60 "adb", 61}; 62 63struct nameint { 64 int value; 65 char *name; 66}; 67 68struct nameint kbdenc_tab[] = { 69 KB_ENCTAB 70 , 71 { 0, 0 } 72}; 73 74struct nameint kbdvar_tab[] = { 75 KB_VARTAB 76 , 77 { 0, 0 } 78}; 79 80extern char *__progname; 81 82void 83kbd_show_enc(kd, idx) 84 kvm_t *kd; 85 int idx; 86{ 87 struct wscons_keydesc r; 88 unsigned long p; 89 struct nameint *n; 90 91 printf("tables available for %s keyboard:\nencoding\n\n", 92 kbtype_tab[idx]); 93 p = nl[idx].n_value; 94 kvm_read(kd, p, &r, sizeof(r)); 95 while (r.name != 0) { 96 n = &kbdenc_tab[0]; 97 while(n->value) { 98 if (n->value == KB_ENCODING(r.name)) { 99 printf("%s",n->name); 100 } 101 n++; 102 } 103 n = &kbdvar_tab[0]; 104 while(n->value) { 105 if ((n->value & KB_VARIANT(r.name)) == n->value) { 106 printf(".%s",n->name); 107 } 108 n++; 109 } 110 printf("\n"); 111 p += sizeof(r); 112 kvm_read(kd, p, &r, sizeof(r)); 113 } 114 printf("\n"); 115} 116 117void 118kbd_list() 119{ 120 int fd, i, kbtype, ret; 121 kvm_t *kd; 122 char device[sizeof "/dev/wskbd00"]; 123 char errbuf[_POSIX2_LINE_MAX]; 124 int pc_kbd = 0; 125 int usb_kbd = 0; 126 int adb_kbd = 0; 127 128 /* Go through all keyboards. */ 129 for (i = 0; i < NUM_KBD; i++) { 130 (void) sprintf(device, "/dev/wskbd%d", i); 131 fd = open(device, O_WRONLY); 132 if (fd < 0) 133 fd = open(device, O_RDONLY); 134 if (fd >= 0) { 135 if (ioctl(fd, WSKBDIO_GTYPE, &kbtype) < 0) 136 err(1, "WDKBDIO_GTYPE"); 137 if ((kbtype == WSKBD_TYPE_PC_XT) || 138 (kbtype == WSKBD_TYPE_PC_AT)) 139 pc_kbd++; 140 if (kbtype == WSKBD_TYPE_USB) 141 usb_kbd++; 142 if (kbtype == WSKBD_TYPE_ADB) 143 adb_kbd++; 144 close(fd); 145 } 146 } 147 148 if ((kd = kvm_openfiles(NULL,NULL,NULL,O_RDONLY, errbuf)) == 0) 149 errx(1, "kvm_openfiles: %s", errbuf); 150 151 if ((ret = kvm_nlist(kd, nl)) == -1) 152 errx(1, "kvm_nlist: %s", kvm_geterr(kd)); 153 154 if (pc_kbd > 0) 155 kbd_show_enc(kd, SA_PCKBD); 156 157 if (usb_kbd > 0) 158 kbd_show_enc(kd, SA_UKBD); 159 160 if (adb_kbd > 0) 161 kbd_show_enc(kd, SA_AKBD); 162 163 kvm_close(kd); 164} 165 166void 167kbd_set(name, verbose) 168 char *name; 169 int verbose; 170{ 171 char buf[_POSIX2_LINE_MAX]; 172 char *c,*b; 173 struct nameint *n; 174 int map = 0,v,i,fd; 175 char device[sizeof "/dev/wskbd00"]; 176 177 c = name; 178 b = buf; 179 while((*c != '.') && (*c != '\0')) { 180 *b++ = *c++; 181 } 182 *b = '\0'; 183 n = &kbdenc_tab[0]; 184 while(n->value) { 185 if (strcmp(n->name,buf) == 0) { 186 map = n->value; 187 } 188 n++; 189 } 190 if (map == 0) 191 errx(1, "unknown encodeing %s", buf); 192 while(*c == '.') { 193 b = buf; 194 c++; 195 while((*c != '.') && (*c != '\0')) { 196 *b++ = *c++; 197 } 198 *b = '\0'; 199 v = 0; 200 n = &kbdvar_tab[0]; 201 while(n->value) { 202 if (strcmp(n->name,buf) == 0) { 203 v = n->value; 204 } 205 n++; 206 } 207 if (v == 0) 208 errx(1, "unknown variant %s", buf); 209 map |= v; 210 } 211 212 /* Go through all keyboards. */ 213 v = 0; 214 for (i = 0; i < NUM_KBD; i++) { 215 (void) sprintf(device, "/dev/wskbd%d", i); 216 fd = open(device, O_WRONLY); 217 if (fd < 0) 218 fd = open(device, O_RDONLY); 219 if (fd >= 0) { 220 if (ioctl(fd, WSKBDIO_SETENCODING, &map) < 0) { 221 if (errno == EINVAL) { 222 fprintf(stderr, "%s: unsupported encoding %s on %s\n", 223 __progname, name, device); 224 } else { 225 err(1, "WDKBDIO_SETENCODING: %s", device); 226 } 227 v--; 228 } 229 v++; 230 close(fd); 231 } 232 } 233 234 if (verbose && v > 0) 235 fprintf(stderr, "keyboard mapping set to %s\n", name); 236} 237