📄 ps2kbdmou_ecos.c
字号:
{ MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, // 120 { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, '|' }, // 125 // In theory there could also be 126 and 127, but those are unused. // But putting them into the table avoids a special case test in the code, // for a cost of only eight bytes. { MWKEY_UNKNOWN, MWKEY_UNKNOWN }, { MWKEY_UNKNOWN, MWKEY_UNKNOWN },};// Now for the E0 sequences. The standard ones are in the range 0x47 to 0x53// 0xE0, 0x5B is the Left Windows key. 0x5C would normally be the right one.// 0xE0, 0x5D is the Menu key. The // The Dell has some additional ones for the dvd player, ignored.// PrintScreen generates a simple sequence 0xE0, 0x2A, 0xE0, 0x37, 0xE0, 0xB7, 0xE0, 0xAA// Break generates 0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5#define PS2KBD_E0_MIN 0x47static const MWKEY ps2kbd_e0_map[] = { MWKEY_HOME, // 0x47 MWKEY_UP, // 0x48 MWKEY_PAGEUP, // 0x49 MWKEY_UNKNOWN, MWKEY_LEFT, // 0x4B MWKEY_UNKNOWN, MWKEY_RIGHT, // 0x4D MWKEY_UNKNOWN, MWKEY_END, // 0x4F MWKEY_DOWN, // 0x50 MWKEY_PAGEDOWN, // 0x51 MWKEY_INSERT, // 0x52 MWKEY_DELETE, // 0x53 MWKEY_UNKNOWN, MWKEY_UNKNOWN, MWKEY_UNKNOWN, MWKEY_UNKNOWN, MWKEY_UNKNOWN, MWKEY_UNKNOWN, MWKEY_UNKNOWN, MWKEY_LMETA, // 0x5B MWKEY_RMETA, // 0x5C MWKEY_MENU // 0x5D};#define PS2KBD_E0_MAX 0x5D// Modifier translations. All modifiers are supported by// this table, even though the keyboard may not actually// have all of them.typedef struct ps2kbd_modifier_entry { MWKEY key; MWKEYMOD modifier; int toggle;} ps2kbd_modifier_entry;static const ps2kbd_modifier_entry ps2kbd_modifier_map[] = { { MWKEY_LSHIFT, MWKMOD_LSHIFT, 0 }, { MWKEY_RSHIFT, MWKMOD_RSHIFT, 0 }, { MWKEY_LCTRL, MWKMOD_LCTRL, 0 }, { MWKEY_RCTRL, MWKMOD_RCTRL, 0 }, { MWKEY_LALT, MWKMOD_LALT, 0 }, { MWKEY_RALT, MWKMOD_RALT, 0 }, { MWKEY_LMETA, MWKMOD_LMETA, 0 }, { MWKEY_RMETA, MWKMOD_RMETA, 0 }, { MWKEY_NUMLOCK, MWKMOD_NUM, 1 }, { MWKEY_CAPSLOCK, MWKMOD_CAPS, 1 }, { MWKEY_ALTGR, MWKMOD_ALTGR, 0 }, { MWKEY_SCROLLOCK, MWKMOD_SCR, 1 }, { MWKEY_UNKNOWN, MWKMOD_NONE }};static voidps2kbd_process_scancodes(void){ static int e0_seen = 0; static MWKEY pending_up = MWKEY_UNKNOWN; static int pending_scancode = 0; static int discard = 0; int scancode; int i; CYG_PRECONDITION(MWKEY_UNKNOWN == ps2kbd_current_key, "There should be no pending key"); if (MWKEY_UNKNOWN != pending_up) { ps2kbd_current_key = pending_up; ps2kbd_current_scancode = pending_scancode; ps2kbd_current_keydown = 0; pending_up = MWKEY_UNKNOWN; return; } while (MWKEY_UNKNOWN == ps2kbd_current_key) { // The ISR will manipulate the scancode buffer directly, so // interrupts have to be disabled temporarily. scancode = -1; cyg_drv_isr_lock(); if (ps2kbd_scancode_buffer_head != ps2kbd_scancode_buffer_tail) { scancode = ps2kbd_scancode_buffer[ps2kbd_scancode_buffer_tail]; ps2kbd_scancode_buffer_tail = (ps2kbd_scancode_buffer_tail + 1) % PS2KBD_SCANCODE_BUFSIZE; } cyg_drv_isr_unlock(); if (scancode == -1) { // No more data to be processed. break; } // Are we in one of the special sequences, where bytes should be // discarded? if (discard > 0) { discard -= 1; continue; } // A real scancode has been extracted. Are we in an E0 sequence? if (e0_seen) { e0_seen = 0; ps2kbd_current_keydown = (0 == (scancode & 0x0080)); scancode &= 0x007F; if ((scancode >= PS2KBD_E0_MIN) && (scancode <= PS2KBD_E0_MAX)) { ps2kbd_current_key = ps2kbd_e0_map[scancode - PS2KBD_E0_MIN]; ps2kbd_current_scancode = 0x80 + scancode - PS2KBD_E0_MIN; // Invent a key scancode } // We may or may not have a valid keycode at this time, so go // around the loop again to check for MWKEY_UNKNOWN continue; } // Is this the start of an E0 sequence? if (0x00E0 == scancode) { e0_seen = 1; continue; } // How about E1? if (0x00E1 == scancode) { // For now there is only one key which generates E1 sequences ps2kbd_current_key = MWKEY_BREAK; ps2kbd_current_keydown = 1; ps2kbd_current_scancode = 0x00E1; // Invent another key scancode pending_up = MWKEY_BREAK; pending_scancode = 0x00E1; discard = 5; return; } // Must be an ordinary key. ps2kbd_current_keydown = (0 == (scancode & 0x0080)); scancode &= 0x007F; ps2kbd_current_scancode = scancode; ps2kbd_current_key = ps2kbd_keymap[scancode].normal; // Detect the modifier keys. for (i = 0; MWKEY_UNKNOWN != ps2kbd_modifier_map[i].key; i++) { if (ps2kbd_current_key == ps2kbd_modifier_map[i].key) { // capslock etc. behave differently. Toggle the current // status on the keyup event, ignore key down (because // of hardware autorepeat). if (ps2kbd_modifier_map[i].toggle) { if (!ps2kbd_current_keydown) { ps2kbd_current_modifiers ^= ps2kbd_modifier_map[i].modifier; } } else if (ps2kbd_current_keydown) { ps2kbd_current_modifiers |= ps2kbd_modifier_map[i].modifier; } else { ps2kbd_current_modifiers &= ~ps2kbd_modifier_map[i].modifier; } break; } } // Cope with some of the modifiers. if (0 != (ps2kbd_current_modifiers & (MWKMOD_LCTRL | MWKMOD_RCTRL))) { // Control key. a-z and A-Z go to ctrl-A - ctrl-Z, i.e. 1 to 26 // Other characters in the range 64 to 96, e.g. [ and ], also // get translated. This includes the A-Z range. if ((64 <= ps2kbd_current_key) && (ps2kbd_current_key < 96)) { ps2kbd_current_key -= 64; } else if (('a' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'z')) { ps2kbd_current_key -= 96; } } else if (ps2kbd_current_modifiers & (MWKMOD_LSHIFT | MWKMOD_RSHIFT)) { // Pick up the shift entry from the keymap ps2kbd_current_key = ps2kbd_keymap[scancode].shifted; } if (ps2kbd_current_modifiers & MWKMOD_CAPS) { // Capslock only affects a-z and A-z if ( ('a' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'z')) { ps2kbd_current_key = (ps2kbd_current_key -'a') + 'A'; } else if (('A' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'Z')) { ps2kbd_current_key = (ps2kbd_current_key -'A') + 'a'; } } // If we have found a real key, the loop will exit. // Otherwise try again. }}static intPS2Kbd_Open(KBDDEVICE* pkbd){ unsigned char buf[1]; ps2_initialize(); buf[0] = KC_KBDC_ENABLE; ps2_send_command_wait(KC_CONTROL_NULL, buf, 1, 0);}static voidPS2Kbd_Close(void){ unsigned char buf[1]; buf[0] = KC_KBDC_STANDARD_DISABLE; ps2_send_command_wait(KC_CONTROL_NULL, buf, 1, 0);}static voidPS2Kbd_GetModifierInfo(MWKEYMOD* modifiers, MWKEYMOD* curmodifiers){ if (NULL != modifiers) { *modifiers = MWKMOD_LSHIFT | MWKMOD_RSHIFT | MWKMOD_LCTRL | MWKMOD_RCTRL | MWKMOD_LALT | MWKMOD_RALT | MWKMOD_LMETA | MWKMOD_RMETA | MWKMOD_NUM | MWKMOD_CAPS | MWKMOD_ALTGR | MWKMOD_SCR; } if (NULL != curmodifiers) { *modifiers = ps2kbd_current_modifiers; }}// Note: it is assumed that there are no concurrent calls to// the poll and read functions.static intPS2Kbd_Poll(void){ if (MWKEY_UNKNOWN == ps2kbd_current_key) { ps2kbd_process_scancodes(); } return MWKEY_UNKNOWN != ps2kbd_current_key;}// Return -1 on error, 0 for no data, 1 for a keypress, 2 for a keyrelease.static intPS2Kbd_Read(MWKEY* buf, MWKEYMOD* modifiers, MWSCANCODE* scancode){ if (MWKEY_UNKNOWN == ps2kbd_current_key) { ps2kbd_process_scancodes(); if (MWKEY_UNKNOWN == ps2kbd_current_key) { return 0; } } if (NULL != buf) { *buf = ps2kbd_current_key; } if (NULL != modifiers) { *modifiers = ps2kbd_current_modifiers; } if (NULL != scancode) { *scancode = ps2kbd_current_scancode; } ps2kbd_current_key = MWKEY_UNKNOWN; return ps2kbd_current_keydown ? 1 : 2;}KBDDEVICE kbddev = { PS2Kbd_Open, PS2Kbd_Close, PS2Kbd_GetModifierInfo, PS2Kbd_Read, PS2Kbd_Poll};#if 0// ----------------------------------------------------------------------------// This code can be used for testing the mouse and keyboard without all// of microwindows present (although the microwindows headers must still be// visible).#include <stdio.h>#include <ctype.h>intmain(int argc, char** argv){ PS2Kbd_Open(&kbddev); PS2Mouse_Open(&mousedev); for ( ; ; ) { while (PS2Mouse_Poll()) { MWCOORD dx, dy, dz; int buttons; PS2Mouse_Read(&dx, &dy, &dz, &buttons); printf("Mouse movement: dx %d, dy %d, dz %d, buttons 0x%02x\n", dx, dy, dz, buttons); } while (PS2Kbd_Poll()) { MWKEY key; MWKEYMOD modifiers; MWSCANCODE scancode; int which; which = PS2Kbd_Read(&key, &modifiers, &scancode); printf("Keyboard event: %s, key %c (%d) (0x%02x), modifiers 0x%02x, scancode %d (0x%02x)\n", (1 == which) ? "press" : "release", isprint(key) ? key : '?', key, key, modifiers, scancode, scancode); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -