1*df69c215Sderaadt /* $OpenBSD: keyboard.c,v 1.14 2019/06/28 13:32:46 deraadt Exp $ */
2e0b2c52dSmickey /* $NetBSD: keyboard.c 1.1 1998/12/28 14:01:17 hannken Exp $ */
3e0b2c52dSmickey
4e0b2c52dSmickey /*-
5e0b2c52dSmickey * Copyright (c) 1998 The NetBSD Foundation, Inc.
6e0b2c52dSmickey * All rights reserved.
7e0b2c52dSmickey *
8e0b2c52dSmickey * This code is derived from software contributed to The NetBSD Foundation
9e0b2c52dSmickey * by Juergen Hannken-Illjes.
10e0b2c52dSmickey *
11e0b2c52dSmickey * Redistribution and use in source and binary forms, with or without
12e0b2c52dSmickey * modification, are permitted provided that the following conditions
13e0b2c52dSmickey * are met:
14e0b2c52dSmickey * 1. Redistributions of source code must retain the above copyright
15e0b2c52dSmickey * notice, this list of conditions and the following disclaimer.
16e0b2c52dSmickey * 2. Redistributions in binary form must reproduce the above copyright
17e0b2c52dSmickey * notice, this list of conditions and the following disclaimer in the
18e0b2c52dSmickey * documentation and/or other materials provided with the distribution.
19e0b2c52dSmickey *
20e0b2c52dSmickey * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21e0b2c52dSmickey * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22e0b2c52dSmickey * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23e0b2c52dSmickey * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24e0b2c52dSmickey * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25e0b2c52dSmickey * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26e0b2c52dSmickey * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27e0b2c52dSmickey * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28e0b2c52dSmickey * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29e0b2c52dSmickey * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30e0b2c52dSmickey * POSSIBILITY OF SUCH DAMAGE.
31e0b2c52dSmickey */
32e0b2c52dSmickey
33e0b2c52dSmickey #include <sys/ioctl.h>
34e0b2c52dSmickey #include <sys/time.h>
35e0b2c52dSmickey #include <dev/wscons/wsksymdef.h>
36e0b2c52dSmickey #include <dev/wscons/wsconsio.h>
37e0b2c52dSmickey #include <err.h>
381222b15bSmaja #include <errno.h>
391222b15bSmaja #include <fcntl.h>
401222b15bSmaja #include <stdio.h>
41e0b2c52dSmickey #include "wsconsctl.h"
42e0b2c52dSmickey
43f7ed5097Sshadchin static u_int kbtype;
44e0b2c52dSmickey static struct wskbd_bell_data bell;
45e0b2c52dSmickey static struct wskbd_bell_data dfbell;
46e0b2c52dSmickey static struct wscons_keymap mapdata[KS_NUMKEYCODES];
47e0b2c52dSmickey struct wskbd_map_data kbmap = { KS_NUMKEYCODES, mapdata }; /* used in map_parse.y
48e0b2c52dSmickey and in util.c */
49e0b2c52dSmickey static struct wskbd_keyrepeat_data repeat;
50e0b2c52dSmickey static struct wskbd_keyrepeat_data dfrepeat;
51e0b2c52dSmickey static int ledstate;
52f7ed5097Sshadchin static kbd_t kbdencoding;
53948faf8eSjung static struct field_pc backlight;
54e0b2c52dSmickey
55e0b2c52dSmickey struct field keyboard_field_tab[] = {
56e0b2c52dSmickey { "type", &kbtype, FMT_KBDTYPE, FLG_RDONLY },
57e0b2c52dSmickey { "bell.pitch", &bell.pitch, FMT_UINT, FLG_MODIFY },
58e0b2c52dSmickey { "bell.period", &bell.period, FMT_UINT, FLG_MODIFY },
59e0b2c52dSmickey { "bell.volume", &bell.volume, FMT_UINT, FLG_MODIFY },
60e0b2c52dSmickey { "bell.pitch.default", &dfbell.pitch, FMT_UINT, FLG_MODIFY },
61e0b2c52dSmickey { "bell.period.default", &dfbell.period, FMT_UINT, FLG_MODIFY },
62e0b2c52dSmickey { "bell.volume.default", &dfbell.volume, FMT_UINT, FLG_MODIFY },
63e0b2c52dSmickey { "map", &kbmap, FMT_KBMAP, FLG_MODIFY|FLG_NOAUTO },
64e0b2c52dSmickey { "repeat.del1", &repeat.del1, FMT_UINT, FLG_MODIFY },
65e0b2c52dSmickey { "repeat.deln", &repeat.delN, FMT_UINT, FLG_MODIFY },
66e0b2c52dSmickey { "repeat.del1.default", &dfrepeat.del1, FMT_UINT, FLG_MODIFY },
67e0b2c52dSmickey { "repeat.deln.default", &dfrepeat.delN, FMT_UINT, FLG_MODIFY },
68e0b2c52dSmickey { "ledstate", &ledstate, FMT_UINT, 0 },
69e0b2c52dSmickey { "encoding", &kbdencoding, FMT_KBDENC, FLG_MODIFY },
70948faf8eSjung { "backlight", &backlight, FMT_PC, FLG_MODIFY|FLG_INIT },
7182bc7287Smickey { NULL }
72e0b2c52dSmickey };
73e0b2c52dSmickey
74e0b2c52dSmickey void
keyboard_get_values(int fd)7554e3cb1dSfgsch keyboard_get_values(int fd)
76e0b2c52dSmickey {
77948faf8eSjung struct wskbd_backlight kbl;
78948faf8eSjung struct field *pf;
79948faf8eSjung
8082bc7287Smickey if (field_by_value(keyboard_field_tab, &kbtype)->flags & FLG_GET)
81*df69c215Sderaadt if (ioctl(fd, WSKBDIO_GTYPE, &kbtype) == -1)
82b0520bc4Smiod warn("WSKBDIO_GTYPE");
83e0b2c52dSmickey
84e0b2c52dSmickey bell.which = 0;
8582bc7287Smickey if (field_by_value(keyboard_field_tab, &bell.pitch)->flags & FLG_GET)
86e0b2c52dSmickey bell.which |= WSKBD_BELL_DOPITCH;
8782bc7287Smickey if (field_by_value(keyboard_field_tab, &bell.period)->flags & FLG_GET)
88e0b2c52dSmickey bell.which |= WSKBD_BELL_DOPERIOD;
8982bc7287Smickey if (field_by_value(keyboard_field_tab, &bell.volume)->flags & FLG_GET)
90e0b2c52dSmickey bell.which |= WSKBD_BELL_DOVOLUME;
91*df69c215Sderaadt if (bell.which != 0 && ioctl(fd, WSKBDIO_GETBELL, &bell) == -1)
92b0520bc4Smiod warn("WSKBDIO_GETBELL");
93e0b2c52dSmickey
94e0b2c52dSmickey dfbell.which = 0;
9582bc7287Smickey if (field_by_value(keyboard_field_tab, &dfbell.pitch)->flags & FLG_GET)
96e0b2c52dSmickey dfbell.which |= WSKBD_BELL_DOPITCH;
9782bc7287Smickey if (field_by_value(keyboard_field_tab, &dfbell.period)->flags & FLG_GET)
98e0b2c52dSmickey dfbell.which |= WSKBD_BELL_DOPERIOD;
9982bc7287Smickey if (field_by_value(keyboard_field_tab, &dfbell.volume)->flags & FLG_GET)
100e0b2c52dSmickey dfbell.which |= WSKBD_BELL_DOVOLUME;
101e0b2c52dSmickey if (dfbell.which != 0 &&
102*df69c215Sderaadt ioctl(fd, WSKBDIO_GETDEFAULTBELL, &dfbell) == -1)
103b0520bc4Smiod warn("WSKBDIO_GETDEFAULTBELL");
104e0b2c52dSmickey
10582bc7287Smickey if (field_by_value(keyboard_field_tab, &kbmap)->flags & FLG_GET) {
106e0b2c52dSmickey kbmap.maplen = KS_NUMKEYCODES;
107*df69c215Sderaadt if (ioctl(fd, WSKBDIO_GETMAP, &kbmap) == -1)
108b0520bc4Smiod warn("WSKBDIO_GETMAP");
109*df69c215Sderaadt if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) == -1)
110fb9de198Smaja warn("WSKBDIO_GETENCODING");
111fb9de198Smaja ksymenc(kbdencoding);
112e0b2c52dSmickey }
113e0b2c52dSmickey
114e0b2c52dSmickey repeat.which = 0;
11582bc7287Smickey if (field_by_value(keyboard_field_tab, &repeat.del1)->flags & FLG_GET)
116e0b2c52dSmickey repeat.which |= WSKBD_KEYREPEAT_DODEL1;
11782bc7287Smickey if (field_by_value(keyboard_field_tab, &repeat.delN)->flags & FLG_GET)
118e0b2c52dSmickey repeat.which |= WSKBD_KEYREPEAT_DODELN;
119e0b2c52dSmickey if (repeat.which != 0 &&
120*df69c215Sderaadt ioctl(fd, WSKBDIO_GETKEYREPEAT, &repeat) == -1)
121b0520bc4Smiod warn("WSKBDIO_GETKEYREPEAT");
122e0b2c52dSmickey
123e0b2c52dSmickey dfrepeat.which = 0;
12482bc7287Smickey if (field_by_value(keyboard_field_tab, &dfrepeat.del1)->flags & FLG_GET)
125e0b2c52dSmickey dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1;
12682bc7287Smickey if (field_by_value(keyboard_field_tab, &dfrepeat.delN)->flags & FLG_GET)
127e0b2c52dSmickey dfrepeat.which |= WSKBD_KEYREPEAT_DODELN;
128e0b2c52dSmickey if (dfrepeat.which != 0 &&
129*df69c215Sderaadt ioctl(fd, WSKBDIO_GETDEFAULTKEYREPEAT, &dfrepeat) == -1)
130009fda48Smiod warn("WSKBDIO_GETDEFAULTKEYREPEAT");
131e0b2c52dSmickey
13282bc7287Smickey if (field_by_value(keyboard_field_tab, &ledstate)->flags & FLG_GET)
133*df69c215Sderaadt if (ioctl(fd, WSKBDIO_GETLEDS, &ledstate) == -1)
134b0520bc4Smiod warn("WSKBDIO_GETLEDS");
135e0b2c52dSmickey
13682bc7287Smickey if (field_by_value(keyboard_field_tab, &kbdencoding)->flags & FLG_GET)
137*df69c215Sderaadt if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) == -1)
138b0520bc4Smiod warn("WSKBDIO_GETENCODING");
139948faf8eSjung
140948faf8eSjung pf = field_by_value(keyboard_field_tab, &backlight);
141948faf8eSjung if (pf->flags & FLG_GET && !(pf->flags & FLG_DEAD)) {
142948faf8eSjung errno = ENOTTY;
143*df69c215Sderaadt if (ioctl(fd, WSKBDIO_GETBACKLIGHT, &kbl) == -1) {
144948faf8eSjung if (errno == ENOTTY)
145948faf8eSjung pf->flags |= FLG_DEAD;
146948faf8eSjung else
147948faf8eSjung warn("WSKBDIO_GETBACKLIGHT");
148948faf8eSjung } else {
149948faf8eSjung backlight.min = kbl.min;
150948faf8eSjung backlight.cur = kbl.curval;
151948faf8eSjung backlight.max = kbl.max;
152948faf8eSjung }
153948faf8eSjung }
154e0b2c52dSmickey }
155e0b2c52dSmickey
156f0cd74dfSmartynas int
keyboard_put_values(int fd)15754e3cb1dSfgsch keyboard_put_values(int fd)
158e0b2c52dSmickey {
159948faf8eSjung struct wskbd_backlight kbl;
160948faf8eSjung struct field *pf;
161948faf8eSjung
162e0b2c52dSmickey bell.which = 0;
16382bc7287Smickey if (field_by_value(keyboard_field_tab, &bell.pitch)->flags & FLG_SET)
164e0b2c52dSmickey bell.which |= WSKBD_BELL_DOPITCH;
16582bc7287Smickey if (field_by_value(keyboard_field_tab, &bell.period)->flags & FLG_SET)
166e0b2c52dSmickey bell.which |= WSKBD_BELL_DOPERIOD;
16782bc7287Smickey if (field_by_value(keyboard_field_tab, &bell.volume)->flags & FLG_SET)
168e0b2c52dSmickey bell.which |= WSKBD_BELL_DOVOLUME;
169*df69c215Sderaadt if (bell.which != 0 && ioctl(fd, WSKBDIO_SETBELL, &bell) == -1) {
170b0520bc4Smiod warn("WSKBDIO_SETBELL");
171f0cd74dfSmartynas return 1;
172b0520bc4Smiod }
173e0b2c52dSmickey
174e0b2c52dSmickey dfbell.which = 0;
17582bc7287Smickey if (field_by_value(keyboard_field_tab, &dfbell.pitch)->flags & FLG_SET)
176e0b2c52dSmickey dfbell.which |= WSKBD_BELL_DOPITCH;
17782bc7287Smickey if (field_by_value(keyboard_field_tab, &dfbell.period)->flags & FLG_SET)
178e0b2c52dSmickey dfbell.which |= WSKBD_BELL_DOPERIOD;
17982bc7287Smickey if (field_by_value(keyboard_field_tab, &dfbell.volume)->flags & FLG_SET)
180e0b2c52dSmickey dfbell.which |= WSKBD_BELL_DOVOLUME;
181e0b2c52dSmickey if (dfbell.which != 0 &&
182*df69c215Sderaadt ioctl(fd, WSKBDIO_SETDEFAULTBELL, &dfbell) == -1) {
183b0520bc4Smiod warn("WSKBDIO_SETDEFAULTBELL");
184f0cd74dfSmartynas return 1;
185b0520bc4Smiod }
186e0b2c52dSmickey
18782bc7287Smickey if (field_by_value(keyboard_field_tab, &kbmap)->flags & FLG_SET) {
188*df69c215Sderaadt if (ioctl(fd, WSKBDIO_SETMAP, &kbmap) == -1) {
189b0520bc4Smiod warn("WSKBDIO_SETMAP");
190f0cd74dfSmartynas return 1;
191f0cd74dfSmartynas }
192b0520bc4Smiod }
193e0b2c52dSmickey
194e0b2c52dSmickey repeat.which = 0;
19582bc7287Smickey if (field_by_value(keyboard_field_tab, &repeat.del1)->flags & FLG_SET)
196e0b2c52dSmickey repeat.which |= WSKBD_KEYREPEAT_DODEL1;
19782bc7287Smickey if (field_by_value(keyboard_field_tab, &repeat.delN)->flags & FLG_SET)
198e0b2c52dSmickey repeat.which |= WSKBD_KEYREPEAT_DODELN;
199e0b2c52dSmickey if (repeat.which != 0 &&
200*df69c215Sderaadt ioctl(fd, WSKBDIO_SETKEYREPEAT, &repeat) == -1) {
201b0520bc4Smiod warn("WSKBDIO_SETKEYREPEAT");
202f0cd74dfSmartynas return 1;
203b0520bc4Smiod }
204e0b2c52dSmickey
205e0b2c52dSmickey dfrepeat.which = 0;
20682bc7287Smickey if (field_by_value(keyboard_field_tab, &dfrepeat.del1)->flags & FLG_SET)
207e0b2c52dSmickey dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1;
20882bc7287Smickey if (field_by_value(keyboard_field_tab, &dfrepeat.delN)->flags & FLG_SET)
209e0b2c52dSmickey dfrepeat.which |= WSKBD_KEYREPEAT_DODELN;
210e0b2c52dSmickey if (dfrepeat.which != 0 &&
211*df69c215Sderaadt ioctl(fd, WSKBDIO_SETDEFAULTKEYREPEAT, &dfrepeat) == -1) {
212b0520bc4Smiod warn("WSKBDIO_SETDEFAULTKEYREPEAT");
213f0cd74dfSmartynas return 1;
214b0520bc4Smiod }
215e0b2c52dSmickey
21682bc7287Smickey if (field_by_value(keyboard_field_tab, &ledstate)->flags & FLG_SET) {
217*df69c215Sderaadt if (ioctl(fd, WSKBDIO_SETLEDS, &ledstate) == -1) {
218b0520bc4Smiod warn("WSKBDIO_SETLEDS");
219f0cd74dfSmartynas return 1;
220e0b2c52dSmickey }
221b0520bc4Smiod }
222e0b2c52dSmickey
22382bc7287Smickey if (field_by_value(keyboard_field_tab, &kbdencoding)->flags & FLG_SET) {
224*df69c215Sderaadt if (ioctl(fd, WSKBDIO_SETENCODING, &kbdencoding) == -1) {
225b0520bc4Smiod warn("WSKBDIO_SETENCODING");
226f0cd74dfSmartynas return 1;
227e0b2c52dSmickey }
228e0b2c52dSmickey }
229f0cd74dfSmartynas
230948faf8eSjung pf = field_by_value(keyboard_field_tab, &backlight);
231948faf8eSjung if (pf->flags & FLG_SET && !(pf->flags & FLG_DEAD)) {
232948faf8eSjung kbl.min = backlight.min;
233948faf8eSjung kbl.curval = backlight.cur;
234948faf8eSjung kbl.max = backlight.max;
235948faf8eSjung errno = ENOTTY;
236*df69c215Sderaadt if (ioctl(fd, WSKBDIO_SETBACKLIGHT, &kbl) == -1) {
237948faf8eSjung if (errno == ENOTTY)
238948faf8eSjung pf->flags |= FLG_DEAD;
239948faf8eSjung else {
240948faf8eSjung warn("WSKBDIO_SETBACKLIGHT");
241948faf8eSjung return 1;
242948faf8eSjung }
243948faf8eSjung }
244948faf8eSjung }
245948faf8eSjung
246f0cd74dfSmartynas return 0;
247b0520bc4Smiod }
2481222b15bSmaja
24954e3cb1dSfgsch char *
keyboard_next_device(int index)25054e3cb1dSfgsch keyboard_next_device(int index)
2511222b15bSmaja {
25254e3cb1dSfgsch static char devname[20];
2531222b15bSmaja
25454e3cb1dSfgsch snprintf(devname, sizeof(devname), "/dev/wskbd%d", index);
25554e3cb1dSfgsch return (devname);
2561222b15bSmaja }
257