xref: /openbsd-src/sbin/wsconsctl/keyboard.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: keyboard.c,v 1.10 2010/08/20 00:20:55 fgsch Exp $	*/
2 /*	$NetBSD: keyboard.c 1.1 1998/12/28 14:01:17 hannken Exp $ */
3 
4 /*-
5  * Copyright (c) 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Juergen Hannken-Illjes.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/ioctl.h>
34 #include <sys/time.h>
35 #include <dev/wscons/wsksymdef.h>
36 #include <dev/wscons/wsconsio.h>
37 #include <err.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include "wsconsctl.h"
42 
43 static int kbtype;
44 static struct wskbd_bell_data bell;
45 static struct wskbd_bell_data dfbell;
46 static struct wscons_keymap mapdata[KS_NUMKEYCODES];
47 struct wskbd_map_data kbmap = { KS_NUMKEYCODES, mapdata };	/* used in map_parse.y
48 							   and in util.c */
49 static struct wskbd_keyrepeat_data repeat;
50 static struct wskbd_keyrepeat_data dfrepeat;
51 static int ledstate;
52 static int kbdencoding;
53 
54 struct field keyboard_field_tab[] = {
55     { "type",			&kbtype,	FMT_KBDTYPE,	FLG_RDONLY },
56     { "bell.pitch",		&bell.pitch,	FMT_UINT,	FLG_MODIFY },
57     { "bell.period",		&bell.period,	FMT_UINT,	FLG_MODIFY },
58     { "bell.volume",		&bell.volume,	FMT_UINT,	FLG_MODIFY },
59     { "bell.pitch.default",	&dfbell.pitch,	FMT_UINT,	FLG_MODIFY },
60     { "bell.period.default",	&dfbell.period,	FMT_UINT,	FLG_MODIFY },
61     { "bell.volume.default",	&dfbell.volume,	FMT_UINT,	FLG_MODIFY },
62     { "map",			&kbmap,		FMT_KBMAP,	FLG_MODIFY|FLG_NOAUTO },
63     { "repeat.del1",		&repeat.del1,	FMT_UINT,	FLG_MODIFY },
64     { "repeat.deln",		&repeat.delN,	FMT_UINT,	FLG_MODIFY },
65     { "repeat.del1.default",	&dfrepeat.del1,	FMT_UINT,	FLG_MODIFY },
66     { "repeat.deln.default",	&dfrepeat.delN,	FMT_UINT,	FLG_MODIFY },
67     { "ledstate",		&ledstate,	FMT_UINT,	0 },
68     { "encoding",		&kbdencoding,	FMT_KBDENC,	FLG_MODIFY },
69     { NULL }
70 };
71 
72 void
73 keyboard_get_values(int fd)
74 {
75 	if (field_by_value(keyboard_field_tab, &kbtype)->flags & FLG_GET)
76 		if (ioctl(fd, WSKBDIO_GTYPE, &kbtype) < 0)
77 			warn("WSKBDIO_GTYPE");
78 
79 	bell.which = 0;
80 	if (field_by_value(keyboard_field_tab, &bell.pitch)->flags & FLG_GET)
81 		bell.which |= WSKBD_BELL_DOPITCH;
82 	if (field_by_value(keyboard_field_tab, &bell.period)->flags & FLG_GET)
83 		bell.which |= WSKBD_BELL_DOPERIOD;
84 	if (field_by_value(keyboard_field_tab, &bell.volume)->flags & FLG_GET)
85 		bell.which |= WSKBD_BELL_DOVOLUME;
86 	if (bell.which != 0 && ioctl(fd, WSKBDIO_GETBELL, &bell) < 0)
87 		warn("WSKBDIO_GETBELL");
88 
89 	dfbell.which = 0;
90 	if (field_by_value(keyboard_field_tab, &dfbell.pitch)->flags & FLG_GET)
91 		dfbell.which |= WSKBD_BELL_DOPITCH;
92 	if (field_by_value(keyboard_field_tab, &dfbell.period)->flags & FLG_GET)
93 		dfbell.which |= WSKBD_BELL_DOPERIOD;
94 	if (field_by_value(keyboard_field_tab, &dfbell.volume)->flags & FLG_GET)
95 		dfbell.which |= WSKBD_BELL_DOVOLUME;
96 	if (dfbell.which != 0 &&
97 	    ioctl(fd, WSKBDIO_GETDEFAULTBELL, &dfbell) < 0)
98 		warn("WSKBDIO_GETDEFAULTBELL");
99 
100 	if (field_by_value(keyboard_field_tab, &kbmap)->flags & FLG_GET) {
101 		kbmap.maplen = KS_NUMKEYCODES;
102 		if (ioctl(fd, WSKBDIO_GETMAP, &kbmap) < 0)
103 			warn("WSKBDIO_GETMAP");
104 		if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) < 0)
105 			warn("WSKBDIO_GETENCODING");
106 		ksymenc(kbdencoding);
107 	}
108 
109 	repeat.which = 0;
110 	if (field_by_value(keyboard_field_tab, &repeat.del1)->flags & FLG_GET)
111 		repeat.which |= WSKBD_KEYREPEAT_DODEL1;
112 	if (field_by_value(keyboard_field_tab, &repeat.delN)->flags & FLG_GET)
113 		repeat.which |= WSKBD_KEYREPEAT_DODELN;
114 	if (repeat.which != 0 &&
115 	    ioctl(fd, WSKBDIO_GETKEYREPEAT, &repeat) < 0)
116 		warn("WSKBDIO_GETKEYREPEAT");
117 
118 	dfrepeat.which = 0;
119 	if (field_by_value(keyboard_field_tab, &dfrepeat.del1)->flags & FLG_GET)
120 		dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1;
121 	if (field_by_value(keyboard_field_tab, &dfrepeat.delN)->flags & FLG_GET)
122 		dfrepeat.which |= WSKBD_KEYREPEAT_DODELN;
123 	if (dfrepeat.which != 0 &&
124 	    ioctl(fd, WSKBDIO_GETKEYREPEAT, &dfrepeat) < 0)
125 		warn("WSKBDIO_GETKEYREPEAT");
126 
127 	if (field_by_value(keyboard_field_tab, &ledstate)->flags & FLG_GET)
128 		if (ioctl(fd, WSKBDIO_GETLEDS, &ledstate) < 0)
129 			warn("WSKBDIO_GETLEDS");
130 
131 	if (field_by_value(keyboard_field_tab, &kbdencoding)->flags & FLG_GET)
132 		if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) < 0)
133 			warn("WSKBDIO_GETENCODING");
134 }
135 
136 int
137 keyboard_put_values(int fd)
138 {
139 	bell.which = 0;
140 	if (field_by_value(keyboard_field_tab, &bell.pitch)->flags & FLG_SET)
141 		bell.which |= WSKBD_BELL_DOPITCH;
142 	if (field_by_value(keyboard_field_tab, &bell.period)->flags & FLG_SET)
143 		bell.which |= WSKBD_BELL_DOPERIOD;
144 	if (field_by_value(keyboard_field_tab, &bell.volume)->flags & FLG_SET)
145 		bell.which |= WSKBD_BELL_DOVOLUME;
146 	if (bell.which != 0 && ioctl(fd, WSKBDIO_SETBELL, &bell) < 0) {
147 		warn("WSKBDIO_SETBELL");
148 		return 1;
149 	}
150 
151 	dfbell.which = 0;
152 	if (field_by_value(keyboard_field_tab, &dfbell.pitch)->flags & FLG_SET)
153 		dfbell.which |= WSKBD_BELL_DOPITCH;
154 	if (field_by_value(keyboard_field_tab, &dfbell.period)->flags & FLG_SET)
155 		dfbell.which |= WSKBD_BELL_DOPERIOD;
156 	if (field_by_value(keyboard_field_tab, &dfbell.volume)->flags & FLG_SET)
157 		dfbell.which |= WSKBD_BELL_DOVOLUME;
158 	if (dfbell.which != 0 &&
159 	    ioctl(fd, WSKBDIO_SETDEFAULTBELL, &dfbell) < 0) {
160 		warn("WSKBDIO_SETDEFAULTBELL");
161 		return 1;
162 	}
163 
164 	if (field_by_value(keyboard_field_tab, &kbmap)->flags & FLG_SET) {
165 		if (ioctl(fd, WSKBDIO_SETMAP, &kbmap) < 0) {
166 			warn("WSKBDIO_SETMAP");
167 			return 1;
168 		}
169 	}
170 
171 	repeat.which = 0;
172 	if (field_by_value(keyboard_field_tab, &repeat.del1)->flags & FLG_SET)
173 		repeat.which |= WSKBD_KEYREPEAT_DODEL1;
174 	if (field_by_value(keyboard_field_tab, &repeat.delN)->flags & FLG_SET)
175 		repeat.which |= WSKBD_KEYREPEAT_DODELN;
176 	if (repeat.which != 0 &&
177 	    ioctl(fd, WSKBDIO_SETKEYREPEAT, &repeat) < 0) {
178 		warn("WSKBDIO_SETKEYREPEAT");
179 		return 1;
180 	}
181 
182 	dfrepeat.which = 0;
183 	if (field_by_value(keyboard_field_tab, &dfrepeat.del1)->flags & FLG_SET)
184 		dfrepeat.which |= WSKBD_KEYREPEAT_DODEL1;
185 	if (field_by_value(keyboard_field_tab, &dfrepeat.delN)->flags & FLG_SET)
186 		dfrepeat.which |= WSKBD_KEYREPEAT_DODELN;
187 	if (dfrepeat.which != 0 &&
188 	    ioctl(fd, WSKBDIO_SETDEFAULTKEYREPEAT, &dfrepeat) < 0) {
189 		warn("WSKBDIO_SETDEFAULTKEYREPEAT");
190 		return 1;
191 	}
192 
193 	if (field_by_value(keyboard_field_tab, &ledstate)->flags & FLG_SET) {
194 		if (ioctl(fd, WSKBDIO_SETLEDS, &ledstate) < 0) {
195 			warn("WSKBDIO_SETLEDS");
196 			return 1;
197 		}
198 	}
199 
200 	if (field_by_value(keyboard_field_tab, &kbdencoding)->flags & FLG_SET) {
201 		if (ioctl(fd, WSKBDIO_SETENCODING, &kbdencoding) < 0) {
202 			warn("WSKBDIO_SETENCODING");
203 			return 1;
204 		}
205 	}
206 
207 	return 0;
208 }
209 
210 char *
211 keyboard_next_device(int index)
212 {
213 	static char devname[20];
214 
215 	snprintf(devname, sizeof(devname), "/dev/wskbd%d", index);
216 	return (devname);
217 }
218