📄 dtop.c
字号:
int c;{ register int i; static int param = 0, cmd, mod, typ; static u_char parms[2]; /* * Emulate the lk201 command codes. */ if (param == 0) { typ = (c & 0x1); cmd = ((c >> 3) & 0xf); mod = ((c >> 1) & 0x3); } else parms[param - 1] = (c & 0x7f); if (c & 0x80) { if (typ) { /* * A peripheral command code. Someday this driver * should know how to send commands to the lk501, * but until then this is all essentially a no-op. */ ; } else { /* * Set modes. These have to be emulated in software. */ if (cmd > 0 && cmd < 15) { cmd--; if (mod & 0x2) for (i = divbeg[cmd]; i <= divend[cmd]; i++) keymodes[i >> 5] |= (1 << (i & 0x1f)); else for (i = divbeg[cmd]; i <= divend[cmd]; i++) keymodes[i >> 5] &= ~(1 << (i & 0x1f)); } } param = 0; } else if (++param > 2) param = 2;}/* * Take a packet off dtop interface * A packet MUST be there, this is not checked for. */#define DTOP_ESC_CHAR 0xf8dtop_escape(c){ /* I donno much about this stuff.. */ switch (c) { case 0xe8: return (0xf8); case 0xe9: return (0xf9); case 0xea: return (0xfa); case 0xeb: return (0xfb); default: /* printf("{esc %x}", c); */ return (c); }}dtop_get_packet(dtop, pkt) dtop_softc_t dtop; dtop_message_t pkt;{ register poll_reg_t poll; register data_reg_t data; register int max, i, len; register unsigned char c; poll = dtop->poll; data = dtop->data; /* * The interface does not handle us the first byte, * which is our address and cannot ever be anything * else but 0x50. This is a good thing, it makes * the average packet exactly one word long, too. */ for (max = 0; (max < DTOP_MAX_POLL) && !DTOP_RX_AVAIL(poll); max++) DELAY(1); if (max == DTOP_MAX_POLL) goto bad; pkt->src_address = DTOP_GET_BYTE(data); for (max = 0; (max < DTOP_MAX_POLL) && !DTOP_RX_AVAIL(poll); max++) DELAY(1); if (max == DTOP_MAX_POLL) goto bad; pkt->code.bits = DTOP_GET_BYTE(data); /* * Now get data and checksum */ len = pkt->code.val.len + 1; c = 0; for (i = 0; i < len; i++) {again: for (max = 0; (max < DTOP_MAX_POLL) && !DTOP_RX_AVAIL(poll); max++) DELAY(1); if (max == DTOP_MAX_POLL) goto bad; if (c == DTOP_ESC_CHAR) { c = dtop_escape(DTOP_GET_BYTE(data) & 0xff); } else { c = DTOP_GET_BYTE(data); if (c == DTOP_ESC_CHAR) goto again; } pkt->body[i] = c; } return (len);bad: dtop->bad_pkts++; return (-1);}/* * Get a keyboard char for the console */dtopKBDGetc(){ register int c; dtop_softc_t dtop; dtop = &dtop_softc[0];again: c = -1; /* * Now check keyboard */ if (DTOP_RX_AVAIL(dtop->poll)) { dtop_message msg; struct dtop_ds *ds; if (dtop_get_packet(dtop, &msg) >= 0) { ds = &dtop->device[DTOP_DEVICE_NO(msg.src_address)]; if (ds->handler == dtop_keyboard_handler) { c = dtop_keyboard_handler( &ds->status, &msg, DTOP_EVENT_RECEIVE_PACKET, -1); if (c > 0) return c; c = -1; } } } if (c == -1) { DELAY(100); goto again; } return c;}intdtopparam(tp, t) struct tty *tp; struct termios *t;{ if (tp->t_ispeed == 0) ttymodem(tp, 0); else /* called too early to invoke ttymodem, sigh */ tp->t_state |= TS_CARR_ON; return (0);} /* * Stop output on a line. *//*ARGSUSED*/dtopstop(tp, flag) register struct tty *tp; int flag;{ int s; s = spltty(); if (tp->t_state & TS_BUSY) { if (!(tp->t_state & TS_TTSTOP)) tp->t_state |= TS_FLUSH; } splx(s);}/* * Default handler function */intdtop_null_device_handler(dev, msg, event, outc) dtop_device_t dev; dtop_message_t msg; int event; int outc;{ /* See if the message was to the default address (powerup) */ /* Uhmm, donno how to handle this. Drop it */ if (event == DTOP_EVENT_RECEIVE_PACKET) dev->unknown_report = *msg; return 0;}/* * Handler for locator devices (mice) */intdtop_locator_handler(dev, msg, event, outc) dtop_device_t dev; dtop_message_t msg; int event; int outc;{ register unsigned short buttons; register short coord; register int moved = 0; static MouseReport currentRep; register MouseReport *mrp = ¤tRep; if (dtopMouseButtons) { mrp->state = 0; /* * Do the position first */ coord = GET_SHORT(msg->body[2], msg->body[3]); if (coord < 0) { coord = -coord; moved = 1; } else if (coord > 0) { mrp->state |= MOUSE_X_SIGN; moved = 1; } mrp->dx = (coord & 0x1f); coord = GET_SHORT(msg->body[4], msg->body[5]); if (coord < 0) { coord = -coord; moved = 1; } else if (coord > 0) { mrp->state |= MOUSE_Y_SIGN; moved = 1; } mrp->dy = (coord & 0x1f); /* * Time for the buttons now * Shuffle button bits around to serial mouse order. */ buttons = GET_SHORT(msg->body[0], msg->body[1]); mrp->state |= (((buttons >> 1) & 0x3) | ((buttons << 2) & 0x4)); if (moved) (*dtopMouseEvent)(mrp); (*dtopMouseButtons)(mrp); } return (0);}/* * Handler for keyboard devices * Special case: outc set for recv packet means * we are inside the kernel debugger */intdtop_keyboard_handler(dev, msg, event, outc) dtop_device_t dev; dtop_message_t msg; int event; int outc;{ register u_char *ls, *le, *ns, *ne; u_char save[11], retc; int msg_len, c, s; struct tty *tp = &dtop_tty[0]; /* * Fiddle about emulating an lk201 keyboard. The lk501 * designers carefully ensured that keyboard handlers could be * stateless, then we turn around and use lots of state to * emulate the stateful lk201, since the X11R5 X servers * only know about the lk201... (oh well) */ /* * Turn off any autorepeat timeout. */ s = splhigh(); if (dev->keyboard.k_ar_state != K_AR_IDLE) { dev->keyboard.k_ar_state = K_AR_IDLE; untimeout(dtop_keyboard_repeat, (void *)dev); } splx(s); msg_len = msg->code.val.len; /* Check for errors */ c = msg->body[0]; if ((c < DTOP_KBD_KEY_MIN) && (c != DTOP_KBD_EMPTY)) { printf("Keyboard error: %x %x %x..\n", msg_len, c, msg->body[1]);#ifdef notdef if (c != DTOP_KBD_OUT_ERR) return -1;#endif /* * Fake an "all ups" to avoid the stuck key syndrome. */ c = msg->body[0] = DTOP_KBD_EMPTY; msg_len = 1; } dev->keyboard.last_msec = TO_MS(time); /* * To make things readable, do a first pass cancelling out * all keys that are still pressed, and a second one generating * events. While generating events, do the upstrokes first * from oldest to youngest, then the downstrokes from oldest * to youngest. This copes with lost packets and provides * a reasonable model even if scans are too slow. */ /* make a copy of new state first */ if (msg_len == 1) save[0] = msg->body[0]; else if (msg_len > 0) bcopy(msg->body, save, msg_len); /* * Cancel out any keys in both the last and current message as * they are unchanged. */ if (msg_len > 0 && dev->keyboard.last_codes_count > 0) { ls = dev->keyboard.last_codes; le = &dev->keyboard.last_codes[dev->keyboard.last_codes_count]; ne = &msg->body[msg_len]; for (; ls < le; ls++) { for (ns = msg->body; ns < ne; ns++) if (*ls == *ns) { *ls = *ns = 0; break; } } } /* * Now generate all upstrokes */ le = dev->keyboard.last_codes; ls = &dev->keyboard.last_codes[dev->keyboard.last_codes_count - 1]; for ( ; ls >= le; ls--) if (c = *ls) { (void) kbdMapChar(c); if (outc == 0 && dtopDivertXInput && (keymodes[(c >> 5) & 0x7] & (1 << (c & 0x1f)))) (*dtopDivertXInput)(c); } /* * And finally the downstrokes */ ne = (char*)msg->body; ns = (char*)&msg->body[msg_len - 1]; retc = 0; for ( ; ns >= ne; ns--) if (*ns) { c = kbdMapChar(*ns); if (outc == 0) { if (dtopDivertXInput) { (*dtopDivertXInput)(*ns); c = -1; /* consumed by X */ } else if (c >= 0) (*linesw[tp->t_line].l_rint)(c, tp); dev->keyboard.k_ar_state = K_AR_ACTIVE; } /* return the related keycode anyways */ if ((c >= 0) && (retc == 0)) retc = c; } outc = retc; /* install new scan state */ if (msg_len == 1) dev->keyboard.last_codes[0] = save[0]; else if (msg_len > 0) bcopy(save, dev->keyboard.last_codes, msg_len); dev->keyboard.last_codes_count = msg_len; if (dev->keyboard.k_ar_state == K_AR_ACTIVE) timeout(dtop_keyboard_repeat, (void *)dev, hz / 2); return (outc);}/* * Do an autorepeat as required. */voiddtop_keyboard_repeat(arg) void *arg;{ dtop_device_t dev = (dtop_device_t)arg; register int i, c; struct tty *tp = dtop_tty; int s = spltty(), gotone = 0; for (i = 0; i < dev->keyboard.last_codes_count; i++) { c = (int)dev->keyboard.last_codes[i]; if (c != DTOP_KBD_EMPTY && (keymodes[(c >> 5) & 0x7] & (1 << (c & 0x1f))) == 0) { dev->keyboard.k_ar_state = K_AR_TRIGGER; if (dtopDivertXInput) { (*dtopDivertXInput)(KEY_REPEAT); gotone = 1; continue; } if ((c = kbdMapChar(KEY_REPEAT)) >= 0) { (*linesw[tp->t_line].l_rint)(c, tp); gotone = 1; } } } if (gotone) timeout(dtop_keyboard_repeat, arg, hz / 20); else dev->keyboard.k_ar_state = K_AR_IDLE; splx(s);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -