⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keynames.c

📁 Linux游戏编程源码
💻 C
字号:
/* More advanced keycode viewer that identifies the keys it encounters. */#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <termios.h>#include <sys/ioctl.h>#include <linux/keyboard.h>#include <linux/kd.h>#include <sys/types.h>/* Our key-mapping table. This will contain printable characters   for some keys.  */char keymap[NR_KEYS];/* We'll assign names to certain keys. */char *keynames[NR_KEYS];/* Locates the arrow keys and the Escape key in the kernel's keymaps.   Fills in the appropriate globals. */void init_keymap(int kb){    struct kbentry entry;    int keycode;    for (keycode = 0; keycode < NR_KEYS; keycode++) {				keymap[keycode] = ' ';	keynames[keycode] = "(unknown)";			/* Look up this key. If the lookup fails, ignore.	   If it succeeds, KVAL(entry.kb_value) will be the	   8-bit representation of the character the kernel	   has mapped to this keycode. */	entry.kb_table = 0;	entry.kb_index = keycode;	if (ioctl(kb, KDGKBENT, &entry) != 0) continue;				/* Is this a printable character?	   NOTE: we do not handle Unicode translation here.	   See the SDL source (SDL_fbevents.c) for	   an example of how this can be done.	   Add in KT_LATIN and KT_ASCII if you want a wider	   range of characters. They're omitted here because	   some characters do not print cleanly. */	if (KTYP(entry.kb_value) == KT_LETTER) {	    keymap[keycode] = KVAL(entry.kb_value);	    keynames[keycode] = "(letter)";	}	/* Since the arrow keys are useful in games, we'll pick	   them out of the swarm. While we're at it, we'll grab	   Enter, Ctrl, and Alt. */	if (entry.kb_value == K_LEFT) keynames[keycode] = "Left arrow";	if (entry.kb_value == K_RIGHT) keynames[keycode] = "Right arrow";	if (entry.kb_value == K_DOWN) keynames[keycode] = "Down arrow";	if (entry.kb_value == K_UP) keynames[keycode] = "Up arrow";	if (entry.kb_value == K_ENTER) keynames[keycode] = "Enter";	if (entry.kb_value == K_ALT) keynames[keycode] = "Left Alt";	if (entry.kb_value == K_ALTGR) keynames[keycode] = "Right Alt";    }    /* Manually plug in keys that the kernel doesn't normally map correctly. */    keynames[29] = "Left Control";    keynames[97] = "Right Control";    keynames[125] = "Left Linux key";   /* usually mislabeled with */    keynames[126] = "Right Linux key";  /* a Windows logo. */    keynames[127] = "Application key";}/* Checks whether or not the given file descriptor is associated with a   local keyboard.   Returns 1 if it is, 0 if not (or if something prevented us from   checking). */int is_keyboard(int fd){    int data;    /* See if the keyboard driver groks this file descriptor. */    data = 0;    if (ioctl(fd, KDGKBTYPE, &data) != 0)	return 0;	    /* In current versions of Linux, the keyboard driver always answers       KB_101 to keyboard type queries. It's probably sufficient to just       check whether the above ioctl succeeds or fails. */    if (data == KB_84) {	printf("84-key keyboard found.\n");	return 1;    } else if (data == KB_101) {	printf("101-key keyboard found.\n");	return 1;    }    /* Sorry, this didn't check out. */    return 0;}int main(){    struct termios old_term, new_term;    int kb = -1; /* keyboard file descriptor */    char *files_to_try[] = {"/dev/tty", "/dev/console", NULL};    int old_mode = -1;    int i;    /* First we need to find a file descriptor that represents the       system's keyboard. This should be /dev/tty, /dev/console, stdin,       stdout, or stderr. We'll try them in that order. If none are       acceptable, we're probably not being run from a VT. */    for (i = 0; files_to_try[i] != NULL; i++) {	/* Try to open the file. */	kb = open(files_to_try[i], O_RDONLY);	if (kb < 0) continue;	/* See if this is valid for our purposes. */	if (is_keyboard(kb)) {	    printf("Using keyboard on %s.\n", files_to_try[i]);	    break;	}			close(kb);    }    /* If those didn't work, not all is lost. We can try the 3 standard       file descriptors, in hopes that one of them might point to a       console. This is not especially likely. */    if (files_to_try[i] == NULL) {		for (kb = 0; kb < 3; kb++) {	    if (is_keyboard(i)) break;	}	printf("Unable to find a file descriptor associated with the "\	       "keyboard.\n"\	       "Perhaps you're not using a virtual terminal?\n");	return 1;    }    /* Find the keyboard's current mode so we can restore it later. */    if (ioctl(kb, KDGKBMODE, &old_mode) != 0) {	printf("Unable to query keyboard mode.\n");	goto error;    }    /* Adjust the terminal's settings. In particular, disable echoing,       signal generation, and line buffering. Any of these could cause       trouble. Save the old settings first. */    if (tcgetattr(kb, &old_term) != 0) {	printf("Unable to query terminal settings.\n");	goto error;    }    new_term = old_term;    new_term.c_iflag = 0;    new_term.c_lflag &= ~(ECHO | ICANON | ISIG);    /* TCSAFLUSH discards unread input before making the change.       A good idea. */    if (tcsetattr(kb, TCSAFLUSH, &new_term) != 0) {	printf("Unable to change terminal settings.\n");    }    /* Put the keyboard in mediumraw mode. */    if (ioctl(kb, KDSKBMODE, K_MEDIUMRAW) != 0) {	printf("Unable to set mediumraw mode.\n");	goto error;    }    /* Discover the keymap. */    init_keymap(kb);    printf("Reading keycodes. Press Escape (keycode 1) to exit.\n");    for (;;) {	unsigned char data;	if (read(kb, &data, 1) < 1) {	    printf("Unable to read data. Trying to exit nicely.\n");	    goto error;	}	/* Print the keycode. The top bit is the pressed/released flag,	   and the lower seven are the keycode. */	printf("%s: %2Xh (%3i)  Char: %c  Special: %s\n",	       (data & 0x80) ? "Released" : " Pressed",	       (unsigned int)data & 0x7F,	       (unsigned int)data & 0x7F,	       keymap[data & 0x7F],	       keynames[data & 0x7F]);	if ((data & 0x7F) == 1) {	    printf("Escape pressed.\n");	    break;	}    }    /* Shut down nicely. */    printf("Exiting normally.\n");    ioctl(kb, KDSKBMODE, old_mode);    tcsetattr(kb, 0, &old_term);    if (kb > 3)	close(kb);    return 0; error:    printf("Cleaning up.\n");    fflush(stdout);    /* Restore the previous mode. Users hate it when they can't use       the keyboard. */    if (old_mode != -1) {	ioctl(kb, KDSKBMODE, old_mode);	tcsetattr(kb, 0, &old_term);    }    /* Only bother closing the keyboard fd if it's not stdin, stdout,       or stderr. */    if (kb > 3)	close(kb);		    return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -