Annotation of Gnu-Mach/chips/dtop_handlers.c, revision 1.1.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.