virtual void init()
  {
    if (mInotifyFd == -1)
    {
      mInotifyFd = inotify_init1(IN_CLOEXEC);
      if (mInotifyFd == -1)
      {
        rtLogWarn("hotplug disabled: %s", getSystemError(errno).c_str());
      }
      else
      {
        rtLogDebug("initializing inotify, adding watch: %s", kDevInput);
        mWatchFd = inotify_add_watch(mInotifyFd, kDevInput, (IN_DELETE | IN_CREATE));
        if (mWatchFd == -1)
        {
          rtLogWarn("hotplug disabled: %s", getSystemError(errno).c_str());
        }
        else
        {
          rtLogDebug("adding change notify descriptor: %d to poll list", mInotifyFd);
          pollfd p;
          p.fd = mInotifyFd;
          p.events = (POLLIN | POLLERR);
          p.revents = 0;
          mFds.push_back(p);
        }
      }
    }

    registerDevices(getKeyboardDevices());
    registerDevices(getMouseDevices());
  }
void RegionDumper::init(const string& path, size_t offset)
{
    m_file = fopen(path.c_str(), "rb");
    if (m_file == NULL) THROW(string("Failed to open file ")+path+" - " + getSystemError());
    if (offset > 0) {
        int ret = fseek(m_file, offset, SEEK_SET);
        if (ret != 0) THROW(string("Failed to seek file ")+path+" - " + getSystemError());
    }
}
  virtual bool next(uint32_t timeoutMillis)
  {
    // reset event state
    for (poll_list::iterator i = mFds.begin(); i != mFds.end(); ++i)
    {
      i->events = POLLIN | POLLERR;
      i->revents = 0;
    }

    int n = poll(&mFds[0], static_cast<int>(mFds.size()), timeoutMillis);
    if (n < 0)
    {
      int err = errno;
      if (err == EINTR)
      {
        rtLogInfo("poll was interrupted by EINTR?");
      }
      else
      {
        rtLogError("error processing events: %s", getSystemError(err).c_str());
        return false;
      }
    }

    bool deviceListChanged = false;
    for (poll_list::iterator i = mFds.begin(); i != mFds.end(); ++i)
    {
      if (i->fd == -1)
      {
        rtLogWarn("invalid file descriptor");
        continue;
      }

      if (!(i->revents & POLLIN))
        continue;

      if (i->fd == mInotifyFd)
        deviceListChanged = processChangeNotify(*i);
      else
        processDescriptor(*i);
    }

    if (deviceListChanged)
    {
      rtLogInfo("device list change notify");
      close(false);
      init();
    }
    return true;
  }