1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * Generic Keyboard Support: Polled I/O support for kbtrans-supported keyboards.
31 */
32
33 #define KEYMAP_SIZE_VARIABLE
34
35 #include <sys/types.h>
36 #include <sys/stream.h>
37 #include <sys/kbd.h>
38 #include <sys/kbio.h>
39 #include <sys/vuid_event.h>
40 #include <sys/consdev.h>
41 #include <sys/kbtrans.h>
42 #include "kbtrans_lower.h"
43 #include "kbtrans_streams.h"
44
45 /*
46 * Internal Function Prototypes
47 */
48 static void kbtrans_polled_pressed(struct kbtrans *, uint_t, kbtrans_key_t,
49 uint_t);
50 static void kbtrans_polled_released(struct kbtrans *, kbtrans_key_t);
51 static void kbtrans_polled_setled(struct kbtrans *);
52 static void kbtrans_polled_setup_repeat(struct kbtrans *, uint_t,
53 kbtrans_key_t);
54 static void kbtrans_polled_cancel_repeat(struct kbtrans *);
55
56 /*
57 * Functions to be called when a key is translated during polled
58 * mode
59 */
60 struct keyboard_callback kbtrans_polled_callbacks = {
61 NULL, /* keypressed_raw */
62 NULL, /* keyreleased_raw */
63 kbtrans_polled_pressed, /* keypressed */
64 kbtrans_polled_released, /* keyreleased */
65 kbtrans_polled_setup_repeat, /* setup_repeat */
66 kbtrans_polled_cancel_repeat, /* cancel_repeat */
67 kbtrans_polled_setled, /* setled */
68 };
69
70 /*
71 * kbtrans_ischar:
72 * Return B_TRUE if character is pending, else return B_FALSE
73 */
74 boolean_t
kbtrans_ischar(struct kbtrans * upper)75 kbtrans_ischar(struct kbtrans *upper)
76 {
77 struct kbtrans_callbacks *cb;
78 struct kbtrans_hardware *hw;
79 kbtrans_key_t key;
80 enum keystate state;
81
82 /*
83 * If we've still got input pending, say so.
84 */
85 if (*upper->kbtrans_polled_pending_chars != '\0') {
86 return (B_TRUE);
87 }
88
89 /*
90 * Reset to an empty buffer.
91 */
92 upper->kbtrans_polled_buf[0] = '\0';
93 upper->kbtrans_polled_pending_chars = upper->kbtrans_polled_buf;
94
95 cb = upper->kbtrans_streams_hw_callbacks;
96 hw = upper->kbtrans_streams_hw;
97
98 /*
99 * Process scancodes until either we have input ready
100 * or we run out of scancodes.
101 */
102 while (cb->kbtrans_polled_keycheck(hw, &key, &state)) {
103 kbtrans_processkey(&upper->kbtrans_lower,
104 &kbtrans_polled_callbacks, key, state);
105 /*
106 * If that generated any input, we're ready.
107 */
108 if (*upper->kbtrans_polled_pending_chars != '\0') {
109 return (B_TRUE);
110 }
111 }
112
113 return (B_FALSE);
114 }
115
116 /*
117 * kbtrans_getchar:
118 * Return a character
119 */
120 int
kbtrans_getchar(struct kbtrans * upper)121 kbtrans_getchar(struct kbtrans *upper)
122 {
123 while (!kbtrans_ischar(upper))
124 /* LOOP */;
125
126 return (*upper->kbtrans_polled_pending_chars++);
127 }
128
129 void
kbtrans_polled_putcode(struct kbtrans * upper,char code)130 kbtrans_polled_putcode(struct kbtrans *upper, char code)
131 {
132 int i;
133
134 /*
135 * NB: KBTRANS_POLLED_BUF_SIZE is one smaller than
136 * the size of the buffer, to allow for a trailing
137 * null.
138 */
139 for (i = 0; i < KBTRANS_POLLED_BUF_SIZE; i++) {
140 if (upper->kbtrans_polled_buf[i] == '\0') {
141 upper->kbtrans_polled_buf[i] = code;
142 upper->kbtrans_polled_buf[i+1] = '\0';
143 return;
144 }
145 }
146 DPRINTF(PRINT_L2, PRINT_MASK_PACKET,
147 (upper, "kbtrans_polled_pressed: "
148 "buffer overflow, character 0x%x discarded\n", code));
149 /*
150 * Didn't fit, throw it on the floor.
151 */
152 }
153
154 /*
155 * kbtrans_polled_pressed:
156 * This function is called when we are in polled mode and a key is
157 * pressed. The key is put into the kbtrans_polled_buf so that it
158 * can be picked up later by kbtrans_ischar()
159 */
160 /*ARGSUSED2*/
161 static void
kbtrans_polled_pressed(struct kbtrans * upper,uint_t entrytype,kbtrans_key_t key,uint_t entry)162 kbtrans_polled_pressed(
163 struct kbtrans *upper,
164 uint_t entrytype,
165 kbtrans_key_t key,
166 uint_t entry)
167 {
168 struct kbtrans_lower *lower = &upper->kbtrans_lower;
169 register char *cp;
170
171 /*
172 * Based on the type of key, we may need to do some ASCII
173 * specific post processing.
174 */
175 switch (entrytype) {
176
177 case BUCKYBITS:
178 case SHIFTKEYS:
179 case FUNNY:
180 /*
181 * There is no ascii equivalent. We will ignore these
182 * keys
183 */
184 break;
185
186 case FUNCKEYS:
187 /*
188 * These will no doubt only cause problems. Ignore them.
189 */
190
191 break;
192
193 case STRING:
194 /*
195 * These are the multi byte keys (Home, Up, Down ...)
196 */
197 cp = &lower->kbtrans_keystringtab[entry & 0x0F][0];
198
199 /*
200 * Copy the string from the keystringtable, and send it
201 * upstream a character at a time.
202 */
203 while (*cp != '\0') {
204 kbtrans_polled_putcode(upper, *cp);
205 cp++;
206 }
207
208 return;
209
210 case PADKEYS:
211 /*
212 * These are the keys on the keypad. Look up the
213 * answer in the kb_numlock_table and send it upstream.
214 */
215 kbtrans_polled_putcode(upper,
216 lower->kbtrans_numlock_table[entry&0x1F]);
217
218 break;
219
220 case 0: /* normal character */
221 default:
222 /*
223 * Send the byte upstream.
224 */
225 kbtrans_polled_putcode(upper, (char)entry);
226 break;
227 }
228 }
229
230 /*
231 * kbtrans_polled_released:
232 * This function is called when a key is released. Nothing is
233 * done.
234 */
235 /*ARGSUSED*/
236 static void
kbtrans_polled_released(struct kbtrans * upper,kbtrans_key_t key)237 kbtrans_polled_released(struct kbtrans *upper, kbtrans_key_t key)
238 {
239 /* Nothing for now */
240 }
241
242 /*
243 * kbtrans_polled_setled:
244 * This function is called to set the LEDs.
245 */
246 static void
kbtrans_polled_setled(struct kbtrans * upper)247 kbtrans_polled_setled(struct kbtrans *upper)
248 {
249 struct kbtrans_callbacks *cb;
250 struct kbtrans_hardware *hw;
251
252 cb = upper->kbtrans_streams_hw_callbacks;
253 hw = upper->kbtrans_streams_hw;
254
255 cb->kbtrans_polled_setled(hw, upper->kbtrans_lower.kbtrans_led_state);
256 }
257
258 /*
259 * kbtrans_polled_setup_repeat:
260 * Function to be called in order to handle a repeating key.
261 * Nothing is done.
262 */
263 /*ARGSUSED*/
264 static void
kbtrans_polled_setup_repeat(struct kbtrans * upper,uint_t entrytype,kbtrans_key_t key)265 kbtrans_polled_setup_repeat(
266 struct kbtrans *upper,
267 uint_t entrytype,
268 kbtrans_key_t key)
269 {
270 /* Nothing for now */
271 }
272
273 /*
274 * kbtrans_polled_cancel_repeat:
275 * Function to be called to cancel a repeating key,
276 * so that we don't end up with an autorepeating key
277 * on the stream because its release was handled by the
278 * polled code.
279 */
280 static void
kbtrans_polled_cancel_repeat(struct kbtrans * upper)281 kbtrans_polled_cancel_repeat(struct kbtrans *upper)
282 {
283 /*
284 * Streams code will time out and will discard the
285 * autorepeat.
286 */
287 upper->kbtrans_lower.kbtrans_repeatkey = 0;
288 }
289