Subversion Repositories HelenOS

Rev

Rev 4346 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4346 Rev 4348
Line 50... Line 50...
50
#include <console/console.h>
50
#include <console/console.h>
51
#include <proc/thread.h>
51
#include <proc/thread.h>
52
#include <arch.h>
52
#include <arch.h>
53
#include <macros.h>
53
#include <macros.h>
54
 
54
 
55
#ifdef CONFIG_SUN_KBD
-
 
56
    #define IGNORE_CODE  0x7f
55
#define IGNORE_CODE  0x7f
57
#endif
-
 
58
 
-
 
59
#define KEY_RELEASE  0x80
56
#define KEY_RELEASE  0x80
60
 
57
 
61
#define PRESSED_SHIFT     (1 << 0)
58
#define PRESSED_SHIFT     (1 << 0)
62
#define PRESSED_CAPSLOCK  (1 << 1)
59
#define PRESSED_CAPSLOCK  (1 << 1)
63
#define LOCKED_CAPSLOCK   (1 << 0)
60
#define LOCKED_CAPSLOCK   (1 << 0)
64
 
61
 
65
static indev_t kbrdout;
-
 
66
 
-
 
67
indev_operations_t kbrdout_ops = {
62
static indev_operations_t kbrd_raw_ops = {
68
    .poll = NULL
63
    .poll = NULL
69
};
64
};
70
 
65
 
71
SPINLOCK_INITIALIZE(keylock);   /**< keylock protects keyflags and lockflags. */
-
 
72
static volatile int keyflags;   /**< Tracking of multiple keypresses. */
-
 
73
static volatile int lockflags;  /**< Tracking of multiple keys lockings. */
-
 
74
 
-
 
75
static void key_released(uint8_t);
-
 
76
static void key_pressed(uint8_t);
-
 
77
 
-
 
78
static void kkbrd(void *arg)
-
 
79
{
-
 
80
    indev_t *in = (indev_t *) arg;
-
 
81
   
-
 
82
    while (true) {
-
 
83
        uint8_t sc = _getc(in);
-
 
84
       
-
 
85
#ifdef CONFIG_SUN_KBD
-
 
86
        if (sc == IGNORE_CODE)
-
 
87
            continue;
-
 
88
#endif
-
 
89
       
-
 
90
        if (sc & KEY_RELEASE)
-
 
91
            key_released(sc ^ KEY_RELEASE);
-
 
92
        else
-
 
93
            key_pressed(sc);
-
 
94
    }
-
 
95
}
-
 
96
 
-
 
97
void kbrd_init(indev_t *devin)
-
 
98
{
-
 
99
    indev_initialize("kbrd", &kbrdout, &kbrdout_ops);
-
 
100
    thread_t *thread
-
 
101
        = thread_create(kkbrd, devin, TASK, 0, "kkbrd", false);
-
 
102
   
-
 
103
    if (thread) {
-
 
104
        stdin = &kbrdout;
-
 
105
        thread_ready(thread);
-
 
106
    }
-
 
107
}
-
 
108
 
-
 
109
/** Process release of key.
66
/** Process release of key.
110
 *
67
 *
111
 * @param sc Scancode of the key being released.
68
 * @param sc Scancode of the key being released.
112
 */
69
 */
113
void key_released(uint8_t sc)
70
static void key_released(kbrd_instance_t *instance, wchar_t sc)
114
{
71
{
115
    spinlock_lock(&keylock);
72
    spinlock_lock(&instance->keylock);
-
 
73
   
116
    switch (sc) {
74
    switch (sc) {
117
    case SC_LSHIFT:
75
    case SC_LSHIFT:
118
    case SC_RSHIFT:
76
    case SC_RSHIFT:
119
        keyflags &= ~PRESSED_SHIFT;
77
        instance->keyflags &= ~PRESSED_SHIFT;
120
        break;
78
        break;
121
    case SC_CAPSLOCK:
79
    case SC_CAPSLOCK:
122
        keyflags &= ~PRESSED_CAPSLOCK;
80
        instance->keyflags &= ~PRESSED_CAPSLOCK;
123
        if (lockflags & LOCKED_CAPSLOCK)
81
        if (instance->lockflags & LOCKED_CAPSLOCK)
124
            lockflags &= ~LOCKED_CAPSLOCK;
82
            instance->lockflags &= ~LOCKED_CAPSLOCK;
125
        else
83
        else
126
            lockflags |= LOCKED_CAPSLOCK;
84
            instance->lockflags |= LOCKED_CAPSLOCK;
127
        break;
85
        break;
128
    default:
86
    default:
129
        break;
87
        break;
130
    }
88
    }
-
 
89
   
131
    spinlock_unlock(&keylock);
90
    spinlock_unlock(&instance->keylock);
132
}
91
}
133
 
92
 
134
/** Process keypress.
93
/** Process keypress.
135
 *
94
 *
136
 * @param sc Scancode of the key being pressed.
95
 * @param sc Scancode of the key being pressed.
137
 */
96
 */
