1 /* $NetBSD: keyboard.c,v 1.7 2005/01/19 20:37:52 xtraeme Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Juergen Hannken-Illjes. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/ioctl.h> 40 #include <sys/time.h> 41 #include <dev/wscons/wsksymdef.h> 42 #include <dev/wscons/wsconsio.h> 43 #include <err.h> 44 #include <errno.h> 45 #include "wsconsctl.h" 46 47 static int kbtype; 48 static int keyclick; 49 static struct wskbd_bell_data bell; 50 static struct wskbd_bell_data dfbell; 51 static struct wscons_keymap mapdata[KS_NUMKEYCODES]; 52 struct wskbd_map_data kbmap = { KS_NUMKEYCODES, mapdata }; /* used in map_parse.y 53 and in util.c */ 54 static struct wskbd_keyrepeat_data repeat; 55 static struct wskbd_keyrepeat_data dfrepeat; 56 static struct wskbd_scroll_data scroll; 57 static int ledstate; 58 static kbd_t kbdencoding; 59 static int havescroll = 1; 60 61 struct field keyboard_field_tab[] = { 62 { "type", &kbtype, FMT_KBDTYPE, FLG_RDONLY }, 63 { "bell.pitch", &bell.pitch, FMT_UINT, FLG_MODIFY }, 64 { "bell.period", &bell.period, FMT_UINT, FLG_MODIFY }, 65 { "bell.volume", &bell.volume, FMT_UINT, FLG_MODIFY }, 66 { "bell.pitch.default", &dfbell.pitch, FMT_UINT, FLG_MODIFY }, 67 { "bell.period.default", &dfbell.period, FMT_UINT, FLG_MODIFY }, 68 { "bell.volume.default", &dfbell.volume, FMT_UINT, FLG_MODIFY }, 69 { "map", &kbmap, FMT_KBMAP, FLG_MODIFY|FLG_NOAUTO }, 70 { "repeat.del1", &repeat.del1, FMT_UINT, FLG_MODIFY }, 71 { "repeat.deln", &repeat.delN, FMT_UINT, FLG_MODIFY }, 72 { "repeat.del1.default", &dfrepeat.del1, FMT_UINT, FLG_MODIFY }, 73 { "repeat.deln.default", &dfrepeat.delN, FMT_UINT, FLG_MODIFY }, 74 { "ledstate", &ledstate, FMT_UINT, 0 }, 75 { "encoding", &kbdencoding, FMT_KBDENC, FLG_MODIFY }, 76 { "keyclick", &keyclick, FMT_UINT, FLG_MODIFY }, 77 { "scroll.mode", &scroll.mode, FMT_UINT, FLG_MODIFY }, 78 { "scroll.modifier", &scroll.modifier, FMT_UINT, FLG_MODIFY }, 79 }; 80 81 int keyboard_field_tab_len = sizeof(keyboard_field_tab)/ 82 sizeof(keyboard_field_tab[0]); 83 84 void 85 keyboard_get_values(int fd) 86 { 87 if (field_by_value(&kbtype)->flags & FLG_GET) 88 if (ioctl(fd, WSKBDIO_GTYPE, &kbtype) < 0) 89 err(1, "WSKBDIO_GTYPE"); 90 91 bell.which = 0; 92 if (field_by_value(&bell.pitch)->flags & FLG_GET) 93 bell.which |= WSKBD_BELL_DOPITCH; 94 if (field_by_value(&bell.period)->flags & FLG_GET) 95 bell.which |= WSKBD_BELL_DOPERIOD; 96 if (field_by_value(&bell.volume)->flags & FLG_GET) 97 bell.which |= WSKBD_BELL_DOVOLUME; 98 if (bell.which != 0 && ioctl(fd, WSKBDIO_GETBELL, &bell) < 0) 99 err(1, "WSKBDIO_GETBELL"); 100 101 dfbell.which = 0; 102 if (field_by_value(&dfbell.pitch)->flags & FLG_GET) 103 dfbell.which |= WSKBD_BELL_DOPITCH; 104 if (field_by_value(&dfbell.period)->flags & FLG_GET) 105 dfbell.which |= WSKBD_BELL_DOPERIOD; 106 if (field_by_value(&dfbell.volume)->flags & FLG_GET) 107 dfbell.which |= WSKBD_BELL_DOVOLUME; 108 if (dfbell.which != 0 && 109 ioctl(fd, WSKBDIO_GETDEFAULTBELL, &dfbell) < 0) 110 err(1, "WSKBDIO_GETDEFAULTBELL"); 111 112 if (field_by_value(&kbmap)->flags & FLG_GET) { 113 kbmap.maplen = KS_NUMKEYCODES; 114 if (ioctl(fd, WSKBDIO_GETMAP, &kbmap) < 0) 115 err(1, "WSKBDIO_GETMAP"); 116 } 117 118 repeat.which = 0; 119 if (field_by_value(&repeat.del1)->flags & FLG_GET) 120 repeat.which |= WSKBD_KEYREPEAT_DODEL1; 121 if (field_by_value(&repeat.delN)->flags & FLG_GET) 122 repeat.which |= WSKBD_KEYREPEAT_DODELN; 123 if (repeat.which != 0 && 124 ioctl(fd, WSKBDIO_GETKEYREPEAT, &repeat) < 0) 125 err(1, "WSKBDIO_GETKEYREPEAT"); 126 127 dfrepeat.which = 0; 128 if (field_by_value(&dfrepeat.del1)->flags & FLG_GET) 129 dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1; 130 if (field_by_value(&dfrepeat.delN)->flags & FLG_GET) 131 dfrepeat.which |= WSKBD_KEYREPEAT_DODELN; 132 if (dfrepeat.which != 0 && 133 ioctl(fd, WSKBDIO_GETKEYREPEAT, &dfrepeat) < 0) 134 err(1, "WSKBDIO_GETKEYREPEAT"); 135 136 if (field_by_value(&ledstate)->flags & FLG_GET) 137 if (ioctl(fd, WSKBDIO_GETLEDS, &ledstate) < 0) 138 err(1, "WSKBDIO_GETLEDS"); 139 140 if (field_by_value(&kbdencoding)->flags & FLG_GET) 141 if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) < 0) 142 err(1, "WSKBDIO_GETENCODING"); 143 144 if (field_by_value(&keyclick)->flags & FLG_GET) { 145 ioctl(fd, WSKBDIO_GETKEYCLICK, &keyclick); 146 /* Optional; don't complain. */ 147 } 148 149 scroll.which = 0; 150 if (field_by_value(&scroll.mode)->flags & FLG_GET) 151 scroll.which |= WSKBD_SCROLL_DOMODE; 152 if (field_by_value(&scroll.modifier)->flags & FLG_GET) 153 scroll.which |= WSKBD_SCROLL_DOMODIFIER; 154 if (scroll.which != 0) { 155 if (ioctl(fd, WSKBDIO_GETSCROLL, &scroll) == -1) { 156 if (errno != ENODEV) 157 err(1, "WSKBDIO_GETSCROLL"); 158 else 159 havescroll = 0; 160 } 161 } 162 } 163 164 void 165 keyboard_put_values(int fd) 166 { 167 bell.which = 0; 168 if (field_by_value(&bell.pitch)->flags & FLG_SET) 169 bell.which |= WSKBD_BELL_DOPITCH; 170 if (field_by_value(&bell.period)->flags & FLG_SET) 171 bell.which |= WSKBD_BELL_DOPERIOD; 172 if (field_by_value(&bell.volume)->flags & FLG_SET) 173 bell.which |= WSKBD_BELL_DOVOLUME; 174 if (bell.which != 0 && ioctl(fd, WSKBDIO_SETBELL, &bell) < 0) 175 err(1, "WSKBDIO_SETBELL"); 176 if (bell.which & WSKBD_BELL_DOPITCH) 177 pr_field(field_by_value(&bell.pitch), " -> "); 178 if (bell.which & WSKBD_BELL_DOPERIOD) 179 pr_field(field_by_value(&bell.period), " -> "); 180 if (bell.which & WSKBD_BELL_DOVOLUME) 181 pr_field(field_by_value(&bell.volume), " -> "); 182 183 dfbell.which = 0; 184 if (field_by_value(&dfbell.pitch)->flags & FLG_SET) 185 dfbell.which |= WSKBD_BELL_DOPITCH; 186 if (field_by_value(&dfbell.period)->flags & FLG_SET) 187 dfbell.which |= WSKBD_BELL_DOPERIOD; 188 if (field_by_value(&dfbell.volume)->flags & FLG_SET) 189 dfbell.which |= WSKBD_BELL_DOVOLUME; 190 if (dfbell.which != 0 && 191 ioctl(fd, WSKBDIO_SETDEFAULTBELL, &dfbell) < 0) 192 err(1, "WSKBDIO_SETDEFAULTBELL"); 193 if (dfbell.which & WSKBD_BELL_DOPITCH) 194 pr_field(field_by_value(&dfbell.pitch), " -> "); 195 if (dfbell.which & WSKBD_BELL_DOPERIOD) 196 pr_field(field_by_value(&dfbell.period), " -> "); 197 if (dfbell.which & WSKBD_BELL_DOVOLUME) 198 pr_field(field_by_value(&dfbell.volume), " -> "); 199 200 if (field_by_value(&kbmap)->flags & FLG_SET) { 201 if (ioctl(fd, WSKBDIO_SETMAP, &kbmap) < 0) 202 err(1, "WSKBDIO_SETMAP"); 203 pr_field(field_by_value(&kbmap), " -> "); 204 } 205 206 repeat.which = 0; 207 if (field_by_value(&repeat.del1)->flags & FLG_SET) 208 repeat.which |= WSKBD_KEYREPEAT_DODEL1; 209 if (field_by_value(&repeat.delN)->flags & FLG_SET) 210 repeat.which |= WSKBD_KEYREPEAT_DODELN; 211 if (repeat.which != 0 && 212 ioctl(fd, WSKBDIO_SETKEYREPEAT, &repeat) < 0) 213 err(1, "WSKBDIO_SETKEYREPEAT"); 214 if (repeat.which & WSKBD_KEYREPEAT_DODEL1) 215 pr_field(field_by_value(&repeat.del1), " -> "); 216 if (repeat.which & WSKBD_KEYREPEAT_DODELN) 217 pr_field(field_by_value(&repeat.delN), " -> "); 218 219 dfrepeat.which = 0; 220 if (field_by_value(&dfrepeat.del1)->flags & FLG_SET) 221 dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1; 222 if (field_by_value(&dfrepeat.delN)->flags & FLG_SET) 223 dfrepeat.which |= WSKBD_KEYREPEAT_DODELN; 224 if (dfrepeat.which != 0 && 225 ioctl(fd, WSKBDIO_SETDEFAULTKEYREPEAT, &dfrepeat) < 0) 226 err(1, "WSKBDIO_SETDEFAULTKEYREPEAT"); 227 if (dfrepeat.which &WSKBD_KEYREPEAT_DODEL1) 228 pr_field(field_by_value(&dfrepeat.del1), " -> "); 229 if (dfrepeat.which & WSKBD_KEYREPEAT_DODELN) 230 pr_field(field_by_value(&dfrepeat.delN), " -> "); 231 232 if (field_by_value(&ledstate)->flags & FLG_SET) { 233 if (ioctl(fd, WSKBDIO_SETLEDS, &ledstate) < 0) 234 err(1, "WSKBDIO_SETLEDS"); 235 pr_field(field_by_value(&ledstate), " -> "); 236 } 237 238 if (field_by_value(&kbdencoding)->flags & FLG_SET) { 239 if (ioctl(fd, WSKBDIO_SETENCODING, &kbdencoding) < 0) 240 err(1, "WSKBDIO_SETENCODING"); 241 pr_field(field_by_value(&kbdencoding), " -> "); 242 } 243 244 if (field_by_value(&keyclick)->flags & FLG_SET) { 245 if (ioctl(fd, WSKBDIO_SETKEYCLICK, &keyclick) < 0) 246 err(1, "WSKBDIO_SETKEYCLICK"); 247 pr_field(field_by_value(&keyclick), " -> "); 248 } 249 250 251 if (havescroll == 0) 252 return; 253 254 scroll.which = 0; 255 if (field_by_value(&scroll.mode)->flags & FLG_SET) 256 scroll.which |= WSKBD_SCROLL_DOMODE; 257 if (field_by_value(&scroll.modifier)->flags & FLG_SET) 258 scroll.which |= WSKBD_SCROLL_DOMODIFIER; 259 260 if (scroll.which & WSKBD_SCROLL_DOMODE) 261 pr_field(field_by_value(&scroll.mode), " -> "); 262 if (scroll.which & WSKBD_SCROLL_DOMODIFIER) 263 pr_field(field_by_value(&scroll.modifier), " -> "); 264 if (scroll.which != 0) { 265 if (ioctl(fd, WSKBDIO_SETSCROLL, &scroll) == -1) { 266 if (errno != ENODEV) 267 err(1, "WSKBDIO_SETSCROLL"); 268 else { 269 warnx("scrolling is not supported by this kernel"); 270 havescroll = 0; 271 } 272 } 273 } 274 } 275 276