keyboard.c revision 1.8 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