static int32 debug_keyboard_interrupt(void *data) { static bool controlPressed = false; static bool altPressed = false; static bool sysReqPressed = false; uint8 key; key = in8(PS2_PORT_DATA); //dprintf("debug_keyboard_interrupt: key = 0x%x\n", key); if (key & 0x80) { if (key == LEFT_CONTROL) controlPressed = false; else if (key == LEFT_ALT) altPressed = false; else if (key == SYS_REQ) sysReqPressed = false; return B_HANDLED_INTERRUPT; } switch (key) { case LEFT_CONTROL: controlPressed = true; break; case LEFT_ALT: case RIGHT_ALT: altPressed = true; break; case SYS_REQ: sysReqPressed = true; break; case DELETE: if (controlPressed && altPressed) arch_cpu_shutdown(true); break; default: if (altPressed && sysReqPressed) { if (debug_emergency_key_pressed(kUnshiftedKeymap[key])) { // we probably have lost some keys, so reset our key states controlPressed = false; sysReqPressed = false; altPressed = false; } } break; } return B_HANDLED_INTERRUPT; }
static int32 keyboard_handle_int(ps2_dev *dev) { enum emergency_keys { EMERGENCY_LEFT_ALT = 0x01, EMERGENCY_RIGHT_ALT = 0x02, EMERGENCY_SYS_REQ = 0x04, }; static int emergencyKeyStatus = 0; raw_key_info keyInfo; uint8 scancode = dev->history[0].data; if (atomic_get(&sKeyboardOpenCount) == 0) return B_HANDLED_INTERRUPT; // TODO: Handle braindead "pause" key special case if (scancode == EXTENDED_KEY) { sIsExtended = true; // TRACE("Extended key\n"); return B_HANDLED_INTERRUPT; } // TRACE("scancode: %x\n", scancode); if ((scancode & 0x80) != 0) { keyInfo.is_keydown = false; scancode &= 0x7f; } else keyInfo.is_keydown = true; if (sIsExtended) { scancode |= 0x80; sIsExtended = false; } // Handle emergency keys if (scancode == LEFT_ALT_KEY || scancode == RIGHT_ALT_KEY) { // left or right alt-key pressed if (keyInfo.is_keydown) { emergencyKeyStatus |= scancode == LEFT_ALT_KEY ? EMERGENCY_LEFT_ALT : EMERGENCY_RIGHT_ALT; } else { emergencyKeyStatus &= ~(scancode == LEFT_ALT_KEY ? EMERGENCY_LEFT_ALT : EMERGENCY_RIGHT_ALT); } } else if (scancode == SYS_REQ_KEY) { if (keyInfo.is_keydown) emergencyKeyStatus |= EMERGENCY_SYS_REQ; else emergencyKeyStatus &= EMERGENCY_SYS_REQ; } else if (emergencyKeyStatus > EMERGENCY_SYS_REQ && debug_emergency_key_pressed(kUnshiftedKeymap[scancode])) { static const int kKeys[] = {LEFT_ALT_KEY, RIGHT_ALT_KEY, SYS_REQ_KEY}; // we probably have lost some keys, so reset our key states emergencyKeyStatus = 0; // send key ups for alt-sysreq keyInfo.timestamp = system_time(); keyInfo.is_keydown = false; for (size_t i = 0; i < sizeof(kKeys) / sizeof(kKeys[0]); i++) { keyInfo.keycode = kATKeycodeMap[kKeys[i] - 1]; if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo)) != 0) release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE); } return B_HANDLED_INTERRUPT; } keyInfo.timestamp = dev->history[0].time; keyInfo.keycode = kATKeycodeMap[scancode - 1]; if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo)) == 0) { // If there is no space left in the buffer, we drop this key stroke. We // avoid dropping old key strokes, to not destroy what already was // typed. return B_HANDLED_INTERRUPT; } release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE); return B_INVOKE_SCHEDULER; }