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

📄 keyboard.c

📁 newos is new operation system
💻 C
字号:
/*** Copyright 2001-2004, Travis Geiselbrecht. All rights reserved.** Distributed under the terms of the NewOS License.*/#include <kernel/kernel.h>#include <kernel/debug.h>#include <kernel/heap.h>#include <kernel/int.h>#include <kernel/sem.h>#include <string.h>#include <stdio.h>#include <kernel/lock.h>#include <kernel/fs/devfs.h>#include <kernel/arch/cpu.h>#include <kernel/dev/arch/sh4/keyboard/keyboard.h>#include <kernel/dev/arch/sh4/maple/maple_bus.h>#include <newos/errors.h>/* Stolen from KOS */static char keymap_noshift[] = {/*0*/	0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',	'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',	'u', 'v', 'w', 'x', 'y', 'z',/*1e*/	'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',/*28*/	'\n', 27, 8, 9, 32, '-', '=', '[', ']', '\\', 0, ';', '\'',/*35*/	'`', ',', '.', '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*46*/	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*53*/	0, '/', '*', '-', '+', 13, '1', '2', '3', '4', '5', '6',/*5f*/	'7', '8', '9', '0', '.', 0};static char keymap_shift[] = {/*0*/	0, 0, 0, 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',	'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',	'U', 'V', 'W', 'X', 'Y', 'Z',/*1e*/	'!', '@', '#', '$', '%', '^', '&', '*', '(', ')',/*28*/	'\n', 27, 8, 9, 32, '_', '+', '{', '}', '|', 0, ':', '"',/*35*/	'~', '<', '>', '?', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*46*/	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*53*/	0, '/', '*', '-', '+', 13, '1', '2', '3', '4', '5', '6',/*5f*/	'7', '8', '9', '0', '.', 0};/* modifier keys */#define KBD_MOD_LCTRL 		(1<<0)#define KBD_MOD_LSHIFT		(1<<1)#define KBD_MOD_LALT		(1<<2)#define KBD_MOD_S1		(1<<3)#define KBD_MOD_RCTRL		(1<<4)#define KBD_MOD_RSHIFT		(1<<5)#define KBD_MOD_RALT		(1<<6)#define KBD_MOD_S2		(1<<7)/* bits for leds : this is not comprensive (need for japanese kbds also) */#define KBD_LED_NUMLOCK		(1<<0)#define KBD_LED_CAPSLOCK	(1<<1)#define KBD_LED_SCRLOCK		(1<<2)/* defines for the keys (argh...) */#define KBD_KEY_NONE		0x00#define KBD_KEY_ERROR		0x01#define KBD_KEY_A		0x04#define KBD_KEY_B		0x05#define KBD_KEY_C		0x06#define KBD_KEY_D		0x07#define KBD_KEY_E		0x08#define KBD_KEY_F		0x09#define KBD_KEY_G		0x0a#define KBD_KEY_H		0x0b#define KBD_KEY_I		0x0c#define KBD_KEY_J		0x0d#define KBD_KEY_K		0x0e#define KBD_KEY_L		0x0f#define KBD_KEY_M		0x10#define KBD_KEY_N		0x11#define KBD_KEY_O		0x12#define KBD_KEY_P		0x13#define KBD_KEY_Q		0x14#define KBD_KEY_R		0x15#define KBD_KEY_S		0x16#define KBD_KEY_T		0x17#define KBD_KEY_U		0x18#define KBD_KEY_V		0x19#define KBD_KEY_W		0x1a#define KBD_KEY_X		0x1b#define KBD_KEY_Y		0x1c#define KBD_KEY_Z		0x1d#define KBD_KEY_1		0x1e#define KBD_KEY_2		0x1f#define KBD_KEY_3		0x20#define KBD_KEY_4		0x21#define KBD_KEY_5		0x22#define KBD_KEY_6		0x23#define KBD_KEY_7		0x24#define KBD_KEY_8		0x25#define KBD_KEY_9		0x26#define KBD_KEY_0		0x27#define KBD_KEY_ENTER		0x28#define KBD_KEY_ESCAPE		0x29#define KBD_KEY_BACKSPACE	0x2a#define KBD_KEY_TAB		0x2b#define KBD_KEY_SPACE		0x2c#define KBD_KEY_MINUS		0x2d#define KBD_KEY_PLUS		0x2e#define KBD_KEY_LBRACKET	0x2f#define KBD_KEY_RBRACKET	0x30#define KBD_KEY_BACKSLASH	0x31#define KBD_KEY_SEMICOLON	0x33#define KBD_KEY_QUOTE		0x34#define KBD_KEY_TILDE		0x35#define KBD_KEY_COMMA		0x36#define KBD_KEY_PERIOD		0x37#define KBD_KEY_SLASH		0x38#define KBD_KEY_CAPSLOCK	0x39#define KBD_KEY_F1		0x3a#define KBD_KEY_F2		0x3b#define KBD_KEY_F3		0x3c#define KBD_KEY_F4		0x3d#define KBD_KEY_F5		0x3e#define KBD_KEY_F6		0x3f#define KBD_KEY_F7		0x40#define KBD_KEY_F8		0x41#define KBD_KEY_F9		0x42#define KBD_KEY_F10		0x43#define KBD_KEY_F11		0x44#define KBD_KEY_F12		0x45#define KBD_KEY_PRINT		0x46#define KBD_KEY_SCRLOCK		0x47#define KBD_KEY_PAUSE		0x48#define KBD_KEY_INSERT		0x49#define KBD_KEY_HOME		0x4a#define KBD_KEY_PGUP		0x4b#define KBD_KEY_DEL		0x4c#define KBD_KEY_END		0x4d#define KBD_KEY_PGDOWN		0x4e#define KBD_KEY_RIGHT		0x4f#define KBD_KEY_LEFT		0x50#define KBD_KEY_DOWN		0x51#define KBD_KEY_UP		0x52#define KBD_KEY_PAD_NUMLOCK	0x53#define KBD_KEY_PAD_DIVIDE	0x54#define KBD_KEY_PAD_MULTIPLY	0x55#define KBD_KEY_PAD_MINUS	0x56#define KBD_KEY_PAD_PLUS	0x57#define KBD_KEY_PAD_ENTER	0x58#define KBD_KEY_PAD_1		0x59#define KBD_KEY_PAD_2		0x5a#define KBD_KEY_PAD_3		0x5b#define KBD_KEY_PAD_4		0x5c#define KBD_KEY_PAD_5		0x5d#define KBD_KEY_PAD_6		0x5e#define KBD_KEY_PAD_7		0x5f#define KBD_KEY_PAD_8		0x60#define KBD_KEY_PAD_9		0x61#define KBD_KEY_PAD_0		0x62#define KBD_KEY_PAD_PERIOD	0x63#define KBD_KEY_S3		0x65typedef struct kbd_cond {	uint8 modifiers;	/* bitmask of shift keys/etc */	uint8 leds;		/* bitmask of leds that are lit */	uint8 keys[6];		/* codes for up to 6 currently pressed keys */} kbd_cond_t;struct maple_keyboard {	thread_id thread;	int fd;	bool caps;	uint8 matrix[256];	sem_id sem;	mutex read_mutex;	char buf[1024];	unsigned int head, tail;} keyboard;static ssize_t _keyboard_read(struct maple_keyboard *k, void *_buf, size_t len);static int keyboard_open(dev_ident ident, dev_cookie *cookie){	*cookie = &keyboard;	return 0;}static int keyboard_close(dev_cookie cookie){	return 0;}static int keyboard_freecookie(dev_cookie cookie){	return 0;}static int keyboard_seek(dev_cookie cookie, off_t pos, seek_type st){	return ERR_NOT_ALLOWED;}static ssize_t keyboard_read(dev_cookie cookie, void *buf, off_t pos, ssize_t len){	struct maple_keyboard *k = (struct maple_keyboard *)cookie;	if(len < 0)		return 0;	return _keyboard_read(k, buf, len);}static ssize_t keyboard_write(dev_cookie cookie, const void *buf, off_t pos, ssize_t len){	return ERR_VFS_READONLY_FS;}static int keyboard_ioctl(dev_cookie cookie, int op, void *buf, size_t len){	return ERR_INVALID_ARGS;}struct dev_calls keyboard_hooks = {	&keyboard_open,	&keyboard_close,	&keyboard_freecookie,	&keyboard_seek,	&keyboard_ioctl,	&keyboard_read,	&keyboard_write,	/* cannot page from keyboard */	NULL,	NULL,	NULL};static ssize_t _keyboard_read(struct maple_keyboard *k, void *_buf, size_t len){	unsigned int saved_tail;	char *buf = _buf;	size_t copied_bytes = 0;	size_t copy_len;	int rc;	if(len > sizeof(k->buf) - 1)		len = sizeof(k->buf) - 1;retry:	// block here until data is ready	rc = sem_acquire_etc(k->sem, 1, SEM_FLAG_INTERRUPTABLE, 0, NULL);	if(rc == ERR_INTERRUPTED) {		return 0;	}	// critical section	mutex_lock(&k->read_mutex);	saved_tail = k->tail;	if(k->head == saved_tail) {		mutex_unlock(&k->read_mutex);		goto retry;	} else {		// copy out of the buffer		if(k->head < saved_tail)			copy_len = min(len, saved_tail - k->head);		else			copy_len = min(len, sizeof(k->buf) - k->head);		memcpy(buf, &k->buf[k->head], copy_len);		copied_bytes = copy_len;		k->head = (k->head + copy_len) % sizeof(k->buf);		if(k->head == 0 && saved_tail > 0 && copied_bytes < len) {			// we wrapped around and have more bytes to read			// copy the first part of the buffer			copy_len = min(saved_tail, len - copied_bytes);			memcpy(&buf[len], &k->buf[0], copy_len);			copied_bytes += copy_len;			k->head = copy_len;		}	}	if(k->head != saved_tail) {		// we did not empty the keyboard queue		sem_release_etc(k->sem, 1, SEM_FLAG_NO_RESCHED);	}	mutex_unlock(&k->read_mutex);	return copied_bytes;}static void enqueue_key(struct maple_keyboard *k, uint8 key, uint8 modifiers){	char ascii = 0;	bool shift;//	dprintf("enqueue_key 0x%x 0x%x\n", key, modifiers);	if(modifiers & (KBD_MOD_LSHIFT | KBD_MOD_RSHIFT))		shift = ~k->caps;	else		shift = k->caps;	switch(key) {		case KBD_KEY_PRINT:			panic("Keyboard Requested Halt\n");			break;		case KBD_KEY_CAPSLOCK:			k->caps = !k->caps;			return; 		case KBD_KEY_F12:			reboot();			break;		default:			if(shift) {				ascii = keymap_shift[key];			} else {				ascii = keymap_noshift[key];			}			break;	}	// add it to the keyboard queue	if(ascii) {		unsigned int temp_tail = k->tail;//		dprintf("ascii = '%c' 0x%x\n", ascii, ascii);	 	// see if the next char will collide with the head		temp_tail++;		temp_tail %= sizeof(k->buf);		if(temp_tail == k->head) {			// buffer overflow, ditch this char			return;		}		k->buf[k->tail] = ascii;		k->tail = temp_tail;		sem_release_etc(k->sem, 1, SEM_FLAG_NO_RESCHED);	}}static int keyboard_thread(){	struct maple_keyboard *k = &keyboard;	maple_command cmd;	maple_frame_t frame;	uint32 outdata;	uint32 indata[64];	int err;	kbd_cond_t *cond;	int i;	dprintf("keyboard_thread entry\n");	cmd.cmd = MAPLE_COMMAND_GETCOND;	cmd.outdatalen = 1;	outdata = MAPLE_FUNC_KEYBOARD;	cmd.outdata = &outdata;	cmd.retframe = &frame;	cmd.indata = indata;	cmd.indatalen = (sizeof(kbd_cond_t) + sizeof(uint32)) / 4;	for(;;) {		thread_snooze(50);		err = sys_ioctl(k->fd, MAPLE_IOCTL_SEND_COMMAND, &cmd, sizeof(cmd));		if(err < NO_ERROR)			continue;		if(frame.cmd != MAPLE_RESPONSE_DATATRF			|| (frame.datalen - 1) != sizeof(kbd_cond_t) / 4			|| *((uint32 *)cmd.indata) != MAPLE_FUNC_KEYBOARD) {			dprintf("error with frame\n");			continue;		}		cond = (kbd_cond_t *)((uint32)cmd.indata + 4);		for(i=0; i<6; i++) {			if(cond->keys[i]) {				if(k->matrix[cond->keys[i]] == 0)					enqueue_key(k, cond->keys[i], cond->modifiers);				k->matrix[cond->keys[i]] = 2;			}		}		for(i=0; i<256; i++) {			if(k->matrix[i] == 1)				k->matrix[i] = 0;			else if(k->matrix[i] == 2)				k->matrix[i] = 1;		}//		dprintf("0x%x 0x%x 0x%x 0x%x ",//			cond->modifiers, cond->leds, cond->keys[0], cond->keys[1]);//		dprintf("0x%x 0x%x 0x%x 0x%x\n",//			cond->keys[2], cond->keys[3], cond->keys[4], cond->keys[5], cond->keys[6]);	}	return 0;}static int setup_keyboard(){	int i;	memset(&keyboard, 0, sizeof(keyboard));	if(mutex_init(&keyboard.read_mutex, "keyboard_read_mutex") < 0)		panic("could not create keyboard read mutex!\n");	keyboard.sem = sem_create(0, "keyboard_sem");	if(keyboard.sem < 0)		panic("could not create keyboard sem!\n");	for(i=0; i<4; i++) {		char temp[128];		int err;		uint32 func;		sprintf(temp,  "/dev/bus/maple/%d/0/ctrl", i);		keyboard.fd = sys_open(temp, 0);		if(keyboard.fd < 0)			continue;		err = sys_ioctl(keyboard.fd, MAPLE_IOCTL_GET_FUNC, &func, sizeof(func));		if(err < NO_ERROR || func != MAPLE_FUNC_KEYBOARD) {			sys_close(keyboard.fd);			keyboard.fd = -1;			continue;		}		// we found one, break		break;	}	if(keyboard.fd < 0)		return -1;	keyboard.thread = thread_create_kernel_thread("maple_keyboard_thread", &keyboard_thread, NULL);	thread_resume_thread(keyboard.thread);	return 0;}int	keyboard_dev_init(kernel_args *ka){	setup_keyboard();	devfs_publish_device("keyboard", NULL, &keyboard_hooks);	return 0;}

⌨️ 快捷键说明

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