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

📄 keyboard.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	unsigned char leds = getleds();	tty = *vtdata.fgconsole->tty;	kbd = vtdata.fgconsole->kbd;	if (rep) {		/*		 * This prevents the kbd_key routine from being called		 * twice, once by this BH, and once by the interrupt		 * routine.  Maybe we should put the key press in a		 * buffer or variable, and then call the BH...		 */		disable_irq (IRQ_KEYBOARDRX);		if (kbd_repeatkey != -1)			kbd_processkey (kbd_repeatkey, 0, 1);		enable_irq (IRQ_KEYBOARDRX);		rep = 0;	}	if (leds != ledstate) {		ledstate = leds;		kbd_drv_setleds(leds);	}}/* * Initialise a kbd struct */int kbd_struct_init (struct vt *vt, int init){	vt->kbd->ledflagstate = vt->kbd->default_ledflagstate = KBD_DEFLEDS;	vt->kbd->ledmode = LED_SHOW_FLAGS;	vt->kbd->lockstate = KBD_DEFLOCK;	vt->kbd->slockstate = 0;	vt->kbd->modeflags = KBD_DEFMODE;	vt->kbd->kbdmode = VC_XLATE;	return 0;}int kbd_ioctl (struct vt *vt, int cmd, unsigned long arg){    asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);    int i;    switch (cmd) {    case KDGKBTYPE:	/*	 * This is naive.	 */	i = verify_area (VERIFY_WRITE, (void *)arg, sizeof (unsigned char));	if (!i)	    put_user (KB_101, (char *)arg);	return i;    case KDADDIO:    case KDDELIO:	/*	 * KDADDIO and KDDELIO may be able to add ports beyond what	 * we reject here, but to be safe...	 */	if (arg < GPFIRST || arg > GPLAST)	    return -EINVAL;	return sys_ioperm (arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;    case KDENABIO:    case KDDISABIO:	return sys_ioperm (GPFIRST, GPLAST, (cmd == KDENABIO)) ? -ENXIO : 0;    case KDMAPDISP:    case KDUNMAPDISP:	/*	 * These work like a combination of mmap and KDENABIO.	 * this could easily be finished.	 */	return -EINVAL;    case KDSKBMODE:	switch (arg) {	case K_RAW:	    vt->kbd->kbdmode = VC_RAW;	    break;	case K_MEDIUMRAW:	    vt->kbd->kbdmode = VC_MEDIUMRAW;	    break;	case K_XLATE:	    vt->kbd->kbdmode = VC_XLATE;	    compute_shiftstate ();	    break;	case K_UNICODE:	    vt->kbd->kbdmode = VC_UNICODE;	    compute_shiftstate ();	    break;	default:	    return -EINVAL;	}	if (tty->ldisc.flush_buffer)	    tty->ldisc.flush_buffer (*vt->tty);	return 0;    case KDGKBMODE:	i = verify_area (VERIFY_WRITE, (void *)arg, sizeof (unsigned long));	if (!i) {	    int ucval;	    ucval = ((vt->kbd->kbdmode == VC_RAW) ? K_RAW :		     (vt->kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :		     (vt->kbd->kbdmode == VC_UNICODE) ? K_UNICODE : K_XLATE);	    put_user (ucval, (int *)arg);	}	return i;    case KDSKBMETA:	/*	 * this could be folded into KDSKBMODE, but for compatibility	 * reasons, it is not so easy to fold kDGKBMETA into KDGKBMODE.	 */	switch (arg) {	case K_METABIT:	    clr_vc_kbd_mode (vt->kbd, VC_META);	    break;	case K_ESCPREFIX:	    set_vc_kbd_mode (vt->kbd, VC_META);	    break;	default:	    return -EINVAL;	}	return 0;    case KDGKBMETA:	i = verify_area (VERIFY_WRITE, (void *)arg, sizeof (unsigned long));	if (!i) {	    int ucval;	    ucval = (vc_kbd_mode (vt->kbd, VC_META) ? K_ESCPREFIX : K_METABIT);	    put_user (ucval, (int *)arg);	}	return i;    case KDGETKEYCODE: {	struct kbkeycode *const a = (struct kbkeycode *)arg;	i = verify_area (VERIFY_WRITE, a, sizeof (struct kbkeycode));	if (!i) {	    unsigned int sc;	    sc = get_user (&a->scancode);	    i = getkeycode (sc);	    if (i > 0)		put_user (i, &a->keycode);	    i = 0;	}	return i;        }    case KDSETKEYCODE: {	struct kbkeycode *const a = (struct kbkeycode *)arg;	i = verify_area (VERIFY_READ, a, sizeof (struct kbkeycode));	if (!i) {	    unsigned int sc, kc;	    sc = get_user (&a->scancode);	    kc = get_user (&a->keycode);	    i = setkeycode (sc, kc);	}	return i;        }    case KDGKBENT: {	struct kbentry *const a = (struct kbentry *)arg;	i = verify_area (VERIFY_WRITE, a, sizeof (struct kbentry));	if (!i) {	    ushort *keymap, val;	    u_char s;	    i = get_user (&a->kb_index);	    if (i >= NR_KEYS)		return -EINVAL;	    s = get_user (&a->kb_table);	    if (s >= MAX_NR_KEYMAPS)		return -EINVAL;	    keymap = key_maps[s];	    if (keymap) {		val = U(keymap[i]);		if (vt->kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)		    val = K_HOLE;	    } else		val = (i ? K_HOLE : K_NOSUCHMAP);	    put_user (val, &a->kb_value);	    i = 0;	}	return i;        }    case KDSKBENT: {	struct kbentry *const a = (struct kbentry *)arg;	i = verify_area (VERIFY_WRITE, a, sizeof (struct kbentry));	if (!i) {	    ushort *key_map;	    u_char s;	    u_short v, ov;	    if ((i = get_user(&a->kb_index)) >= NR_KEYS)		return -EINVAL;	    if ((s = get_user(&a->kb_table)) >= MAX_NR_KEYMAPS)		return -EINVAL;	    v = get_user(&a->kb_value);	    if (!i && v == K_NOSUCHMAP) {		/* disallocate map */		key_map = key_maps[s];		if (s && key_map) {		    key_maps[s] = 0;		    if (key_map[0] == U(K_ALLOCATED)) {			kfree_s(key_map, sizeof(plain_map));			keymap_count--;		    }		}		return 0;	    }	    if (KTYP(v) < NR_TYPES) {		if (KVAL(v) > max_vals[KTYP(v)])		    return -EINVAL;	    } else		if (kbd->kbdmode != VC_UNICODE)		    return -EINVAL;	    /* assignment to entry 0 only tests validity of args */	    if (!i)		return 0;	    if (!(key_map = key_maps[s])) {		int j;					if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && !suser())		    return -EPERM;		key_map = (ushort *) kmalloc(sizeof(plain_map),					     GFP_KERNEL);		if (!key_map)		    return -ENOMEM;		key_maps[s] = key_map;		key_map[0] = U(K_ALLOCATED);		for (j = 1; j < NR_KEYS; j++)		    key_map[j] = U(K_HOLE);		keymap_count++;	    }	    ov = U(key_map[i]);	    if (v == ov)		return 0;	/* nothing to do */	    /*	     * Only the Superuser can set or unset the Secure	     * Attention Key.	     */	    if (((ov == K_SAK) || (v == K_SAK)) && !suser())		return -EPERM;	    key_map[i] = U(v);	    if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))		compute_shiftstate();	    return 0;	}	return i;        }    case KDGKBSENT: {	struct kbsentry *a = (struct kbsentry *)arg;	char *p;	u_char *q;	int sz;	i = verify_area(VERIFY_WRITE, (void *)a, sizeof(struct kbsentry));	if (i)	    return i;	if ((i = get_user(&a->kb_func)) >= MAX_NR_FUNC || i < 0)	    return -EINVAL;	sz = sizeof(a->kb_string) - 1; /* sz should have been					  a struct member */	q = a->kb_string;	p = func_table[i];	if(p)	    for ( ; *p && sz; p++, sz--)		put_user(*p, q++);	put_user('\0', q);	return ((p && *p) ? -EOVERFLOW : 0);        }    case KDSKBSENT: {	struct kbsentry * const a = (struct kbsentry *)arg;	int delta;	char *first_free, *fj, *fnw;	int j, k, sz;	u_char *p;	char *q;	i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbsentry));	if (i)	    return i;	if ((i = get_user(&a->kb_func)) >= MAX_NR_FUNC)	    return -EINVAL;	q = func_table[i];	first_free = funcbufptr + (funcbufsize - funcbufleft);	for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) ;	if (j < MAX_NR_FUNC)	    fj = func_table[j];	else	    fj = first_free;	delta = (q ? -strlen(q) : 1);	sz = sizeof(a->kb_string); 	/* sz should have been					   a struct member */	for (p = a->kb_string; get_user(p) && sz; p++,sz--)	    delta++;	if (!sz)	    return -EOVERFLOW;	if (delta <= funcbufleft) { 	/* it fits in current buf */	    if (j < MAX_NR_FUNC) {		memmove(fj + delta, fj, first_free - fj);		for (k = j; k < MAX_NR_FUNC; k++)		    if (func_table[k])			func_table[k] += delta;	    }	    if (!q)		func_table[i] = fj;	    funcbufleft -= delta;	} else {			/* allocate a larger buffer */	    sz = 256;	    while (sz < funcbufsize - funcbufleft + delta)		sz <<= 1;	    fnw = (char *) kmalloc(sz, GFP_KERNEL);	    if(!fnw)		return -ENOMEM;	    if (!q)		func_table[i] = fj;	    if (fj > funcbufptr)		memmove(fnw, funcbufptr, fj - funcbufptr);	    for (k = 0; k < j; k++)		if (func_table[k])		    func_table[k] = fnw + (func_table[k] - funcbufptr);	    if (first_free > fj) {		memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);		for (k = j; k < MAX_NR_FUNC; k++)		    if (func_table[k])			func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;	    }	    if (funcbufptr != func_buf)		kfree_s(funcbufptr, funcbufsize);	    funcbufptr = fnw;	    funcbufleft = funcbufleft - delta + sz - funcbufsize;	    funcbufsize = sz;	}	for (p = a->kb_string, q = func_table[i]; ; p++, q++)	    if (!(*q = get_user(p)))		break;	return 0;	}    case KDGKBDIACR: {	struct kbdiacrs *a = (struct kbdiacrs *)arg;	i = verify_area(VERIFY_WRITE, (void *) a, sizeof(struct kbdiacrs));	if (i)	    return i;	put_user(accent_table_size, &a->kb_cnt);	memcpy_tofs(a->kbdiacr, accent_table,		    accent_table_size*sizeof(struct kbdiacr));	return 0;	}    case KDSKBDIACR: {	struct kbdiacrs *a = (struct kbdiacrs *)arg;	unsigned int ct;	i = verify_area(VERIFY_READ, (void *) a, sizeof(struct kbdiacrs));	if (i)	    return i;	ct = get_user(&a->kb_cnt);	if (ct >= MAX_DIACR)	    return -EINVAL;	accent_table_size = ct;	memcpy_fromfs(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));	return 0;	}    /* the ioctls below read/set the flags usually shown in the leds */    /* don't use them - they will go away without warning */    case KDGKBLED:	i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));	if (i)	    return i;	put_user(vt->kbd->ledflagstate |		    (vt->kbd->default_ledflagstate << 4), (char *) arg);	return 0;    case KDSKBLED:	if (arg & ~0x77)	    return -EINVAL;	vt->kbd->ledflagstate = (arg & 7);	vt->kbd->default_ledflagstate = ((arg >> 4) & 7);	set_leds ();	return 0;    /* the ioctls below only set the lights, not the functions */    /* for those, see KDGKBLED and KDSKBLED above */    case KDGETLED:	i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned char));	if (i)	    	return i;	put_user(getledstate(), (char *) arg);	return 0;    case KDSETLED:	setledstate(kbd, arg);	return 0;    /*     * A process can indicate its willingness to accept signals     * generated by pressing an appropriate key combination.     * Thus, one can have a daemon that e.g. spawns a new console     * upon a keypess and then changes to it.     * Probably init should be changed to do this (and have a     * field ks (`keyboard signal') in inittab describing the     * desired acion), so that the number of background daemons     * does not increase.     */    case KDSIGACCEPT: {	if (arg < 1 || arg > NSIG || arg == SIGKILL)	    return -EINVAL;	spawnpid = current->pid;	spawnsig = arg;	return 0;	}    default:	return -ENOIOCTLCMD;    }}int kbd_init (void){	int ret;	init_bh(KEYBOARD_BH, kbd_bh);	ret = kbd_drv_init();	mark_bh(KEYBOARD_BH);	return ret;}

⌨️ 快捷键说明

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