[BACK]Return to swkbd.c CVS log [TXT][DIR] Up to [local] / prex-old / dev / arm / gba

Annotation of prex-old/dev/arm/gba/swkbd.c, Revision 1.1.1.1

1.1       nbrk        1: /*-
                      2:  * Copyright (c) 2005, Kohsuke Ohtani
                      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:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. Neither the name of the author nor the names of any co-contributors
                     14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * swkbd.c - GBA software keyboard driver
                     32:  */
                     33:
                     34: /**
                     35:  * This driver emulates a generic keyboard by using GBA keypad.
                     36:  *
                     37:  * <Key assign>
                     38:  *
                     39:  * On-screen keyboard:
                     40:  *
                     41:  *  A        : Select pointed key
                     42:  *  B        : Enter key
                     43:  *  Select   : Hide keyboard
                     44:  *  Start    :
                     45:  *  Right    : Move keyboard cursor right
                     46:  *  Left     : Move keyboard cursor left
                     47:  *  Up       : Move keyboard cursor up
                     48:  *  Down     : Move keyboard cursor down
                     49:  *  Button R : Toggle shift state
                     50:  *  Button L : Toggle shift state
                     51:  *
                     52:  * No on-screen keyboard:
                     53:  *
                     54:  *  A        : A key
                     55:  *  B        : B key
                     56:  *  Select   : Show keyboard
                     57:  *  Start    : Enter key
                     58:  *  Right    : Right key
                     59:  *  Left     : Left key
                     60:  *  Up       : Up key
                     61:  *  Down     : Down key
                     62:  *  Button R : R key
                     63:  *  Button L : L Key
                     64:  *
                     65:  */
                     66:
                     67: #include <driver.h>
                     68: #include <prex/keycode.h>
                     69: #include <sys/tty.h>
                     70: #include "lcd.h"
                     71: #include "kbd_img.h"
                     72: #include "keymap.h"
                     73:
                     74: extern void console_attach(struct tty **tpp);
                     75: extern void keypad_attach(void (*handler)(u_char));
                     76:
                     77: /*
                     78:  * Since GBA does not kick interrupt for the button release, we have
                     79:  * to wait for a while after button is pressed. Otherwise, many key
                     80:  * events are queued by one button press.
                     81:  */
                     82: #define CURSOR_WAIT    100     /* 100 msec */
                     83: #define BUTTON_WAIT    200     /* 200 msec */
                     84:
                     85: static int kbd_init(void);
                     86: static int kbd_ioctl(device_t, int, u_long);
                     87:
                     88: static void move_cursor(void);
                     89:
                     90: /*
                     91:  * Driver structure
                     92:  */
                     93: struct driver kbd_drv = {
                     94:        /* name */      "GBA S/W Keyboard",
                     95:        /* order */     11,
                     96:        /* init */      kbd_init,
                     97: };
                     98:
                     99: static struct devio kbd_io = {
                    100:        /* open */      NULL,
                    101:        /* close */     NULL,
                    102:        /* read */      NULL,
                    103:        /* write */     NULL,
                    104:        /* ioctl */     kbd_ioctl,
                    105:        /* event */     NULL,
                    106: };
                    107:
                    108: static device_t kbd_dev;       /* Device object */
                    109: static struct tty *tty;
                    110: static struct timer kbd_tmr;
                    111:
                    112: /* Meta key status */
                    113: static int shift;
                    114: static int alt;
                    115: static int ctrl;
                    116: static int capslk;
                    117:
                    118: static int kbd_on;
                    119: static int kbd_page;
                    120: static volatile int ignore_key;
                    121: static u_int pos_x, pos_y;
                    122: static int cur_obj;            /* Current object for cursor */
                    123:
                    124: /*
                    125:  * Select keyboard page.
                    126:  *
                    127:  *   Page0 ... Text only
                    128:  *   Page1 ... Text & Normal keyboard
                    129:  *   Page2 ... Text & Shifted keyboard
                    130:  */
                    131: static void
                    132: kbd_select(int page)
                    133: {
                    134:
                    135:        if (page == 0)
                    136:                REG_DISPCNT = 0x0840;   /* only BG3 */
                    137:        else if (page == 1) {
                    138:                REG_DISPCNT = 0x1A40;   /* use BG1&3 */
                    139:                move_cursor();
                    140:        } else {
                    141:                REG_DISPCNT = 0x1C40;   /* use BG2&3 */
                    142:                move_cursor();
                    143:        }
                    144:        kbd_page = page;
                    145: }
                    146:
                    147: /*
                    148:  * Toggle keyboard type: normal or shift.
                    149:  */
                    150: static void
                    151: kbd_toggle(void)
                    152: {
                    153:        int page;
                    154:
                    155:        if (kbd_page == 0)
                    156:                return;
                    157:        if (capslk)
                    158:                page = shift ? 1 : 2;
                    159:        else
                    160:                page = shift ? 2 : 1;
                    161:        kbd_select(page);
                    162: }
                    163:
                    164: /*
                    165:  * Timer call back handler.
                    166:  * Just clear ignoring flag.
                    167:  */
                    168: static void
                    169: kbd_timeout(u_long tmp)
                    170: {
                    171:
                    172:        ignore_key = 0;
                    173: }
                    174:
                    175: /*
                    176:  * Move cursor to point key.
                    177:  */
                    178: static void
                    179: move_cursor(void)
                    180: {
                    181:        uint16_t *oam = OAM;
                    182:        struct _key_info *ki;
                    183:        int i, x, y;
                    184:
                    185:        ki = (struct _key_info *)&key_info[pos_y][pos_x];
                    186:        x = ki->pos_x + 108;
                    187:        y = pos_y * 8 + 11;
                    188:        i = 0;
                    189:        switch (ki->width) {
                    190:        case 9: i = 0; break;
                    191:        case 11: i = 1; break;
                    192:        case 12: i = 2; break;
                    193:        case 13: i = 3; break;
                    194:        case 15: i = 4; break;
                    195:        case 17: i = 5; break;
                    196:        case 19: i = 6; break;
                    197:        case 53: i = 7; break;
                    198:        }
                    199:        if (i != cur_obj) {
                    200:                oam[cur_obj * 4] = (uint16_t)((oam[cur_obj * 4] & 0xff00) | 160);
                    201:                oam[cur_obj * 4 + 1] = (uint16_t)((oam[cur_obj * 4 + 1] & 0xfe00) | 240);
                    202:                cur_obj = i;
                    203:        }
                    204:        oam[i * 4] = (uint16_t)((oam[i * 4] & 0xff00) | y);
                    205:        oam[i * 4 + 1] = (uint16_t)((oam[i * 4 + 1] & 0xfe00) | x);
                    206: }
                    207:
                    208: /*
                    209:  * Process key press
                    210:  */
                    211: static void
                    212: key_press(void)
                    213: {
                    214:        struct _key_info *ki;
                    215:        u_char ac;
                    216:
                    217:        ki = (struct _key_info *)&key_info[pos_y][pos_x];
                    218:        ac = ki->normal;
                    219:
                    220:        /* Check meta key */
                    221:        switch (ac) {
                    222:        case K_SHFT:
                    223:                shift = !shift;
                    224:                kbd_toggle();
                    225:                return;
                    226:        case K_CTRL:
                    227:                ctrl = !ctrl;
                    228:                return;
                    229:        case K_ALT:
                    230:                alt = !alt;
                    231:                return;
                    232:        case K_CAPS:
                    233:                capslk = !capslk;
                    234:                kbd_toggle();
                    235:                return;
                    236:        }
                    237:        /* Check ctrl & shift state */
                    238:        if (ctrl) {
                    239:                if (ac >= 'a' && ac <= 'z')
                    240:                        ac = ac - 'a' + 0x01;
                    241:                else if (ac == '\\')
                    242:                        ac = 0x1c;
                    243:                else
                    244:                        ac = 0;
                    245:        } else if (kbd_page == 2)
                    246:                ac = ki->shifted;
                    247:
                    248:        if (ac == 0)
                    249:                return;
                    250:
                    251:        /* Check caps lock state */
                    252:        if (capslk) {
                    253:                if (ac >= 'A' && ac <= 'Z')
                    254:                        ac += 'a' - 'A';
                    255:                else if (ac >= 'a' && ac <= 'z')
                    256:                        ac -= 'a' - 'A';
                    257:        }
                    258:
                    259:        /* Check alt key */
                    260:        if (alt)
                    261:                ac |= 0x80;
                    262:
                    263:        /* Insert key to queue */
                    264:        tty_input(ac, tty);
                    265:
                    266:        /* Reset meta status */
                    267:        if (shift) {
                    268:                shift = 0;
                    269:                kbd_toggle();
                    270:        }
                    271:        if (ctrl)
                    272:                ctrl = 0;
                    273:        if (alt)
                    274:                alt = 0;
                    275: }
                    276:
                    277: /*
                    278:  * Input handler
                    279:  * This routine will be called by keypad ISR.
                    280:  */
                    281: static void
                    282: kbd_isr(u_char c)
                    283: {
                    284:        int move = 0;
                    285:        int timeout = BUTTON_WAIT;
                    286:
                    287:        if (ignore_key)
                    288:                return;
                    289:
                    290:        /* Select key */
                    291:        if (c == '\t') {
                    292:                kbd_on = !kbd_on;
                    293:                kbd_select(kbd_on);
                    294:
                    295:                /* Reset meta status */
                    296:                shift = 0;
                    297:                alt = 0;
                    298:                ctrl = 0;
                    299:                capslk = 0;
                    300:                goto out;
                    301:        }
                    302:
                    303:        /* Direct input */
                    304:        if (!kbd_on) {
                    305:                tty_input(c, tty);
                    306:                goto out;
                    307:        }
                    308:
                    309:        switch (c) {
                    310:        case K_LEFT:
                    311:                if (pos_x > 0) {
                    312:                        if (pos_y == 4 && pos_x >=4 && pos_x <= 8) /* Space */
                    313:                                pos_x = 3;
                    314:                        pos_x--;
                    315:                        move = 1;
                    316:                }
                    317:                break;
                    318:        case K_RGHT:
                    319:                if (pos_x < max_x[pos_y]) {
                    320:                        if (pos_y == 4 && pos_x > 3 && pos_x <= 7) /* Space */
                    321:                                pos_x = 8;
                    322:                        pos_x++;
                    323:                        move = 1;
                    324:                }
                    325:                break;
                    326:        case K_UP:
                    327:                if (pos_y > 0 ) {
                    328:                        pos_y--;
                    329:                        move = 1;
                    330:                        if (pos_x > max_x[pos_y])
                    331:                                pos_x = max_x[pos_y];
                    332:                }
                    333:                break;
                    334:        case K_DOWN:
                    335:                if (pos_y < 4) {
                    336:                        pos_y++;
                    337:                        move = 1;
                    338:                        if (pos_x > max_x[pos_y])
                    339:                                pos_x = max_x[pos_y];
                    340:                }
                    341:                break;
                    342:        case 'A':
                    343:                key_press();
                    344:                break;
                    345:        case 'B':
                    346:                tty_input('\n', tty);
                    347:                break;
                    348:        case 'R':
                    349:        case 'L':
                    350:                shift = shift ? 0 : 1;
                    351:                kbd_toggle();
                    352:                break;
                    353:        case '\n':
                    354: #ifdef CONFIG_KDUMP
                    355:                debug_dump(1);  /* Thread dump */
                    356:                debug_dump(2);  /* Thread dump */
                    357:                debug_dump(7);  /* VM dump */
                    358: #endif
                    359:                break;
                    360:        }
                    361:        if (move) {
                    362:                timeout = CURSOR_WAIT;
                    363:                move_cursor();
                    364:        }
                    365: out:
                    366:        ignore_key = 1;
                    367:        timer_callout(&kbd_tmr, kbd_timeout, 0, timeout);
                    368:        return;
                    369: }
                    370:
                    371: /*
                    372:  * I/O control
                    373:  */
                    374: static int
                    375: kbd_ioctl(device_t dev, int cmd, u_long arg)
                    376: {
                    377:
                    378:        return 0;
                    379: }
                    380:
                    381: /*
                    382:  * Init font
                    383:  */
                    384: static void
                    385: init_kbd_image(void)
                    386: {
                    387:        uint8_t bit;
                    388:        uint16_t val1, val2;
                    389:        uint16_t *pal = BG_PALETTE;
                    390:        uint16_t *tile1 = KBD1_TILE;
                    391:        uint16_t *tile2 = KBD2_TILE;
                    392:        uint16_t *map1 = KBD1_MAP;
                    393:        uint16_t *map2 = KBD2_MAP;
                    394:        int i, j, row, col;
                    395:
                    396:        /* Load tiles for keyboard image */
                    397:        for (i = 0; i < 32; i++)
                    398:                tile1[i] = 0;
                    399:
                    400:        for (i = 0; i < 64 * 12; i++) {
                    401:                bit = 0x01;
                    402:                for (j = 0; j < 4; j++) {
                    403:                        val1 = kbd1_bitmap[i] & bit ? 0xff : 0x03;
                    404:                        val2 = kbd2_bitmap[i] & bit ? 0xff : 0x03;
                    405:                        bit = bit << 1;
                    406:                        val1 |= kbd1_bitmap[i] & bit ? 0xff00 : 0x0300;
                    407:                        val2 |= kbd2_bitmap[i] & bit ? 0xff00 : 0x0300;
                    408:                        bit = bit << 1;
                    409:                        tile1[i * 4 + 32 + j] = val1;
                    410:                        tile2[i * 4 + j] = val2;
                    411:                }
                    412:        }
                    413:
                    414:
                    415:        /* Setup map */
                    416:        i = 1;
                    417:        for (row = 1; row < 7; row++) {
                    418:                for (col = 13; col < 29; col++) {
                    419:                        map1[row * 32 + col] = (uint16_t)i;
                    420:                        map2[row * 32 + col] = (uint16_t)(i + 127);
                    421:                        i++;
                    422:                }
                    423:        }
                    424:
                    425:        pal[3] = RGB(0,0,31);   /* Kbd bg color */
                    426:        pal[255] = RGB(28,28,28);       /* Kbd color */
                    427:
                    428:        /* Setup video */
                    429:        REG_BG1CNT = 0x1284;    /* Size0, 256color, priority0 */
                    430:        REG_BG2CNT = 0x1484;    /* Size0, 256color, priority0 */
                    431:        kbd_select(1);
                    432: }
                    433:
                    434: /*
                    435:  * Initialize keyboard cursor
                    436:  */
                    437: static void
                    438: init_cursor(void)
                    439: {
                    440:        int i, j;
                    441:        uint8_t bit;
                    442:        uint16_t val;
                    443:        uint16_t *oam = OAM;
                    444:        uint16_t *cur = CURSOR_DATA;
                    445:        uint16_t *pal = SPL_PALETTE;
                    446:
                    447:        /* Move out all objects */
                    448:        for (i = 0; i < 128; i++) {
                    449:                oam[0] = 160;
                    450:                oam[1] = 240;
                    451:                oam += 4;
                    452:        }
                    453:        /* Load cursor splite */
                    454:        for (i = 0; i < 64 * 7 + 64 * 8; i++) {
                    455:                bit = 0x01;
                    456:                for (j = 0; j < 4; j++) {
                    457:                        val = cursor_bitmap[i] & bit ? 0xff : 0;
                    458:                        bit = bit << 1;
                    459:                        val |= cursor_bitmap[i] & bit ? 0xff00 : 0;
                    460:                        bit = bit << 1;
                    461:                        cur[i * 4 + j] = val;
                    462:                }
                    463:        }
                    464:
                    465:        /* Setup cursors */
                    466:        oam = OAM;
                    467:        for (i = 0; i < 7; i++) {
                    468:                oam[0] = (uint16_t)(0x6000 + 160); /* 256 color, Horizontal */
                    469:                oam[1] = (uint16_t)(0x8000 + 240); /* 32x16 */
                    470:                oam[2] = (uint16_t)(i * 16); /* Tile number */
                    471:                oam += 4;
                    472:        }
                    473:        /* for space key */
                    474:        oam[0] = 0x6000 + 160; /* 256 color, Horizontal */
                    475:        oam[1] = 0xC000 + 240; /* 64x32 */
                    476:        oam[2] = 112;
                    477:
                    478:        pal[255] = RGB(31,0,0); /* cursor color */
                    479: }
                    480:
                    481: /*
                    482:  * Initialize
                    483:  */
                    484: static int
                    485: kbd_init(void)
                    486: {
                    487:
                    488:        kbd_dev = device_create(&kbd_io, "kbd", DF_CHR);
                    489:        ASSERT(kbd_dev);
                    490:
                    491:        ignore_key = 0;
                    492:        cur_obj = 0;
                    493:        kbd_on = 1;
                    494:        kbd_page = 0;
                    495:        pos_x = 0;
                    496:        pos_y = 0;
                    497:
                    498:        timer_init(&kbd_tmr);
                    499:        init_cursor();
                    500:        init_kbd_image();
                    501:        move_cursor();
                    502:
                    503:        /* Hook keypad isr */
                    504:        keypad_attach(kbd_isr);
                    505:
                    506:        /* Attach to console */
                    507:        console_attach(&tty);
                    508:        return 0;
                    509: }
                    510:

CVSweb