138
void key_pressed(uint8_t sc)
97
static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
139
{
98
{
140
    char *map = sc_primary_map;
99
    bool letter;
141
    char ascii = sc_primary_map[sc];
100
    bool shift;
142
    bool shift, capslock;
101
    bool capslock;
-
 
102
   
143
    bool letter = false;
103
    spinlock_lock(&instance->keylock);
144
   
104
   
145
    spinlock_lock(&keylock);
-
 
146
    switch (sc) {
105
    switch (sc) {
147
    case SC_LSHIFT:
106
    case SC_LSHIFT:
148
    case SC_RSHIFT:
107
    case SC_RSHIFT:
149
        keyflags |= PRESSED_SHIFT;
108
        instance->keyflags |= PRESSED_SHIFT;
150
        break;
109
        break;
151
    case SC_CAPSLOCK:
110
    case SC_CAPSLOCK:
152
        keyflags |= PRESSED_CAPSLOCK;
111
        instance->keyflags |= PRESSED_CAPSLOCK;
153
        break;
-
 
154
    case SC_SPEC_ESCAPE:
-
 
155
        break;
112
        break;
156
    case SC_LEFTARR:
113
    case SC_SCAN_ESCAPE:
157
        indev_push_character(stdin, 0x1b);
-
 
158
        indev_push_character(stdin, 0x5b);
-
 
159
        indev_push_character(stdin, 0x44);
-
 
160
        break;
-
 
161
    case SC_RIGHTARR:
-
 
162
        indev_push_character(stdin, 0x1b);
-
 
163
        indev_push_character(stdin, 0x5b);
-
 
164
        indev_push_character(stdin, 0x43);
-
 
165
        break;
-
 
166
    case SC_UPARR:
-
 
167
        indev_push_character(stdin, 0x1b);
-
 
168
        indev_push_character(stdin, 0x5b);
-
 
169
        indev_push_character(stdin, 0x41);
-
 
170
        break;
-
 
171
    case SC_DOWNARR:
-
 
172
        indev_push_character(stdin, 0x1b);
-
 
173
        indev_push_character(stdin, 0x5b);
-
 
174
        indev_push_character(stdin, 0x42);
-
 
175
        break;
-
 
176
    case SC_HOME:
-
 
177
        indev_push_character(stdin, 0x1b);
-
 
178
        indev_push_character(stdin, 0x4f);
-
 
179
        indev_push_character(stdin, 0x48);
-
 
180
        break;
-
 
181
    case SC_END:
-
 
182
        indev_push_character(stdin, 0x1b);
-
 
183
        indev_push_character(stdin, 0x4f);
-
 
184
        indev_push_character(stdin, 0x46);
-
 
185
        break;
-
 
186
    case SC_DELETE:
-
 
187
        indev_push_character(stdin, 0x1b);
-
 
188
        indev_push_character(stdin, 0x5b);
-
 
189
        indev_push_character(stdin, 0x33);
-
 
190
        indev_push_character(stdin, 0x7e);
-
 
191
        break;
114
        break;
192
    default:
115
    default:
193
        letter = islower(ascii);
116
        letter = islower(sc_primary_map[sc]);
194
        capslock = (keyflags & PRESSED_CAPSLOCK) ||
117
        shift = instance->keyflags & PRESSED_SHIFT;
195
            (lockflags & LOCKED_CAPSLOCK);
118
        capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
196
        shift = keyflags & PRESSED_SHIFT;
119
            (instance->lockflags & LOCKED_CAPSLOCK);
-
 
120
       
197
        if (letter && capslock)
121
        if ((letter) && (capslock))
198
            shift = !shift;
122
            shift = !shift;
-
 
123
       
199
        if (shift)
124
        if (shift)
200
            map = sc_secondary_map;
125
            indev_push_character(instance->sink, sc_secondary_map[sc]);
-
 
126
        else
201
        indev_push_character(stdin, map[sc]);
127
            indev_push_character(instance->sink, sc_primary_map[sc]);
202
        break;
128
        break;
203
    }
129
    }
-
 
130
   
204
    spinlock_unlock(&keylock);
131
    spinlock_unlock(&instance->keylock);
-
 
132
}
-
 
133
 
-
 
134
static void kkbrd(void *arg)
-
 
135
{
-
 
136
    kbrd_instance_t *instance = (kbrd_instance_t *) arg;
-
 
137
   
-
 
138
    while (true) {
-
 
139
        wchar_t sc = indev_pop_character(&instance->raw);
-
 
140
       
-
 
141
        if (sc == IGNORE_CODE)
-
 
142
            continue;
-
 
143
       
-
 
144
        if (sc & KEY_RELEASE)
-
 
145
            key_released(instance, (sc ^ KEY_RELEASE) & 0x7f);
-
 
146
        else
-
 
147
            key_pressed(instance, sc & 0x7f);
-
 
148
    }
-
 
149
}
-
 
150
 
-
 
151
kbrd_instance_t *kbrd_init(void)
-
 
152
{
-
 
153
    kbrd_instance_t *instance
-
 
154
        = malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
-
 
155
    if (instance) {
-
 
156
        instance->thread
-
 
157
            = thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false);
-
 
158
       
-
 
159
        if (!instance->thread) {
-
 
160
            free(instance);
-
 
161
            return NULL;
-
 
162
        }
-
 
163
       
-
 
164
        instance->sink = NULL;
-
 
165
        indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
-
 
166
       
-
 
167
        spinlock_initialize(&instance->keylock, "instance_keylock");
-
 
168
        instance->keyflags = 0;
-
 
169
        instance->lockflags = 0;
-
 
170
    }
-
 
171
   
-
 
172
    return instance;
-
 
173
}
-
 
174
 
-
 
175
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
-
 
176
{
-
 
177
    ASSERT(instance);
-
 
178
    ASSERT(sink);
-
 
179
   
-
 
180
    instance->sink = sink;
-
 
181
    thread_ready(instance->thread);
-
 
182
   
-
 
183
    return &instance->raw;
205
}
184
}
206
 
185
 
207
/** @}
186
/** @}
208
 */
187
 */