📄 pcvt_kbd.c
字号:
if(meta_down) { switch(key) { case 95: /* / */ altkpflag = 0; more_chars = (u_char *)"\033OQ"; return(more_chars); case 100: /* * */ altkpflag = 0; more_chars = (u_char *)"\033OR"; return(more_chars); case 105: /* - */ altkpflag = 0; more_chars = (u_char *)"\033OS"; return(more_chars); } } if(meta_down || altgr_down) { if((n = keypad2num[key-91]) >= 0) { if(!altkpflag) { /* start ALT-KP mode */ altkpflag = 1; altkpval = 0; } altkpval *= 10; altkpval += n; } else altkpflag = 0; return 0; } if(!(vsp->num_lock)) { if(key2ascii[key].shift.subtype == STR) more_chars = (u_char *)thisdef.shift; else fnc = key2ascii[key].shift.what.func; } else { if(key2ascii[key].unshift.subtype == STR) more_chars = (u_char *)thisdef.unshift; else fnc = key2ascii[key].unshift.what.func; } if(fnc) (*fnc)(); /* execute function */ return(more_chars); case KBD_CURSOR: fnc = NULL; more_chars = NULL; if(vsp->ckm) { if(key2ascii[key].shift.subtype == STR) more_chars = (u_char *)thisdef.shift; else fnc = key2ascii[key].shift.what.func; } else { if(key2ascii[key].unshift.subtype == STR) more_chars = (u_char *)thisdef.unshift; else fnc = key2ascii[key].unshift.what.func; } if(fnc) (*fnc)(); /* execute function */ return(more_chars); case KBD_NUM: /* special kp-num handling */ more_chars = NULL; if(meta_down) { more_chars = (u_char *)"\033OP"; /* PF1 */ } else { vsp->num_lock ^= 1; update_led(); } return(more_chars); case KBD_RETURN: more_chars = NULL; if(!(vsp->num_lock)) { more_chars = (u_char *)thisdef.shift; } else { more_chars = (u_char *)thisdef.unshift; } if(vsp->lnm && (*more_chars == '\r')) { more_chars = (u_char *)"\r\n"; /* CR LF */ } if(meta_down) {#if PCVT_META_ESC metachar[1] = *more_chars;#else metachar[0] = *more_chars | 0x80;#endif more_chars = metachar; } return(more_chars); case KBD_META: /* these keys are */ case KBD_ALTGR: /* handled directly */ case KBD_SCROLL: /* by the keyboard */ case KBD_CAPS: /* handler - they are */ case KBD_SHFTLOCK: /* ignored here */ case KBD_CTL: case KBD_NONE: default: return 0; }}/*---------------------------------------------------------------------------* * get keystrokes from the keyboard. * if noblock = 0, wait until a key is pressed. * else return NULL if no characters present. *---------------------------------------------------------------------------*/#if PCVT_KBD_FIFOextern u_char pcvt_kbd_fifo[];extern int pcvt_kbd_rptr;extern short pcvt_kbd_count;#endifu_char *sgetc(int noblock){ u_char *cp; u_char dt; u_char key; u_short type;#if PCVT_KBD_FIFO && PCVT_SLOW_INTERRUPT int s;#endif static u_char kbd_lastkey = 0; /* last keystroke */ static struct { u_char extended: 1; /* extended prefix seen */ u_char ext1: 1; /* extended prefix 1 seen */ u_char breakseen: 1; /* break code seen */ u_char vshift: 1; /* virtual shift pending */ u_char vcontrol: 1; /* virtual control pending */ u_char sysrq: 1; /* sysrq pressed */ } kbd_status = {0};#ifdef XSERVER static char keybuf[2] = {0}; /* the second 0 is a delimiter! */#endif /* XSERVER */#ifdef _I386_ISA_KBDIO_H_ int c;#endif /* _I386_ISA_KBDIO_H_ */loop:#ifdef XSERVER#ifndef _I386_ISA_KBDIO_H_#if PCVT_KBD_FIFO /* see if there is data from the keyboard available either from */ /* the keyboard fifo or from the 8042 keyboard controller */ if (pcvt_kbd_count || (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)) { if (!pcvt_kbd_count) /* source = 8042 */ { PCVT_KBD_DELAY(); /* 7 us delay */ dt = inb(CONTROLLER_DATA); /* get from obuf */ } else /* source = keyboard fifo */ { 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 /* !PCVT_KB_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_ */ /* * If x mode is active, only care for locking keys, then * return the scan code instead of any key translation. * Additionally, this prevents us from any attempts to * execute pcvt internal functions caused by keys (such * as screen flipping). * XXX For now, only the default locking key definitions * are recognized (i.e. if you have overloaded you "A" key * as NUMLOCK, that wont effect X mode:-) * Changing this would be nice, but would require modifi- * cations to the X server. After having this, X will * deal with the LEDs itself, so we are committed. */ /* * Iff PCVT_USL_VT_COMPAT is defined, the behaviour has * been fixed. We need not care about any keys here, since * there are ioctls that deal with the lock key / LED stuff. */ if (pcvt_kbd_raw) { keybuf[0] = dt;#if PCVT_FREEBSD > 210 add_keyboard_randomness(dt);#endif /* PCVT_FREEBSD > 210 */#if !PCVT_USL_VT_COMPAT if ((dt & 0x80) == 0) /* key make */ switch(dt) { case 0x45: /* XXX on which virt screen? */ vsp->num_lock ^= 1; update_led(); break; case 0x3a: vsp->caps_lock ^= 1; update_led(); break; case 0x46: vsp->scroll_lock ^= 1; update_led(); break; }#endif /* !PCVT_USL_VT_COMPAT */#if PCVT_EMU_MOUSE /* * The (mouse systems) mouse emulator. The mouse * device allocates the first device node that is * not used by a virtual terminal. (E.g., you have * eight vtys, /dev/ttyv0 thru /dev/ttyv7, so the * mouse emulator were /dev/ttyv8.) * Currently the emulator only works if the keyboard * is in raw (PC scan code) mode. This is the typic- * al case when running the X server. * It is activated if the num locks LED is active * for the current vty, and if the mouse device * has been opened by at least one process. It * grabs the numerical keypad events (but only * the "non-extended", so the separate arrow keys * continue to work), and three keys for the "mouse * buttons", preferrably F1 thru F3. Any of the * eight directions (N, NE, E, SE, S, SW, W, NW) * is supported, and frequent key presses (less * than e.g. half a second between key presses) * cause the emulator to accelerate the pointer * movement by 6, while single presses result in * single moves, so each point can be reached. */ /* * NB: the following code is spagghetti. * Only eat it with lotta tomato ketchup and * Parmesan cheese:-) */ /* * look whether we will have to steal the keys * and cook them into mouse events */ if(vsp->num_lock && mouse.opened) { int button, accel, i; enum mouse_dir { MOUSE_NW, MOUSE_N, MOUSE_NE, MOUSE_W, MOUSE_0, MOUSE_E, MOUSE_SW, MOUSE_S, MOUSE_SE } move; struct timeval now; dev_t dummy = makedev(0, mouse.minor); struct tty *mousetty = get_pccons(dummy); /* * strings to send for each mouse event, * indexed by the movement direction and * the "accelerator" value (TRUE for frequent * key presses); note that the first byte * of each string is actually overwritten * by the current button value before sending * the string */ static u_char mousestrings[2][MOUSE_SE+1][5] = { { /* first, the non-accelerated strings*/ {0x87, -1, 1, 0, 0}, /* NW */ {0x87, 0, 1, 0, 0}, /* N */ {0x87, 1, 1, 0, 0}, /* NE */ {0x87, -1, 0, 0, 0}, /* W */ {0x87, 0, 0, 0, 0}, /* 0 */ {0x87, 1, 0, 0, 0}, /* E */ {0x87, -1, -1, 0, 0}, /* SW */ {0x87, 0, -1, 0, 0}, /* S */ {0x87, 1, -1, 0, 0} /* SE */ }, { /* now, 6 steps at once */ {0x87, -4, 4, 0, 0}, /* NW */ {0x87, 0, 6, 0, 0}, /* N */ {0x87, 4, 4, 0, 0}, /* NE */ {0x87, -6, 0, 0, 0}, /* W */ {0x87, 0, 0, 0, 0}, /* 0 */ {0x87, 6, 0, 0, 0}, /* E */ {0x87, -4, -4, 0, 0}, /* SW */ {0x87, 0, -6, 0, 0}, /* S */ {0x87, 4, -4, 0, 0} /* SE */ } }; if(dt == 0xe0) { /* ignore extended scan codes */ mouse.extendedseen = 1; goto no_mouse_event; } if(mouse.extendedseen) { mouse.extendedseen = 0; goto no_mouse_event; } mouse.extendedseen = 0; /* * Note that we cannot use a switch here * since we want to have the keycodes in * a variable */ if((dt & 0x7f) == mousedef.leftbutton) { button = 4; goto do_button; } else if((dt & 0x7f) == mousedef.middlebutton) { button = 2; goto do_button; } else if((dt & 0x7f) == mousedef.rightbutton) { button = 1; do_button: /* * i would really like to give * some acustical support * (pling/plong); i am not sure * whether it is safe to call * sysbeep from within an intr * service, since it calls * timeout in turn which mani- * pulates the spl mask - jw */# define PLING sysbeep(PCVT_SYSBEEPF / 1500, 2)# define PLONG sysbeep(PCVT_SYSBEEPF / 1200, 2) if(mousedef.stickybuttons) { if(dt & 0x80) { mouse.breakseen = 1; return (u_char *)0; } else if(mouse.buttons == button && !mouse.breakseen) { /* ignore repeats */ return (u_char *)0; } else mouse.breakseen = 0; if(mouse.buttons == button) { /* release it */ mouse.buttons = 0; PLONG; } else { /* * eventually, release * any other button, * and stick this one */ mouse.buttons = button; PLING; } } else { if(dt & 0x80) { mouse.buttons &= ~button; PLONG; } else if((mouse.buttons & button) == 0) { mouse.buttons |= button; PLING; } /*else: ignore same btn press*/ } move = MOUSE_0; accel = 0; }# undef PLING# undef PLONG else switch(dt & 0x7f) { /* the arrow keys - KP 1 thru KP 9 */ case 0x47: move = MOUSE_NW; goto do_move; case 0x48: move = MOUSE_N; goto do_move; case 0x49: move = MOUSE_NE; goto do_move; case 0x4b: move = MOUSE_W; goto do_move; case 0x4c: move = MOUSE_0; goto do_move; case 0x4d: move = MOUSE_E; goto do_move; case 0x4f: move = MOUSE_SW; goto do_move; case 0x50: move = MOUSE_S; goto do_move; case 0x51: move = MOUSE_SE; do_move: if(dt & 0x80) /* * arrow key break events are * of no importance for us */ return (u_char *)0; /* * see whether the last move did * happen "recently", i.e. before * less than half a second */ gettime(&now); timevalsub(&now, &mouse.lastmove); mouse.lastmove = time; accel = (now.tv_sec == 0 && now.tv_usec < mousedef.acceltime); break; default: /* not a mouse-emulating key */ goto no_mouse_event; } mousestrings[accel][move][0] = 0x80 + (~mouse.buttons & 7); /* finally, send the string */ for(i = 0; i < 5; i++) (*linesw[mousetty->t_line].l_rint) (mousestrings[accel][move][i], mousetty); return (u_char *)0; /* not a kbd event */ }no_mouse_event:#endif /* PCVT_EMU_MOUSE */ return ((u_char *)keybuf); } }#else /* !XSERVER */#ifndef _I386_ISA_KBDIO_H_# if PCVT_KBD_FIFO /* see if there is data from the keyboard available either from */ /* the keyboard fifo or from the 8042 keyboard controller */ if (pcvt_kbd_count || (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)) { if (!noblock || kbd_polling) /* source = 8042 */ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -