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

📄 sunkbd.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* handle the case that two shift or control		   keys are depressed simultaneously */		if (k_down[value])			k_down[value]--;	} else		k_down[value]++;	if (k_down[value])		shift_state |= (1 << value);	else		shift_state &= ~ (1 << value);	/* kludge, no joke... */	if (up_flag && shift_state != old_state && npadch != -1) {		put_queue(npadch & 0xff);		npadch = -1;	}}/* called after returning from RAW mode or when changing consoles -   recompute k_down[] and shift_state from key_down[] *//* maybe called when keymap is undefined, so that shiftkey release is seen */void compute_shiftstate(void){	int i, j, k, sym, val;	shift_state = 0;	for(i=0; i < SIZE(k_down); i++)	  k_down[i] = 0;	for(i=0; i < SIZE(key_down); i++)	  if(key_down[i]) {	/* skip this word if not a single bit on */	    k = i*BITS_PER_LONG;	    for(j=0; j<BITS_PER_LONG; j++,k++)	      if(test_bit(k, key_down)) {		sym = U(plain_map[k]);		if(KTYP(sym) == KT_SHIFT) {		  val = KVAL(sym);		  if (val == KVAL(K_CAPSSHIFT))		    val = KVAL(K_SHIFT);		  k_down[val]++;		  shift_state |= (1<<val);		}	      }	  }}static void do_meta(unsigned char value, char up_flag){	if (up_flag)		return;	if (vc_kbd_mode(kbd, VC_META)) {		put_queue('\033');		put_queue(value);	} else		put_queue(value | 0x80);}static void do_ascii(unsigned char value, char up_flag){	int base;	if (up_flag)		return;	if (value < 10)    /* decimal input of code, while Alt depressed */	    base = 10;	else {       /* hexadecimal input of code, while AltGr depressed */	    value -= 10;	    base = 16;	}	if (npadch == -1)	  npadch = value;	else	  npadch = npadch * base + value;}static void do_lock(unsigned char value, char up_flag){	if (up_flag || rep)		return;	chg_vc_kbd_lock(kbd, value);}/* * The leds display either (i) the status of NumLock, CapsLock, ScrollLock, * or (ii) whatever pattern of lights people want to show using KDSETLED, * or (iii) specified bits of specified words in kernel memory. */static unsigned char ledstate = 0xff; /* undefined */static unsigned char ledioctl;unsigned char getledstate(void) {    return ledstate;}void setledstate(struct kbd_struct *kbd, unsigned int led) {    if (!(led & ~7)) {	ledioctl = led;	kbd->ledmode = LED_SHOW_IOCTL;    } else	kbd->ledmode = LED_SHOW_FLAGS;    set_leds();}static struct ledptr {    unsigned int *addr;    unsigned int mask;    unsigned char valid:1;} ledptrs[3];void register_leds(int console, unsigned int led,		   unsigned int *addr, unsigned int mask) {    struct kbd_struct *kbd = kbd_table + console;    if (led < 3) {	ledptrs[led].addr = addr;	ledptrs[led].mask = mask;	ledptrs[led].valid = 1;	kbd->ledmode = LED_SHOW_MEM;    } else	kbd->ledmode = LED_SHOW_FLAGS;}static inline unsigned char getleds(void){    struct kbd_struct *kbd = kbd_table + fg_console;    unsigned char leds;    if (kbd->ledmode == LED_SHOW_IOCTL)      return ledioctl;    leds = kbd->ledflagstate;    if (kbd->ledmode == LED_SHOW_MEM) {	if (ledptrs[0].valid) {	    if (*ledptrs[0].addr & ledptrs[0].mask)	      leds |= 1;	    else	      leds &= ~1;	}	if (ledptrs[1].valid) {	    if (*ledptrs[1].addr & ledptrs[1].mask)	      leds |= 2;	    else	      leds &= ~2;	}	if (ledptrs[2].valid) {	    if (*ledptrs[2].addr & ledptrs[2].mask)	      leds |= 4;	    else	      leds &= ~4;	}    }    return leds;}/* * This routine is the bottom half of the keyboard interrupt * routine, and runs with all interrupts enabled. It does * console changing, led setting and copy_to_cooked, which can * take a reasonably long time. * * Aside from timing (which isn't really that important for * keyboard interrupts as they happen often), using the software * interrupt routines for this thing allows us to easily mask * this when we don't want any of the above to happen. Not yet * used, but this allows for easy and efficient race-condition * prevention later on. */static void kbd_bh(void){	unsigned char leds = getleds();	if (leds != ledstate) {		ledstate = leds;		send_cmd(SKBDCMD_SETLED);		send_cmd(vcleds_to_sunkbd(leds));	}}int kbd_init(void){	int i, opt_node;	struct kbd_struct kbd0;	extern struct tty_driver console_driver;	kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;	kbd0.ledmode = LED_SHOW_FLAGS;	kbd0.lockstate = KBD_DEFLOCK;	kbd0.modeflags = KBD_DEFMODE;	kbd0.kbdmode = VC_XLATE; 	for (i = 0 ; i < MAX_NR_CONSOLES ; i++)		kbd_table[i] = kbd0;	ttytab = console_driver.table;	/* XXX Check keyboard-click? property in 'options' PROM node XXX */	if(sparc_cpu_model != sun4) {		opt_node = prom_getchild(prom_root_node);		opt_node = prom_searchsiblings(opt_node, "options");		i = prom_getintdefault(opt_node, "keyboard-click?", -1);		if(i != -1)			sunkbd_clickp = 1;		else			sunkbd_clickp = 0;	} else {		sunkbd_clickp = 0;	}	init_bh(KEYBOARD_BH, kbd_bh);	mark_bh(KEYBOARD_BH);	return 0;}/* /dev/kbd support */#define KBD_QSIZE 32static Firm_event kbd_queue [KBD_QSIZE];static int kbd_head, kbd_tail;char kbd_opened;static struct wait_queue *kbd_wait;static struct fasync_struct *kb_fasync;voidpush_kbd (int scan){	int next = (kbd_head + 1) % KBD_QSIZE;	if (scan == KBD_IDLE)		return;	if (next != kbd_tail){		kbd_queue [kbd_head].id = scan & KBD_KEYMASK;		kbd_queue [kbd_head].value=scan & KBD_UP ? VKEY_UP : VKEY_DOWN;		kbd_queue [kbd_head].time = xtime;		kbd_head = next;	}	if (kb_fasync)		kill_fasync (kb_fasync, SIGIO);	wake_up_interruptible (&kbd_wait);}static intkbd_read (struct inode *inode, struct file *f, char *buffer, int count){	struct wait_queue wait = { current, NULL };	char *end, *p;	/* Return EWOULDBLOCK, because this is what the X server expects */	if (kbd_head == kbd_tail){		if (f->f_flags & O_NONBLOCK)			return -EWOULDBLOCK;		add_wait_queue (&kbd_wait, &wait);		while (kbd_head == kbd_tail && !(current->signal & ~current->blocked)){			current->state = TASK_INTERRUPTIBLE;			schedule ();		}		current->state = TASK_RUNNING;		remove_wait_queue (&kbd_wait, &wait);	}	/* There is data in the keyboard, fill the user buffer */	end = buffer+count;	p = buffer;	for (; p < end && kbd_head != kbd_tail; p += sizeof (Firm_event)){		*(Firm_event *)p = kbd_queue [kbd_tail];#ifdef KBD_DEBUG		printk ("[%s]", kbd_queue [kbd_tail].value == VKEY_UP ? "UP" : "DOWN");#endif		kbd_tail++;		kbd_tail %= KBD_QSIZE;	}	return p-buffer;}/* Needed by X */static intkbd_fasync (struct inode *inode, struct file *filp, int on){	int retval;	retval = fasync_helper (inode, filp, on, &kb_fasync);	if (retval < 0)		return retval;	return 0;}static intkbd_select (struct inode *i, struct file *f, int sel_type, select_table *wait){	if (sel_type != SEL_IN)		return 0;	if (kbd_head != kbd_tail)		return 1;	select_wait (&kbd_wait, wait);	return 0;}static intkbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg){	switch (cmd){	case KIOCTYPE:	          /* return keyboard type */		if (verify_area (VERIFY_WRITE, (void *)arg, sizeof (int)))			return -EFAULT;	        *(int *) arg = sunkbd_type;		break;	case KIOCGTRANS:		if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))			return -EFAULT;	        *(int *) arg = TR_UNTRANS_EVENT;		break;	case KIOCTRANS:		if (verify_area (VERIFY_READ, (void *) arg, sizeof (int)))			return -EFAULT;	        if (*(int *) arg != TR_UNTRANS_EVENT)			return -EINVAL;		break;	case KIOCLAYOUT:		if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))			return -EFAULT;	        *(int *) arg = sunkbd_layout;		break;	case KIOCSDIRECT:		if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))			return -EFAULT;#ifndef CODING_NEW_DRIVER		if (*(int *) arg)			kbd_redirected = fg_console + 1;		else			kbd_redirected = 0;		kbd_table [fg_console].kbdmode = kbd_redirected ? VC_RAW : VC_XLATE;#endif		break;	case KIOCCMD:		/* Need to support beep on/off, keyclick on/off */		return 0;	case FIONREAD:		/* return number of bytes in kbd queue */	{		int count;				if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))			return -EFAULT;		count = kbd_head - kbd_tail;		* (int *)arg = (count < 0) ? KBD_QSIZE - count : count;		return 0;	}	default:		printk ("Unknown Keyboard ioctl: %8.8x\n", cmd);		return -EINVAL;	}	return 0;}static intkbd_open (struct inode *i, struct file *f){	if (kbd_opened)		return 0;	kbd_opened = fg_console + 1;	kbd_head = kbd_tail = 0;	return 0;}static voidkbd_close (struct inode *i, struct file *f){	if (kbd_redirected)		kbd_table [kbd_opened-1].kbdmode = VC_XLATE;	kbd_redirected = 0;	kbd_opened = 0;	kbd_fasync (i, f, 0);}static structfile_operations kbd_fops ={	NULL,			/* seek */	kbd_read,		/* read */	NULL,			/* write */	NULL,			/* readdir */	kbd_select,		/* select */	kbd_ioctl,		/* ioctl */	NULL,			/* mmap */	kbd_open,		/* open */	kbd_close,		/* close */	NULL,			/* fsync */	kbd_fasync,		/* fasync */	NULL,			/* check_media_change */	NULL,			/* revalidate */};voidkeyboard_zsinit(void){	int timeout = 0;	/* Test out the leds */	sunkbd_type = 255;	send_cmd(SKBDCMD_RESET);	while((sunkbd_type==255) && timeout < 500000) {		udelay(100);		timeout += 20;	}	if(timeout>=500000) {		printk("keyboard: not present\n");		return;	}	if(sunkbd_type != SUNKBD_TYPE4) {		printk("Sun TYPE %d keyboard detected ", sunkbd_type);	} else {		udelay(200);		timeout=0;		while(timeout++ < 500000)			barrier();		printk("Sun TYPE %d keyboard detected ",		       ((sunkbd_layout==SUNKBD_LOUT_TYP5) ? 5 : 4));	}	if(sunkbd_type == SUNKBD_TYPE2)		sunkbd_clickp = 0;	if(sunkbd_clickp)		printk("with keyclick\n");	else		printk("without keyclick\n");	/* Dork with led lights, then turn them all off */	send_cmd(SKBDCMD_SETLED); send_cmd(0xf); /* All on */	send_cmd(SKBDCMD_SETLED); send_cmd(0x0); /* All off */	/* Register the /dev/kbd interface */	if (register_chrdev (KBD_MAJOR, "kbd", &kbd_fops)){		printk ("Could not register /dev/kbd device\n");		return;	}	return;}

⌨️ 快捷键说明

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