Exemplo n.º 1
0
    bool
    set_config(const int32_t* const config_vector, mach_vm_size_t config_size)
    {
      // ------------------------------------------------------------
      // check
      if (! remapclasses_) {
        IOLOG_ERROR("%s remapclasses_ == NULL.\n", __FUNCTION__);
        return false;
      }

      if (config_size != (BRIDGE_ESSENTIAL_CONFIG_INDEX__END__ + remapclasses_->size()) * sizeof(int32_t)) {
        IOLOG_ERROR("%s config_size mismatch.\n", __FUNCTION__);
        return false;
      }

      // ------------------------------------------------------------
      // essential config
      const int32_t* p = config_vector;
      Config::set_essential_config(p, BRIDGE_ESSENTIAL_CONFIG_INDEX__END__);
      // remapclasses config
      p += BRIDGE_ESSENTIAL_CONFIG_INDEX__END__;
      for (size_t i = 0; i < remapclasses_->size(); ++i) {
        RemapClass* rc = (*remapclasses_)[i];
        if (! rc) {
          IOLOG_ERROR("%s RemapClass == NULL.\n", __FUNCTION__);
        } else {
          rc->setEnabled(p[i]);
        }
      }

      refresh();

      return true;
    }
Exemplo n.º 2
0
    // ======================================================================
    static void
    refresh_timer_callback(OSObject* owner, IOTimerEventSource* sender)
    {
      if (! remapclasses_) {
        IOLOG_ERROR("RemapClassManager::refresh_core remapclasses_ == NULL.\n");
        return;
      }

      // ----------------------------------------
      if (enabled_remapclasses_) {
        delete enabled_remapclasses_;
      }
      enabled_remapclasses_ = new Vector_RemapClassPointer();
      if (! enabled_remapclasses_) return;

      // ----------------------------------------
      KeyboardRepeat::cancel();

      statusmessage_[0] = '\0';

      isEventInputQueueDelayEnabled_ = false;

      for (size_t i = 0; i < remapclasses_->size(); ++i) {
        RemapClass* p = (*remapclasses_)[i];
        if (! p) continue;

        if (p->enabled()) {
          enabled_remapclasses_->push_back(p);

          const char* msg = p->get_statusmessage();
          if (msg) {
            strlcat(statusmessage_, msg, sizeof(statusmessage_));
            strlcat(statusmessage_, " ", sizeof(statusmessage_));
          }

          if (p->is_simultaneouskeypresses()) {
            isEventInputQueueDelayEnabled_ = true;
          }
        }
      }

      if (strcmp(statusmessage_, lastmessage_) != 0) {
        strlcpy(lastmessage_, statusmessage_, sizeof(lastmessage_));

        int index = BRIDGE_USERCLIENT_STATUS_MESSAGE_EXTRA;
        CommonData::clear_statusmessage(index);
        CommonData::append_statusmessage(index, statusmessage_);
        CommonData::send_notification_statusmessage(index);
      }
    }
Exemplo n.º 3
0
    bool
    isEnabled(size_t configindex)
    {
      if (! remapclasses_) return false;

      if (configindex >= remapclasses_->size()) {
        IOLOG_ERROR("RemapClass::isEnabled invalid configindex.\n");
        return false;
      }

      RemapClass* p = (*remapclasses_)[configindex];
      if (! p) return false;

      return p->enabled();
    }
Exemplo n.º 4
0
    bool
    remap_dropkeyafterremap(const Params_KeyboardEventCallBack& params)
    {
      bool dropped = false;

      if (enabled_remapclasses_) {
        for (size_t i = 0; i < enabled_remapclasses_->size(); ++i) {
          RemapClass* p = (*enabled_remapclasses_)[i];
          if (p) {
            if (p->remap_dropkeyafterremap(params)) dropped = true;
          }
        }
      }

      return dropped;
    }
Exemplo n.º 5
0
    // ======================================================================
    static void
    refresh_core(OSObject* owner, IOTimerEventSource* sender)
    {
      IOLockWrapper::ScopedLock lk(lock_);

      if (! remapclasses_) return;

      // ----------------------------------------
      if (enabled_remapclasses_) {
        delete enabled_remapclasses_;
      }
      enabled_remapclasses_ = new Vector_RemapClassPointer();
      if (! enabled_remapclasses_) return;

      // ----------------------------------------
      KeyboardRepeat::cancel();

      statusmessage_[0] = '\0';

      isEventInputQueueDelayEnabled_ = false;

      for (size_t i = 0; i < remapclasses_->size(); ++i) {
        RemapClass* p = (*remapclasses_)[i];
        if (! p) continue;

        if (p->enabled()) {
          enabled_remapclasses_->push_back(p);

          const char* msg = p->get_statusmessage();
          if (msg) {
            strlcat(statusmessage_, msg, sizeof(statusmessage_));
            strlcat(statusmessage_, " ", sizeof(statusmessage_));
          }

          if (p->is_simultaneouskeypresses()) {
            isEventInputQueueDelayEnabled_ = true;
          }
        }
      }

      if (strcmp(statusmessage_, lastmessage_) != 0) {
        KeyRemap4MacBook_bridge::StatusMessage::Request request(KeyRemap4MacBook_bridge::StatusMessage::MESSAGETYPE_EXTRA, statusmessage_);
        KeyRemap4MacBook_client::sendmsg(KeyRemap4MacBook_bridge::REQUEST_STATUS_MESSAGE, &request, sizeof(request), NULL, 0);
        strlcpy(lastmessage_, statusmessage_, sizeof(lastmessage_));
      }
    }
Exemplo n.º 6
0
    bool
    remap_simultaneouskeypresses(void)
    {
      bool queue_changed = false;

      if (enabled_remapclasses_) {
        for (size_t i = 0; i < enabled_remapclasses_->size(); ++i) {
          RemapClass* p = (*enabled_remapclasses_)[i];
          if (p) {
            if (p->remap_simultaneouskeypresses()) {
              queue_changed = true;
            }
          }
        }
      }

      return queue_changed;
    }
Exemplo n.º 7
0
    bool
    isEnabled(size_t configindex)
    {
      // isEnabled called in remap_key, remap_consumer, ...
      // So, don't make ScopedLock(lock_).

      if (! remapclasses_) return false;

      if (configindex >= remapclasses_->size()) {
        IOLOG_ERROR("RemapClass::isEnabled invalid configindex.\n");
        return false;
      }

      RemapClass* p = (*remapclasses_)[configindex];
      if (! p) return false;

      return p->enabled();
    }
Exemplo n.º 8
0
bool VirtualKey::VK_CONFIG::handle(const Params_KeyboardEventCallBack& params, AutogenId autogenId) {
  RemapClass* remapclass = nullptr;
  bool value_old = false;

  for (size_t i = 0; i < items_.size(); ++i) {
    remapclass = items_[i].remapclass;
    KeyCode keycode_toggle(items_[i].keycode_toggle);
    KeyCode keycode_force_on(items_[i].keycode_force_on);
    KeyCode keycode_force_off(items_[i].keycode_force_off);
    KeyCode keycode_sync_keydownup(items_[i].keycode_sync_keydownup);

    if (!remapclass) return false;

    value_old = remapclass->enabled();

    if (params.key == keycode_toggle) {
      if (params.repeat) goto finish;

      if (params.ex_iskeydown) {
        remapclass->toggleEnabled();
        goto refresh;
      }
      goto finish;

    } else if (params.key == keycode_force_on) {
      if (params.repeat) goto finish;

      if (params.ex_iskeydown) {
        remapclass->setEnabled(true);
        goto refresh;
      }
      goto finish;

    } else if (params.key == keycode_force_off) {
      if (params.repeat) goto finish;

      if (params.ex_iskeydown) {
        remapclass->setEnabled(false);
        goto refresh;
      }
      goto finish;

    } else if (params.key == keycode_sync_keydownup) {
      if (params.repeat) goto finish;

      if (params.ex_iskeydown) {
        remapclass->setEnabled(true);
      } else {
        remapclass->setEnabled(false);
      }
      goto refresh;
    }
  }

  return false;

refresh:
  if (remapclass) {
    bool value_new = remapclass->enabled();

    // * send_notification_to_userspace takes a time.
    // * VK_CONFIG_FORCE_OFF_* might not change remapclass state.
    // Therefore, we call send_notification_to_userspace only if needed.

    if (value_old != value_new) {
      RemapClassManager::refresh();

      // Tell remapclass status is changed to userspace.
      org_pqrs_driver_Karabiner_UserClient_kext::send_notification_to_userspace(BRIDGE_USERCLIENT_NOTIFICATION_TYPE_CONFIG_ENABLED_UPDATED, remapclass->get_configindex());
    }
  }

finish:
  EventOutputQueue::FireModifiers::fire();
  return true;
}
Exemplo n.º 9
0
  bool
  VirtualKey::VK_CONFIG::handle(const Params_KeyboardEventCallBack& params)
  {
    if (! items_) return false;

    RemapClass* remapclass = NULL;

    for (size_t i = 0; i < items_->size(); ++i) {
      remapclass                          = (*items_)[i].remapclass;
      unsigned int keycode_toggle         = (*items_)[i].keycode_toggle;
      unsigned int keycode_force_on       = (*items_)[i].keycode_force_on;
      unsigned int keycode_force_off      = (*items_)[i].keycode_force_off;
      unsigned int keycode_sync_keydownup = (*items_)[i].keycode_sync_keydownup;

      if (! remapclass) return false;

      if (params.ex_iskeydown && params.repeat == false) {
        /*  */ if (params.key == keycode_toggle) {
          remapclass->toggleEnabled();
          goto refresh;

        } else if (params.key == keycode_force_on) {
          remapclass->setEnabled(true);
          goto refresh;

        } else if (params.key == keycode_force_off) {
          remapclass->setEnabled(false);
          goto refresh;

        } else if (params.key == keycode_sync_keydownup) {
          remapclass->setEnabled(true);
          goto refresh;
        }

      } else if (params.eventType == EventType::UP) {
        if (params.key == keycode_toggle ||
            params.key == keycode_force_on ||
            params.key == keycode_force_off) {
          goto finish;
        }

        if (params.key == keycode_sync_keydownup) {
          remapclass->setEnabled(false);
          goto refresh;
        }
      }
    }

    return false;

  refresh:
    RemapClassManager::refresh();

    // Tell remapclass status is changed to userspace.
    if (remapclass) {
      org_pqrs_driver_KeyRemap4MacBook_UserClient_kext::send_notification_to_userspace(BRIDGE_USERCLIENT_NOTIFICATION_TYPE_CONFIG_ENABLED_UPDATED, remapclass->get_configindex());
    }

  finish:
    EventOutputQueue::FireModifiers::fire();
    return true;
  }