Example #1
0
void org_pqrs_driver_NoEjectDelay::stop(IOService* provider) {
  IOLOG_INFO("stop\n");

  // ----------------------------------------
  org_pqrs_NoEjectDelay::GlobalLock::terminate();

  // ----------------------------------------
  if (timerEventSource_) {
    if (workLoop_) {
      workLoop_->removeEventSource(timerEventSource_);
    }

    timerEventSource_->release();
    timerEventSource_ = NULL;
  }

  if (workLoop_) {
    workLoop_->release();
    workLoop_ = NULL;
  }

  // ----------------------------------------
  if (notifier_hookKeyboard_) { notifier_hookKeyboard_->remove(); }
  if (notifier_unhookKeyboard_) { notifier_unhookKeyboard_->remove(); }
  if (notifier_hookEventService_) { notifier_hookEventService_->remove(); }
  if (notifier_unhookEventService_) { notifier_unhookEventService_->remove(); }

  super::stop(provider);
}
Example #2
0
// ----------------------------------------
bool org_pqrs_driver_NoEjectDelay::IOHIKeyboard_gIOMatchedNotification_callback(void* target, void* refCon, IOService* newService, IONotifier* notifier) {
  org_pqrs_NoEjectDelay::GlobalLock::ScopedLock lk;
  if (!lk) return false;

  // ----------------------------------------
  org_pqrs_driver_NoEjectDelay* self = reinterpret_cast<org_pqrs_driver_NoEjectDelay*>(target);
  if (!self) return false;

  if (!newService) return false;

  // ----------------------------------------
  const char* name = newService->getName();
  const char* pname = getProductPropertyCStringNoCopy(newService);
  if (name && pname) {
    IOLOG_INFO("device: %s (%s)\n", pname, name);
  }

  // ----------------------------------------
  for (int i = 0; i < MAXNUM_DEVICES; ++i) {
    if (!self->devices_[i]) {
      self->devices_[i] = newService;
      return true;
    }
  }

  IOLOG_WARN("There is no space for the new device. Please increase MAXNUM_DEVICES.\n");
  return true;
}
Example #3
0
bool org_pqrs_driver_Seil::start(IOService* provider) {
    IOLOG_INFO("start\n");

    bool res = super::start(provider);
    if (!res) {
        return res;
    }

    org_pqrs_Seil::GlobalLock::initialize();

    notifier_hookKeyboard_ = addMatchingNotification(gIOMatchedNotification,
                             serviceMatching("IOHIKeyboard"),
                             org_pqrs_driver_Seil::IOHIKeyboard_gIOMatchedNotification_callback,
                             this, nullptr, 0);
    if (notifier_hookKeyboard_ == nullptr) {
        IOLOG_ERROR("initialize_notification notifier_hookKeyboard_ == nullptr\n");
        return false;
    }

    notifier_unhookKeyboard_ = addMatchingNotification(gIOTerminatedNotification,
                               serviceMatching("IOHIKeyboard"),
                               org_pqrs_driver_Seil::IOHIKeyboard_gIOTerminatedNotification_callback,
                               this, nullptr, 0);
    if (notifier_unhookKeyboard_ == nullptr) {
        IOLOG_ERROR("initialize_notification notifier_unhookKeyboard_ == nullptr\n");
        return false;
    }

    // Publish ourselves so clients can find us
    registerService();

    return res;
}
Example #4
0
bool org_pqrs_driver_NoEjectDelay::start(IOService* provider) {
  IOLOG_INFO("start\n");

  bool res = super::start(provider);
  if (!res) { return res; }

  // ----------------------------------------
  org_pqrs_NoEjectDelay::GlobalLock::initialize();

  // ----------------------------------------
  notifier_hookKeyboard_ = addMatchingNotification(gIOMatchedNotification,
                                                   serviceMatching("IOHIKeyboard"),
                                                   org_pqrs_driver_NoEjectDelay::IOHIKeyboard_gIOMatchedNotification_callback,
                                                   this, NULL, 0);
  if (notifier_hookKeyboard_ == NULL) {
    IOLOG_ERROR("initialize_notification notifier_hookKeyboard_ == NULL\n");
    return false;
  }

  notifier_unhookKeyboard_ = addMatchingNotification(gIOTerminatedNotification,
                                                     serviceMatching("IOHIKeyboard"),
                                                     org_pqrs_driver_NoEjectDelay::IOHIKeyboard_gIOTerminatedNotification_callback,
                                                     this, NULL, 0);
  if (notifier_unhookKeyboard_ == NULL) {
    IOLOG_ERROR("initialize_notification notifier_unhookKeyboard_ == NULL\n");
    return false;
  }

  notifier_hookEventService_ = addMatchingNotification(gIOMatchedNotification,
                                                       serviceMatching("IOHIDEventService"),
                                                       org_pqrs_driver_NoEjectDelay::IOHIKeyboard_gIOMatchedNotification_callback,
                                                       this, NULL, 0);
  if (notifier_hookEventService_ == NULL) {
    IOLOG_ERROR("initialize_notification notifier_hookEventService_ == NULL\n");
    return false;
  }

  notifier_unhookEventService_ = addMatchingNotification(gIOTerminatedNotification,
                                                         serviceMatching("IOHIDEventService"),
                                                         org_pqrs_driver_NoEjectDelay::IOHIKeyboard_gIOTerminatedNotification_callback,
                                                         this, NULL, 0);
  if (notifier_unhookEventService_ == NULL) {
    IOLOG_ERROR("initialize_notification notifier_unhookEventService_ == NULL\n");
    return false;
  }

  // ----------------------------------------
  workLoop_ = IOWorkLoop::workLoop();
  if (!workLoop_) return false;

  timerEventSource_ = IOTimerEventSource::timerEventSource(this, timer_callback);
  if (!timerEventSource_) return false;

  if (workLoop_->addEventSource(timerEventSource_) != kIOReturnSuccess) return false;

  timerEventSource_->setTimeoutMS(TIMER_INTERVAL_MS);

  // ----------------------------------------
  return res;
}
Example #5
0
// ----------------------------------------------------------------------
bool
org_pqrs_driver_Karabiner::init(OSDictionary* dict)
{
  IOLOG_INFO("init\n");

  bool res = super::init(dict);
  return res;
}
Example #6
0
void
org_pqrs_driver_NoEjectDelay::timer_callback(OSObject* target, IOTimerEventSource* sender)
{
  org_pqrs_NoEjectDelay::GlobalLock::ScopedLock lk;
  if (! lk) return;

  // ----------------------------------------
  org_pqrs_driver_NoEjectDelay* self = OSDynamicCast(org_pqrs_driver_NoEjectDelay, target);
  if (! self) return;

  // ----------------------------------------
  // supportsF12Eject becomes true when user logged in even if supportsF12Eject is false.
  // Therefore, we need to overwrite this value from timer.

  for (int i = 0; i < MAXNUM_DEVICES; ++i) {
    if (! self->devices_[i]) continue;

    // set Eject delay.
    {
      {
        IOHIDConsumer* consumer = OSDynamicCast(IOHIDConsumer, self->devices_[i]);
        if (consumer) {
          // We are using private header of IOHIDConsumer.
          // So, we need to check "consumer->_provider is IOHIDEventService" by OSDynamicCast.
          IOHIDEventService* service = OSDynamicCast(IOHIDEventService, consumer->_provider);
          setEjectDelayMS(service);
        }
      }
      {
        IOHIDKeyboard* keyboard = OSDynamicCast(IOHIDKeyboard, self->devices_[i]);
        if (keyboard) {
          // Like above, we need to check _provider.
          IOHIDEventService* service = OSDynamicCast(IOHIDEventService, keyboard->_provider);
          setEjectDelayMS(service);
        }
      }
    }

    // disable F12Eject
    {
      IOHIKeyboard* keyboard = OSDynamicCast(IOHIKeyboard, self->devices_[i]);
      if (keyboard) {
        IOHIKeyboardMapper* mapper = OSDynamicCast(IOHIKeyboardMapper, keyboard->_keyMap);
        if (mapper &&
            mapper->_reserved &&
            mapper->_reserved->supportsF12Eject != 0) {
          IOLOG_INFO("Unset supportsF12Eject\n");
          mapper->_reserved->supportsF12Eject = 0;
        }
      }
    }
  }

  if (sender) {
    sender->setTimeoutMS(TIMER_INTERVAL_MS);
  }
}
Example #7
0
// ----------------------------------------------------------------------
bool org_pqrs_driver_Seil::init(OSDictionary* dict) {
  IOLOG_INFO("init %s\n", ostype);

  bool res = super::init(dict);

  memset(&configuration_, 0, sizeof(configuration_));

  return res;
}
Example #8
0
 void
 RemapClass::log_allocation_count(void)
 {
   IOLOG_INFO("RemapClass::allocation_count_ %d/%d (memory usage: %d%% of %dKB)\n",
              allocation_count_,
              MAX_ALLOCATION_COUNT,
              allocation_count_ * 100 / MAX_ALLOCATION_COUNT,
              static_cast<int>(MAX_ALLOCATION_COUNT * sizeof(uint32_t) / 1024));
 }
