|
|
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*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.