source: mainline/kernel/genarch/src/kbd/key.c@ 4544884

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4544884 was af75db9, checked in by Martin Decky <martin@…>, 17 years ago

remove (almost all) platform dependent code from drivers

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup genarch
30 * @{
31 */
32/**
33 * @file
34 * @brief Key processing.
35 */
36
37#include <genarch/kbd/key.h>
38#include <genarch/kbd/scanc.h>
39#ifdef CONFIG_I8042
40#include <genarch/kbd/scanc_pc.h>
41#endif
42
43#if (defined(US)) || (defined(US3))
44#include <genarch/kbd/scanc_sun.h>
45#endif
46
47#include <synch/spinlock.h>
48#include <console/chardev.h>
49#include <macros.h>
50
51#define PRESSED_SHIFT (1<<0)
52#define PRESSED_CAPSLOCK (1<<1)
53#define LOCKED_CAPSLOCK (1<<0)
54
55#define ACTIVE_READ_BUFF_SIZE 16 /* Must be power of 2 */
56
57chardev_t kbrd;
58
59static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE];
60
61SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */
62static volatile int keyflags; /**< Tracking of multiple keypresses. */
63static volatile int lockflags; /**< Tracking of multiple keys lockings. */
64
65/** Process release of key.
66 *
67 * @param sc Scancode of the key being released.
68 */
69void key_released(uint8_t sc)
70{
71 spinlock_lock(&keylock);
72 switch (sc) {
73 case SC_LSHIFT:
74 case SC_RSHIFT:
75 keyflags &= ~PRESSED_SHIFT;
76 break;
77 case SC_CAPSLOCK:
78 keyflags &= ~PRESSED_CAPSLOCK;
79 if (lockflags & LOCKED_CAPSLOCK)
80 lockflags &= ~LOCKED_CAPSLOCK;
81 else
82 lockflags |= LOCKED_CAPSLOCK;
83 break;
84 default:
85 break;
86 }
87 spinlock_unlock(&keylock);
88}
89
90/** Process keypress.
91 *
92 * @param sc Scancode of the key being pressed.
93 */
94void key_pressed(uint8_t sc)
95{
96 char *map = sc_primary_map;
97 char ascii = sc_primary_map[sc];
98 bool shift, capslock;
99 bool letter = false;
100
101 spinlock_lock(&keylock);
102 switch (sc) {
103 case SC_LSHIFT:
104 case SC_RSHIFT:
105 keyflags |= PRESSED_SHIFT;
106 break;
107 case SC_CAPSLOCK:
108 keyflags |= PRESSED_CAPSLOCK;
109 break;
110 case SC_SPEC_ESCAPE:
111 break;
112 case SC_LEFTARR:
113 chardev_push_character(&kbrd, 0x1b);
114 chardev_push_character(&kbrd, 0x5b);
115 chardev_push_character(&kbrd, 0x44);
116 break;
117 case SC_RIGHTARR:
118 chardev_push_character(&kbrd, 0x1b);
119 chardev_push_character(&kbrd, 0x5b);
120 chardev_push_character(&kbrd, 0x43);
121 break;
122 case SC_UPARR:
123 chardev_push_character(&kbrd, 0x1b);
124 chardev_push_character(&kbrd, 0x5b);
125 chardev_push_character(&kbrd, 0x41);
126 break;
127 case SC_DOWNARR:
128 chardev_push_character(&kbrd, 0x1b);
129 chardev_push_character(&kbrd, 0x5b);
130 chardev_push_character(&kbrd, 0x42);
131 break;
132 case SC_HOME:
133 chardev_push_character(&kbrd, 0x1b);
134 chardev_push_character(&kbrd, 0x4f);
135 chardev_push_character(&kbrd, 0x48);
136 break;
137 case SC_END:
138 chardev_push_character(&kbrd, 0x1b);
139 chardev_push_character(&kbrd, 0x4f);
140 chardev_push_character(&kbrd, 0x46);
141 break;
142 case SC_DELETE:
143 chardev_push_character(&kbrd, 0x1b);
144 chardev_push_character(&kbrd, 0x5b);
145 chardev_push_character(&kbrd, 0x33);
146 chardev_push_character(&kbrd, 0x7e);
147 break;
148 default:
149 letter = islower(ascii);
150 capslock = (keyflags & PRESSED_CAPSLOCK) ||
151 (lockflags & LOCKED_CAPSLOCK);
152 shift = keyflags & PRESSED_SHIFT;
153 if (letter && capslock)
154 shift = !shift;
155 if (shift)
156 map = sc_secondary_map;
157 chardev_push_character(&kbrd, map[sc]);
158 break;
159 }
160 spinlock_unlock(&keylock);
161}
162
163uint8_t active_read_buff_read(void)
164{
165 static int i=0;
166 i &= (ACTIVE_READ_BUFF_SIZE-1);
167 if(!active_read_buff[i]) {
168 return 0;
169 }
170 return active_read_buff[i++];
171}
172
173void active_read_buff_write(uint8_t ch)
174{
175 static int i=0;
176 active_read_buff[i] = ch;
177 i++;
178 i &= (ACTIVE_READ_BUFF_SIZE-1);
179 active_read_buff[i]=0;
180}
181
182
183void active_read_key_pressed(uint8_t sc)
184{
185 char *map = sc_primary_map;
186 char ascii = sc_primary_map[sc];
187 bool shift, capslock;
188 bool letter = false;
189
190 /*spinlock_lock(&keylock);*/
191 switch (sc) {
192 case SC_LSHIFT:
193 case SC_RSHIFT:
194 keyflags |= PRESSED_SHIFT;
195 break;
196 case SC_CAPSLOCK:
197 keyflags |= PRESSED_CAPSLOCK;
198 break;
199 case SC_SPEC_ESCAPE:
200 break;
201 case SC_LEFTARR:
202 active_read_buff_write(0x1b);
203 active_read_buff_write(0x5b);
204 active_read_buff_write(0x44);
205 break;
206 case SC_RIGHTARR:
207 active_read_buff_write(0x1b);
208 active_read_buff_write(0x5b);
209 active_read_buff_write(0x43);
210 break;
211 case SC_UPARR:
212 active_read_buff_write(0x1b);
213 active_read_buff_write(0x5b);
214 active_read_buff_write(0x41);
215 break;
216 case SC_DOWNARR:
217 active_read_buff_write(0x1b);
218 active_read_buff_write(0x5b);
219 active_read_buff_write(0x42);
220 break;
221 case SC_HOME:
222 active_read_buff_write(0x1b);
223 active_read_buff_write(0x4f);
224 active_read_buff_write(0x48);
225 break;
226 case SC_END:
227 active_read_buff_write(0x1b);
228 active_read_buff_write(0x4f);
229 active_read_buff_write(0x46);
230 break;
231 case SC_DELETE:
232 active_read_buff_write(0x1b);
233 active_read_buff_write(0x5b);
234 active_read_buff_write(0x33);
235 active_read_buff_write(0x7e);
236 break;
237 default:
238 letter = islower(ascii);
239 capslock = (keyflags & PRESSED_CAPSLOCK) ||
240 (lockflags & LOCKED_CAPSLOCK);
241 shift = keyflags & PRESSED_SHIFT;
242 if (letter && capslock)
243 shift = !shift;
244 if (shift)
245 map = sc_secondary_map;
246 active_read_buff_write(map[sc]);
247 break;
248 }
249 /*spinlock_unlock(&keylock);*/
250
251}
252
253/** @}
254 */
Note: See TracBrowser for help on using the repository browser.