Example #9
0
void org_pqrs_driver_NoEjectDelay::setEjectDelayMS(IOHIDEventService* service) {
  if (!service) return;
  if (!service->_reserved) return;

  const int DELAY = 5;
  if ((service->_reserved->keyboard).eject.delayMS != DELAY) {
    IOLOG_INFO("Set eject.delayMS\n");
    (service->_reserved->keyboard).eject.delayMS = DELAY;
  }
}
Example #10
0
void
org_pqrs_driver_Karabiner::stop(IOService* provider)
{
  IOLOG_INFO("stop\n");

  terminate_notification();
  org_pqrs_Karabiner::Core::stop();

  super::stop(provider);
}
Example #11
0
// ----------------------------------------------------------------------
bool org_pqrs_driver_Seil::init(OSDictionary* dict) {
    IOLOG_INFO("init %s\n", ostype);

    bool res = super::init(dict);

    memset(&configuration_, 0, sizeof(configuration_));
    notifier_hookKeyboard_ = nullptr;
    notifier_unhookKeyboard_ = nullptr;

    return res;
}
Example #12
0
// ----------------------------------------------------------------------
bool org_pqrs_driver_NoEjectDelay::init(OSDictionary* dict) {
  IOLOG_INFO("init %s\n", NoEjectDelay_version);

  notifier_hookKeyboard_ = NULL;
  notifier_unhookKeyboard_ = NULL;
  workLoop_ = NULL;
  timerEventSource_ = NULL;
  for (int i = 0; i < MAXNUM_DEVICES; ++i) {
    devices_[i] = NULL;
  }

  return super::init(dict);
}
Example #13
0
void org_pqrs_driver_Seil::stop(IOService* provider) {
    IOLOG_INFO("stop\n");

    for (int i = 0; i < MAXNUM_KEYBOARD; ++i) {
        hookedKeyboard_[i].terminate();
    }

    if (notifier_hookKeyboard_) notifier_hookKeyboard_->remove();
    if (notifier_unhookKeyboard_) notifier_unhookKeyboard_->remove();

    org_pqrs_Seil::GlobalLock::terminate();

    super::stop(provider);
}
Example #14
0
bool
org_pqrs_driver_Karabiner::start(IOService* provider)
{
  IOLOG_INFO("start\n");

  bool res = super::start(provider);
  if (! res) return res;

  org_pqrs_Karabiner::Core::start();
  if (! initialize_notification()) return false;

  // Publish ourselves so clients can find us
  registerService();

  return res;
}
Example #15
0
// ----------------------------------------------------------------------
bool org_pqrs_driver_Seil::isTargetDevice(IOHIKeyboard* kbd) {
    if (!kbd) return false;

    // ------------------------------------------------------------
    uint32_t vendorID = 0;
    uint32_t productID = 0;

    IORegistryEntry* dev = kbd;

    while (dev) {
        const OSNumber* vid = nullptr;
        vid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDVendorIDKey));

        const OSNumber* pid = nullptr;
        pid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDProductIDKey));

        if (vid && pid) {
            vendorID = vid->unsigned32BitValue();
            productID = pid->unsigned32BitValue();

            goto finish;
        }

        // check parent property.
        dev = dev->getParentEntry(IORegistryEntry::getPlane(kIOServicePlane));
    }

