Subversion Repositories HelenOS

Rev

Rev 2409 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2337 kebrt 1
/*
2
 * Copyright (c) 2007 Michal Kebrt
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
 
2350 kebrt 29
/** @addtogroup kbdarm32gxemul GXemul
30
 * @brief   HelenOS arm32 GXEmul uspace keyboard handler.
31
 * @ingroup  kbdarm32
2337 kebrt 32
 * @{
33
 */
34
/** @file
2350 kebrt 35
 *  @brief GXemul uspace keyboard handler.
2337 kebrt 36
 */
37
 
38
#include <ipc/ipc.h>
39
#include <sysinfo.h>
40
#include <kbd.h>
41
#include <keys.h>
2360 kebrt 42
#include <bool.h>
2337 kebrt 43
 
2360 kebrt 44
 
2409 kebrt 45
/* GXemul key codes in no-framebuffer mode. */
2337 kebrt 46
#define GXEMUL_KEY_F1  0x504f1bL
47
#define GXEMUL_KEY_F2  0x514f1bL
48
#define GXEMUL_KEY_F3  0x524f1bL
49
#define GXEMUL_KEY_F4  0x534f1bL
50
#define GXEMUL_KEY_F5  0x35315b1bL
51
#define GXEMUL_KEY_F6  0x37315b1bL
52
#define GXEMUL_KEY_F7  0x38315b1bL
53
#define GXEMUL_KEY_F8  0x39315b1bL
54
#define GXEMUL_KEY_F9  0x30325b1bL
55
#define GXEMUL_KEY_F10 0x31325b1bL
56
#define GXEMUL_KEY_F11 0x33325d1bL
57
#define GXEMUL_KEY_F12 0x34325b1bL 
58
 
2409 kebrt 59
/** Start code of F5-F12 keys. */
60
#define GXEMUL_KEY_F5_F12_START_CODE 0x7e
2360 kebrt 61
 
2409 kebrt 62
/* GXemul key codes in framebuffer mode. */
2360 kebrt 63
#define GXEMUL_FB_KEY_F1 0x504f5b1bL
64
#define GXEMUL_FB_KEY_F2 0x514f5b1bL
65
#define GXEMUL_FB_KEY_F3 0x524f5b1bL
66
#define GXEMUL_FB_KEY_F4 0x534f5b1bL
67
#define GXEMUL_FB_KEY_F5 0x35315b1bL
68
#define GXEMUL_FB_KEY_F6 0x37315b1bL
69
#define GXEMUL_FB_KEY_F7 0x38315b1bL
70
#define GXEMUL_FB_KEY_F8 0x39315b1bL
71
#define GXEMUL_FB_KEY_F9 0x38325b1bL
72
#define GXEMUL_FB_KEY_F10 0x39325b1bL
73
#define GXEMUL_FB_KEY_F11 0x33325b1bL
74
#define GXEMUL_FB_KEY_F12 0x34325b1bL
75
 
76
 
2350 kebrt 77
/** Function keys start code (F1=0x101) */
2337 kebrt 78
#define FUNCTION_KEYS 0x100
79
 
2360 kebrt 80
static irq_cmd_t gxemul_cmds[] = {
2337 kebrt 81
    {
82
        CMD_MEM_READ_1,
83
        (void *) 0,
84
        0,
85
        2
86
    }
87
};
88
 
2360 kebrt 89
static irq_code_t gxemul_kbd = {
2337 kebrt 90
    1,
91
    gxemul_cmds
92
};
93
 
94
 
2360 kebrt 95
/** Framebuffer switched on. */
96
static bool fb;
97
 
98
 
2337 kebrt 99
/*
100
// Please preserve this code (it can be used to determine scancodes)
101
int to_hex(int v)
102
{
103
        return "0123456789ABCDEF"[v];
104
}
105
*/
106
 
2350 kebrt 107
 
2360 kebrt 108
/** Process data sent when a key is pressed (in no-framebuffer mode).
2350 kebrt 109
 *  
2409 kebrt 110
 *  @param keybuffer Buffer of pressed key.
2350 kebrt 111
 *  @param scan_code Scan code.
112
 *
2409 kebrt 113
 *  @return Always 1.
2350 kebrt 114
 */
