[BACK]Return to akbd.c CVS log [TXT][DIR] Up to [local] / sys / dev / adb

Annotation of sys/dev/adb/akbd.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: akbd.c,v 1.6 2007/03/13 20:56:56 miod Exp $   */
        !             2: /*     $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $    */
        !             3:
        !             4: /*
        !             5:  * Copyright (C) 1998  Colin Wood
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *     This product includes software developed by Colin Wood.
        !            19:  * 4. The name of the author may not be used to endorse or promote products
        !            20:  *    derived from this software without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            31:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #include <sys/param.h>
        !            35: #include <sys/timeout.h>
        !            36: #include <sys/kernel.h>
        !            37: #include <sys/device.h>
        !            38: #include <sys/systm.h>
        !            39:
        !            40: #include <dev/wscons/wsconsio.h>
        !            41: #include <dev/wscons/wskbdvar.h>
        !            42: #include <dev/wscons/wsksymdef.h>
        !            43: #include <dev/wscons/wsksymvar.h>
        !            44:
        !            45: #include <machine/autoconf.h>
        !            46: #include <machine/cpu.h>
        !            47:
        !            48: #include <dev/adb/adb.h>
        !            49: #include <dev/adb/akbdmap.h>
        !            50: #include <dev/adb/akbdvar.h>
        !            51:
        !            52: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !            53: #define KEYBOARD_ARRAY
        !            54: #endif
        !            55: #include <dev/adb/keyboard.h>
        !            56:
        !            57: /*
        !            58:  * Function declarations.
        !            59:  */
        !            60: int    akbdmatch(struct device *, void *, void *);
        !            61: void   akbdattach(struct device *, struct device *, void *);
        !            62:
        !            63: /* Driver definition. */
        !            64: struct cfattach akbd_ca = {
        !            65:        sizeof(struct akbd_softc), akbdmatch, akbdattach
        !            66: };
        !            67: struct cfdriver akbd_cd = {
        !            68:        NULL, "akbd", DV_DULL
        !            69: };
        !            70:
        !            71: int    akbd_enable(void *, int);
        !            72: void   akbd_set_leds(void *, int);
        !            73: int    akbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !            74:
        !            75:
        !            76: struct wskbd_accessops akbd_accessops = {
        !            77:        akbd_enable,
        !            78:        akbd_set_leds,
        !            79:        akbd_ioctl,
        !            80: };
        !            81:
        !            82: struct wskbd_mapdata akbd_keymapdata = {
        !            83:        akbd_keydesctab,
        !            84: #ifdef AKBD_LAYOUT
        !            85:        AKBD_LAYOUT,
        !            86: #else
        !            87:        KB_US,
        !            88: #endif
        !            89: };
        !            90:
        !            91: void   akbd_adbcomplete(caddr_t, caddr_t, int);
        !            92: void   akbd_capslockwrapper(struct akbd_softc *, int);
        !            93: void   akbd_input(struct akbd_softc *, int);
        !            94: void   akbd_processevent(struct akbd_softc *, adb_event_t *);
        !            95: void   akbd_rawrepeat(void *v);
        !            96: #ifdef notyet
        !            97: u_char getleds(int);
        !            98: int    setleds(struct akbd_softc *, u_char);
        !            99: void   blinkleds(struct akbd_softc *);
        !           100: #endif
        !           101:
        !           102: int
        !           103: akbdmatch(struct device *parent, void *vcf, void *aux)
        !           104: {
        !           105:        struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
        !           106:
        !           107:        if (aa_args->origaddr == ADBADDR_KBD)
        !           108:                return (1);
        !           109:        else
        !           110:                return (0);
        !           111: }
        !           112:
        !           113: void
        !           114: akbdattach(struct device *parent, struct device *self, void *aux)
        !           115: {
        !           116:        ADBSetInfoBlock adbinfo;
        !           117:        struct akbd_softc *sc = (struct akbd_softc *)self;
        !           118:        struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
        !           119:        int error, kbd_done;
        !           120:        short cmd;
        !           121:        u_char buffer[9];
        !           122:        struct wskbddev_attach_args a;
        !           123:        static int akbd_console_initted;
        !           124:        int wskbd_eligible = 1;
        !           125:
        !           126:        sc->origaddr = aa_args->origaddr;
        !           127:        sc->adbaddr = aa_args->adbaddr;
        !           128:        sc->handler_id = aa_args->handler_id;
        !           129:
        !           130:        sc->sc_leds = (u_int8_t)0x00;   /* initially off */
        !           131:        sc->sc_caps = 0;
        !           132:
        !           133:        adbinfo.siServiceRtPtr = (Ptr)akbd_adbcomplete;
        !           134:        adbinfo.siDataAreaAddr = (caddr_t)sc;
        !           135:
        !           136:        printf(": ");
        !           137:        switch (sc->handler_id) {
        !           138:        case ADB_STDKBD:
        !           139:                printf("standard keyboard\n");
        !           140:                break;
        !           141:        case ADB_ISOKBD:
        !           142:                printf("standard keyboard (ISO layout)\n");
        !           143:                break;
        !           144:        case ADB_EXTKBD:
        !           145:                cmd = ADBTALK(sc->adbaddr, 1);
        !           146:                kbd_done =
        !           147:                    (adb_op_sync((Ptr)buffer, cmd) == 0);
        !           148:
        !           149:                /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
        !           150:                if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
        !           151:                        printf("Mouseman (non-EMP) pseudo keyboard\n");
        !           152:                        adbinfo.siServiceRtPtr = (Ptr)0;
        !           153:                        adbinfo.siDataAreaAddr = (Ptr)0;
        !           154:                        wskbd_eligible = 0;
        !           155:                } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
        !           156:                        printf("Trackman (non-EMP) pseudo keyboard\n");
        !           157:                        adbinfo.siServiceRtPtr = (Ptr)0;
        !           158:                        adbinfo.siDataAreaAddr = (Ptr)0;
        !           159:                        wskbd_eligible = 0;
        !           160:                } else {
        !           161:                        printf("extended keyboard\n");
        !           162: #ifdef notyet
        !           163:                        blinkleds(sc);
        !           164: #endif
        !           165:                }
        !           166:                break;
        !           167:        case ADB_EXTISOKBD:
        !           168:                printf("extended keyboard (ISO layout)\n");
        !           169: #ifdef notyet
        !           170:                blinkleds(sc);
        !           171: #endif
        !           172:                break;
        !           173:        case ADB_KBDII:
        !           174:                printf("keyboard II\n");
        !           175:                break;
        !           176:        case ADB_ISOKBDII:
        !           177:                printf("keyboard II (ISO layout)\n");
        !           178:                break;
        !           179:        case ADB_PBKBD:
        !           180:                printf("PowerBook keyboard\n");
        !           181:                break;
        !           182:        case ADB_PBISOKBD:
        !           183:                printf("PowerBook keyboard (ISO layout)\n");
        !           184:                break;
        !           185:        case ADB_ADJKPD:
        !           186:                printf("adjustable keypad\n");
        !           187:                wskbd_eligible = 0;
        !           188:                break;
        !           189:        case ADB_ADJKBD:
        !           190:                printf("adjustable keyboard\n");
        !           191:                break;
        !           192:        case ADB_ADJISOKBD:
        !           193:                printf("adjustable keyboard (ISO layout)\n");
        !           194:                break;
        !           195:        case ADB_ADJJAPKBD:
        !           196:                printf("adjustable keyboard (Japanese layout)\n");
        !           197:                break;
        !           198:        case ADB_PBEXTISOKBD:
        !           199:                printf("PowerBook extended keyboard (ISO layout)\n");
        !           200:                break;
        !           201:        case ADB_PBEXTJAPKBD:
        !           202:                printf("PowerBook extended keyboard (Japanese layout)\n");
        !           203:                break;
        !           204:        case ADB_JPKBDII:
        !           205:                printf("keyboard II (Japanese layout)\n");
        !           206:                break;
        !           207:        case ADB_PBEXTKBD:
        !           208:                printf("PowerBook extended keyboard\n");
        !           209:                break;
        !           210:        case ADB_DESIGNKBD:
        !           211:                printf("extended keyboard\n");
        !           212: #ifdef notyet
        !           213:                blinkleds(sc);
        !           214: #endif
        !           215:                break;
        !           216:        case ADB_PBJPKBD:
        !           217:                printf("PowerBook keyboard (Japanese layout)\n");
        !           218:                break;
        !           219:        case ADB_PBG3JPKBD:
        !           220:                printf("PowerBook G3 keyboard (Japanese layout)\n");
        !           221:                break;
        !           222:        case ADB_PBG4KBD:
        !           223:                printf("PowerBook G4 keyboard (Inverted T)\n");
        !           224:                break;
        !           225:        case ADB_IBITISOKBD:
        !           226:                printf("iBook keyboard with inverted T (ISO layout)\n");
        !           227:                break;
        !           228:        default:
        !           229:                printf("mapped device (%d)\n", sc->handler_id);
        !           230: #if 0
        !           231:                wskbd_eligible = 0;
        !           232: #endif
        !           233:                break;
        !           234:        }
        !           235:        error = set_adb_info(&adbinfo, sc->adbaddr);
        !           236: #ifdef ADB_DEBUG
        !           237:        if (adb_debug)
        !           238:                printf("akbd: returned %d from set_adb_info\n", error);
        !           239: #endif
        !           240:
        !           241: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           242:        timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc);
        !           243: #endif
        !           244:
        !           245:        if (akbd_is_console() && wskbd_eligible)
        !           246:                a.console = (++akbd_console_initted == 1);
        !           247:        else
        !           248:                a.console = 0;
        !           249:        a.keymap = &akbd_keymapdata;
        !           250:        a.accessops = &akbd_accessops;
        !           251:        a.accesscookie = sc;
        !           252:
        !           253:        sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
        !           254: }
        !           255:
        !           256:
        !           257: /*
        !           258:  * Handle putting the keyboard data received from the ADB into
        !           259:  * an ADB event record.
        !           260:  */
        !           261: void
        !           262: akbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
        !           263: {
        !           264:        adb_event_t event;
        !           265:        struct akbd_softc *sc;
        !           266:        int adbaddr;
        !           267: #ifdef ADB_DEBUG
        !           268:        int i;
        !           269:
        !           270:        if (adb_debug)
        !           271:                printf("adb: transaction completion\n");
        !           272: #endif
        !           273:
        !           274:        adbaddr = ADB_CMDADDR(adb_command);
        !           275:        sc = (struct akbd_softc *)data_area;
        !           276:
        !           277:        event.byte_count = buffer[0];
        !           278:        memcpy(event.bytes, buffer + 1, event.byte_count);
        !           279:
        !           280: #ifdef ADB_DEBUG
        !           281:        if (adb_debug) {
        !           282:                printf("akbd: from %d at %d (org %d) %d:", adbaddr,
        !           283:                    sc->handler_id, sc->origaddr, buffer[0]);
        !           284:                for (i = 1; i <= buffer[0]; i++)
        !           285:                        printf(" %x", buffer[i]);
        !           286:                printf("\n");
        !           287:        }
        !           288: #endif
        !           289:
        !           290:        if (sc->sc_wskbddev != NULL)
        !           291:                akbd_processevent(sc, &event);
        !           292: }
        !           293:
        !           294: #ifdef notyet
        !           295: /*
        !           296:  * Get the actual hardware LED state and convert it to softc format.
        !           297:  */
        !           298: u_char
        !           299: getleds(int addr)
        !           300: {
        !           301:        short cmd;
        !           302:        u_char buffer[9], leds;
        !           303:
        !           304:        leds = 0x00;    /* all off */
        !           305:        buffer[0] = 0;
        !           306:
        !           307:        cmd = ADBTALK(addr, 2);
        !           308:        if (adb_op_sync((Ptr)buffer, cmd) == 0 &&
        !           309:            buffer[0] > 0)
        !           310:                leds = ~(buffer[2]) & 0x07;
        !           311:
        !           312:        return (leds);
        !           313: }
        !           314:
        !           315: /*
        !           316:  * Set the keyboard LED's.
        !           317:  *
        !           318:  * Automatically translates from ioctl/softc format to the
        !           319:  * actual keyboard register format
        !           320:  */
        !           321: int
        !           322: setleds(struct akbd_softc *sc, u_char leds)
        !           323: {
        !           324:        int addr;
        !           325:        short cmd;
        !           326:        u_char buffer[9];
        !           327:
        !           328:        addr = sc->adbaddr;
        !           329:        buffer[0] = 0;
        !           330:
        !           331:        cmd = ADBTALK(addr, 2);
        !           332:        if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
        !           333:                return (EIO);
        !           334:
        !           335:        leds = ~leds & 0x07;
        !           336:        buffer[2] &= 0xf8;
        !           337:        buffer[2] |= leds;
        !           338:
        !           339:        cmd = ADBLISTEN(addr, 2);
        !           340:        adb_op_sync((Ptr)buffer, cmd);
        !           341:
        !           342:        /* talk R2 */
        !           343:        cmd = ADBTALK(addr, 2);
        !           344:        if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
        !           345:                return (EIO);
        !           346:
        !           347:        if ((buffer[2] & 0xf8) != leds)
        !           348:                return (EIO);
        !           349:        else
        !           350:                return (0);
        !           351: }
        !           352:
        !           353: /*
        !           354:  * Toggle all of the LED's on and off, just for show.
        !           355:  */
        !           356: void
        !           357: blinkleds(struct akbd_softc *sc)
        !           358: {
        !           359:        u_char origleds;
        !           360:
        !           361:        origleds = getleds(sc->adbaddr);
        !           362:        setleds(sc, LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK);
        !           363:        delay(400000);
        !           364:        setleds(sc, origleds);
        !           365:
        !           366:        if (origleds & LED_NUMLOCK)
        !           367:                sc->sc_leds |= WSKBD_LED_NUM;
        !           368:        if (origleds & LED_CAPSLOCK)
        !           369:                sc->sc_leds |= WSKBD_LED_CAPS;
        !           370:        if (origleds & LED_SCROLL_LOCK)
        !           371:                sc->sc_leds |= WSKBD_LED_SCROLL;
        !           372: }
        !           373: #endif
        !           374:
        !           375: int
        !           376: akbd_enable(void *v, int on)
        !           377: {
        !           378:        return 0;
        !           379: }
        !           380:
        !           381: void
        !           382: akbd_set_leds(void *v, int on)
        !           383: {
        !           384: #ifdef notyet
        !           385:        struct akbd_softc *sc = v;
        !           386:        int leds;
        !           387:
        !           388:        if (sc->sc_extended) {
        !           389:                if (sc->sc_leds == on)
        !           390:                        return;
        !           391:
        !           392:                leds = 0;
        !           393:                if (on & WSKBD_LED_NUM)
        !           394:                        leds |= LED_NUMLOCK;
        !           395:                if (on & WSKBD_LED_CAPS)
        !           396:                        leds |= LED_CAPSLOCK;
        !           397:                if (on & WSKBD_LED_SCROLL)
        !           398:                        leds |= LED_SCROLL_LOCK;
        !           399:
        !           400:                setleds(sc, leds);
        !           401:        }
        !           402: #endif
        !           403: }
        !           404:
        !           405: int
        !           406: akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           407: {
        !           408:        struct akbd_softc *sc = v;
        !           409:
        !           410:        switch (cmd) {
        !           411:
        !           412:        case WSKBDIO_GTYPE:
        !           413:                *(int *)data = WSKBD_TYPE_ADB;
        !           414:                return 0;
        !           415:        case WSKBDIO_SETLEDS:
        !           416:                akbd_set_leds(v, *(int *)data);
        !           417:                return 0;
        !           418:        case WSKBDIO_GETLEDS:
        !           419:                *(int *)data = sc->sc_leds;
        !           420:                return 0;
        !           421: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           422:        case WSKBDIO_SETMODE:
        !           423:                sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
        !           424:                timeout_del(&sc->sc_rawrepeat_ch);
        !           425:                return (0);
        !           426: #endif
        !           427:
        !           428: #ifdef mac68k  /* XXX not worth creating akbd_machdep_ioctl() */
        !           429:        case WSKBDIO_BELL:
        !           430:        case WSKBDIO_COMPLEXBELL:
        !           431: #define d ((struct wskbd_bell_data *)data)
        !           432:                mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume);
        !           433: #undef d
        !           434:                return (0);
        !           435: #endif
        !           436:
        !           437:        default:
        !           438:                return (-1);
        !           439:        }
        !           440: }
        !           441:
        !           442: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           443: void
        !           444: akbd_rawrepeat(void *v)
        !           445: {
        !           446:        struct akbd_softc *sc = v;
        !           447:        int s;
        !           448:
        !           449:        s = spltty();
        !           450:        wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
        !           451:        splx(s);
        !           452:        timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
        !           453: }
        !           454: #endif
        !           455:
        !           456: /*
        !           457:  * The ``caps lock'' key is special: since on earlier keyboards, the physical
        !           458:  * key stays down when pressed, we will get a notification of the key press,
        !           459:  * but not of the key release. Then, when it is pressed again, we will not get
        !           460:  * a notification of the key press, but will see the key release.
        !           461:  *
        !           462:  * This is not exactly true. We see the missing release and press events both
        !           463:  * as the release of the power (reset) key.
        !           464:  *
        !           465:  * To avoid confusing them with real power key presses, we maintain two
        !           466:  * states for the caps lock key: logically down (from wscons' point of view),
        !           467:  * and ``physically'' down (from the adb messages point of view), to ignore
        !           468:  * the power key. But since one may press the power key while the caps lock
        !           469:  * is held down, we also have to remember the state of the power key... this
        !           470:  * is quite messy.
        !           471:  */
        !           472:
        !           473: /*
        !           474:  * Values for caps lock state machine
        !           475:  */
        !           476: #define        CL_DOWN_ADB     0x01
        !           477: #define        CL_DOWN_LOGICAL 0x02
        !           478: #define        CL_DOWN_RESET   0x04
        !           479:
        !           480: /*
        !           481:  * Given a keyboard ADB event, decode the keycodes and pass them to wskbd.
        !           482:  */
        !           483: void
        !           484: akbd_processevent(struct akbd_softc *sc, adb_event_t *event)
        !           485: {
        !           486:        switch (event->byte_count) {
        !           487:        case 1:
        !           488:                akbd_capslockwrapper(sc, event->bytes[0]);
        !           489:                break;
        !           490:        case 2:
        !           491:                /*
        !           492:                 * The reset (or power) key sends 0x7f7f on press and
        !           493:                 * 0xffff on release, and we ignore it.
        !           494:                 */
        !           495:                if (event->bytes[0] == event->bytes[1] &&
        !           496:                    ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
        !           497:                        if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
        !           498:                                SET(sc->sc_caps, CL_DOWN_RESET);
        !           499:                        else {
        !           500:                                if (ISSET(sc->sc_caps, CL_DOWN_RESET))
        !           501:                                        CLR(sc->sc_caps, CL_DOWN_RESET);
        !           502:                                else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {
        !           503:                                        akbd_input(sc, ISSET(sc->sc_caps,
        !           504:                                            CL_DOWN_LOGICAL) ?
        !           505:                                              ADBK_KEYDOWN(ADBK_CAPSLOCK) :
        !           506:                                              ADBK_KEYUP(ADBK_CAPSLOCK));
        !           507:                                        sc->sc_caps ^= CL_DOWN_LOGICAL;
        !           508:                                }
        !           509:                        }
        !           510:                } else {
        !           511:                        akbd_capslockwrapper(sc, event->bytes[0]);
        !           512:                        akbd_capslockwrapper(sc, event->bytes[1]);
        !           513:                }
        !           514:                break;
        !           515:        default:
        !           516: #ifdef DIAGNOSTIC
        !           517:                printf("%s: unexpected message length %d\n",
        !           518:                    sc->sc_dev.dv_xname, event->byte_count);
        !           519: #endif
        !           520:                break;
        !           521:        }
        !           522:
        !           523: }
        !           524:
        !           525: void
        !           526: akbd_capslockwrapper(struct akbd_softc *sc, int key)
        !           527: {
        !           528:        if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK)
        !           529:                sc->sc_caps ^= CL_DOWN_ADB;
        !           530:
        !           531:        if (key != 0xff)
        !           532:                akbd_input(sc, key);
        !           533: }
        !           534:
        !           535: int adb_polledkey;
        !           536: void
        !           537: akbd_input(struct akbd_softc *sc, int key)
        !           538: {
        !           539:        int press, val;
        !           540:        int type;
        !           541:
        !           542:        press = ADBK_PRESS(key);
        !           543:        val = ADBK_KEYVAL(key);
        !           544:
        !           545:        type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
        !           546:
        !           547:        if (adb_polling) {
        !           548:                adb_polledkey = key;
        !           549: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           550:        } else if (sc->sc_rawkbd) {
        !           551:                char cbuf[MAXKEYS *2];
        !           552:                int c, j, s;
        !           553:                int npress;
        !           554:
        !           555:                j = npress = 0;
        !           556:
        !           557:                c = keyboard[val];
        !           558:                if (c == 0) {
        !           559:                        return; /* XXX */
        !           560:                }
        !           561:                if (c & 0x80)
        !           562:                        cbuf[j++] = 0xe0;
        !           563:                cbuf[j] = c & 0x7f;
        !           564:                if (type == WSCONS_EVENT_KEY_UP) {
        !           565:                        cbuf[j] |= 0x80;
        !           566:                } else {
        !           567:                        /* this only records last key pressed */
        !           568:                        if (c & 0x80)
        !           569:                                sc->sc_rep[npress++] = 0xe0;
        !           570:                        sc->sc_rep[npress++] = c & 0x7f;
        !           571:                }
        !           572:                j++;
        !           573:                s = spltty();
        !           574:                wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
        !           575:                splx(s);
        !           576:                timeout_del(&sc->sc_rawrepeat_ch);
        !           577:                sc->sc_nrep = npress;
        !           578:                if (npress != 0)
        !           579:                        timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
        !           580: #endif
        !           581:        } else {
        !           582:                wskbd_input(sc->sc_wskbddev, type, val);
        !           583:        }
        !           584: }

CVSweb