FreeBSD/sys/dev/vkbd/vkbd.c
/* Read char from the keyboard (stolen from atkbd.c) */
Read char from the keyboard (stolen from atkbd.c)
Read char from the keyboard ( stolen from atkbd . c )
static u_int
vkbd_read_char(keyboard_t *kbd, int wait)
{
	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
	u_int		 action;
	int		 scancode, keycode;
	VKBD_LOCK(state);
next_code:
	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
		action = state->ks_composed_char;
		state->ks_composed_char = 0;
		if (action > UCHAR_MAX) {
			VKBD_UNLOCK(state);
			return (ERRKEY);
		}
		VKBD_UNLOCK(state);
		return (action);
	}
	scancode = vkbd_data_read(state, wait);
	if (scancode == -1) {
		VKBD_UNLOCK(state);
		return (NOKEY);
	}
	kbd->kb_count ++;
	if (state->ks_mode == K_RAW) {
		VKBD_UNLOCK(state);
		return (scancode);
	}
	keycode = scancode & 0x7F;
	switch (state->ks_prefix) {
	case 0x00:	
		switch(scancode) {
		case 0xB8:	
			if (state->ks_flags & COMPOSE) {
				state->ks_flags &= ~COMPOSE;
				if (state->ks_composed_char > UCHAR_MAX)
					state->ks_composed_char = 0;
			}
			break;
		case 0x38:	
			if (!(state->ks_flags & COMPOSE)) {
				state->ks_flags |= COMPOSE;
				state->ks_composed_char = 0;
			}
			break;
		case 0xE0:
		case 0xE1:
			state->ks_prefix = scancode;
			goto next_code;
		}
		break;
	case 0xE0:      
		state->ks_prefix = 0;
		switch (keycode) {
		case 0x1C:	
			keycode = 0x59;
			break;
		case 0x1D:	
			keycode = 0x5A;
			break;
		case 0x35:	
			keycode = 0x5B;
			break;
		case 0x37:	
			keycode = 0x5C;
			break;
		case 0x38:	
			keycode = 0x5D;
			break;
		case 0x46:	
			keycode = 0x68;
			break;
		case 0x47:	
			keycode = 0x5E;
			break;
		case 0x48:	
			keycode = 0x5F;
			break;
		case 0x49:	
			keycode = 0x60;
			break;
		case 0x4B:	
			keycode = 0x61;
			break;
		case 0x4D:	
			keycode = 0x62;
			break;
		case 0x4F:	
			keycode = 0x63;
			break;
		case 0x50:	
			keycode = 0x64;
			break;
		case 0x51:	
			keycode = 0x65;
			break;
		case 0x52:	
			keycode = 0x66;
			break;
		case 0x53:	
			keycode = 0x67;
			break;
		case 0x5b:	
			keycode = 0x69;
			break;
		case 0x5c:	
			keycode = 0x6a;
			break;
		case 0x5d:	
			keycode = 0x6b;
			break;
		case 0x5e:	
			keycode = 0x6d;
			break;
		case 0x5f:	
			keycode = 0x6e;
			break;
		case 0x63:	
			keycode = 0x6f;
			break;
		default:	
			goto next_code;
		}
		break;
	case 0xE1:	
		state->ks_prefix = 0;
		if (keycode == 0x1D)
			state->ks_prefix = 0x1D;
		goto next_code;
	case 0x1D:	
		state->ks_prefix = 0;
		if (keycode != 0x45)
			goto next_code;
		keycode = 0x68;
		break;
	}
	if (kbd->kb_type == KB_84) {
		switch (keycode) {
		case 0x37:	
			if (state->ks_flags & SHIFTS)
				keycode = 0x5c;	
			break;
		case 0x45:	
			if (state->ks_flags & CTLS)
				keycode = 0x68;	
			break;
		case 0x46:	
			if (state->ks_flags & CTLS)
				keycode = 0x6c;	
			break;
		}
	} else if (kbd->kb_type == KB_101) {
		switch (keycode) {
		case 0x5c:	
			if (state->ks_flags & ALTS)
				keycode = 0x54;	
			break;
		case 0x68:	
			if (state->ks_flags & CTLS)
				keycode = 0x6c;	
			break;
		}
	}
	if (state->ks_mode == K_CODE) {
		VKBD_UNLOCK(state);
		return (keycode | (scancode & 0x80));
	}
	if (state->ks_flags & COMPOSE) {
		switch (keycode | (scancode & 0x80)) {
		case 0x47: case 0x48: case 0x49:	
			state->ks_composed_char *= 10;
			state->ks_composed_char += keycode - 0x40;
			if (state->ks_composed_char > UCHAR_MAX) {
				VKBD_UNLOCK(state);
				return (ERRKEY);
			}
			goto next_code;
		case 0x4B: case 0x4C: case 0x4D:	
			state->ks_composed_char *= 10;
			state->ks_composed_char += keycode - 0x47;
			if (state->ks_composed_char > UCHAR_MAX) {
				VKBD_UNLOCK(state);
				return (ERRKEY);
			}
			goto next_code;
		case 0x4F: case 0x50: case 0x51:	
			state->ks_composed_char *= 10;
			state->ks_composed_char += keycode - 0x4E;
			if (state->ks_composed_char > UCHAR_MAX) {
				VKBD_UNLOCK(state);
				return (ERRKEY);
			}
			goto next_code;
		case 0x52:	
			state->ks_composed_char *= 10;
			if (state->ks_composed_char > UCHAR_MAX) {
				VKBD_UNLOCK(state);
				return (ERRKEY);
			}
			goto next_code;
		case 0xC7: case 0xC8: case 0xC9:	
		case 0xCB: case 0xCC: case 0xCD:	
		case 0xCF: case 0xD0: case 0xD1:	
		case 0xD2:				
			goto next_code;
		case 0x38:				
			break;
		default:
			if (state->ks_composed_char > 0) {
				state->ks_flags &= ~COMPOSE;
				state->ks_composed_char = 0;
				VKBD_UNLOCK(state);
				return (ERRKEY);
			}
			break;
		}
	}
	action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
			&state->ks_state, &state->ks_accents);
	if (action == NOKEY)
		goto next_code;
	VKBD_UNLOCK(state);
	return (action);
}
static u_int vkbd_read_char ( keyboard_t * kbd , int wait ) { vkbd_state_t * state = ( vkbd_state_t * ) kbd -> kb_data ; u_int action ; int scancode , keycode ; VKBD_LOCK ( state ) ; next_code : if ( ! ( state -> ks_flags & COMPOSE ) && ( state -> ks_composed_char > 0 ) ) { action = state -> ks_composed_char ; state -> ks_composed_char = 0 ; if ( action > UCHAR_MAX ) { VKBD_UNLOCK ( state ) ; return ( ERRKEY ) ; } VKBD_UNLOCK ( state ) ; return ( action ) ; } scancode = vkbd_data_read ( state , wait ) ; if ( scancode == -1 ) { VKBD_UNLOCK ( state ) ; return ( NOKEY ) ; } kbd -> kb_count ++ ; if ( state -> ks_mode == K_RAW ) { VKBD_UNLOCK ( state ) ; return ( scancode ) ; } keycode = scancode & 0x7F ; switch ( state -> ks_prefix ) { case 0x00 : switch ( scancode ) { case 0xB8 : if ( state -> ks_flags & COMPOSE ) { state -> ks_flags &= ~ COMPOSE ; if ( state -> ks_composed_char > UCHAR_MAX ) state -> ks_composed_char = 0 ; } break ; case 0x38 : if ( ! ( state -> ks_flags & COMPOSE ) ) { state -> ks_flags |= COMPOSE ; state -> ks_composed_char = 0 ; } break ; case 0xE0 : case 0xE1 : state -> ks_prefix = scancode ; goto next_code ; } break ; case 0xE0 : state -> ks_prefix = 0 ; switch ( keycode ) { case 0x1C : keycode = 0x59 ; break ; case 0x1D : keycode = 0x5A ; break ; case 0x35 : keycode = 0x5B ; break ; case 0x37 : keycode = 0x5C ; break ; case 0x38 : keycode = 0x5D ; break ; case 0x46 : keycode = 0x68 ; break ; case 0x47 : keycode = 0x5E ; break ; case 0x48 : keycode = 0x5F ; break ; case 0x49 : keycode = 0x60 ; break ; case 0x4B : keycode = 0x61 ; break ; case 0x4D : keycode = 0x62 ; break ; case 0x4F : keycode = 0x63 ; break ; case 0x50 : keycode = 0x64 ; break ; case 0x51 : keycode = 0x65 ; break ; case 0x52 : keycode = 0x66 ; break ; case 0x53 : keycode = 0x67 ; break ; case 0x5b : keycode = 0x69 ; break ; case 0x5c : keycode = 0x6a ; break ; case 0x5d : keycode = 0x6b ; break ; case 0x5e : keycode = 0x6d ; break ; case 0x5f : keycode = 0x6e ; break ; case 0x63 : keycode = 0x6f ; break ; default : goto next_code ; } break ; case 0xE1 : state -> ks_prefix = 0 ; if ( keycode == 0x1D ) state -> ks_prefix = 0x1D ; goto next_code ; case 0x1D : state -> ks_prefix = 0 ; if ( keycode != 0x45 ) goto next_code ; keycode = 0x68 ; break ; } if ( kbd -> kb_type == KB_84 ) { switch ( keycode ) { case 0x37 : if ( state -> ks_flags & SHIFTS ) keycode = 0x5c ; break ; case 0x45 : if ( state -> ks_flags & CTLS ) keycode = 0x68 ; break ; case 0x46 : if ( state -> ks_flags & CTLS ) keycode = 0x6c ; break ; } } else if ( kbd -> kb_type == KB_101 ) { switch ( keycode ) { case 0x5c : if ( state -> ks_flags & ALTS ) keycode = 0x54 ; break ; case 0x68 : if ( state -> ks_flags & CTLS ) keycode = 0x6c ; break ; } } if ( state -> ks_mode == K_CODE ) { VKBD_UNLOCK ( state ) ; return ( keycode | ( scancode & 0x80 ) ) ; } if ( state -> ks_flags & COMPOSE ) { switch ( keycode | ( scancode & 0x80 ) ) { case 0x47 : case 0x48 : case 0x49 : state -> ks_composed_char *= 10 ; state -> ks_composed_char += keycode - 0x40 ; if ( state -> ks_composed_char > UCHAR_MAX ) { VKBD_UNLOCK ( state ) ; return ( ERRKEY ) ; } goto next_code ; case 0x4B : case 0x4C : case 0x4D : state -> ks_composed_char *= 10 ; state -> ks_composed_char += keycode - 0x47 ; if ( state -> ks_composed_char > UCHAR_MAX ) { VKBD_UNLOCK ( state ) ; return ( ERRKEY ) ; } goto next_code ; case 0x4F : case 0x50 : case 0x51 : state -> ks_composed_char *= 10 ; state -> ks_composed_char += keycode - 0x4E ; if ( state -> ks_composed_char > UCHAR_MAX ) { VKBD_UNLOCK ( state ) ; return ( ERRKEY ) ; } goto next_code ; case 0x52 : state -> ks_composed_char *= 10 ; if ( state -> ks_composed_char > UCHAR_MAX ) { VKBD_UNLOCK ( state ) ; return ( ERRKEY ) ; } goto next_code ; case 0xC7 : case 0xC8 : case 0xC9 : case 0xCB : case 0xCC : case 0xCD : case 0xCF : case 0xD0 : case 0xD1 : case 0xD2 : goto next_code ; case 0x38 : break ; default : if ( state -> ks_composed_char > 0 ) { state -> ks_flags &= ~ COMPOSE ; state -> ks_composed_char = 0 ; VKBD_UNLOCK ( state ) ; return ( ERRKEY ) ; } break ; } } action = genkbd_keyaction ( kbd , keycode , scancode & 0x80 , & state -> ks_state , & state -> ks_accents ) ; if ( action == NOKEY ) goto next_code ; VKBD_UNLOCK ( state ) ; return ( action ) ; }
Read char from the keyboard (stolen from atkbd.c)
Read char from the keyboard ( stolen from atkbd . c )
/* do we have a composed char to return? */ /* see if there is something in the keyboard port */ /* XXX FIXME: check for -1 if wait == 1! */ /* return the byte as is for the K_RAW mode */ /* translate the scan code into a keycode */ /* normal scancode */ /* left alt (compose key) released */ /* left alt (compose key) pressed */ /* 0xE0 prefix */ /* right enter key */ /* right ctrl key */ /* keypad divide key */ /* print scrn key */ /* right alt key (alt gr) */ /* ctrl-pause/break on AT 101 (see below) */ /* grey home key */ /* grey up arrow key */ /* grey page up key */ /* grey left arrow key */ /* grey right arrow key */ /* grey end key */ /* grey down arrow key */ /* grey page down key */ /* grey insert key */ /* grey delete key */ /* the following 3 are only used on the MS "Natural" keyboard */ /* left Window key */ /* right Window key */ /* menu key */ /* power key */ /* sleep key */ /* wake key */ /* ignore everything else */ /* 0xE1 prefix */ /* 
		 * The pause/break key on the 101 keyboard produces:
		 * E1-1D-45 E1-9D-C5
		 * Ctrl-pause/break produces:
		 * E0-46 E0-C6 (See above.)
		 */ /* NOT REACHED */ /* pause / break */ /* *(numpad)/print screen */ /* print screen */ /* num lock/pause */ /* pause */ /* scroll lock/break */ /* break */ /* print screen */ /* sysrq */ /* pause/break */ /* break */ /* return the key code in the K_CODE mode */ /* compose a character code */ /* key pressed, process it */ /* keypad 7,8,9 */ /* keypad 4,5,6 */ /* keypad 1,2,3 */ /* keypad 0 */ /* key released, no interest here */ /* keypad 7,8,9 */ /* keypad 4,5,6 */ /* keypad 1,2,3 */ /* keypad 0 */ /* left alt key */ /* keycode to key action */