Subversion Repositories HelenOS

Rev

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