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

📄 keyboard.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Keyboard library functions *//* H. Hanemaayer (hhanemaa@cs.ruu.nl) *//* Apr 03 1998: Added fake mouse event and some cleanup by 101 (Attila Lendvai)        				e-mail: 101@kempelen.inf.bme.hu *//* * May 28 1998: Changed __keyboard_eventhandler to * __svgalib_keyboard_eventhandler and made non-static to allow for fake * keyboard events for the wheelmice (Brion Vibber <brion@pobox.com>) * * July 3 1998: Added keyboard remapping support - brion*//* * Keyboard I/O based on showkey.c from kbd-0.84 package. * This is an initial version, it isn't very safe yet since it only catches * sigsegv.*//* #define DEBUG_KEYBOARD */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <sys/ioctl.h>#include <fcntl.h>#include <termios.h>#include <linux/kd.h>/* linux/keyboard.h defines NR_KEYS and some scancode-like constants, so it *//* should also be useful for svgalib programs using the keyboard. It misses *//* a few KERNEL ifdefs around kernel data structures though. */#include <linux/keyboard.h>#include <sys/vt.h>/* Needed to check uid of keymap files */#include <sys/stat.h>#include <unistd.h>#include <vga.h>#include "../libvga.h"#include "vgakeyboard.h"#include "driver.h"void (*__svgalib_keyboard_eventhandler) (int, int);static struct termios oldkbdtermios, newkbdtermios;static int oldkbmode;/* vga.c needs to check that: */int __svgalib_kbd_fd = -1; /* nowadays merely used as a flag */static int c_state, ctrl_state, alt_state, functionkey_state, win_state;static int translatemode = 0;static unsigned char state[NR_KEYS];	/* NR_KEYS is defined in linux/keyboard.h */static int keymap[NR_KEYS];static int usekeymap = 0;    /* If nonzero, we translate scancodes */static int rootkeymaps = 0;  /* If nonzero, only load keymaps owned by root */static char keynames[NR_KEYS][MAX_KEYNAME_LEN] = {    /* The default US QWERTY layout */    "",    "Escape", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero", "minus", "equal", "Delete",    "Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "bracketleft", "bracketright", "Return",    "Control", "a", "s", "d", "f", "g", "h", "j", "k", "l", "semicolon", "apostrophe", "grave",    "Shift", "backslash", "z", "x", "c", "v", "b", "n", "m", "comma", "period", "slash", "Shift", "KP_Multiply",    "Alt", "space", "Caps_Lock",    "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",    "Num_Lock", "Scroll_Lock",    "KP_7", "KP_8", "KP_9", "KP_Subtract",    "KP_4", "KP_5", "KP_6", "KP_Add",    "KP_1", "KP_2", "KP_3",    "KP_0", "KP_Period",    "Last_Console", "", "less", "F11", "F12", "", "", "", "", "", "", "",    "KP_Enter", "Control", "KP_Divide", "Control_backslash", "AltGr", "Break",    "Find", "Up", "Prior", "Left", "Right", "Select", "Down", "Next", "Insert",    "Remove", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};static void default_handler(int, int);static char *kbd_load_keymap(char *ptr);static void kbd_update_keymap(void);static int kbd_mapkey(int inscancode);static struct FakeMouseEvent {  int	data;  short type;  short flags;  int   scancode;  char  keyname[MAX_KEYNAME_LEN];} **fake_mouse_events = 0;/* Number of events per scancode */static short *fme_numberof = 0;/* Number of scancodes used */static int fme_used = 0;/* Fake event flags */#define FMEF_TRIGGERED	1	/* Triggered, */#define FMEF_AT_PRESS	2	/* Request at press (or if false at release)*/#define FMEF_AT_BOTH	4	/* Request at press/release too */#define FMEF_REPEAT	8	/* Keep on sending fake events */#define FME_TYPE_BUTTON  1#define FME_TYPE_DELTAX  2#define FME_TYPE_DELTAY  3#define FME_TYPE_DELTAZ	 4#define FME_TYPE_IGNOREX 5#define FME_TYPE_IGNOREY 6#define FME_TYPE_IGNOREZ 7#define FME_TYPE_BUTTON1 8#define FME_TYPE_BUTTON2 9#define FME_TYPE_BUTTON3 10static int expand_events(int n) {    struct FakeMouseEvent *newptr = 0;/*    int n; */  if ( ! fake_mouse_events) {#ifdef DEBUG_KEYBOARD      fprintf(stderr," Allocating space for FMEs...\n");#endif    if ( (fake_mouse_events = malloc(sizeof(void *) * NR_KEYS)) == 0) { error:      fputs("svgalib: keyboard-config: out of memory ?! Fake mouse events might be disabled !", stderr);      return 0;    } else {      if ( (fme_numberof = malloc(sizeof(short) * NR_KEYS)) == 0) {        free(fake_mouse_events);        fake_mouse_events = 0;        goto error;      }      memset(fake_mouse_events, 0, sizeof(void *) * NR_KEYS);      memset(fme_numberof, 0, sizeof(short) * NR_KEYS);    }  }#ifdef DEBUG_KEYBOARD  fprintf(stderr," Expanding FME #%d... ", n);#endif  if ( (newptr = realloc(fake_mouse_events[n],                         sizeof(struct FakeMouseEvent) * ++fme_numberof[n])) != 0 ) {#ifdef DEBUG_KEYBOARD  fprintf(stderr,"it's all good.\n");#endif    fake_mouse_events[n] = newptr;    return 1;  } else {    goto error;  }}static char *kbd_config_options[] = {  "kbd_fake_mouse_event", "kbd_keymap", "kbd_only_root_keymaps", NULL};static char *kbd_process_option(int option, int mode) {  char *ptr;  short type   = 0;  short ignore_type   = 0;  short flags  = FMEF_AT_PRESS;  int data     = 0;  int scancode = 0;  int event_ok = 0;  int n = 0;  struct FakeMouseEvent *event;  char keyname[MAX_KEYNAME_LEN];    switch (option) {    case 0: /* kbd_fake_mouse_event */	if ( (ptr = strtok(NULL, " ")) == 0) {  param_needed:	  fprintf(stderr, "svgalib: kbd-config: too few parameters for \'%s\'\n",	  		kbd_config_options[option]);	  return ptr;        } else if ( (scancode = __svgalib_mapkeyname(ptr)) == -1) {	  fprintf(stderr, "svgalib: kbd-config: \'%s\' is not a valid scancode\n", ptr);	  return ptr;        }        strncpy(keyname, ptr, MAX_KEYNAME_LEN);        /* Find the event for this key if there is one*/#ifdef DEBUG_KEYBOARD        fprintf(stderr," Looking for fme for key \'%s\'... ", keyname);#endif        for(n = 0; n < fme_used; n++)            if(strcmp(fake_mouse_events[n]->keyname, keyname) == 0)                break;        if(n == fme_used)            fme_used++;#ifdef DEBUG_KEYBOARD        fprintf(stderr," found at #%d.\n", n);#endif          read_event:	if ( (ptr = strtok(NULL, " ")) == 0) {	  if ( event_ok )	    break;	  else  	    goto param_needed;	}	if ( ! strcasecmp(ptr, "both")) {	   flags |= FMEF_AT_BOTH;	   goto read_event;	} else if ( ! strcasecmp(ptr, "up")) {	   flags &= ~FMEF_AT_PRESS;	   flags &= ~FMEF_AT_BOTH;	   goto read_event;	} else if ( ! strcasecmp(ptr, "down")) {	   flags |= FMEF_AT_PRESS;	   flags &= ~FMEF_AT_BOTH;	   goto read_event;	} else if ( ! strcasecmp(ptr, "repeat")) {	   flags |= FMEF_REPEAT;	   goto read_event;	} else if ( ! strcasecmp(ptr, "discrete")) {	   flags &= ~FMEF_REPEAT;	   goto read_event;	} else if ( ! strcasecmp(ptr, "button")) {	   type = FME_TYPE_BUTTON;	   if ( (ptr = strtok(NULL, " ")) == 0)	     goto param_needed;	   if ( (data = atoi(ptr)) == 0  ||  data > 10) {	     fprintf(stderr, "svgalib: kbd-config: \'%s\' is not a valid mouse button\n", ptr);	     return ptr;	   }  store_event:#ifdef DEBUG_KEYBOARD  printf(" Fake Mouse Event: scancode: %ld;  type: %ld;  data: %ld;  flags: %ld\n", (long)scancode, (long)type, (long)data, (long)flags);#endif	   if ( ! expand_events(n))	     return ptr;           event = &fake_mouse_events[n][fme_numberof[n] - 1];	   event -> type  = type;	   event -> flags = flags;	   event -> data  = data;           event -> scancode = scancode;           strcpy(event -> keyname, keyname);	   event_ok = 1;	   goto read_event;	} else if ( ! strcasecmp(ptr, "deltax")) {	   type        = FME_TYPE_DELTAX;	   ignore_type = FME_TYPE_IGNOREX;  process_delta:	   if ( (ptr = strtok(NULL, " ")) == 0)	     goto param_needed;	   if ( ! strcasecmp(ptr, "off")) {	     type = ignore_type;	     data = 1;	     goto store_event;	   } else if ( ! strcasecmp(ptr, "on")) {	     type = ignore_type;	     data = 0;	     goto store_event;	   } else if ( (data = atoi(ptr)) == 0) {	     fprintf(stderr, "svgalib: kbd-config: \'%s\' is not a valid delta\n", ptr);	     return ptr;	   }	   goto store_event;	} else if ( ! strcasecmp(ptr, "deltay")) {	   type        = FME_TYPE_DELTAY;	   ignore_type = FME_TYPE_IGNOREY;	   goto process_delta;	} else if ( ! strcasecmp(ptr, "deltaz")) {	   type        = FME_TYPE_DELTAZ;	   ignore_type = FME_TYPE_IGNOREZ;	   goto process_delta;	} else if ( ! strcasecmp(ptr, "button1")) {	   type = FME_TYPE_BUTTON1;  process_button:	   if ( (ptr = strtok(NULL, " ")) == 0)	     goto param_needed;	   if ( ! strcasecmp(ptr, "pressed")) {	     data = 1;	   } else if ( ! strcasecmp(ptr, "released")) {	     data = 0;	   } else {	     fprintf(stderr, "svgalib: kbd-config: \'%s\' is not a legal parameter for command "	     	"\'button[123]\'. Should be either \'pressed\' or \'released\'\n", ptr);	     return ptr;	   }	   goto store_event;	} else if ( ! strcasecmp(ptr, "button2")) {	   type = FME_TYPE_BUTTON2;	   goto process_button;	} else if ( ! strcasecmp(ptr, "button3")) {	   type = FME_TYPE_BUTTON3;	   goto process_button;	} else if ( ! event_ok) {	  fprintf(stderr, "svgalib: kbd-config: illegal mouse event: \'%s\'\n", ptr);	  return ptr;	} else	  return ptr;    	break;    case 1: /* kbd_keymap */         if ( (ptr = strtok(NULL, " ")) == 0 ) {             goto param_needed;         } else             if(kbd_load_keymap(ptr))                 return ptr;         break;  case 2: /* kbd_only_root_keymaps */#ifdef DEBUG_KEYBOARD      fprintf(stderr, " Setting rootkeymaps to 1.\n");#endif      rootkeymaps = 1;      break;  }  return strtok(NULL, " ");};int keyboard_init_return_fd(void) {    char *ptr;    keyboard_translatekeys(translatemode); /* Honour 'nosigint' setting */    /* Install default keyboard handler. */    __svgalib_keyboard_eventhandler = default_handler;    __svgalib_open_devconsole();    __svgalib_kbd_fd = __svgalib_tty_fd; /* We are initialized. */    if (ioctl(__svgalib_kbd_fd, KDGKBMODE, &oldkbmode)) {	printf("svgalib: cannot get keyboard mode.\n");	return -1;    }    tcgetattr(__svgalib_kbd_fd, &oldkbdtermios);    newkbdtermios = oldkbdtermios;    newkbdtermios.c_lflag &= ~(ICANON | ECHO | ISIG);    newkbdtermios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);    newkbdtermios.c_cc[VMIN] = 0;	/* Making these 0 seems to have the */    newkbdtermios.c_cc[VTIME] = 0;	/* desired effect. */    tcsetattr(__svgalib_kbd_fd, TCSAFLUSH, &newkbdtermios);    ioctl(__svgalib_kbd_fd, KDSKBMODE, K_MEDIUMRAW);    keyboard_clearstate();    __svgalib_read_options(kbd_config_options, kbd_process_option);    /* Check SVGALIB_KEYMAP env var */    if ( (ptr = getenv("SVGALIB_KEYMAP")) != 0) {        kbd_load_keymap(ptr);    }    return __svgalib_kbd_fd;		/* OK, return fd. */}/* Old compatible init function. */int keyboard_init(void){    if (keyboard_init_return_fd() == -1)	return -1;    else	return 0;}void keyboard_close(void) {    if (__svgalib_kbd_fd < 0)	return;    if (fake_mouse_events) {      int i;      for (i = 0; i < NR_KEYS; i++) {        if (fake_mouse_events[i])          free(fake_mouse_events[i]);      }      free(fake_mouse_events);      fake_mouse_events = NULL;    }    ioctl(__svgalib_kbd_fd, KDSKBMODE, oldkbmode);    tcsetattr(__svgalib_kbd_fd, 0, &oldkbdtermios);    __svgalib_kbd_fd = -1;}/* For now, we assume there's no console switching. *//* (Actually, there won't be any unless we catch the console switching *//* keys). */#define KBDREADBUFFERSIZE 32static int keyboard_getevents(int wait){/* Read keyboard device, and handle events. *//* If wait == 1, process at least one event and return. *//* If wait == 0, handle all accumulated events; return 0 if no events *//* were handled, 1 otherwise. *//* Wait mode doesn't seem to work very well; the keyboard repeat delay is *//* present. I don't understand fcntl. */    static unsigned char buf[KBDREADBUFFERSIZE];    static int kfdmode = 0;	/* 1 = DELAY, 0 = NDELAY */    int bytesread, i;    int eventhandled;    eventhandled = 0;  again:    if (kfdmode == 1) {		/* This only happens for wait == 1. */#if 0	struct termios kbdtermios;#endif	int flags;	/* We don't want to wait, set NDELAY mode. */	fcntl(__svgalib_kbd_fd, F_GETFL, &flags);	fcntl(__svgalib_kbd_fd, F_SETFL, flags | O_NDELAY);#if 0	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 = 0;    }    bytesread = read(__svgalib_kbd_fd, buf, KBDREADBUFFERSIZE);    if (wait == 1 && bytesread < 1) {#if 0	struct termios kbdtermios;#endif	int flags;	/* We already handled an event, no need to wait for another. */	if (eventhandled)	    return 1;	/* Wait mode, we'll sleep on reads. */	fcntl(__svgalib_kbd_fd, F_GETFL, &flags);	fcntl(__svgalib_kbd_fd, F_SETFL, flags & ~O_NDELAY);#if 0

⌨️ 快捷键说明

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