📄 kbd.c
字号:
* We will find out when a RESET comes along. */ return (-1); } down = !KEY_UP(c); c = ks->kbd_cur[KEY_CODE(c)]; if (c & KEY_MAGIC) { switch (c) { case KEY_LSHIFT: ks->kbd_lshift = down; break; case KEY_RSHIFT: ks->kbd_rshift = down; break; case KEY_ALLUP: ks->kbd_anyshift = 0; ks->kbd_control = 0; break; case KEY_CONTROL: ks->kbd_control = down; /* FALLTHROUGH */ case KEY_IGNORE: return (-1); default: panic("kbd_translate"); } if (ks->kbd_anyshift) ks->kbd_cur = ks->kbd_shifted; else ks->kbd_cur = ks->kbd_unshifted; return (-1); } if (!down) return (-1); if (ks->kbd_control) { /* control space and unshifted control atsign return null */ if (c == ' ' || c == '2') return (0); /* unshifted control hat */ if (c == '6') return ('^' & 0x1f); /* standard controls */ if (c >= '@' && c < 0x7f) return (c & 0x1f); } return (c);}voidkbd_rint(register int c){ register struct kbd_softc *k = &kbd_softc; register struct firm_event *fe; register int put; /* * Reset keyboard after serial port overrun, so we can resynch. * The printf below should be shortened and/or replaced with a * call to log() after this is tested (and how will we test it?!). */ if (c & (TTY_FE|TTY_PE)) { printf("keyboard input parity or framing error (0x%x)\n", c); (void) ttyoutput(KBD_CMD_RESET, k->k_kbd); (*k->k_kbd->t_oproc)(k->k_kbd); return; } /* Read the keyboard id if we read a KBD_RESET last time */ if (k->k_state.kbd_takeid) { k->k_state.kbd_takeid = 0; k->k_state.kbd_id = c; kbd_reset(&k->k_state); return; } /* If we have been reset, setup to grab the keyboard id next time */ if (c == KBD_RESET) { k->k_state.kbd_takeid = 1; return; } /* * If /dev/kbd is not connected in event mode, but we are sending * data to /dev/console, translate and send upstream. Note that * we will get this while opening /dev/kbd if it is not already * open and we do not know its type. */ if (!k->k_evmode) { c = kbd_translate(c, &k->k_state); if (c >= 0 && k->k_cons != NULL) ttyinput(c, k->k_cons); return; } /* * IDLEs confuse the MIT X11R4 server badly, so we must drop them. * This is bad as it means the server will not automatically resync * on all-up IDLEs, but I did not drop them before, and the server * goes crazy when it comes time to blank the screen.... */ if (c == KBD_IDLE) return; /* * Keyboard is generating events. Turn this keystroke into an * event and put it in the queue. If the queue is full, the * keystroke is lost (sorry!). */ put = k->k_events.ev_put; fe = &k->k_events.ev_q[put]; put = (put + 1) % EV_QSIZE; if (put == k->k_events.ev_get) { log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */ return; } fe->id = KEY_CODE(c); fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; fe->time = time; k->k_events.ev_put = put; EV_WAKEUP(&k->k_events);}intkbdopen(dev_t dev, int flags, int mode, struct proc *p){ int s, error; if (kbd_softc.k_events.ev_io) return (EBUSY); kbd_softc.k_events.ev_io = p; /* * If no console keyboard, tell the device to open up, maybe for * the first time. Then make sure we know what kind of keyboard * it is. */ if (kbd_softc.k_cons == NULL) (*kbd_softc.k_open)(kbd_softc.k_kbd); error = 0; s = spltty(); if (kbd_softc.k_state.kbd_cur == NULL) { (void) ttyoutput(KBD_CMD_RESET, kbd_softc.k_kbd); error = tsleep((caddr_t)&kbd_softc.k_state, PZERO | PCATCH, devopn, hz); if (error == EWOULDBLOCK) /* no response */ error = ENXIO; } splx(s); if (error) { kbd_softc.k_events.ev_io = NULL; return (error); } ev_init(&kbd_softc.k_events); return (0);}intkbdclose(dev_t dev, int flags, int mode, struct proc *p){ /* * Turn off event mode, dump the queue, and close the keyboard * unless it is supplying console input. */ kbd_softc.k_evmode = 0; ev_fini(&kbd_softc.k_events); if (kbd_softc.k_cons == NULL) (*kbd_softc.k_close)(kbd_softc.k_kbd); kbd_softc.k_events.ev_io = NULL; return (0);}intkbdread(dev_t dev, struct uio *uio, int flags){ return (ev_read(&kbd_softc.k_events, uio, flags));}/* this routine should not exist, but is convenient to write here for now */intkbdwrite(dev_t dev, struct uio *uio, int flags){ return (EOPNOTSUPP);}intkbdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p){ register struct kbd_softc *k = &kbd_softc; switch (cmd) { case KIOCTRANS: if (*(int *)data == TR_UNTRANS_EVENT) return (0); break; case KIOCGTRANS: /* * Get translation mode */ *(int *)data = TR_UNTRANS_EVENT; return (0); case KIOCGETKEY: if (((struct kiockey *)data)->kio_station == 118) { /* * This is X11 asking if a type 3 keyboard is * really a type 3 keyboard. Say yes. */ ((struct kiockey *)data)->kio_entry = HOLE; return (0); } break; case KIOCCMD: /* * ``unimplemented commands are ignored'' (blech) * so cannot check return value from kbd_docmd */#ifdef notyet while (kbd_docmd(*(int *)data, 1) == ENOSPC) /*ERESTART?*/ (void) sleep((caddr_t)&lbolt, TTOPRI);#else (void) kbd_docmd(*(int *)data, 1);#endif return (0); case KIOCTYPE: *(int *)data = k->k_state.kbd_id; return (0); case KIOCSDIRECT: k->k_evmode = *(int *)data; return (0); case FIONBIO: /* we will remove this someday (soon???) */ return (0); case FIOASYNC: k->k_events.ev_async = *(int *)data != 0; return (0); case TIOCSPGRP: if (*(int *)data != k->k_events.ev_io->p_pgid) return (EPERM); return (0); default: return (ENOTTY); } /* * We identified the ioctl, but we do not handle it. */ return (EOPNOTSUPP); /* misuse, but what the heck */}intkbdselect(dev_t dev, int rw, struct proc *p){ return (ev_select(&kbd_softc.k_events, rw, p));}/* * Execute a keyboard command; return 0 on success. * If `isuser', force a small delay before output if output queue * is flooding. (The keyboard runs at 1200 baud, or 120 cps.) */intkbd_docmd(int cmd, int isuser){ register struct tty *tp = kbd_softc.k_kbd; register struct kbd_softc *k = &kbd_softc; int s; if (tp == NULL) return (ENXIO); /* ??? */ switch (cmd) { case KBD_CMD_BELL: case KBD_CMD_NOBELL: /* Supported by type 2, 3, and 4 keyboards */ break; case KBD_CMD_CLICK: /* Unsupported by type 2 keyboards */ if (k->k_state.kbd_id != KB_SUN2) { k->k_state.kbd_click = 1; break; } return (EINVAL); case KBD_CMD_NOCLICK: /* Unsupported by type 2 keyboards */ if (k->k_state.kbd_id != KB_SUN2) { k->k_state.kbd_click = 0; break; } return (EINVAL); default: return (EINVAL); /* ENOTTY? EOPNOTSUPP? */ } if (isuser) { s = spltty(); if (tp->t_outq.c_cc > 120) (void) tsleep((caddr_t)&lbolt, TTIPRI, ttyout, 0); splx(s); } if (ttyoutput(cmd, tp) >= 0) return (ENOSPC); /* ERESTART? */ (*tp->t_oproc)(tp); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -