Mon 14 Oct 23:06:38 CEST 2024
This commit is contained in:
		
							parent
							
								
									0a4c242310
								
							
						
					
					
						commit
						37615a46d7
					
				
							
								
								
									
										163
									
								
								kernel/keyboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								kernel/keyboard.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,163 @@ | ||||||
|  | /*
 | ||||||
|  | Copyright (C) 2015-2019 The University of Notre Dame | ||||||
|  | This software is distributed under the GNU General Public License. | ||||||
|  | See the file LICENSE for details. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "console.h" | ||||||
|  | #include "ioports.h" | ||||||
|  | #include "interrupt.h" | ||||||
|  | #include "kernel/ascii.h" | ||||||
|  | #include "kernelcore.h" | ||||||
|  | #include "event_queue.h" | ||||||
|  | 
 | ||||||
|  | #define KEYBOARD_PORT 0x60 | ||||||
|  | 
 | ||||||
|  | #define KEYMAP_SHIFT    1 | ||||||
|  | #define KEYMAP_ALT      2 | ||||||
|  | #define KEYMAP_CTRL     3 | ||||||
|  | #define KEYMAP_CAPSLOCK 4 | ||||||
|  | #define KEYMAP_NUMLOCK  5 | ||||||
|  | #define KEYMAP_ALPHA    6 | ||||||
|  | #define KEYMAP_NUMPAD   8 | ||||||
|  | #define KEYMAP_ALTGR    9 | ||||||
|  | 
 | ||||||
|  | /* sent before certain keys such as up, down, left, or right. */ | ||||||
|  | #define KEYCODE_EXTRA (uint8_t)0xE0 | ||||||
|  | #define KEYCODE_UP    (uint8_t)0x48 | ||||||
|  | #define KEYCODE_DOWN  (uint8_t)0x42 | ||||||
|  | #define KEYCODE_LEFT  (uint8_t)0x4B | ||||||
|  | #define KEYCODE_RIGHT (uint8_t)0x4D | ||||||
|  | 
 | ||||||
|  | #define BUFFER_SIZE 256 | ||||||
|  | 
 | ||||||
|  | struct keymap { | ||||||
|  | 	char normal; | ||||||
|  | 	char shifted; | ||||||
|  | 	char ctrled; | ||||||
|  | 	char special; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct keymap keymap[] = { | ||||||
|  | #include "keymap.de.pc.c" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static int shift_mode = 0; | ||||||
|  | static int alt_mode = 0; | ||||||
|  | static int altgr_mode = 0; | ||||||
|  | static int ctrl_mode = 0; | ||||||
|  | static int capslock_mode = 0; | ||||||
|  | static int numlock_mode = 0; | ||||||
|  | 
 | ||||||
|  | static void keyboard_interrupt_l2( uint8_t code ) | ||||||
|  | { | ||||||
|  | 	int direction; | ||||||
|  | 	int event; | ||||||
|  | 
 | ||||||
|  | 	if(code & 0x80) { | ||||||
|  | 		direction = 0; | ||||||
|  | 		event = EVENT_KEY_UP; | ||||||
|  | 		code = code & 0x7f; | ||||||
|  | 	} else { | ||||||
|  | 		direction = 1; | ||||||
|  | 		event = EVENT_KEY_DOWN; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	struct keymap *k = &keymap[code]; | ||||||
|  | 	if(k->special == KEYMAP_SHIFT) { | ||||||
|  | 		shift_mode = direction; | ||||||
|  | 	} else if(k->special == KEYMAP_ALT) { | ||||||
|  | 		alt_mode = direction; | ||||||
|  | 	} else if(k->special == KEYMAP_ALTGR) { | ||||||
|  |     // @blab+ ALTGR hack
 | ||||||
|  | 		altgr_mode = direction; | ||||||
|  | 	} else if(k->special == KEYMAP_CTRL) { | ||||||
|  | 		ctrl_mode = direction; | ||||||
|  | 	} else if(k->special == KEYMAP_CAPSLOCK) { | ||||||
|  | 		if(direction == 0) capslock_mode = !capslock_mode; | ||||||
|  | 	} else if(k->special == KEYMAP_NUMLOCK) { | ||||||
|  | 		if(direction == 0) numlock_mode = !numlock_mode; | ||||||
|  | 	} else { | ||||||
|  | 		if(direction && ctrl_mode && alt_mode && k->normal == ASCII_DEL) { | ||||||
|  | 			reboot(); | ||||||
|  | 		} else if(capslock_mode) { | ||||||
|  | 			if(k->special==KEYMAP_ALPHA && !shift_mode) { | ||||||
|  | 				event_queue_post_root(event,k->shifted,0,0); | ||||||
|  | 			} else { | ||||||
|  | 				event_queue_post_root(event,k->normal,0,0); | ||||||
|  | 			}	 | ||||||
|  | 		} else if(numlock_mode) { | ||||||
|  | 			if(k->special==KEYMAP_NUMPAD && !shift_mode) { | ||||||
|  | 				event_queue_post_root(event,k->shifted,0,0); | ||||||
|  | 			} else { | ||||||
|  | 				event_queue_post_root(event,k->normal,0,0); | ||||||
|  | 			}	 | ||||||
|  | 		} else if(shift_mode) { | ||||||
|  | 			event_queue_post_root(event,k->shifted,0,0); | ||||||
|  | 		} else if(ctrl_mode) { | ||||||
|  | 			event_queue_post_root(event,k->ctrled,0,0); | ||||||
|  | 		} else if(altgr_mode) { | ||||||
|  | 		  // @blab+ ALTGR hack
 | ||||||
|  | 			event_queue_post_root(event,k->special,0,0); | ||||||
|  | 		} else { | ||||||
|  | 			event_queue_post_root(event,k->normal,0,0); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int expect_extra = 0; | ||||||
|  | 
 | ||||||
|  | static void keyboard_interrupt(int i, int intr_code) | ||||||
|  | { | ||||||
|  | 	uint8_t code = inb(KEYBOARD_PORT); | ||||||
|  | 	uint8_t c = KEY_INVALID; | ||||||
|  | 
 | ||||||
|  |   // printf("[%x]",code);
 | ||||||
|  | 
 | ||||||
|  | 	if(code == KEYCODE_EXTRA) { | ||||||
|  | 		expect_extra = 1; | ||||||
|  | 		return; | ||||||
|  | 	} else if(expect_extra) { | ||||||
|  | 		expect_extra = 0; | ||||||
|  | 		switch(code) { | ||||||
|  | 		  // @blab+ ALTGR hack
 | ||||||
|  | 		  case 0x38: | ||||||
|  | 		  case 0xb8: | ||||||
|  | 		    // keymap: use next reserved row (normally nulled)
 | ||||||
|  | 		    // {KEY_INVALID, KEY_INVALID, KEY_INVALID, KEYMAP_ALT},#
 | ||||||
|  | 		    // ..
 | ||||||
|  |         // {KEY_INVALID, KEY_INVALID, KEY_INVALID, KEYMAP_ALTGR},
 | ||||||
|  | 		    c = code+3; | ||||||
|  | 		    break; | ||||||
|  | 			case KEYCODE_UP: | ||||||
|  | 				c = KEY_UP; | ||||||
|  | 				break; | ||||||
|  | 			case KEYCODE_DOWN: | ||||||
|  | 				c = KEY_DOWN; | ||||||
|  | 				break; | ||||||
|  | 			case KEYCODE_LEFT: | ||||||
|  | 				c = KEY_LEFT; | ||||||
|  | 				break; | ||||||
|  | 			case KEYCODE_RIGHT: | ||||||
|  | 				c = KEY_RIGHT; | ||||||
|  | 				break; | ||||||
|  | 			default: | ||||||
|  | 				return; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		c = code; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	keyboard_interrupt_l2(c); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void keyboard_init() | ||||||
|  | { | ||||||
|  | 	interrupt_register(33, keyboard_interrupt); | ||||||
|  | 	interrupt_enable(33); | ||||||
|  | 	printf("keyboard: ready\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user