finish:
    enum {
        VENDOR_LOGITECH = 0x046d,
        PRODUCT_LOGITECH_G700_LASER_MOUSE = 0xc06b,
    };

    if (vendorID == VENDOR_LOGITECH && productID == PRODUCT_LOGITECH_G700_LASER_MOUSE) {
        IOLOG_INFO("vendorID:0x%04x, productID:0x%04x (skipped)\n", vendorID, productID);
        return false;
    }

    return true;
}
Example #16
0
// ----------------------------------------------------------------------
void org_pqrs_driver_Seil::HookedKeyboard::initialize(IOHIKeyboard* p) {
    IOHIDKeyboard* hid = OSDynamicCast(IOHIDKeyboard, p);

    if (hid) {
        kbd_ = p;

        for (int i = 0; i < BRIDGE_KEY_INDEX__END__; ++i) {
            KeyMapIndex::Value idx = KeyMapIndex::bridgeKeyindexToValue(i);
            if (idx != KeyMapIndex::NONE) {
                originalKeyCode_[i] = hid->_usb_2_adb_keymap[idx];
            }
        }

#if 0
        // Dump _usb_2_adb_keymap
        for (size_t i = 0; i < sizeof(hid->_usb_2_adb_keymap) / sizeof(hid->_usb_2_adb_keymap[0]); ++i) {
            IOLOG_INFO("%d = %d\n", static_cast<int>(i), hid->_usb_2_adb_keymap[i]);
        }
#endif
    }

    refresh();
}
Example #17
0
void org_pqrs_driver_NoEjectDelay::free(void) {
  IOLOG_INFO("free\n");
  super::free();
}
Example #18
0
void
org_pqrs_driver_Karabiner::free(void)
{
  IOLOG_INFO("free\n");
  super::free();
}
 void
 RemapClass::log_allocation_count(void)
 {
   IOLOG_INFO("RemapClass::allocation_count_ %d/%d (capacity %d%%)\n", allocation_count_, MAX_ALLOCATION_COUNT, allocation_count_ * 100 / MAX_ALLOCATION_COUNT);
 }
