📄 pcvt_kbd.c
字号:
PCVT_KBD_DELAY(); /* 7 us delay */ dt = inb(CONTROLLER_DATA); } else /* source = keyboard fifo */ { dt = pcvt_kbd_fifo[pcvt_kbd_rptr++]; /* yes, get it ! */ PCVT_DISABLE_INTR(); pcvt_kbd_count--; PCVT_ENABLE_INTR(); if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ) pcvt_kbd_rptr = 0; } }#else /* !PCVT_KBD_FIFO */ /* see if there is data from the keyboard available from the 8042 */ if(inb(CONTROLLER_CTRL) & STATUS_OUTPBF) { PCVT_KBD_DELAY(); /* 7 us delay */ dt = inb(CONTROLLER_DATA); /* yes, get data ! */ }#endif /* !PCVT_KBD_FIFO */#else /* _I386_ISA_KBDIO_H_ */#if PCVT_KBD_FIFO if (pcvt_kbd_count) { dt = pcvt_kbd_fifo[pcvt_kbd_rptr++]; PCVT_DISABLE_INTR(); pcvt_kbd_count--; PCVT_ENABLE_INTR(); if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ) pcvt_kbd_rptr = 0; } else#endif /* PCVT_KBD_FIFO */ if (!noblock) { while ((c = read_kbd_data(kbdc)) == -1) ; dt = c; } else { if ((c = read_kbd_data_no_wait(kbdc)) == -1) return NULL; dt = c; }#endif /* !_I386_ISA_KBDIO_H_ */#endif /* !XSERVER */#ifndef _I386_ISA_KBDIO_H_ else { if(noblock) return NULL; else goto loop; }#endif /* !_I386_ISA_KBDIO_H_ */#if PCVT_SHOWKEYS showkey (' ', dt);#endif /* PCVT_SHOWKEYS */ /* lets look what we got */ switch(dt) { case KEYB_R_OVERRUN0: /* keyboard buffer overflow */#if PCVT_SCANSET == 2 case KEYB_R_SELFOK: /* keyboard selftest ok */#endif /* PCVT_SCANSET == 2 */ case KEYB_R_ECHO: /* keyboard response to KEYB_C_ECHO */ case KEYB_R_ACK: /* acknowledge after command has rx'd*/ case KEYB_R_SELFBAD: /* keyboard selftest FAILED */ case KEYB_R_DIAGBAD: /* keyboard self diagnostic failure */ case KEYB_R_RESEND: /* keyboard wants us to resend cmnd */ case KEYB_R_OVERRUN1: /* keyboard buffer overflow */ break; case KEYB_R_EXT1: /* keyboard extended scancode pfx 2 */ kbd_status.ext1 = 1; /* FALLTHROUGH */ case KEYB_R_EXT0: /* keyboard extended scancode pfx 1 */ kbd_status.extended = 1; break;#if PCVT_SCANSET == 2 case KEYB_R_BREAKPFX: /* break code prefix for set 2 and 3 */ kbd_status.breakseen = 1; break;#endif /* PCVT_SCANSET == 2 */ default: goto regular; /* regular key */ } if(noblock) return NULL; else goto loop; /* got a normal scan key */regular:#if PCVT_FREEBSD > 210 add_keyboard_randomness(dt);#endif /* PCVT_FREEBSD > 210 */#if PCVT_SCANSET == 1 kbd_status.breakseen = dt & 0x80 ? 1 : 0; dt &= 0x7f;#endif /* PCVT_SCANSET == 1 */ /* make a keycode from scan code */ if(dt >= sizeof scantokey / sizeof(u_char)) key = 0; else key = kbd_status.extended ? extscantokey[dt] : scantokey[dt]; if(kbd_status.ext1 && key == 64) /* virtual control key */ key = 129; kbd_status.extended = kbd_status.ext1 = 0;#if PCVT_CTRL_ALT_DEL /* Check for cntl-alt-del */ if((key == 76) && ctrl_down && (meta_down||altgr_down)) shutdown_nice();#endif /* PCVT_CTRL_ALT_DEL */#if !(PCVT_NETBSD || PCVT_FREEBSD >= 200)#include "ddb.h"#endif /* !(PCVT_NETBSD || PCVT_FREEBSD >= 200) */#if NDDB > 0 || defined(DDB) /* Check for cntl-alt-esc */ if((key == 110) && ctrl_down && (meta_down || altgr_down)) { static u_char in_Debugger; if(!in_Debugger) { in_Debugger = 1;#if PCVT_FREEBSD /* the string is actually not used... */ Debugger("kbd");#else Debugger();#endif in_Debugger = 0; if(noblock) return NULL; else goto loop; } }#endif /* NDDB > 0 || defined(DDB) */ /* look for keys with special handling */ if(key == 128) { /* * virtual shift; sent around PrtScr, and around the arrow * keys if the NumLck LED is on */ kbd_status.vshift = !kbd_status.breakseen; key = 0; /* no key */ } else if(key == 129) { /* * virtual control - the most ugly thingie at all * the Pause key sends: * <virtual control make> <numlock make> <virtual control * break> <numlock break> */ if(!kbd_status.breakseen) kbd_status.vcontrol = 1; /* else: let the numlock hook clear this */ key = 0; /* no key */ } else if(key == 90) { /* NumLock, look whether this is rather a Pause */ if(kbd_status.vcontrol) key = 126; /* * if this is the final break code of a Pause key, * clear the virtual control status, too */ if(kbd_status.vcontrol && kbd_status.breakseen) kbd_status.vcontrol = 0; } else if(key == 127) { /* * a SysRq; some keyboards are brain-dead enough to * repeat the SysRq key make code by sending PrtScr * make codes; other keyboards do not repeat SysRq * at all. We keep track of the SysRq state here. */ kbd_status.sysrq = !kbd_status.breakseen; } else if(key == 124) { /* * PrtScr; look whether this is really PrtScr or rather * a silly repeat of a SysRq key */ if(kbd_status.sysrq) /* ignore the garbage */ key = 0; } /* in NOREPEAT MODE ignore the key if it was the same as before */ if(!kbrepflag && key == kbd_lastkey && !kbd_status.breakseen) { if(noblock) return NULL; else goto loop; } type = key2ascii[key].type; if(type & KBD_OVERLOAD) type = ovltbl[key2ascii[key].ovlindex].type; type &= KBD_MASK; switch(type) { case KBD_SHFTLOCK: if(!kbd_status.breakseen && key != kbd_lastkey) { vsp->shift_lock ^= 1; } break; case KBD_CAPS: if(!kbd_status.breakseen && key != kbd_lastkey) { vsp->caps_lock ^= 1; update_led(); } break; case KBD_SCROLL: if(!kbd_status.breakseen && key != kbd_lastkey) { vsp->scroll_lock ^= 1; update_led(); if(!(vsp->scroll_lock)) { /* someone may be sleeping */ wakeup((caddr_t)&(vsp->scroll_lock)); } } break; case KBD_SHIFT: shift_down = kbd_status.breakseen ? 0 : 1; break; case KBD_META: meta_down = kbd_status.breakseen ? 0 : 0x80; break; case KBD_ALTGR: altgr_down = kbd_status.breakseen ? 0 : 1; break; case KBD_CTL: ctrl_down = kbd_status.breakseen ? 0 : 1; break; case KBD_NONE: default: break; /* deliver a key */ } if(kbd_status.breakseen) { key |= 0x80; kbd_status.breakseen = 0; kbd_lastkey = 0; /* -hv- I know this is a bug with */ } /* N-Key-Rollover, but I ignore that */ else /* because avoidance is too complicated */ kbd_lastkey = key; cp = xlatkey2ascii(key); /* have a key */ if(cp == NULL && !noblock) goto loop; return cp;}/*---------------------------------------------------------------------------* * reflect status of locking keys & set led's *---------------------------------------------------------------------------*/static voidsetlockkeys(int snc){ vsp->scroll_lock = snc & 1; vsp->num_lock = (snc & 2) ? 1 : 0; vsp->caps_lock = (snc & 4) ? 1 : 0; update_led();}/*---------------------------------------------------------------------------* * remove a key definition *---------------------------------------------------------------------------*/static intrmkeydef(int key){ register Ovl_tbl *ref; if(key==0 || key > MAXKEYNUM) return EINVAL; if(key2ascii[key].type & KBD_OVERLOAD) { ref = &ovltbl[key2ascii[key].ovlindex]; ref->keynum = 0; ref->type = 0; ref->unshift[0] = ref->shift[0] = ref->ctrl[0] = ref->altgr[0] = 0; key2ascii[key].type &= KBD_MASK; } return 0;}/*---------------------------------------------------------------------------* * overlay a key *---------------------------------------------------------------------------*/static intsetkeydef(Ovl_tbl *data){ register i; if( data->keynum > MAXKEYNUM || (data->type & KBD_MASK) == KBD_BREAK || (data->type & KBD_MASK) > KBD_SHFTLOCK) return EINVAL; data->unshift[KBDMAXOVLKEYSIZE] = data->shift[KBDMAXOVLKEYSIZE] = data->ctrl[KBDMAXOVLKEYSIZE] = data->altgr[KBDMAXOVLKEYSIZE] = 0; data->subu = data->subs = data->subc = data->suba = KBD_SUBT_STR; /* just strings .. */ data->type |= KBD_OVERLOAD; /* mark overloaded */ /* if key already overloaded, use that slot else find free slot */ if(key2ascii[data->keynum].type & KBD_OVERLOAD) { i = key2ascii[data->keynum].ovlindex; } else { for(i=0; i<OVLTBL_SIZE; i++) if(ovltbl[i].keynum==0) break; if(i==OVLTBL_SIZE) return ENOSPC; /* no space, abuse of ENOSPC(!) */ } ovltbl[i] = *data; /* copy new data string */ key2ascii[data->keynum].type |= KBD_OVERLOAD; /* mark key */ key2ascii[data->keynum].ovlindex = i; return 0;}/*---------------------------------------------------------------------------* * keyboard ioctl's entry *---------------------------------------------------------------------------*/intkbdioctl(Dev_t dev, int cmd, caddr_t data, int flag){ int key; switch(cmd) { case KBDRESET: doreset(); ovlinit(1); settpmrate(KBD_TPD500|KBD_TPM100); setlockkeys(0); break; case KBDGTPMAT: *(int *)data = tpmrate; break; case KBDSTPMAT: settpmrate(*(int *)data); break; case KBDGREPSW: *(int *)data = kbrepflag; break; case KBDSREPSW: kbrepflag = (*(int *)data) & 1; break; case KBDGLEDS: *(int *)data = ledstate; break; case KBDSLEDS: update_led(); /* ??? */ break; case KBDGLOCK: *(int *)data = ( (vsp->scroll_lock) | (vsp->num_lock * 2) | (vsp->caps_lock * 4)); break; case KBDSLOCK: setlockkeys(*(int *)data); break; case KBDGCKEY: key = ((Ovl_tbl *)data)->keynum; return getckeydef(key,(Ovl_tbl *)data); case KBDSCKEY: key = ((Ovl_tbl *)data)->keynum; return setkeydef((Ovl_tbl *)data); case KBDGOKEY: key = ((Ovl_tbl *)data)->keynum; return getokeydef(key,(Ovl_tbl *)data); case KBDRMKEY: key = *(int *)data; return rmkeydef(key); case KBDDEFAULT: ovlinit(1); break; default: /* proceed with vga ioctls */ return -1; } return 0;}#if PCVT_EMU_MOUSE/*--------------------------------------------------------------------------* * mouse emulator ioctl *--------------------------------------------------------------------------*/intmouse_ioctl(Dev_t dev, int cmd, caddr_t data){ struct mousedefs *def = (struct mousedefs *)data; switch(cmd) { case KBDMOUSEGET: *def = mousedef; break; case KBDMOUSESET: mousedef = *def; break; default: return -1; } return 0;}#endif /* PCVT_EMU_MOUSE */#if PCVT_USL_VT_COMPAT/*---------------------------------------------------------------------------* * convert ISO-8859 style keycode into IBM 437 *---------------------------------------------------------------------------*/static inline u_chariso2ibm(u_char c){ if(c < 0x80) return c; return iso2ibm437[c - 0x80];}/*---------------------------------------------------------------------------* * build up a USL style keyboard map *---------------------------------------------------------------------------*/voidget_usl_keymap(keymap_t *map){ int i; bzero((caddr_t)map, sizeof(keymap_t)); map->n_keys = 0x59; /* that many keys we know about */ for(i = 1; i < N_KEYNUMS; i++) { Ovl_tbl kdef; u_char c; int j; int idx = key2scan1[i]; if(idx == 0 || idx >= map->n_keys) continue; getckeydef(i, &kdef); kdef.type &= KBD_MASK; switch(kdef.type) { case KBD_ASCII:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -