1 /* $NetBSD: keyboard.c,v 1.8 2006/02/05 18:11:46 jmmv 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 42 #include <dev/wscons/wsksymdef.h> 43 #include <dev/wscons/wsconsio.h> 44 45 #include <err.h> 46 #include <errno.h> 47 #include <stdlib.h> 48 49 #include "wsconsctl.h" 50 51 static int kbtype; 52 static int keyclick; 53 static struct wskbd_bell_data bell; 54 static struct wskbd_bell_data dfbell; 55 static struct wscons_keymap mapdata[KS_NUMKEYCODES]; 56 struct wskbd_map_data kbmap = /* used in map_parse.y and in util.c */ 57 { KS_NUMKEYCODES, mapdata }; 58 static struct wskbd_keyrepeat_data repeat; 59 static struct wskbd_keyrepeat_data dfrepeat; 60 static struct wskbd_scroll_data scroll; 61 static int ledstate; 62 static kbd_t kbdencoding; 63 static int havescroll = 1; 64 65 struct field keyboard_field_tab[] = { 66 { "type", &kbtype, FMT_KBDTYPE, FLG_RDONLY }, 67 { "bell.pitch", &bell.pitch, FMT_UINT, FLG_MODIFY }, 68 { "bell.period", &bell.period, FMT_UINT, FLG_MODIFY }, 69 { "bell.volume", &bell.volume, FMT_UINT, FLG_MODIFY }, 70 { "bell.pitch.default", &dfbell.pitch, FMT_UINT, FLG_MODIFY }, 71 { "bell.period.default", &dfbell.period, FMT_UINT, FLG_MODIFY }, 72 { "bell.volume.default", &dfbell.volume, FMT_UINT, FLG_MODIFY }, 73 { "map", &kbmap, FMT_KBMAP, FLG_MODIFY | 74 FLG_NOAUTO }, 75 { "repeat.del1", &repeat.del1, FMT_UINT, FLG_MODIFY }, 76 { "repeat.deln", &repeat.delN, FMT_UINT, FLG_MODIFY }, 77 { "repeat.del1.default", &dfrepeat.del1, FMT_UINT, FLG_MODIFY }, 78 { "repeat.deln.default", &dfrepeat.delN, FMT_UINT, FLG_MODIFY }, 79 { "ledstate", &ledstate, FMT_UINT, 0 }, 80 { "encoding", &kbdencoding, FMT_KBDENC, FLG_MODIFY }, 81 { "keyclick", &keyclick, FMT_UINT, FLG_MODIFY }, 82 { "scroll.mode", &scroll.mode, FMT_UINT, FLG_MODIFY }, 83 { "scroll.modifier", &scroll.modifier, FMT_UINT, FLG_MODIFY }, 84 }; 85 86 int keyboard_field_tab_len = sizeof(keyboard_field_tab) / 87 sizeof(keyboard_field_tab[0]); 88 89 void 90 keyboard_get_values(int fd) 91 { 92 93 if (field_by_value(&kbtype)->flags & FLG_GET) 94 if (ioctl(fd, WSKBDIO_GTYPE, &kbtype) < 0) 95 err(EXIT_FAILURE, "WSKBDIO_GTYPE"); 96 97 bell.which = 0; 98 if (field_by_value(&bell.pitch)->flags & FLG_GET) 99 bell.which |= WSKBD_BELL_DOPITCH; 100 if (field_by_value(&bell.period)->flags & FLG_GET) 101 bell.which |= WSKBD_BELL_DOPERIOD; 102 if (field_by_value(&bell.volume)->flags & FLG_GET) 103 bell.which |= WSKBD_BELL_DOVOLUME; 104 if (bell.which != 0 && ioctl(fd, WSKBDIO_GETBELL, &bell) < 0) 105 err(EXIT_FAILURE, "WSKBDIO_GETBELL"); 106 107 dfbell.which = 0; 108 if (field_by_value(&dfbell.pitch)->flags & FLG_GET) 109 dfbell.which |= WSKBD_BELL_DOPITCH; 110 if (field_by_value(&dfbell.period)->flags & FLG_GET) 111 dfbell.which |= WSKBD_BELL_DOPERIOD; 112 if (field_by_value(&dfbell.volume)->flags & FLG_GET) 113 dfbell.which |= WSKBD_BELL_DOVOLUME; 114 if (dfbell.which != 0 && 115 ioctl(fd, WSKBDIO_GETDEFAULTBELL, &dfbell) < 0) 116 err(EXIT_FAILURE, "WSKBDIO_GETDEFAULTBELL"); 117 118 if (field_by_value(&kbmap)->flags & FLG_GET) { 119 kbmap.maplen = KS_NUMKEYCODES; 120 if (ioctl(fd, WSKBDIO_GETMAP, &kbmap) < 0) 121 err(EXIT_FAILURE, "WSKBDIO_GETMAP"); 122 } 123 124 repeat.which = 0; 125 if (field_by_value(&repeat.del1)->flags & FLG_GET) 126 repeat.which |= WSKBD_KEYREPEAT_DODEL1; 127 if (field_by_value(&repeat.delN)->flags & FLG_GET) 128 repeat.which |= WSKBD_KEYREPEAT_DODELN; 129 if (repeat.which != 0 && 130 ioctl(fd, WSKBDIO_GETKEYREPEAT, &repeat) < 0) 131 err(EXIT_FAILURE, "WSKBDIO_GETKEYREPEAT"); 132 133 dfrepeat.which = 0; 134 if (field_by_value(&dfrepeat.del1)->flags & FLG_GET) 135 dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1; 136 if (field_by_value(&dfrepeat.delN)->flags & FLG_GET) 137 dfrepeat.which |= WSKBD_KEYREPEAT_DODELN; 138 if (dfrepeat.which != 0 && 139 ioctl(fd, WSKBDIO_GETKEYREPEAT, &dfrepeat) < 0) 140 err(EXIT_FAILURE, "WSKBDIO_GETKEYREPEAT"); 141 142 if (field_by_value(&ledstate)->flags & FLG_GET) 143 if (ioctl(fd, WSKBDIO_GETLEDS, &ledstate) < 0) 144 err(EXIT_FAILURE, "WSKBDIO_GETLEDS"); 145 146 if (field_by_value(&kbdencoding)->flags & FLG_GET) 147 if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) < 0) 148 err(EXIT_FAILURE, "WSKBDIO_GETENCODING"); 149 150 if (field_by_value(&keyclick)->flags & FLG_GET) { 151 ioctl(fd, WSKBDIO_GETKEYCLICK, &keyclick); 152 /* Optional; don't complain. */ 153 } 154 155 scroll.which = 0; 156 if (field_by_value(&scroll.mode)->flags & FLG_GET) 157 scroll.which |= WSKBD_SCROLL_DOMODE; 158 if (field_by_value(&scroll.modifier)->flags & FLG_GET) 159 scroll.which |= WSKBD_SCROLL_DOMODIFIER; 160 if (scroll.which != 0) { 161 if (ioctl(fd, WSKBDIO_GETSCROLL, &scroll) == -1) { 162 if (errno != ENODEV) 163 err(EXIT_FAILURE, "WSKBDIO_GETSCROLL"); 164 else 165 havescroll = 0; 166 } 167 } 168 } 169 170 void 171 keyboard_put_values(int fd) 172 { 173 174 bell.which = 0; 175 if (field_by_value(&bell.pitch)->flags & FLG_SET) 176 bell.which |= WSKBD_BELL_DOPITCH; 177 if (field_by_value(&bell.period)->flags & FLG_SET) 178 bell.which |= WSKBD_BELL_DOPERIOD; 179 if (field_by_value(&bell.volume)->flags & FLG_SET) 180 bell.which |= WSKBD_BELL_DOVOLUME; 181 if (bell.which != 0 && ioctl(fd, WSKBDIO_SETBELL, &bell) < 0) 182 err(EXIT_FAILURE, "WSKBDIO_SETBELL"); 183 if (bell.which & WSKBD_BELL_DOPITCH) 184 pr_field(field_by_value(&bell.pitch), " -> "); 185 if (bell.which & WSKBD_BELL_DOPERIOD) 186 pr_field(field_by_value(&bell.period), " -> "); 187 if (bell.which & WSKBD_BELL_DOVOLUME) 188 pr_field(field_by_value(&bell.volume), " -> "); 189 190 dfbell.which = 0; 191 if (field_by_value(&dfbell.pitch)->flags & FLG_SET) 192 dfbell.which |= WSKBD_BELL_DOPITCH; 193 if (field_by_value(&dfbell.period)->flags & FLG_SET) 194 dfbell.which |= WSKBD_BELL_DOPERIOD; 195 if (field_by_value(&dfbell.volume)->flags & FLG_SET) 196 dfbell.which |= WSKBD_BELL_DOVOLUME; 197 if (dfbell.which != 0 && 198 ioctl(fd, WSKBDIO_SETDEFAULTBELL, &dfbell) < 0) 199 err(EXIT_FAILURE, "WSKBDIO_SETDEFAULTBELL"); 200 if (dfbell.which & WSKBD_BELL_DOPITCH) 201 pr_field(field_by_value(&dfbell.pitch), " -> "); 202 if (dfbell.which & WSKBD_BELL_DOPERIOD) 203 pr_field(field_by_value(&dfbell.period), " -> "); 204 if (dfbell.which & WSKBD_BELL_DOVOLUME) 205 pr_field(field_by_value(&dfbell.volume), " -> "); 206 207 if (field_by_value(&kbmap)->flags & FLG_SET) { 208 if (ioctl(fd, WSKBDIO_SETMAP, &kbmap) < 0) 209 err(EXIT_FAILURE, "WSKBDIO_SETMAP"); 210 pr_field(field_by_value(&kbmap), " -> "); 211 } 212 213 repeat.which = 0; 214 if (field_by_value(&repeat.del1)->flags & FLG_SET) 215 repeat.which |= WSKBD_KEYREPEAT_DODEL1; 216 if (field_by_value(&repeat.delN)->flags & FLG_SET) 217 repeat.which |= WSKBD_KEYREPEAT_DODELN; 218 if (repeat.which != 0 && 219 ioctl(fd, WSKBDIO_SETKEYREPEAT, &repeat) < 0) 220 err(EXIT_FAILURE, "WSKBDIO_SETKEYREPEAT"); 221 if (repeat.which & WSKBD_KEYREPEAT_DODEL1) 222 pr_field(field_by_value(&repeat.del1), " -> "); 223 if (repeat.which & WSKBD_KEYREPEAT_DODELN) 224 pr_field(field_by_value(&repeat.delN), " -> "); 225 226 dfrepeat.which = 0; 227 if (field_by_value(&dfrepeat.del1)->flags & FLG_SET) 228 dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1; 229 if (field_by_value(&dfrepeat.delN)->flags & FLG_SET) 230 dfrepeat.which |= WSKBD_KEYREPEAT_DODELN; 231 if (dfrepeat.which != 0 && 232 ioctl(fd, WSKBDIO_SETDEFAULTKEYREPEAT, &dfrepeat) < 0) 233 err(EXIT_FAILURE, "WSKBDIO_SETDEFAULTKEYREPEAT"); 234 if (dfrepeat.which &WSKBD_KEYREPEAT_DODEL1) 235 pr_field(field_by_value(&dfrepeat.del1), " -> "); 236 if (dfrepeat.which & WSKBD_KEYREPEAT_DODELN) 237 pr_field(field_by_value(&dfrepeat.delN), " -> "); 238 239 if (field_by_value(&ledstate)->flags & FLG_SET) { 240 if (ioctl(fd, WSKBDIO_SETLEDS, &ledstate) < 0) 241 err(EXIT_FAILURE, "WSKBDIO_SETLEDS"); 242 pr_field(field_by_value(&ledstate), " -> "); 243 } 244 245 if (field_by_value(&kbdencoding)->flags & FLG_SET) { 246 if (ioctl(fd, WSKBDIO_SETENCODING, &kbdencoding) < 0) 247 err(EXIT_FAILURE, "WSKBDIO_SETENCODING"); 248 pr_field(field_by_value(&kbdencoding), " -> "); 249 } 250 251 if (field_by_value(&keyclick)->flags & FLG_SET) { 252 if (ioctl(fd, WSKBDIO_SETKEYCLICK, &keyclick) < 0) 253 err(EXIT_FAILURE, "WSKBDIO_SETKEYCLICK"); 254 pr_field(field_by_value(&keyclick), " -> "); 255 } 256 257 258 if (havescroll == 0) 259 return; 260 261 scroll.which = 0; 262 if (field_by_value(&scroll.mode)->flags & FLG_SET) 263 scroll.which |= WSKBD_SCROLL_DOMODE; 264 if (field_by_value(&scroll.modifier)->flags & FLG_SET) 265 scroll.which |= WSKBD_SCROLL_DOMODIFIER; 266 267 if (scroll.which & WSKBD_SCROLL_DOMODE) 268 pr_field(field_by_value(&scroll.mode), " -> "); 269 if (scroll.which & WSKBD_SCROLL_DOMODIFIER) 270 pr_field(field_by_value(&scroll.modifier), " -> "); 271 if (scroll.which != 0) { 272 if (ioctl(fd, WSKBDIO_SETSCROLL, &scroll) == -1) { 273 if (errno != ENODEV) 274 err(EXIT_FAILURE, "WSKBDIO_SETSCROLL"); 275 else { 276 warnx("scrolling is not supported by this " 277 "kernel"); 278 havescroll = 0; 279 } 280 } 281 } 282 } 283 284