Example #20
0
  RemapClass::RemapClass(const unsigned int* initialize_vector, bool enabledvalue) :
    statusmessage_(NULL),
    enabled_(enabledvalue),
    is_simultaneouskeypresses_(false)
  {
    // ------------------------------------------------------------
    // check parameters.
    //
#define CHECK_INITIALIZE_VECTOR {                                 \
    if (! initialize_vector) {                                    \
      IOLOG_ERROR("RemapClass::RemapClass invalid parameter.\n"); \
      return;                                                     \
    }                                                             \
}

    CHECK_INITIALIZE_VECTOR;

    // --------------------
    // check version
    unsigned int version = initialize_vector[0];
    ++initialize_vector;
    CHECK_INITIALIZE_VECTOR;

    if (version != BRIDGE_REMAPCLASS_INITIALIZE_VECTOR_FORMAT_VERSION) {
      IOLOG_INFO("RemapClass::RemapClass version mismatch.\n");
      return;
    }

    // ------------------------------------------------------------
    // initialize items_ from vector
    unsigned int total_length = initialize_vector[0];
    ++initialize_vector;
    CHECK_INITIALIZE_VECTOR;

    if (total_length == 0) return;

    if (allocation_count_ + total_length > MAX_ALLOCATION_COUNT) {
      IOLOG_ERROR("RemapClass::RemapClass too many allocation_count_.\n");
      return;
    }
    allocation_count_ += total_length;

    // --------------------
    unsigned int total_tmp = 0;
    for (;;) {
      unsigned int size = initialize_vector[0];
      ++initialize_vector;
      ++total_tmp;
      CHECK_INITIALIZE_VECTOR;

      // ----------------------------------------
      if (size > 0) {
        unsigned int type = initialize_vector[0];

        if (BRIDGE_REMAPTYPE_NONE < type && type < BRIDGE_REMAPTYPE_END) {
          Item* newp = new Item(initialize_vector, size);
          items_.push_back(newp);

          if (type == BRIDGE_REMAPTYPE_SIMULTANEOUSKEYPRESSES) {
            is_simultaneouskeypresses_ = true;
          }

        } else if (BRIDGE_FILTERTYPE_NONE < type && type < BRIDGE_FILTERTYPE_END) {
          if (items_.size() == 0) {
            IOLOG_ERROR("RemapClass::RemapClass invalid filter (%d).\n", type);
            return;
          }
          Item* p = items_.back();
          if (p) {
            p->append_filter(initialize_vector, size);
          }

        } else if (type == BRIDGE_STATUSMESSAGE) {
          if (statusmessage_) {
            delete[] statusmessage_;
          }
          statusmessage_ = new char[size];
          if (statusmessage_) {
            for (size_t i = 0; i < size - 1; ++i) {
              statusmessage_[i] = initialize_vector[i + 1];
            }
            statusmessage_[size - 1] = '\0';
          }

        } else if (type == BRIDGE_VK_CONFIG) {
          if (size == 5) {
            unsigned int keycode_toggle         = initialize_vector[1];
            unsigned int keycode_force_on       = initialize_vector[2];
            unsigned int keycode_force_off      = initialize_vector[3];
            unsigned int keycode_sync_keydownup = initialize_vector[4];
            Handle_VK_CONFIG::add_item(this,
                                       keycode_toggle,
                                       keycode_force_on,
                                       keycode_force_off,
                                       keycode_sync_keydownup);
          }

        } else {
          IOLOG_ERROR("RemapClass::RemapClass unknown type:%d.\n", type);
          return;
        }

        initialize_vector += size;
        total_tmp += size;
        CHECK_INITIALIZE_VECTOR;
      }

      // ----------------------------------------
      if (total_tmp == total_length) return;
      if (total_tmp > total_length) {
        IOLOG_ERROR("RemapClass::RemapClass invalid initialize_vector. (total_length:%d, total_tmp:%d)\n", total_length, total_tmp);
        return;
      }
    }
  }
