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::fire_timer_callback(OSObject* owner, IOTimerEventSource* sender)
  {
    if (! queue_) return;

    IOLOG_DEVEL("KeyboardRepeat::fire queue_->size = %d\n", static_cast<int>(queue_->size()));

    // ----------------------------------------
    for (KeyboardRepeat::Item* p = static_cast<KeyboardRepeat::Item*>(queue_->front()); p; p = static_cast<KeyboardRepeat::Item*>(p->getnext())) {
      switch ((p->params).type) {
        case ParamsUnion::KEYBOARD:
        {
          Params_KeyboardEventCallBack* params = (p->params).params.params_KeyboardEventCallBack;
          if (params) {
            switch (p->type) {
              case Item::TYPE_NORMAL:
              {
                Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(params->eventType,
                                                                                               params->flags,
                                                                                               params->key,
                                                                                               params->keyboardType,
                                                                                               queue_->size() == 1 ? true : false));
                if (ptr) {
                  EventOutputQueue::FireKey::fire(*ptr);
                }
                break;
              }

              case Item::TYPE_DOWNUP:
              {
                EventOutputQueue::FireKey::fire_downup(params->flags,
                                                       params->key,
                                                       params->keyboardType);
                break;
              }
            }
          }
          break;
        }

        case ParamsUnion::KEYBOARD_SPECIAL:
        {
          Params_KeyboardSpecialEventCallback* params = (p->params).params.params_KeyboardSpecialEventCallback;
          if (params) {
            Params_KeyboardSpecialEventCallback::auto_ptr ptr(Params_KeyboardSpecialEventCallback::alloc(params->eventType,
                                                                                                         params->flags,
                                                                                                         params->key,
                                                                                                         queue_->size() == 1 ? true : false));
            if (ptr) {
              EventOutputQueue::FireConsumer::fire(*ptr);
            }
          }
          break;
        }

        case ParamsUnion::UPDATE_FLAGS:
        case ParamsUnion::RELATIVE_POINTER:
        case ParamsUnion::SCROLL_WHEEL:
        case ParamsUnion::WAIT:
          // do nothing
          break;
      }
    }

    fire_timer_.setTimeoutMS(keyRepeat_);
  }