Esempio n. 1
0
  // ----------------------------------------------------------------------
  void
  EventInputQueue::push_KeyboardSpecialEventCallback(OSObject* target,
                                                     unsigned int eventType,
                                                     unsigned int flags,
                                                     unsigned int key,
                                                     unsigned int flavor,
                                                     UInt64 guid,
                                                     bool repeat,
                                                     AbsoluteTime ts,
                                                     OSObject* sender,
                                                     void* refcon)
  {
    IOLockWrapper::ScopedLock lk_eventlock(CommonData::getEventLock());
    if (! lk_eventlock) return;
    IOLockWrapper::ScopedLock lk(timer_.getlock());
    if (! lk) return;

    // ------------------------------------------------------------
    Params_KeyboardSpecialEventCallback::auto_ptr ptr(Params_KeyboardSpecialEventCallback::alloc(EventType(eventType), Flags(flags), ConsumerKeyCode(key),
                                                                                                 flavor, guid, repeat));
    if (! ptr) return;
    Params_KeyboardSpecialEventCallback& params = *ptr;

    // ------------------------------------------------------------
    DeviceVendor deviceVendor(0);
    DeviceProduct deviceProduct(0);
    {
      IOLockWrapper::ScopedLock lk_device(ListHookedKeyboard::instance().getListLock());
      if (! lk_device) return;

      IOHIKeyboard* device = OSDynamicCast(IOHIKeyboard, sender);
      if (! device) return;

      ListHookedConsumer::Item* item = static_cast<ListHookedConsumer::Item*>(ListHookedConsumer::instance().get_nolock(device));

      // ------------------------------------------------------------
      CommonData::setcurrent_ts(ts);
      deviceVendor = item->getVendor();
      deviceProduct = item->getProduct();
    }

    // ------------------------------------------------------------
    // Because we handle the key repeat ourself, drop the key repeat by hardware.
    if (repeat) return;

    // ------------------------------------------------------------
    bool retainFlagStatusTemporaryCount = false;
    bool updateWorkspaceData = params.ex_iskeydown;
    enqueue_(params, retainFlagStatusTemporaryCount, updateWorkspaceData, deviceVendor, deviceProduct);

    setTimer();
  }
  // ----------------------------------------------------------------------
  void
  EventInputQueue::push_RelativePointerEventCallback(OSObject* target,
                                                     int buttons_raw,
                                                     int dx,
                                                     int dy,
                                                     AbsoluteTime ts,
                                                     OSObject* sender,
                                                     void* refcon)
  {
    IOLockWrapper::ScopedLock lk_eventlock(CommonData::getEventLock());
    if (! lk_eventlock) return;
    IOLockWrapper::ScopedLock lk(timer_.getlock());
    if (! lk) return;

    // ------------------------------------------------------------
    Buttons buttons(buttons_raw);
    Buttons justPressed;
    Buttons justReleased;

    DeviceVendor deviceVendor(0);
    DeviceProduct deviceProduct(0);
    {
      IOLockWrapper::ScopedLock lk_device(ListHookedKeyboard::instance().getListLock());
      if (! lk_device) return;

      IOHIPointing* device = OSDynamicCast(IOHIPointing, sender);
      if (! device) return;

      ListHookedPointing::Item* item = static_cast<ListHookedPointing::Item*>(ListHookedPointing::instance().get_nolock(device));
      if (! item) return;

      // ------------------------------------------------------------
      CommonData::setcurrent_ts(ts);
      deviceVendor = item->getVendor();
      deviceProduct = item->getProduct();

      // ------------------------------------------------------------
      justPressed = buttons.justPressed(item->get_previousbuttons());
      justReleased = buttons.justReleased(item->get_previousbuttons());
      item->set_previousbuttons(buttons);
    }

    // ------------------------------------------------------------
    // divide an event into button and cursormove events.
    for (int i = 0; i < ButtonStatus::MAXNUM; ++i) {
      PointingButton btn(1 << i);
      if (justPressed.isOn(btn)) {
        Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(buttons, 0, 0, btn, true));
        if (! ptr) return;
        bool retainFlagStatusTemporaryCount = Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_lazy_modifiers_with_mouse_event);
        enqueue_(*ptr, retainFlagStatusTemporaryCount, deviceVendor, deviceProduct);
      }
      if (justReleased.isOn(btn)) {
        Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(buttons, 0, 0, btn, false));
        if (! ptr) return;
        bool retainFlagStatusTemporaryCount = Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_lazy_modifiers_with_mouse_event);
        enqueue_(*ptr, retainFlagStatusTemporaryCount, deviceVendor, deviceProduct);
      }
    }
    Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(buttons, dx, dy, PointingButton::NONE, false));
    if (! ptr) return;
    bool retainFlagStatusTemporaryCount = true;
    enqueue_(*ptr, retainFlagStatusTemporaryCount, deviceVendor, deviceProduct);

    setTimer();
  }
  // ======================================================================
  void
  EventInputQueue::push_KeyboardEventCallback(OSObject* target,
                                              unsigned int eventType,
                                              unsigned int flags,
                                              unsigned int key,
                                              unsigned int charCode,
                                              unsigned int charSet,
                                              unsigned int origCharCode,
                                              unsigned int origCharSet,
                                              unsigned int keyboardType,
                                              bool repeat,
                                              AbsoluteTime ts,
                                              OSObject* sender,
                                              void* refcon)
  {
    IOLockWrapper::ScopedLock lk_eventlock(CommonData::getEventLock());
    if (! lk_eventlock) return;
    IOLockWrapper::ScopedLock lk(timer_.getlock());
    if (! lk) return;

    // ------------------------------------------------------------
    KeyboardType newkeyboardtype(keyboardType);
    RemapClassManager::remap_setkeyboardtype(newkeyboardtype);

    KeyCode newkey(key);
    Flags newflags(flags);
    KeyCode::normalizeKey(newkey, newflags, EventType(eventType), newkeyboardtype);

    // ------------------------------------------------------------
    Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType(eventType),
                                                                                   newflags,
                                                                                   newkey,
                                                                                   CharCode(charCode),
                                                                                   CharSet(charSet),
                                                                                   OrigCharCode(origCharCode),
                                                                                   OrigCharSet(origCharSet),
                                                                                   newkeyboardtype,
                                                                                   repeat));
    if (! ptr) return;
    Params_KeyboardEventCallBack& params = *ptr;

    // ------------------------------------------------------------
    DeviceVendor deviceVendor(0);
    DeviceProduct deviceProduct(0);
    {
      IOLockWrapper::ScopedLock lk_device(ListHookedKeyboard::instance().getListLock());
      if (! lk_device) return;

      IOHIKeyboard* device = OSDynamicCast(IOHIKeyboard, sender);
      if (! device) return;

      ListHookedKeyboard::Item* item = static_cast<ListHookedKeyboard::Item*>(ListHookedKeyboard::instance().get_nolock(device));
      if (! item) return;

      // ------------------------------------------------------------
      // Logitech Cordless Presenter (LCP) Hack
      //
      // When an LCP is first plugged in, it will send a CONTROL_L down event
      // when the first pageup/pagedown key is pressed without sending a corresponding
      // up event -- effectively rendering the device (and the Mac) useless until it is
      // unplugged from the system.
      //
      // Similarly, when the volume keys are first pressed, a SHIFT_L down event
      // is generated, with now up event.
      //
      // This code effectively throws these events away if they are received from an LCP.
      //
      // *** LCP has 6 keys (Page Up, Page Down, a 'B' key, an 'Esc' key, and volume up / down keys). ***
      // *** So, we can drop CONTROL_L and SHIFT_L without a problem. ***
      if (item->isEqualVendorProduct(DeviceVendor::LOGITECH, DeviceProduct::LOGITECH_CORDLESS_PRESENTER)) {
        if (params.key == KeyCode::CONTROL_L) return;
        if (params.key == KeyCode::SHIFT_L) return;
      }

      // ------------------------------------------------------------
      // "ts & keyboardType" are not used in filters like <not>/<only>.
      // Therefore, we can set current ts and keyboardType here.
      CommonData::setcurrent_ts(ts);
      CommonData::setcurrent_keyboardType(params.keyboardType);
      deviceVendor = item->getVendor();
      deviceProduct = item->getProduct();
    }

    // ------------------------------------------------------------
    // Because we handle the key repeat ourself, drop the key repeat by hardware.
    if (repeat) return;

    // ------------------------------------------------------------
    bool retainFlagStatusTemporaryCount = false;
    bool push_back = true;
    enqueue_(params, retainFlagStatusTemporaryCount, deviceVendor, deviceProduct, push_back);

    setTimer();
  }