Example #21
0
// ======================================================================
void EventInputQueue::fire_timer_callback(OSObject* /*notuse_owner*/, IOTimerEventSource* /*notuse_sender*/) {
  // IOLOG_DEVEL("EventInputQueue::fire queue_.size = %d\n", static_cast<int>(queue_.size()));

  // ------------------------------------------------------------
  // Ignore key bouncing (chattering).
  if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_ignore_bouncing_events)) {
  retry:
    for (Item* p = static_cast<Item*>(queue_.safe_front()); p; p = static_cast<Item*>(p->getnext())) {
      // Search key up, key down event.
      bool iskeydown;
      if (p->getParamsBase().iskeydown(iskeydown) && !iskeydown) {
        Item* keyUpEvent = p;

        FromEvent fromEvent(p->getParamsBase());

        for (Item* q = static_cast<Item*>(p->getnext()); q; q = static_cast<Item*>(q->getnext())) {
          if (fromEvent.isTargetUpEvent(q->getParamsBase())) {
            break;

          } else if (fromEvent.isTargetDownEvent(q->getParamsBase())) {
            Item* keyDownEvent = q;

            uint32_t ms1 = (keyUpEvent->ic).getmillisec();
            uint32_t ms2 = (keyDownEvent->ic).getmillisec();
            uint32_t interval = ms1 - ms2;

            uint32_t threshold = 0;
            switch (fromEvent.getType()) {
            case FromEvent::Type::KEY:
            case FromEvent::Type::CONSUMER_KEY:
              threshold = Config::get_ignore_bouncing_threshold_for_keyboard();
              break;
            case FromEvent::Type::POINTING_BUTTON:
              threshold = Config::get_ignore_bouncing_threshold_for_mice();
              break;
            case FromEvent::Type::NONE:
              break;
            }

            if (interval < threshold) {
              IOLOG_INFO("Bouncing events are removed. (interval: %d, threshold: %d)\n", interval, threshold);

              queue_.erase_and_delete(keyUpEvent);
              queue_.erase_and_delete(keyDownEvent);
              goto retry;

            } else {
              IOLOG_INFO("Bouncing events? (interval: %d, threshold: %d)\n", interval, threshold);
            }
          }
        }
      }
    }
  }

  // ------------------------------------------------------------
  // handle SimultaneousKeyPresses
  while (true) {
    Item* front = static_cast<Item*>(queue_.safe_front());
    if (!front) return;

    // ------------------------------------------------------------
    // clear temporary_count_
    //
    // Don't call FlagStatus::set(key, flags) here.
    // If SimultaneousKeyPresses is enabled, keys may be dropped.
    // For example, Shift_L+Shift_R to Space is enabled, Shift_L and Shift_R may be dropped.
    // If we call FlagStatus::set(key, flags) here, dropped keys are kept as pushed status.
    // So, call FlagStatus::set(key, flags) after EventInputQueue.
    // ------------------------------------------------------------
    if (!front->retainFlagStatusTemporaryCount) {
      FlagStatus::globalFlagStatus().set();
    }

    CommonData::setcurrent_deviceIdentifier(front->deviceIdentifier);
    {
      auto params = (front->getParamsBase()).get_Params_KeyboardEventCallBack();
      if (params) {
        CommonData::setcurrent_keyboardType(params->keyboardType);
      }
    }

    bool iskeydown = false;
    if (!(front->getParamsBase()).iskeydown(iskeydown)) {
      iskeydown = true;
    }

    if (!RemapClassManager::remap_simultaneouskeypresses(iskeydown)) {
      break;
    }
  }

  // ------------------------------------------------------------
  // handle BlockUntilKeyUp
  //
  // Note:
  // We need to handle BlockUntilKeyUp after SimultaneousKeyPresses
  // in order to avoid unintended modification by SimultaneousKeyPresses.
  bool needToFire = BlockUntilKeyUpHander::doBlockUntilKeyUp();
  if (needToFire) {
    doFire();
  }

  setTimer();
}
Example #22
0
void org_pqrs_driver_Seil::free(void) {
    IOLOG_INFO("free\n");

    super::free();
}