source: mainline/kernel/genarch/src/kbrd/kbrd_at.c@ 13db2044

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 13db2044 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2009 Vineeth Pillai
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 PC/AT Keyboard processing.
35 */
36
37#include <assert.h>
38#include <genarch/kbrd/kbrd.h>
39#include <genarch/kbrd/scanc.h>
40
41#include <genarch/kbrd/scanc_at.h>
42
43#include <synch/spinlock.h>
44#include <console/chardev.h>
45#include <console/console.h>
46#include <proc/thread.h>
47#include <arch.h>
48#include <macros.h>
49
50#define PRESSED_SHIFT (1 << 0)
51#define PRESSED_CAPSLOCK (1 << 1)
52#define LOCKED_CAPSLOCK (1 << 0)
53
54#define AT_KEY_RELEASE 0xF0
55#define AT_ESC_KEY 0xE0
56#define AT_CAPS_SCAN_CODE 0x58
57#define AT_NUM_SCAN_CODE 0x77
58#define AT_SCROLL_SCAN_CODE 0x7E
59
60static bool is_lock_key(wchar_t);
61
62static indev_operations_t kbrd_raw_ops = {
63 .poll = NULL
64};
65
66/** Process release of key.
67 *
68 * @param sc Scancode of the key being released.
69 */
70static void key_released(kbrd_instance_t *instance, wchar_t sc)
71{
72 spinlock_lock(&instance->keylock);
73
74 switch (sc) {
75 case SC_LSHIFT:
76 case SC_RSHIFT:
77 instance->keyflags &= ~PRESSED_SHIFT;
78 break;
79 case SC_CAPSLOCK:
80 instance->keyflags &= ~PRESSED_CAPSLOCK;
81 if (instance->lockflags & LOCKED_CAPSLOCK)
82 instance->lockflags &= ~LOCKED_CAPSLOCK;
83 else
84 instance->lockflags |= LOCKED_CAPSLOCK;
85 break;
86 default:
87 break;
88 }
89
90 spinlock_unlock(&instance->keylock);
91}
92
93/** Process keypress.
94 *
95 * @param sc Scancode of the key being pressed.
96 */
97static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
98{
99 bool letter;
100 bool shift;
101 bool capslock;
102
103 spinlock_lock(&instance->keylock);
104
105 switch (sc) {
106 case SC_LSHIFT:
107 case SC_RSHIFT:
108 instance->keyflags |= PRESSED_SHIFT;
109 break;
110 case SC_CAPSLOCK:
111 instance->keyflags |= PRESSED_CAPSLOCK;
112 break;
113 case SC_SCAN_ESCAPE:
114 break;
115 default:
116 letter = islower(sc_primary_map[sc]);
117 shift = instance->keyflags & PRESSED_SHIFT;
118 capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
119 (instance->lockflags & LOCKED_CAPSLOCK);
120
121 if ((letter) && (capslock))
122 shift = !shift;
123
124 if (shift)
125 indev_push_character(instance->sink, sc_secondary_map[sc]);
126 else
127 indev_push_character(instance->sink, sc_primary_map[sc]);
128 break;
129 }
130
131 spinlock_unlock(&instance->keylock);
132}
133
134static void kkbrd(void *arg)
135{
136 static int key_released_flag = 0;
137 static int is_locked = 0;
138 kbrd_instance_t *instance = (kbrd_instance_t *) arg;
139
140 while (true) {
141 wchar_t sc = indev_pop_character(&instance->raw);
142
143 if (sc == AT_KEY_RELEASE) {
144 key_released_flag = 1;
145 } else {
146 if (key_released_flag) {
147 key_released_flag = 0;
148 if (is_lock_key(sc)) {
149 if (!is_locked) {
150 is_locked = 1;
151 } else {
152 is_locked = 0;
153 continue;
154 }
155 }
156 key_released(instance, sc);
157
158 } else {
159 if (is_lock_key(sc) && is_locked)
160 continue;
161 key_pressed(instance, sc);
162 }
163 }
164
165 }
166}
167
168kbrd_instance_t *kbrd_init(void)
169{
170 kbrd_instance_t *instance;
171
172 instance = malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
173 if (instance) {
174 instance->thread = thread_create(kkbrd, (void *) instance, TASK, 0,
175 "kkbrd");
176
177 if (!instance->thread) {
178 free(instance);
179 return NULL;
180 }
181
182 instance->sink = NULL;
183 indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
184
185 spinlock_initialize(&instance->keylock, "kbrd_at.instance.keylock");
186 instance->keyflags = 0;
187 instance->lockflags = 0;
188 }
189
190 return instance;
191}
192
193indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
194{
195 assert(instance);
196 assert(sink);
197
198 instance->sink = sink;
199 thread_ready(instance->thread);
200
201 return &instance->raw;
202}
203
204static bool is_lock_key(wchar_t sc)
205{
206 return ((sc == AT_CAPS_SCAN_CODE) || (sc == AT_NUM_SCAN_CODE) ||
207 (sc == AT_SCROLL_SCAN_CODE));
208}
209
210/** @}
211 */
Note: See TracBrowser for help on using the repository browser.