void KeyboardRepeat::fire_timer_callback(OSObject* owner, IOTimerEventSource* sender) { IOLOG_DEVEL("KeyboardRepeat::fire queue_.size = %d\n", static_cast<int>(queue_.size())); // ---------------------------------------- for (KeyboardRepeat::Item* p = static_cast<KeyboardRepeat::Item*>(queue_.safe_front()); p; p = static_cast<KeyboardRepeat::Item*>(p->getnext())) { { { auto params = (p->getParamsBase()).get_Params_KeyboardEventCallBack(); if (params) { EventOutputQueue::FireKey::fire( Params_KeyboardEventCallBack( params->eventType, params->flags, params->key, params->keyboardType, queue_.size() == 1 ? true : false)); } } { auto params = (p->getParamsBase()).get_Params_KeyboardSpecialEventCallback(); if (params) { EventOutputQueue::FireConsumer::fire( Params_KeyboardSpecialEventCallback( params->eventType, params->flags, params->key, queue_.size() == 1 ? true : false)); } } { auto params = (p->getParamsBase()).get_Params_RelativePointerEventCallback(); if (params) { EventOutputQueue::FireRelativePointer::fire(params->buttons, params->dx, params->dy); } } } } fire_timer_.setTimeoutMS(keyRepeat_); }
void KeyboardRepeat::set(EventType eventType, Flags flags, KeyCode key, KeyboardType keyboardType, int delayUntilRepeat, int keyRepeat) { if (key == KeyCode::VK_NONE) return; if (eventType == EventType::MODIFY) { goto cancel; } else if (eventType == EventType::UP) { // The repetition of plural keys is controlled by manual operation. // So, we ignore it. if (queue_.size() != 1) return; // We stop key repeat only when the repeating key is up. KeyboardRepeat::Item* p = static_cast<KeyboardRepeat::Item*>(queue_.safe_front()); if (p) { auto params = (p->getParamsBase()).get_Params_KeyboardEventCallBack(); if (params && key == params->key) { goto cancel; } } } else if (eventType == EventType::DOWN) { cancel(); primitive_add(eventType, flags, key, keyboardType); primitive_start(delayUntilRepeat, keyRepeat); IOLOG_DEVEL("KeyboardRepeat::set key:%d flags:0x%x\n", key.get(), flags.get()); } else { goto cancel; } return; cancel: cancel(); }