Annotation of Gnu-Mach/chips/dtop_handlers.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1992 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     File: dtop_handlers.c
        !            28:  *     Author: Alessandro Forin, Carnegie Mellon University
        !            29:  *     Date:   1/92
        !            30:  *
        !            31:  *     Handler functions for devices attached to the DESKTOP bus.
        !            32:  */
        !            33: 
        !            34: #include <dtop.h>
        !            35: #if    NDTOP > 0
        !            36: 
        !            37: #include <mach_kdb.h>
        !            38: 
        !            39: #include <machine/machspl.h>           /* spl definitions */
        !            40: #include <mach/std_types.h>
        !            41: #include <device/io_req.h>
        !            42: #include <device/tty.h>
        !            43: 
        !            44: #include <chips/busses.h>
        !            45: #include <chips/serial_defs.h>
        !            46: #include <chips/screen_defs.h>
        !            47: #include <mips/PMAX/tc.h>
        !            48: 
        !            49: #include <chips/dtop.h>
        !            50: #include <chips/lk201.h>
        !            51: 
        !            52: /*
        !            53:  * Default handler function
        !            54:  */
        !            55: int
        !            56: dtop_null_device_handler(
        !            57:         dtop_device_t  dev,
        !            58:         dtop_message_t msg,
        !            59:         int            event,
        !            60:         unsigned char  outc)
        !            61: {
        !            62:        /* See if the message was to the default address (powerup) */
        !            63: 
        !            64:        /* Uhmm, donno how to handle this. Drop it */
        !            65:        if (event == DTOP_EVENT_RECEIVE_PACKET)
        !            66:                dev->unknown_report = *msg;
        !            67:        return 0;
        !            68: }
        !            69: 
        !            70: /*
        !            71:  * Handler for locator devices (mice)
        !            72:  */
        !            73: int
        !            74: dtop_locator_handler(
        !            75:         dtop_device_t  dev,
        !            76:         dtop_message_t msg,
        !            77:         int            event,
        !            78:         unsigned char  outc)
        !            79: {
        !            80:        register unsigned short buttons;
        !            81:        register short          coord;
        !            82: #if    BYTE_MSF
        !            83: #      define  get_short(b0,b1)        (((b1)<<8)|(b0))
        !            84: #else
        !            85: #      define  get_short(b0,b1)        (((b0)<<8)|(b1))
        !            86: #endif
        !            87: 
        !            88:        /*
        !            89:         * Do the position first
        !            90:         */
        !            91:        {
        !            92:                register int            i;
        !            93:                register boolean_t      moved;
        !            94:                int                     delta_coords[L_COORD_MAX];
        !            95: 
        !            96:                /*
        !            97:                 * Get all coords, see if it moved at all (buttons!)
        !            98:                 */
        !            99:                moved = FALSE;
        !           100:                for (i = 0; i < dev->locator.n_coords; i++) {
        !           101: 
        !           102:                        coord = get_short(msg->body[2+(i<<1)],
        !           103:                                          msg->body[3+(i<<1)]);
        !           104: 
        !           105:                        if (dev->locator.relative) {
        !           106:                                /*
        !           107:                                 * Flame on
        !           108:                                 * I am getting tired of this, why do they have to
        !           109:                                 * keep this bug around ?  Religion ?  Damn, they
        !           110:                                 * design a keyboard for X11 use and forget the mouse ?
        !           111:                                 * Flame off
        !           112:                                 */
        !           113: #define        BOGUS_DEC_X_AXIS
        !           114: #ifdef BOGUS_DEC_X_AXIS
        !           115:                                if (i == 1) coord = - coord;
        !           116: #endif /* BOGUS_DEC_X_AXIS */
        !           117:                                /* dev->locator.coordinate[i] += coord; */
        !           118:                        } else {
        !           119:                                register unsigned int   old_coord;
        !           120: 
        !           121:                                old_coord = dev->locator.coordinate[i];
        !           122:                                dev->locator.coordinate[i] = coord;
        !           123:                                coord = old_coord - coord;
        !           124:                        }
        !           125:                        delta_coords[i] = coord;
        !           126:                        if (coord != 0)
        !           127:                                moved = TRUE;
        !           128:                }
        !           129:                if (moved) {
        !           130:                        /* scale and threshold done higher up */
        !           131:                        screen_motion_event( 0,
        !           132:                                dev->locator.type,
        !           133:                                delta_coords[0],
        !           134:                                delta_coords[1]);
        !           135:                }
        !           136:        }
        !           137: 
        !           138:        /*
        !           139:         * Time for the buttons now
        !           140:         */
        !           141: #define        new_buttons     coord
        !           142:        new_buttons = get_short(msg->body[0],msg->body[1]);
        !           143:        buttons = new_buttons ^ dev->locator.prev_buttons;
        !           144:        if (buttons) {
        !           145:                register int    i, type;
        !           146: 
        !           147:                dev->locator.prev_buttons = new_buttons;
        !           148:                for (i = 0; buttons; i++, buttons >>= 1) {
        !           149: 
        !           150:                        if ((buttons & 1) == 0) continue;
        !           151: 
        !           152:                        type = (new_buttons & (1<<i)) ? 
        !           153:                                EVT_BUTTON_DOWN : EVT_BUTTON_UP;
        !           154:                        screen_keypress_event(  0,
        !           155:                                                dev->locator.type,
        !           156:                                                dev->locator.button_code[i],
        !           157:                                                type);
        !           158:                }
        !           159:        }
        !           160: #undef new_buttons
        !           161: }
        !           162: 
        !           163: /*
        !           164:  * Handler for keyboard devices
        !           165:  * Special case: outc set for recv packet means
        !           166:  * we are inside the kernel debugger
        !           167:  */
        !           168: int
        !           169: dtop_keyboard_handler(
        !           170:         dtop_device_t  dev,
        !           171:         dtop_message_t msg,
        !           172:         int            event,
        !           173:         unsigned char  outc)
        !           174: {
        !           175:        char            save[11];
        !           176:        register int    msg_len, c;
        !           177: 
        !           178:        /*
        !           179:         * Well, really this code handles just an lk401 and in
        !           180:         * a very primitive way at that.  Should at least emulate
        !           181:         * an lk201 decently, and make that a pluggable module.
        !           182:         * Sigh.
        !           183:         */
        !           184: 
        !           185:        if (event != DTOP_EVENT_RECEIVE_PACKET) {
        !           186:                switch (event) {
        !           187:                case DTOP_EVENT_POLL:
        !           188:                    {
        !           189:                        register unsigned int   t, t0;
        !           190: 
        !           191:                        /*
        !           192:                         * Note we will always have at least the
        !           193:                         * end-of-list marker present (a zero)
        !           194:                         * Here stop and trigger of autorepeat.
        !           195:                         * Do not repeat shift keys, either.
        !           196:                         */
        !           197:                        {
        !           198:                                register unsigned char  uc, i = 0;
        !           199: 
        !           200: rpt_char:
        !           201:                                uc = dev->keyboard.last_codes[i];
        !           202: 
        !           203:                                if (uc == DTOP_KBD_EMPTY) {
        !           204:                                        dev->keyboard.k_ar_state = K_AR_OFF;
        !           205:                                        return 0;
        !           206:                                }
        !           207:                                if ((uc >= LK_R_SHIFT) && (uc <= LK_R_ALT)) {
        !           208:                                        /* sometimes swapped. Grrr. */
        !           209:                                        if (++i < dev->keyboard.last_codes_count) 
        !           210:                                                goto rpt_char;
        !           211:                                        dev->keyboard.k_ar_state = K_AR_OFF;
        !           212:                                        return 0;
        !           213:                                }
        !           214:                                c = uc;
        !           215:                        }
        !           216: 
        !           217:                        /*
        !           218:                         * Got a char. See if enough time from stroke,
        !           219:                         * or from last repeat.
        !           220:                         */
        !           221:                        t0 = (dev->keyboard.k_ar_state == K_AR_TRIGGER) ? 30 : 500;
        !           222:                        t = approx_time_in_msec();
        !           223:                        if ((t - dev->keyboard.last_msec) < t0)
        !           224:                                return 0;
        !           225: 
        !           226:                        dev->keyboard.k_ar_state = K_AR_TRIGGER;
        !           227: 
        !           228:                        /*
        !           229:                         * Simplest thing to do is to mimic lk201
        !           230:                         */
        !           231:                        outc = lk201_input(0, LK_REPEAT);
        !           232:                        if ( ! screen_keypress_event(   0,
        !           233:                                                        DEV_KEYBD,
        !           234:                                                        c,
        !           235:                                                        EVT_BUTTON_UP)) {
        !           236:                                if (outc > 0) cons_input(0, outc, 0);
        !           237:                        } else
        !           238:                                screen_keypress_event(  0,
        !           239:                                                        DEV_KEYBD,
        !           240:                                                        c,
        !           241:                                                        EVT_BUTTON_DOWN);
        !           242:                        return 0;
        !           243:                    }
        !           244:                default:        gimmeabreak();/*fornow*/
        !           245:                }
        !           246:                return -1;
        !           247:        }
        !           248: 
        !           249:        msg_len = msg->code.val.len;
        !           250: 
        !           251:        /* Check for errors */
        !           252:        c = msg->body[0];
        !           253:        if ((c < DTOP_KBD_KEY_MIN) && (c != DTOP_KBD_EMPTY)) {
        !           254:                printf("Keyboard error: %x %x %x..\n", msg_len, c, msg->body[1]);
        !           255:                if (c != DTOP_KBD_OUT_ERR) return -1;
        !           256:                /* spec sez if scan list overflow still there is data */
        !           257:                msg->body[0] = 0;
        !           258:        }
        !           259: 
        !           260:        dev->keyboard.last_msec = approx_time_in_msec();
        !           261: 
        !           262:        switch (dev->keyboard.k_ar_state) {
        !           263:        case K_AR_IDLE:
        !           264:                /* if from debugger, timeouts might not be working yet */
        !           265:                if (outc == 0xff)
        !           266:                        break;
        !           267:                dtop_keyboard_autorepeat( dev );
        !           268:                /* fall through */
        !           269:        case K_AR_TRIGGER:
        !           270:                dev->keyboard.k_ar_state = K_AR_ACTIVE;
        !           271:                break;
        !           272:        case K_AR_ACTIVE:
        !           273:                break;
        !           274:        case K_AR_OFF:  gimmeabreak();  /* ??? */
        !           275:                dev->keyboard.k_ar_state = K_AR_IDLE;
        !           276:        }
        !           277: 
        !           278:        /*
        !           279:         * We can only assume that pressed keys are reported in the
        !           280:         * same order (a minimum of sanity, please) across scans.
        !           281:         * To make things readable, do a first pass cancelling out
        !           282:         * all keys that are still pressed, and a second one generating
        !           283:         * events.  While generating events, do the upstrokes first
        !           284:         * from oldest to youngest, then the downstrokes from oldest
        !           285:         * to youngest.  This copes with lost packets and provides
        !           286:         * a reasonable model even if scans are too slow.
        !           287:         */
        !           288: 
        !           289:        /* make a copy of new state first */
        !           290:        {
        !           291:                register char   *p, *q, *e;
        !           292: 
        !           293:                p = save;
        !           294:                q = (char*)msg->body;
        !           295:                e = (char*)&msg->body[msg_len];
        !           296: 
        !           297:                while (q < e)
        !           298:                        *p++ = *q++;
        !           299:        }
        !           300: 
        !           301:        /*
        !           302:         * Do the cancelling pass
        !           303:         */
        !           304:        {
        !           305:                register char   *ls, *le, *ns, *ne, *sync;
        !           306: 
        !           307:                ls = (char*)dev->keyboard.last_codes;
        !           308:                le = (char*)&dev->keyboard.last_codes[dev->keyboard.last_codes_count];
        !           309:                ns = (char*)msg->body;
        !           310:                ne = (char*)&msg->body[msg_len];
        !           311: 
        !           312:                /* sync marks where to restart scanning, saving
        !           313:                   time thanks to ordering constraints */
        !           314:                for (sync = ns; ls < le; ls++) {
        !           315:                        register char   c = *ls;
        !           316:                        for (ns = sync; ns < ne; ns++)
        !           317:                                if (c == *ns) {
        !           318:                                        *ls = *ns = 0;
        !           319:                                        sync = ns + 1;
        !           320:                                        break;
        !           321:                                }
        !           322:                        /* we could already tell if c is an upstroke,
        !           323:                           but see the above discussion about errors */
        !           324:                }
        !           325:        }
        !           326:        /*
        !           327:         * Now generate all upstrokes
        !           328:         */
        !           329:        {
        !           330:                register char   *ls, *le;
        !           331:                register unsigned char  c;
        !           332: 
        !           333:                le = (char*)dev->keyboard.last_codes;
        !           334:                ls = (char*)&dev->keyboard.last_codes[dev->keyboard.last_codes_count - 1];
        !           335: 
        !           336:                for ( ; ls >= le; ls--)
        !           337:                    if (c = *ls) {
        !           338:                        /* keep kernel notion of lk201 state consistent */
        !           339:                        (void) lk201_input(0,c);                        
        !           340: 
        !           341:                        if (outc == 0)
        !           342:                            screen_keypress_event(0,
        !           343:                                                  DEV_KEYBD,
        !           344:                                                  c,
        !           345:                                                  EVT_BUTTON_UP);
        !           346:                    }
        !           347:        }
        !           348:        /*
        !           349:         * And finally the downstrokes
        !           350:         */
        !           351:        {
        !           352:                register char   *ns, *ne, c, retc;
        !           353: 
        !           354:                ne = (char*)msg->body;
        !           355:                ns = (char*)&msg->body[msg_len - 1];
        !           356:                retc = 0;
        !           357: 
        !           358:                for ( ; ns >= ne; ns--)
        !           359:                    if (c = *ns) {
        !           360:                        register unsigned char  data;
        !           361: 
        !           362:                        data = c;
        !           363:                        c = lk201_input(0, data);
        !           364: 
        !           365:                        if (c == -2) {  /* just returned from kdb */
        !           366:                                /* NOTE: many things have happened while
        !           367:                                   we were sitting on the stack, now it
        !           368:                                   is last_codes that holds the truth */
        !           369: #if 1
        !           370:                                /* But the truth might not be welcome.
        !           371:                                   If we get out because we hit RETURN
        !           372:                                   on the rconsole line all is well,
        !           373:                                   but if we did it from the keyboard
        !           374:                                   we get here on the downstroke. Then
        !           375:                                   we will get the upstroke which we
        !           376:                                   would give to X11. People complained
        !           377:                                   about this extra keypress..  so they
        !           378:                                   lose everything. */
        !           379: 
        !           380:                                dev->keyboard.last_codes_count = 1;
        !           381:                                dev->keyboard.last_codes[0] = 0;
        !           382: #endif
        !           383:                                return -1;
        !           384:                        }
        !           385: 
        !           386:                        /*
        !           387:                         * If X11 had better code for the keyboard this
        !           388:                         * would be an EVT_BUTTON_DOWN.  But that would
        !           389:                         * screwup the REPEAT function. Grrr.
        !           390:                         */
        !           391:                        /* outc non zero sez we are in the debugger */
        !           392:                        if (outc == 0) {
        !           393:                            if (screen_keypress_event(0,
        !           394:                                                  DEV_KEYBD,
        !           395:                                                  data,
        !           396:                                                  EVT_BUTTON_DOWN))
        !           397:                                c = -1; /* consumed by X */
        !           398:                            else
        !           399:                                if (c > 0) cons_input(0, c, 0);
        !           400:                        }
        !           401:                        /* return the xlated keycode anyways */
        !           402:                        if ((c > 0) && (retc == 0))
        !           403:                            retc = c;
        !           404:                    }
        !           405:                outc = retc;
        !           406:        }
        !           407:        /* install new scan state */
        !           408:        {
        !           409:                register char   *p, *q, *e;
        !           410: 
        !           411:                p = (char*)dev->keyboard.last_codes;
        !           412:                q = (char*)save;
        !           413:                e = (char*)&save[msg_len];
        !           414: 
        !           415:                while (q < e)
        !           416:                        *p++ = *q++;
        !           417:                dev->keyboard.last_codes_count = msg_len;
        !           418:        }
        !           419:        return outc;
        !           420: }
        !           421: 
        !           422: /*
        !           423:  * Polled operations: we must do autorepeat by hand. Sigh.
        !           424:  */
        !           425: dtop_keyboard_autorepeat(
        !           426:        dtop_device_t   dev)
        !           427: {
        !           428:        spl_t   s = spltty();
        !           429: 
        !           430:        if (dev->keyboard.k_ar_state != K_AR_IDLE)
        !           431:                dtop_keyboard_handler( dev, 0, DTOP_EVENT_POLL, 0);
        !           432: 
        !           433:        if (dev->keyboard.k_ar_state == K_AR_OFF)
        !           434:                dev->keyboard.k_ar_state = K_AR_IDLE;
        !           435:        else
        !           436:                timeout( dtop_keyboard_autorepeat, dev, dev->keyboard.poll_frequency);
        !           437: 
        !           438:        splx(s);
        !           439: }
        !           440: 
        !           441: #endif /*NDTOP>0*/

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.