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

📄 keyboard.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
  int s;  retries = MAX_KB_BUSY_RETRIES + 1;	/* wait until not busy */  do {      s = sys_inb(KB_STATUS, &status);      if (status & KB_OUT_FULL) {          s = sys_inb(KEYBD, &temp);	/* discard value */      }      if (! (status & (KB_IN_FULL|KB_OUT_FULL)) )          break;			/* wait until ready */  } while (--retries != 0);		/* continue unless timeout */   return(retries);		/* zero on timeout, positive if ready */}/*===========================================================================* *				kb_ack					     * *===========================================================================*/PRIVATE int kb_ack(){/* Wait until kbd acknowledges last command; return zero if this times out. */  int retries, s;  u8_t u8val;  retries = MAX_KB_ACK_RETRIES + 1;  do {      s = sys_inb(KEYBD, &u8val);      if (u8val == KB_ACK)	          break;		/* wait for ack */  } while(--retries != 0);	/* continue unless timeout */  return(retries);		/* nonzero if ack received */}/*===========================================================================* *				kb_init					     * *===========================================================================*/PUBLIC void kb_init(tp)tty_t *tp;{/* Initialize the keyboard driver. */  tp->tty_devread = kb_read;	/* input function */}/*===========================================================================* *				kb_init_once				     * *===========================================================================*/PUBLIC void kb_init_once(void){  int i;  set_leds();			/* turn off numlock led */  scan_keyboard();		/* discard leftover keystroke */      /* Clear the function key observers array. Also see func_key(). */      for (i=0; i<12; i++) {          fkey_obs[i].proc_nr = NONE;	/* F1-F12 observers */          fkey_obs[i].events = 0;	/* F1-F12 observers */          sfkey_obs[i].proc_nr = NONE;	/* Shift F1-F12 observers */          sfkey_obs[i].events = 0;	/* Shift F1-F12 observers */      }      /* Set interrupt handler and enable keyboard IRQ. */      irq_hook_id = KEYBOARD_IRQ;	/* id to be returned on interrupt */      if ((i=sys_irqsetpolicy(KEYBOARD_IRQ, IRQ_REENABLE, &irq_hook_id)) != OK)          panic("TTY",  "Couldn't set keyboard IRQ policy", i);      if ((i=sys_irqenable(&irq_hook_id)) != OK)          panic("TTY", "Couldn't enable keyboard IRQs", i);      kbd_irq_set |= (1 << KEYBOARD_IRQ);}/*===========================================================================* *				kbd_loadmap				     * *===========================================================================*/PUBLIC int kbd_loadmap(m)message *m;{/* Load a new keymap. */  int result;  result = sys_vircopy(m->PROC_NR, D, (vir_bytes) m->ADDRESS,  	SELF, D, (vir_bytes) keymap,   	(vir_bytes) sizeof(keymap));  return(result);}/*===========================================================================* *				do_fkey_ctl				     * *===========================================================================*/PUBLIC void do_fkey_ctl(m_ptr)message *m_ptr;			/* pointer to the request message */{/* This procedure allows processes to register a function key to receive * notifications if it is pressed. At most one binding per key can exist. */  int i;   int result;  switch (m_ptr->FKEY_REQUEST) {	/* see what we must do */  case FKEY_MAP:			/* request for new mapping */      result = OK;			/* assume everything will be ok*/      for (i=0; i < 12; i++) {		/* check F1-F12 keys */          if (bit_isset(m_ptr->FKEY_FKEYS, i+1) ) {#if DEAD_CODE	/* Currently, we don't check if the slot is in use, so that IS	 * can recover after a crash by overtaking its existing mappings.	 * In future, a better solution will be implemented.	 */              if (fkey_obs[i].proc_nr == NONE) { #endif    	          fkey_obs[i].proc_nr = m_ptr->m_source;    	          fkey_obs[i].events = 0;    	          bit_unset(m_ptr->FKEY_FKEYS, i+1);#if DEAD_CODE    	      } else {    	          printf("WARNING, fkey_map failed F%d\n", i+1);    	          result = EBUSY;	/* report failure, but try rest */    	      }#endif    	  }      }      for (i=0; i < 12; i++) {		/* check Shift+F1-F12 keys */          if (bit_isset(m_ptr->FKEY_SFKEYS, i+1) ) {#if DEAD_CODE              if (sfkey_obs[i].proc_nr == NONE) { #endif    	          sfkey_obs[i].proc_nr = m_ptr->m_source;    	          sfkey_obs[i].events = 0;    	          bit_unset(m_ptr->FKEY_SFKEYS, i+1);#if DEAD_CODE    	      } else {    	          printf("WARNING, fkey_map failed Shift F%d\n", i+1);    	          result = EBUSY;	/* report failure but try rest */    	      }#endif    	  }      }      break;  case FKEY_UNMAP:      result = OK;			/* assume everything will be ok*/      for (i=0; i < 12; i++) {		/* check F1-F12 keys */          if (bit_isset(m_ptr->FKEY_FKEYS, i+1) ) {              if (fkey_obs[i].proc_nr == m_ptr->m_source) {     	          fkey_obs[i].proc_nr = NONE;    	          fkey_obs[i].events = 0;    	          bit_unset(m_ptr->FKEY_FKEYS, i+1);    	      } else {    	          result = EPERM;	/* report failure, but try rest */    	      }    	  }      }      for (i=0; i < 12; i++) {		/* check Shift+F1-F12 keys */          if (bit_isset(m_ptr->FKEY_SFKEYS, i+1) ) {              if (sfkey_obs[i].proc_nr == m_ptr->m_source) {     	          sfkey_obs[i].proc_nr = NONE;    	          sfkey_obs[i].events = 0;    	          bit_unset(m_ptr->FKEY_SFKEYS, i+1);    	      } else {    	          result = EPERM;	/* report failure, but try rest */    	      }    	  }      }      break;  case FKEY_EVENTS:      m_ptr->FKEY_FKEYS = m_ptr->FKEY_SFKEYS = 0;      for (i=0; i < 12; i++) {		/* check (Shift+) F1-F12 keys */          if (fkey_obs[i].proc_nr == m_ptr->m_source) {              if (fkey_obs[i].events) {                   bit_set(m_ptr->FKEY_FKEYS, i+1);                  fkey_obs[i].events = 0;              }          }          if (sfkey_obs[i].proc_nr == m_ptr->m_source) {              if (sfkey_obs[i].events) {                   bit_set(m_ptr->FKEY_SFKEYS, i+1);                  sfkey_obs[i].events = 0;              }          }      }      break;  default:          result =  EINVAL;		/* key cannot be observed */  }  /* Almost done, return result to caller. */  m_ptr->m_type = result;  send(m_ptr->m_source, m_ptr);}/*===========================================================================* *				func_key				     * *===========================================================================*/PRIVATE int func_key(scode)int scode;			/* scan code for a function key */{/* This procedure traps function keys for debugging purposes. Observers of  * function keys are kept in a global array. If a subject (a key) is pressed * the observer is notified of the event. Initialization of the arrays is done * in kb_init, where NONE is set to indicate there is no interest in the key. * Returns FALSE on a key release or if the key is not observable. */  message m;  int key;  int proc_nr;  int i,s;  /* Ignore key releases. If this is a key press, get full key code. */  if (scode & KEY_RELEASE) return(FALSE);	/* key release */  key = map_key(scode);		 		/* include modifiers */  /* Key pressed, now see if there is an observer for the pressed key.   *	       F1-F12	observers are in fkey_obs array.    *	SHIFT  F1-F12	observers are in sfkey_req array.    *	CTRL   F1-F12	reserved (see kb_read)   *	ALT    F1-F12	reserved (see kb_read)   * Other combinations are not in use. Note that Alt+Shift+F1-F12 is yet   * defined in <minix/keymap.h>, and thus is easy for future extensions.   */  if (F1 <= key && key <= F12) {		/* F1-F12 */      proc_nr = fkey_obs[key - F1].proc_nr;	      fkey_obs[key - F1].events ++ ;	  } else if (SF1 <= key && key <= SF12) {	/* Shift F2-F12 */      proc_nr = sfkey_obs[key - SF1].proc_nr;	      sfkey_obs[key - SF1].events ++;	  }  else {      return(FALSE);				/* not observable */  }  /* See if an observer is registered and send it a message. */  if (proc_nr != NONE) {       m.NOTIFY_TYPE = FKEY_PRESSED;      notify(proc_nr);  }  return(TRUE);}/*===========================================================================* *				show_key_mappings			     * *===========================================================================*/PRIVATE void show_key_mappings(){    int i,s;    struct proc proc;    printf("\n");    printf("System information.   Known function key mappings to request debug dumps:\n");    printf("-------------------------------------------------------------------------\n");    for (i=0; i<12; i++) {      printf(" %sF%d: ", i+1<10? " ":"", i+1);      if (fkey_obs[i].proc_nr != NONE) {          if ((s=sys_getproc(&proc, fkey_obs[i].proc_nr))!=OK)              printf("sys_getproc: %d\n", s);          printf("%-14.14s", proc.p_name);      } else {          printf("%-14.14s", "<none>");      }      printf("    %sShift-F%d: ", i+1<10? " ":"", i+1);      if (sfkey_obs[i].proc_nr != NONE) {          if ((s=sys_getproc(&proc, sfkey_obs[i].proc_nr))!=OK)              printf("sys_getproc: %d\n", s);          printf("%-14.14s", proc.p_name);      } else {          printf("%-14.14s", "<none>");      }      printf("\n");    }    printf("\n");    printf("Press one of the registered function keys to trigger a debug dump.\n");    printf("\n");}/*===========================================================================* *				scan_keyboard				     * *===========================================================================*/PRIVATE int scan_keyboard(){/* Fetch the character from the keyboard hardware and acknowledge it. */  pvb_pair_t byte_in[2], byte_out[2];    byte_in[0].port = KEYBD;	/* get the scan code for the key struck */  byte_in[1].port = PORT_B;	/* strobe the keyboard to ack the char */  sys_vinb(byte_in, 2);		/* request actual input */  pv_set(byte_out[0], PORT_B, byte_in[1].value | KBIT); /* strobe bit high */  pv_set(byte_out[1], PORT_B, byte_in[1].value);	/* then strobe low */  sys_voutb(byte_out, 2);	/* request actual output */  return(byte_in[0].value);		/* return scan code */}/*===========================================================================* *				do_panic_dumps 				     * *===========================================================================*/PUBLIC void do_panic_dumps(m)message *m;			/* request message to TTY */{/* Wait for keystrokes for printing debugging info and reboot. */  int quiet, code;  /* A panic! Allow debug dumps until user wants to shutdown. */  printf("\nHit ESC to reboot, DEL to shutdown, F-keys for debug dumps\n");  (void) scan_keyboard();	/* ack any old input */  quiet = scan_keyboard();/* quiescent value (0 on PC, last code on AT)*/  for (;;) {	tickdelay(10);	/* See if there are pending request for output, but don't block. 	 * Diagnostics can span multiple printf()s, so do it in a loop.	 */	while (nb_receive(ANY, m) == OK) {		switch(m->m_type) {		case FKEY_CONTROL: do_fkey_ctl(m);      break;		case SYS_SIG:	   do_new_kmess(m);	break;		case DIAGNOSTICS:  do_diagnostics(m);	break;		default:	;	/* do nothing */ 		}		tickdelay(1);		/* allow more */	}	code = scan_keyboard();	if (code != quiet) {		/* A key has been pressed. */		switch (code) {			/* possibly abort MINIX */		case ESC_SCAN:  sys_abort(RBT_REBOOT); 	return;			case DEL_SCAN:  sys_abort(RBT_HALT); 	return;			}		(void) func_key(code);	     	/* check for function key */		quiet = scan_keyboard();	}  }}

⌨️ 快捷键说明

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