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;
}
Пример #2
0
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;
}