bool PointingRelativeToScroll::remap(RemapPointingParams_relative& remapParams) { bool active = fromkeychecker_.isactive(); if (remapParams.isremapped) return false; if (fromButton_ == PointingButton::NONE) { if (! FlagStatus::makeFlags().isOn(fromFlags_)) return false; } else { if (! fromkeychecker_.isFromPointingButton(remapParams.params, fromButton_, fromFlags_) && ! active) return false; } remapParams.isremapped = true; if (fromButton_ == PointingButton::NONE) { goto doremap; } // first time if (! active) { // if the source buttons contains left button, we cancel left click for iPhoto, or some applications. // iPhoto store the scroll events when left button is pressed, and restore events after left button is released. // PointingRelativeToScroll doesn't aim it, we release the left button and do normal scroll event. ButtonStatus::decrease(fromButton_); EventOutputQueue::FireRelativePointer::fire(); ButtonStatus::increase(fromButton_); absolute_distance_ = 0; begin_ic_.begin(); chained_ic_.begin(); chained_delta1_ = 0; chained_delta2_ = 0; goto doremap; } // last time if (! fromkeychecker_.isactive()) { cancelScroll(); const uint32_t DISTANCE_THRESHOLD = 5; const uint32_t TIME_THRESHOLD = 300; if (absolute_distance_ <= DISTANCE_THRESHOLD && begin_ic_.getmillisec() < TIME_THRESHOLD) { // Fire by a click event. ButtonStatus::increase(fromButton_); EventOutputQueue::FireRelativePointer::fire(); ButtonStatus::decrease(fromButton_); EventOutputQueue::FireRelativePointer::fire(); } return true; } doremap: // We need to call EventWatcher::on here. // See the comments in EventInputQueue::fire_timer_callback. EventWatcher::on(); toscroll(remapParams); return true; }
void PointingRelativeToScroll::toscroll(RemapPointingParams_relative& remapParams) { if (! queue_) return; // ---------------------------------------- const uint32_t CANCEL_THRESHOLD = 100; if (chained_ic_.getmillisec() > CANCEL_THRESHOLD) { chained_delta1_ = 0; chained_delta2_ = 0; cancelScroll(); } int delta1 = -remapParams.params.dy; int delta2 = -remapParams.params.dx; chained_ic_.begin(); // ---------------------------------------- if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_option_pointing_disable_vertical_scroll)) delta1 = 0; if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_option_pointing_disable_horizontal_scroll)) delta2 = 0; // ---------------------------------------- // ignore minuscule move const unsigned int abs1 = abs(delta1); const unsigned int abs2 = abs(delta2); if (abs1 > abs2 * 2) { delta2 = 0; } if (abs2 > abs1 * 2) { delta1 = 0; } // ---------------------------------------- // Fixation processing if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_option_pointing_enable_scrollwheel_fixation)) { // When 300ms passes from the last event, we reset a value. const uint32_t FIXATION_MILLISEC = 300; if (fixation_ic_.getmillisec() > FIXATION_MILLISEC) { fixation_begin_ic_.begin(); fixation_delta1_ = 0; fixation_delta2_ = 0; } fixation_ic_.begin(); if (fixation_delta1_ > fixation_delta2_ * 2) { delta2 = 0; } if (fixation_delta2_ > fixation_delta1_ * 2) { delta1 = 0; } // Only first 1000ms performs the addition of fixation_delta1, fixation_delta2. const uint32_t FIXATION_EARLY_MILLISEC = 1000; if (fixation_begin_ic_.getmillisec() < FIXATION_EARLY_MILLISEC) { if (delta1 == 0) fixation_delta2_ += abs2; if (delta2 == 0) fixation_delta1_ += abs1; } } // ------------------------------------------------------------ // when sign is different if (0 > delta1 * chained_delta1_ || 0 > delta2 * chained_delta2_) { queue_->clear(); chained_delta1_ = delta1; chained_delta2_ = delta2; } else if (abs(delta1) > abs(chained_delta1_) || abs(delta2) > abs(chained_delta2_)) { // greater delta. chained_delta1_ = delta1; chained_delta2_ = delta2; } absolute_distance_ += abs(chained_delta1_) + abs(chained_delta2_); queue_->push_back(new Item(chained_delta1_ * EventOutputQueue::FireScrollWheel::DELTA_SCALE, chained_delta2_ * EventOutputQueue::FireScrollWheel::DELTA_SCALE)); currentFromFlags_ = fromFlags_; timer_.setTimeoutMS(SCROLL_INTERVAL_MS, false); }
bool PointingRelativeToScroll::remap(RemapParams& remapParams) { // ------------------------------------------------------------ // PointingRelativeToScroll grabs all pointing movement events. // Therefore, if user write inappropriate <autogen> (empty flags and empty buttons), // user cannot control pointing device at all. // // For example: // <autogen>__PointingRelativeToScroll__ PointingButton::LEFT | PointingButton::RIGHT</autogen> // // (Buttons(LEFT | RIGHT) will be ignored. So, this autogen is interpreted as // <autogen>__PointingRelativeToScroll__</autogen>.) // // Skip on error in order to avoid this situation. if (fromEvent_.getType() == FromEvent::Type::NONE && fromFlags_ == Flags(0)) { IOLOG_WARN("Ignore __PointingRelativeToScroll__ with no option. " "Please use \"__PointingRelativeToScroll__ PointingButton::NONE\".\n"); return false; } // ------------------------------------------------------------ if (remapParams.isremapped) return false; bool useFromEvent = true; if (fromEvent_.getType() == FromEvent::Type::NONE) { useFromEvent = false; } if (fromEvent_.getType() == FromEvent::Type::POINTING_BUTTON && fromEvent_.getPointingButton() == PointingButton::NONE) { useFromEvent = false; } if (! useFromEvent) { if (! FlagStatus::makeFlags().isOn(fromFlags_)) return false; goto doremap; } else { // FromEvent == KeyCode or ConsumerKeyCode or PointingButton. bool pressingStateChanged = fromEvent_.changePressingState(remapParams.paramsUnion, FlagStatus::makeFlags(), fromFlags_); if (pressingStateChanged) { if (fromEvent_.isPressing()) { // down event FlagStatus::decrease(fromEvent_.getModifierFlag()); ButtonStatus::decrease(fromEvent_.getPointingButton()); absolute_distance_ = 0; begin_ic_.begin(); chained_ic_.begin(); chained_delta1_ = 0; chained_delta2_ = 0; } else { // up event FlagStatus::increase(fromEvent_.getModifierFlag()); ButtonStatus::increase(fromEvent_.getPointingButton()); cancelScroll(); const uint32_t DISTANCE_THRESHOLD = 5; const uint32_t TIME_THRESHOLD = 300; if (absolute_distance_ <= DISTANCE_THRESHOLD && begin_ic_.getmillisec() < TIME_THRESHOLD) { // Fire by a click event. if (isToKeysDefined_) { keytokey_.call_remap_with_VK_PSEUDO_KEY(EventType::DOWN); keytokey_.call_remap_with_VK_PSEUDO_KEY(EventType::UP); } else { toEvent_.fire_downup(FlagStatus::makeFlags()); } } } // ignore this event. goto returntrue; } else { if (! fromEvent_.isPressing()) { return false; } } } doremap: // change only cursor move events. { Params_RelativePointerEventCallback* params = remapParams.paramsUnion.get_Params_RelativePointerEventCallback(); if (! params) return false; if (params->ex_button != PointingButton::NONE) return false; } // We need to call EventWatcher::on here. // See the comments in EventInputQueue::fire_timer_callback. EventWatcher::on(); toscroll(remapParams); returntrue: remapParams.isremapped = true; return true; }