2409 kebrt 115
static int gxemul_kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code)
2337 kebrt 116
{
2409 kebrt 117
    // holds at most 4 latest scan codes
118
    static unsigned long buf = 0;
2337 kebrt 119
 
2409 kebrt 120
    // number of scan codes in #buf
2337 kebrt 121
    static int count = 0;  
122
 
2409 kebrt 123
    /*
2360 kebrt 124
    // Preserve for detecting scan codes.
2409 kebrt 125
    keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
126
    keybuffer_push(keybuffer, to_hex(scan_code&0xf));
127
    keybuffer_push(keybuffer, 'X');
128
    keybuffer_push(keybuffer, 'Y');
129
    return 1;
130
    */
2337 kebrt 131
 
2409 kebrt 132
    if (scan_code == '\r') {
2337 kebrt 133
        scan_code = '\n';
2409 kebrt 134
    }
135
 
136
    if (scan_code == GXEMUL_KEY_F5_F12_START_CODE) {
2337 kebrt 137
        switch (buf) {
138
        case GXEMUL_KEY_F5:
139
            keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
140
            buf = count = 0;
141
            return 1;
142
        case GXEMUL_KEY_F6:
143
            keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
144
            buf = count = 0;
145
            return 1;
146
        case GXEMUL_KEY_F7:
147
            keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
148
            buf = count = 0;
149
            return 1;
150
        case GXEMUL_KEY_F8:
151
            keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
152
            buf = count = 0;
153
            return 1;
154
        case GXEMUL_KEY_F9:
155
            keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
156
            buf = count = 0;
157
            return 1;
158
        case GXEMUL_KEY_F10:
159
            keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
160
            buf = count = 0;
161
            return 1;
162
        case GXEMUL_KEY_F11:
163
            keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
164
            buf = count = 0;
165
            return 1;
166
        case GXEMUL_KEY_F12:
167
            keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
168
            buf = count = 0;
169
            return 1;
170
        default:
171
            keybuffer_push(keybuffer, buf & 0xff);
2409 kebrt 172
            keybuffer_push(keybuffer, (buf >> 8)  & 0xff);
173
            keybuffer_push(keybuffer, (buf >> 16) & 0xff);
174
            keybuffer_push(keybuffer, (buf >> 24) & 0xff);
2337 kebrt 175
            keybuffer_push(keybuffer, scan_code);
176
            buf = count = 0;
177
            return 1;
178
        }
179
    }
180
 
2409 kebrt 181
    // add to buffer
182
    buf |= ((unsigned long) scan_code) << (8 * (count++));
2337 kebrt 183
 
2409 kebrt 184
    if ((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) {
2337 kebrt 185
        keybuffer_push(keybuffer, buf);
186
        buf = count = 0;
187
        return 1;
188
    }
189
 
2409 kebrt 190
    if (count <= 1) {
2337 kebrt 191
        return 1;
2409 kebrt 192
    }
2337 kebrt 193
 
194
    if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff)
195
        && (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) {
196
 
197
        keybuffer_push(keybuffer, buf & 0xff);
198
        keybuffer_push(keybuffer, (buf >> 8) &0xff);
199
        buf = count = 0;
200
        return 1;
201
    }
202
 
2409 kebrt 203
    if (count <= 2) {
2337 kebrt 204
        return 1;
2409 kebrt 205
    }
2337 kebrt 206
 
207
    switch (buf) {
208
    case GXEMUL_KEY_F1:
209
        keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
210
        buf = count = 0;
211
        return 1;
212
    case GXEMUL_KEY_F2:
213
        keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
214
        buf = count = 0;
215
        return 1;
216
    case GXEMUL_KEY_F3:
217
        keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
218
        buf = count = 0;
219
        return 1;
220
    case GXEMUL_KEY_F4:
221
        keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
222
        buf = count = 0;
223
        return 1;
224
    }
225
 
226
 
2409 kebrt 227
    if ((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff)
2337 kebrt 228
        && (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) {
229
 
230
        keybuffer_push(keybuffer, buf & 0xff);
231
        keybuffer_push(keybuffer, (buf >> 8) & 0xff);
232
        keybuffer_push(keybuffer, (buf >> 16) & 0xff);
2409 kebrt 233
        buf = count = 0;
2337 kebrt 234
        return 1;
235
    }
236
 
2409 kebrt 237
    if (count <= 3) {
2337 kebrt 238
        return 1;
2409 kebrt 239
    }
2337 kebrt 240
 
241
    switch (buf) {
242
    case GXEMUL_KEY_F5:
243
    case GXEMUL_KEY_F6:
244
    case GXEMUL_KEY_F7:
245
    case GXEMUL_KEY_F8:
246
    case GXEMUL_KEY_F9:
247
    case GXEMUL_KEY_F10:
248
    case GXEMUL_KEY_F11:
249
    case GXEMUL_KEY_F12:
250
        return 1;
251
    default:
252
        keybuffer_push(keybuffer, buf & 0xff);
2409 kebrt 253
        keybuffer_push(keybuffer, (buf >> 8)  & 0xff);
254
        keybuffer_push(keybuffer, (buf >> 16) & 0xff);
255
        keybuffer_push(keybuffer, (buf >> 24) & 0xff);
2337 kebrt 256
        buf = count = 0;
257
        return 1;
258
    }
2409 kebrt 259
 
2337 kebrt 260
    return 1;
261
}
262
 
263
 
2360 kebrt 264
/** Process data sent when a key is pressed (in framebuffer mode).
265
 *  
2409 kebrt 266
 *  @param keybuffer Buffer of pressed keys.
2360 kebrt 267
 *  @param scan_code Scan code.
268
 *
2409 kebrt 269
 *  @return Always 1.
2360 kebrt 270
 */
2409 kebrt 271
static int gxemul_kbd_process_fb(keybuffer_t *keybuffer, int scan_code)
2360 kebrt 272
{
2409 kebrt 273
    // holds at most 4 latest scan codes
2360 kebrt 274
    static unsigned long buf = 0;
275
 
2409 kebrt 276
    // number of scan codes in #buf
277
    static int count = 0;  
278
 
279
    /*
280
    // Please preserve this code (it can be used to determine scancodes)
2360 kebrt 281
    keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
282
    keybuffer_push(keybuffer, to_hex(scan_code&0xf));
283
    keybuffer_push(keybuffer, ' ');
284
    keybuffer_push(keybuffer, ' ');
285
    return 1;
286
    */
287
 
2409 kebrt 288
    if (scan_code == '\r') {
2360 kebrt 289
        scan_code = '\n';
2409 kebrt 290
    }
2360 kebrt 291
 
2409 kebrt 292
    // add to buffer
293
    buf |= ((unsigned long) scan_code) << (8*(count++));
2360 kebrt 294
 
295
 
296
    if ((buf & 0xff) != (GXEMUL_FB_KEY_F1 & 0xff)) {
297
        keybuffer_push(keybuffer, buf);
298
        buf = count = 0;
299
        return 1;
300
    }
301
 
2409 kebrt 302
    if (count <= 1) {
2360 kebrt 303
        return 1;
2409 kebrt 304
    }
2360 kebrt 305
 
306
    if ((buf & 0xffff) != (GXEMUL_FB_KEY_F1 & 0xffff)) {
307
        keybuffer_push(keybuffer, buf & 0xff);
308
        keybuffer_push(keybuffer, (buf >> 8) &0xff);
309
        buf = count = 0;
310
        return 1;
311
    }
312
 
2409 kebrt 313
    if (count <= 2) {
2360 kebrt 314
        return 1;
2409 kebrt 315
    }
2360 kebrt 316
 
317
    if ((buf & 0xffffff) != (GXEMUL_FB_KEY_F1 & 0xffffff)
318
        && (buf & 0xffffff) != (GXEMUL_FB_KEY_F5 & 0xffffff)
319
        && (buf & 0xffffff) != (GXEMUL_FB_KEY_F9 & 0xffffff)) {
320
 
321
        keybuffer_push(keybuffer, buf & 0xff);
322
        keybuffer_push(keybuffer, (buf >> 8) & 0xff);
323
        keybuffer_push(keybuffer, (buf >> 16) & 0xff);
324
        buf = count = 0;
325
        return 1;
326
    }
327
 
2409 kebrt 328
    if (count <= 3) {
2360 kebrt 329
        return 1;
2409 kebrt 330
    }
2360 kebrt 331
 
332
    switch (buf) {
333
    case GXEMUL_FB_KEY_F1:
334
        keybuffer_push(keybuffer,FUNCTION_KEYS | 1 );
2409 kebrt 335
        buf = count = 0;
2360 kebrt 336
        return 1;
337
    case GXEMUL_FB_KEY_F2:
338
        keybuffer_push(keybuffer,FUNCTION_KEYS | 2 );
2409 kebrt 339
        buf = count = 0;
2360 kebrt 340
        return 1;
341
    case GXEMUL_FB_KEY_F3:
342
        keybuffer_push(keybuffer,FUNCTION_KEYS | 3 );
2409 kebrt 343
        buf = count = 0;
2360 kebrt 344
        return 1;
345
    case GXEMUL_FB_KEY_F4:
346
        keybuffer_push(keybuffer,FUNCTION_KEYS | 4 );
2409 kebrt 347
        buf = count = 0;
2360 kebrt 348
        return 1;
349
    case GXEMUL_FB_KEY_F5:
350
        keybuffer_push(keybuffer,FUNCTION_KEYS | 5 );
2409 kebrt 351
        buf = count = 0;
2360 kebrt 352
        return 1;
353
    case GXEMUL_FB_KEY_F6:
354
        keybuffer_push(keybuffer,FUNCTION_KEYS | 6 );
2409 kebrt 355
        buf = count = 0;
2360 kebrt 356
        return 1;
357
    case GXEMUL_FB_KEY_F7:
358
        keybuffer_push(keybuffer,FUNCTION_KEYS | 7 );
2409 kebrt 359
        buf = count = 0;
2360 kebrt 360
        return 1;
361
    case GXEMUL_FB_KEY_F8:
362
        keybuffer_push(keybuffer,FUNCTION_KEYS | 8 );
2409 kebrt 363
        buf = count = 0;
2360 kebrt 364
        return 1;
365
    case GXEMUL_FB_KEY_F9:
366
        keybuffer_push(keybuffer,FUNCTION_KEYS | 9 );
2409 kebrt 367
        buf = count = 0;
2360 kebrt 368
        return 1;
369
    case GXEMUL_FB_KEY_F10:
370
        keybuffer_push(keybuffer,FUNCTION_KEYS | 10 );
2409 kebrt 371
        buf = count = 0;
2360 kebrt 372
        return 1;
373
    case GXEMUL_FB_KEY_F11:
374
        keybuffer_push(keybuffer,FUNCTION_KEYS | 11 );
2409 kebrt 375
        buf = count = 0;
2360 kebrt 376
        return 1;
377
    case GXEMUL_FB_KEY_F12:
378
        keybuffer_push(keybuffer,FUNCTION_KEYS | 12 );
2409 kebrt 379
        buf = count = 0;
2360 kebrt 380
        return 1;
381
    default:
382
        keybuffer_push(keybuffer, buf & 0xff );
2409 kebrt 383
        keybuffer_push(keybuffer, (buf >> 8)  & 0xff);
384
        keybuffer_push(keybuffer, (buf >> 16) & 0xff);
385
        keybuffer_push(keybuffer, (buf >> 24) & 0xff);
386
        buf = count = 0;
2360 kebrt 387
        return 1;
388
    }
2409 kebrt 389
 
2360 kebrt 390
    return 1;
391
}
392
 
393
 
2350 kebrt 394
/** Initializes keyboard handler. */
2337 kebrt 395
int kbd_arch_init(void)
396
{
2360 kebrt 397
    fb = (sysinfo_value("fb.kind") == 1);
2337 kebrt 398
    gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
399
    ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd);
400
    return 0;
401
}
402
 
403
 
2350 kebrt 404
/** Process data sent when a key is pressed.
405
 *  
2409 kebrt 406
 *  @param keybuffer Buffer of pressed keys.
2350 kebrt 407
 *  @param call      IPC call.
408
 *
2409 kebrt 409
 *  @return Always 1.
2350 kebrt 410
 */
2337 kebrt 411
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
412
{
413
    int scan_code = IPC_GET_ARG2(*call);
414
 
2360 kebrt 415
    if (fb) {
2409 kebrt 416
        return gxemul_kbd_process_fb(keybuffer, scan_code);
2360 kebrt 417
    } else {
2409 kebrt 418
        return gxemul_kbd_process_no_fb(keybuffer, scan_code);
2360 kebrt 419
    }
420
 
2337 kebrt 421
}
422
 
423
/** @}
424
 */