1 /* $NetBSD: keyboard.c,v 1.8 2006/02/05 18:11:46 jmmv Exp $ */
4 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Juergen Hannken-Illjes.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/ioctl.h>
35 #include <dev/wscons/wsksymdef.h>
36 #include <dev/wscons/wsconsio.h>
42 #include "wsconsctl.h"
46 static struct wskbd_bell_data bell
;
47 static struct wskbd_bell_data dfbell
;
48 static struct wscons_keymap mapdata
[KS_NUMKEYCODES
];
49 struct wskbd_map_data kbmap
= /* used in map_parse.y and in util.c */
50 { KS_NUMKEYCODES
, mapdata
};
51 static struct wskbd_keyrepeat_data repeat
;
52 static struct wskbd_keyrepeat_data dfrepeat
;
53 static struct wskbd_scroll_data scroll
;
55 static kbd_t kbdencoding
;
56 static int havescroll
= 1;
58 struct field keyboard_field_tab
[] = {
59 { "type", &kbtype
, FMT_KBDTYPE
, FLG_RDONLY
},
60 { "bell.pitch", &bell
.pitch
, FMT_UINT
, FLG_MODIFY
},
61 { "bell.period", &bell
.period
, FMT_UINT
, FLG_MODIFY
},
62 { "bell.volume", &bell
.volume
, FMT_UINT
, FLG_MODIFY
},
63 { "bell.pitch.default", &dfbell
.pitch
, FMT_UINT
, FLG_MODIFY
},
64 { "bell.period.default", &dfbell
.period
, FMT_UINT
, FLG_MODIFY
},
65 { "bell.volume.default", &dfbell
.volume
, FMT_UINT
, FLG_MODIFY
},
66 { "map", &kbmap
, FMT_KBMAP
, FLG_MODIFY
|
68 { "repeat.del1", &repeat
.del1
, FMT_UINT
, FLG_MODIFY
},
69 { "repeat.deln", &repeat
.delN
, FMT_UINT
, FLG_MODIFY
},
70 { "repeat.del1.default", &dfrepeat
.del1
, FMT_UINT
, FLG_MODIFY
},
71 { "repeat.deln.default", &dfrepeat
.delN
, FMT_UINT
, FLG_MODIFY
},
72 { "ledstate", &ledstate
, FMT_UINT
, 0 },
73 { "encoding", &kbdencoding
, FMT_KBDENC
, FLG_MODIFY
},
74 { "keyclick", &keyclick
, FMT_UINT
, FLG_MODIFY
},
75 { "scroll.mode", &scroll
.mode
, FMT_UINT
, FLG_MODIFY
},
76 { "scroll.modifier", &scroll
.modifier
, FMT_UINT
, FLG_MODIFY
},
79 int keyboard_field_tab_len
= sizeof(keyboard_field_tab
) /
80 sizeof(keyboard_field_tab
[0]);
83 keyboard_get_values(int fd
)
86 if (field_by_value(&kbtype
)->flags
& FLG_GET
)
87 if (ioctl(fd
, WSKBDIO_GTYPE
, &kbtype
) < 0)
88 err(EXIT_FAILURE
, "WSKBDIO_GTYPE");
91 if (field_by_value(&bell
.pitch
)->flags
& FLG_GET
)
92 bell
.which
|= WSKBD_BELL_DOPITCH
;
93 if (field_by_value(&bell
.period
)->flags
& FLG_GET
)
94 bell
.which
|= WSKBD_BELL_DOPERIOD
;
95 if (field_by_value(&bell
.volume
)->flags
& FLG_GET
)
96 bell
.which
|= WSKBD_BELL_DOVOLUME
;
97 if (bell
.which
!= 0 && ioctl(fd
, WSKBDIO_GETBELL
, &bell
) < 0)
98 err(EXIT_FAILURE
, "WSKBDIO_GETBELL");
101 if (field_by_value(&dfbell
.pitch
)->flags
& FLG_GET
)
102 dfbell
.which
|= WSKBD_BELL_DOPITCH
;
103 if (field_by_value(&dfbell
.period
)->flags
& FLG_GET
)
104 dfbell
.which
|= WSKBD_BELL_DOPERIOD
;
105 if (field_by_value(&dfbell
.volume
)->flags
& FLG_GET
)
106 dfbell
.which
|= WSKBD_BELL_DOVOLUME
;
107 if (dfbell
.which
!= 0 &&
108 ioctl(fd
, WSKBDIO_GETDEFAULTBELL
, &dfbell
) < 0)
109 err(EXIT_FAILURE
, "WSKBDIO_GETDEFAULTBELL");
111 if (field_by_value(&kbmap
)->flags
& FLG_GET
) {
112 kbmap
.maplen
= KS_NUMKEYCODES
;
113 if (ioctl(fd
, WSKBDIO_GETMAP
, &kbmap
) < 0)
114 err(EXIT_FAILURE
, "WSKBDIO_GETMAP");
118 if (field_by_value(&repeat
.del1
)->flags
& FLG_GET
)
119 repeat
.which
|= WSKBD_KEYREPEAT_DODEL1
;
120 if (field_by_value(&repeat
.delN
)->flags
& FLG_GET
)
121 repeat
.which
|= WSKBD_KEYREPEAT_DODELN
;
122 if (repeat
.which
!= 0 &&
123 ioctl(fd
, WSKBDIO_GETKEYREPEAT
, &repeat
) < 0)
124 err(EXIT_FAILURE
, "WSKBDIO_GETKEYREPEAT");
127 if (field_by_value(&dfrepeat
.del1
)->flags
& FLG_GET
)
128 dfrepeat
.which
|= WSKBD_KEYREPEAT_DODEL1
;
129 if (field_by_value(&dfrepeat
.delN
)->flags
& FLG_GET
)
130 dfrepeat
.which
|= WSKBD_KEYREPEAT_DODELN
;
131 if (dfrepeat
.which
!= 0 &&
132 ioctl(fd
, WSKBDIO_GETKEYREPEAT
, &dfrepeat
) < 0)
133 err(EXIT_FAILURE
, "WSKBDIO_GETKEYREPEAT");
135 if (field_by_value(&ledstate
)->flags
& FLG_GET
)
136 if (ioctl(fd
, WSKBDIO_GETLEDS
, &ledstate
) < 0)
137 err(EXIT_FAILURE
, "WSKBDIO_GETLEDS");
139 if (field_by_value(&kbdencoding
)->flags
& FLG_GET
)
140 if (ioctl(fd
, WSKBDIO_GETENCODING
, &kbdencoding
) < 0)
141 err(EXIT_FAILURE
, "WSKBDIO_GETENCODING");
143 if (field_by_value(&keyclick
)->flags
& FLG_GET
) {
144 ioctl(fd
, WSKBDIO_GETKEYCLICK
, &keyclick
);
145 /* Optional; don't complain. */
149 if (field_by_value(&scroll
.mode
)->flags
& FLG_GET
)
150 scroll
.which
|= WSKBD_SCROLL_DOMODE
;
151 if (field_by_value(&scroll
.modifier
)->flags
& FLG_GET
)
152 scroll
.which
|= WSKBD_SCROLL_DOMODIFIER
;
153 if (scroll
.which
!= 0) {
154 if (ioctl(fd
, WSKBDIO_GETSCROLL
, &scroll
) == -1) {
156 err(EXIT_FAILURE
, "WSKBDIO_GETSCROLL");
164 keyboard_put_values(int fd
)
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(EXIT_FAILURE
, "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
), " -> ");
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(EXIT_FAILURE
, "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
), " -> ");
200 if (field_by_value(&kbmap
)->flags
& FLG_SET
) {
201 if (ioctl(fd
, WSKBDIO_SETMAP
, &kbmap
) < 0)
202 err(EXIT_FAILURE
, "WSKBDIO_SETMAP");
203 pr_field(field_by_value(&kbmap
), " -> ");
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(EXIT_FAILURE
, "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
), " -> ");
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(EXIT_FAILURE
, "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
), " -> ");
232 if (field_by_value(&ledstate
)->flags
& FLG_SET
) {
233 if (ioctl(fd
, WSKBDIO_SETLEDS
, &ledstate
) < 0)
234 err(EXIT_FAILURE
, "WSKBDIO_SETLEDS");
235 pr_field(field_by_value(&ledstate
), " -> ");
238 if (field_by_value(&kbdencoding
)->flags
& FLG_SET
) {
239 if (ioctl(fd
, WSKBDIO_SETENCODING
, &kbdencoding
) < 0)
240 err(EXIT_FAILURE
, "WSKBDIO_SETENCODING");
241 pr_field(field_by_value(&kbdencoding
), " -> ");
244 if (field_by_value(&keyclick
)->flags
& FLG_SET
) {
245 if (ioctl(fd
, WSKBDIO_SETKEYCLICK
, &keyclick
) < 0)
246 err(EXIT_FAILURE
, "WSKBDIO_SETKEYCLICK");
247 pr_field(field_by_value(&keyclick
), " -> ");
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
;
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) {
267 err(EXIT_FAILURE
, "WSKBDIO_SETSCROLL");
269 warnx("scrolling is not supported by this "