📄 keyboard.c
字号:
tcgetattr(__svgalib_kbd_fd, &kbdtermios); kbdtermios.c_lflag = kbdtermios.c_lflag & ~(ICANON | ECHO | ISIG); kbdtermios.c_cc[VMIN] = 0; kbdtermios.c_cc[VTIME] = 0; tcsetattr(__svgalib_kbd_fd, TCSANOW, &kbdtermios);#endif kfdmode = 1; bytesread = read(__svgalib_kbd_fd, buf, 1); } if (wait == 0 && bytesread < 1) return eventhandled; if (bytesread >= 1) eventhandled = 1; for (i = 0; i < bytesread; i++) { unsigned char scancode = kbd_mapkey(buf[i] & 0x7f); unsigned char is_pressed = (buf[i] & 0x80) ? 0 : 1; /* Check for ctrl-c. */ switch (scancode) { case SCANCODE_C: c_state = is_pressed; break; case SCANCODE_LEFTCONTROL: case SCANCODE_RIGHTCONTROL: ctrl_state = is_pressed; break; case SCANCODE_LEFTALT: case SCANCODE_RIGHTALT: alt_state = is_pressed; break; case SCANCODE_LEFTWIN: case SCANCODE_RIGHTWIN: win_state = is_pressed; break; case SCANCODE_F1 ... SCANCODE_F10: functionkey_state = (is_pressed) ? functionkey_state | 1 << (scancode - SCANCODE_F1) : functionkey_state & ~(1 << (scancode - SCANCODE_F1)); break; } if (fake_mouse_events && __svgalib_mouse_fd > -1) { int n; for(n = 0; n < fme_used; n++) if(fake_mouse_events[n][0].scancode == scancode) break; if(fme_numberof[n]) { int i; int dx=0, dy=0, dz=0, but=0; /* To gather mutiple events into one */ int but_changed = 0; struct FakeMouseEvent *event; for (i = 0; i < fme_numberof[n]; i++) { int request_at_down; short flags; event = &fake_mouse_events[n][i]; if (!is_pressed) event -> flags &= ~FMEF_TRIGGERED; flags = event -> flags; request_at_down = (event -> flags & FMEF_AT_PRESS) ? 1 : 0;#ifdef DEBUG_KEYBOARD printf(" event type: %ld; flags: %ld; data: %ld; is_pressed: %ld\n", (long)event->type, (long)flags, (long)event->data, (long)is_pressed);#endif if (flags & FMEF_AT_BOTH || request_at_down == is_pressed) {#ifdef DEBUG_KEYBOARD printf(" flags: %ld\n", (long)flags);#endif if ( (! (flags & FMEF_TRIGGERED)) || flags & FMEF_REPEAT) {#ifdef DEBUG_KEYBOARD printf(" triggering\n");#endif switch (event -> type) { case FME_TYPE_BUTTON1: but = (event -> data) ? but | 4 : but & ~4; but_changed = 1; break; case FME_TYPE_BUTTON2: but = (event -> data) ? but | 1 : but & ~1; but_changed = 1; break; case FME_TYPE_BUTTON3: but = (event -> data) ? but | 2 : but & ~2; but_changed = 1; break; case FME_TYPE_IGNOREX: __svgalib_m_ignore_dx = event -> data; break; case FME_TYPE_IGNOREY: __svgalib_m_ignore_dy = event -> data; break; case FME_TYPE_IGNOREZ: __svgalib_m_ignore_dz = event -> data; break; case FME_TYPE_DELTAX: dx += event -> data; break; case FME_TYPE_DELTAY: dy += event -> data; break; case FME_TYPE_DELTAZ: dz += event -> data; break; } if (is_pressed) event -> flags |= FMEF_TRIGGERED; } } } if ((dx || dy || dz || but_changed) && __svgalib_mouse_eventhandler) { __svgalib_mouse_eventhandler(but, dx, dy, dz, 0, 0, 0);#ifdef DEBUG_KEYBOARD printf("\tfake_mouse_event triggered; but: %ld; dx: %ld; dy: %ld; dz: %ld\n", (long)but, (long)dx, (long)dy, (long)dz);#endif } } } if (ctrl_state && c_state && !(translatemode & DONT_CATCH_CTRLC)) raise(SIGINT); if ((alt_state && functionkey_state)||(win_state && functionkey_state)) { /* VT switch. */ /* *** what about F11 & F12? */ int j, vt = 0; struct vt_stat vts; for (j = 0; j < 12; j++) if (functionkey_state & (1 << j)) { vt = j + 1; if(win_state)j+=12; break; } /* Do not switch vt's if need not to */ ioctl(__svgalib_tty_fd, VT_GETSTATE, &vts); if(vt != vts.v_active) { /* if switching vt's, need to clear keystates */ keyboard_clearstate(); /* * This will generate a signal catched by * svgalib to restore textmode. */ ioctl(__svgalib_tty_fd, VT_ACTIVATE, vt); return 1; } } __svgalib_keyboard_eventhandler(scancode, (buf[i] & 0x80) ? KEY_EVENTRELEASE : KEY_EVENTPRESS); } /* Handle other events that have accumulated. */ goto again;}int keyboard_update(void){ return keyboard_getevents(0); /* Don't wait. */}void keyboard_waitforupdate(void){ keyboard_getevents(1); /* Wait for event. */ return;}void keyboard_seteventhandler(void (*handler) (int, int)){ __svgalib_keyboard_eventhandler = handler;}/* Default event handler. */void keyboard_setdefaulteventhandler(void){ __svgalib_keyboard_eventhandler = default_handler;}static int checkscancode(int scancode){ if (scancode < 0 || scancode >= NR_KEYS) { printf("svgalib: keyboard scancode out of range (%d).\n", scancode); return 1; } return 0;}static void default_handler(int scancode, int newstate){ if (checkscancode(scancode)) return; if (translatemode & TRANSLATE_CURSORKEYS) /* Map cursor key block to keypad cursor keys. */ switch (scancode) { case SCANCODE_CURSORBLOCKUP: scancode = SCANCODE_CURSORUP; break; case SCANCODE_CURSORBLOCKLEFT: scancode = SCANCODE_CURSORLEFT; break; case SCANCODE_CURSORBLOCKRIGHT: scancode = SCANCODE_CURSORRIGHT; break; case SCANCODE_CURSORBLOCKDOWN: scancode = SCANCODE_CURSORDOWN; break; } if (translatemode & TRANSLATE_DIAGONAL) { /* Translate diagonal keypad keys to two keypad cursor keys. */ switch (scancode) { case SCANCODE_CURSORUPLEFT: state[SCANCODE_CURSORUP] = newstate; state[SCANCODE_CURSORLEFT] = newstate; break; case SCANCODE_CURSORUPRIGHT: state[SCANCODE_CURSORUP] = newstate; state[SCANCODE_CURSORRIGHT] = newstate; break; case SCANCODE_CURSORDOWNLEFT: state[SCANCODE_CURSORDOWN] = newstate; state[SCANCODE_CURSORLEFT] = newstate; break; case SCANCODE_CURSORDOWNRIGHT: state[SCANCODE_CURSORDOWN] = newstate; state[SCANCODE_CURSORRIGHT] = newstate; break; } } if ((translatemode & TRANSLATE_KEYPADENTER) && scancode == SCANCODE_KEYPADENTER) scancode = SCANCODE_ENTER;#if 0 /* This happens very often. */ if (state[scancode] == newstate) { printf("svgalib: keyboard event does not match (scancode = %d)\n", scancode); return; }#endif state[scancode] = newstate;}void keyboard_clearstate(void){ memset(state, 0, NR_KEYS); ctrl_state = c_state = alt_state = 0; functionkey_state = 0;}int keyboard_keypressed(int scancode){ if (checkscancode(scancode)) return 0; return state[scancode];}char * keyboard_getstate(void){ return state;}void keyboard_translatekeys(int mode){ translatemode = mode; if (__svgalib_nosigint) translatemode |= DONT_CATCH_CTRLC;}static int kbd_mapkey(int inscancode){ if (usekeymap) return keymap[inscancode]; else return inscancode;}static char *kbd_load_keymap(char *ptr){ /* Find the specified keymap file */ /* For now, use a full pathname */ FILE *keymapfile;#ifdef DEBUG_KEYBOARD fprintf(stderr, " Trying to load keymap \'%s\'...\n",ptr);#endif /* If so configured check if the file is owned by root */ if(rootkeymaps) { struct stat fs; if(stat(ptr, &fs)) { fprintf(stderr, "svgalib: kbd-config: cannot stat keymap file \'%s\'\n", ptr); return ptr; } else if(fs.st_uid != 0) { fprintf(stderr, "svgalib: kbd-config: keymap file \'%s\' not owned by root\n", ptr); return ptr; } } if((keymapfile = fopen(ptr, "rt"))) { /* Load it in! */ char buf[81], nbuf[81]; int i, l = 0, insc, outsc; buf[80] = nbuf[80] = 0; /* Protect somewhat against overruns */ /* Disable the keymap until we're done in case something goes wrong... */ usekeymap = 0; /* Initialize keymap */ for (i = 0; i < NR_KEYS; keymap[i++] = i); while(!feof(keymapfile)) { /* Read */ fgets(buf, 80, keymapfile); l++; /* Ignore comments & blank lines */ if ((buf[0] != '#') && (buf[0] != '\n')) { /* Interpret the numbers */ if((i = sscanf(buf, "%d %d %s", &insc, &outsc, nbuf) == 3)) { if(checkscancode(insc)) continue; if(checkscancode(outsc)) continue; keymap[insc] = outsc; strncpy(keynames[insc], nbuf, MAX_KEYNAME_LEN); } else { fprintf(stderr, "svgalib: kbd-config: skipping line %d of keymap - bad %sput scancode\n", l, ((i == 1)?("out"):("in"))); } } } usekeymap = 1; /* Update the mouse driver's fake keyboard events */#ifdef DEBUG_KEYBOARD fprintf(stderr, " Keymap loaded. Updating fake keyboard events...\n");#endif __svgalib_mouse_update_keymap(); /* And the fake mouse events */#ifdef DEBUG_KEYBOARD fprintf(stderr, " Updating fake mouse events...\n");#endif kbd_update_keymap(); fclose(keymapfile); } else { fprintf(stderr, "svgalib: kbd-config: keymap file \'%s\' cannot be opened\n", ptr); return ptr; } return NULL;}int __svgalib_mapkeyname(const char *keyname){ int scancode; char *ptr;#ifdef DEBUG_KEYBOARD fprintf(stderr, " Attempting to map \'%s\' to a scancode...", keyname);#endif if(!keyname) { fprintf(stderr, "svgalib: kbd-config: can't use NULL keyname!\n"); return -1; } if(!*keyname) { fprintf(stderr, "svgalib: kbd-config: can't use empty keyname!\n"); return -1; } /* Is it a number? */ scancode = strtol(keyname, &ptr, 0); if(ptr != keyname) { /* Is it in range? */ if((scancode < 0) || (scancode >= NR_KEYS)) { fprintf(stderr, "svgalib: kbd-config: scancode %s out of range!\n",keyname); return -1; } else {#ifdef DEBUG_KEYBOARD fprintf(stderr, " mapped numerically to %d.\n", scancode);#endif return scancode; } } /* Look up a symbolic name */ for(scancode = 0; scancode < NR_KEYS; scancode++) {#ifdef DEBUG_KEYBOARD fprintf(stderr, " (%s)", keynames[scancode]);#endif if(strncasecmp(keyname, keynames[scancode], MAX_KEYNAME_LEN) == 0) {#ifdef DEBUG_KEYBOARD fprintf(stderr, " mapped symbolically to %d", scancode); if(usekeymap) fprintf(stderr, ", remapped to %d", kbd_mapkey(scancode)); fprintf(stderr, ".\n");#endif return kbd_mapkey(scancode); } }#ifdef DEBUG_KEYBOARD fprintf(stderr, " no match!\n");#endif /* No match */ return -1;}static void kbd_update_keymap(void){ /* Remap the scancodes of the fake mouse events */ int n, i=0; for(n = 0; n < fme_used; n++) if(fake_mouse_events[n]) { /*for(i = 0; i < fme_numberof[n]; i++)*/ fake_mouse_events[n][i].scancode = __svgalib_mapkeyname(fake_mouse_events[n][i].keyname); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -