xref: /openbsd-src/sbin/wsconsctl/keyboard.c (revision df69c215c7c66baf660f3f65414fd34796c96152)
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