Rosario 3D

My developer blog

Monthly Archives: December 2010

Who need focus?

I’m trying to read get data from various devices for my engine, but I didn’t find a good way to read joystick data with Xlib. Then I read about Evdev.

Basically you can read the files called /dev/input/event* to get the data, it read almost everything, mouse, keyboard, tablet, joystick, wheel.. And the good thing is that it fit perfectly with the multi thread event environment I wrote for my engine.
With ioctl you can get some information about the device *name, id, driver version…)
Then you can read the structure input_event from the file.

The cool thigh about evdev is that you are reading the raw data from the device, so you don’t need the focus.

You can check the linux/input.h file to check the data you can read from the input_event structure.

Here some dirt and quick test, the select is used to check more files/device simultaneously.
The code is based on evtest.

#include <linux/input.h>
#include <algorithm>
#include <vector>
#include <iostream>

#include <fcntl.h>
#include <cstring>

struct DeviceHandle{
  int file_;
  char deviceName_[256];
};
using namespace std;

int main( int argc, char **argv)
{
  int nfds = 0;
  vector<DeviceHandle> handle;
  fd_set readSet;
  FD_ZERO(&readSet);
  if(argc-1 <= 0){
    cerr << "You must specify some file\n";
    return EXIT_FAILURE;
  }
  for(unsigned int i = 1; i < argc; ++i){
    int file;
    if((file = open(argv[i], O_RDONLY)) >= 0 ){
      nfds = std::max(nfds, file);
      DeviceHandle dh;
      if(ioctl(file, EVIOCGNAME(sizeof(handle[i].deviceName_)), dh.deviceName_) < 0)
        strcpy(dh.deviceName_, "Unknow");
      dh.file_ = file;
      handle.push_back(dh);
      FD_SET(file, &readSet);
    }else{
      cerr << argv[i] << " is not a valid file or permission denied.\n" ;
    }
  }
  if(handle.size() == 0){
    cerr << "No valid files\n";
    return EXIT_FAILURE;
  }
  while(1){
    struct input_event ev[64];
    int ifd = select(nfds, &readSet, NULL, NULL, NULL);
    if(ifd < 0){
      cerr << "Select fail\n";
      return EXIT_FAILURE;
    }else {
      for(auto it = handle.begin(); it != handle.end(); ++it){
        if(FD_ISSET(it->file_, &readSet)){
          cout << "Event from: " << it->deviceName_ << std::endl;
          int rd = read(it->file_, ev, sizeof(input_event) * 64);
          rd /= sizeof(input_event);
          for(unsigned int j = 0; j < rd; ++j)
            cout << "Time : " << ev[j].time.tv_sec << "." << ev[j].time.tv_usec << "  == Type: "  << ev[j].type << endl;
        }
      }
    }
    for(auto it = handle.begin(); it != handle.end(); ++it)
      FD_SET(it->file_, &readSet);
  }
  for(auto it = handle.begin(); it != handle.end(); ++it)
    close(it->file_);
  return EXIT_SUCCESS;
}

To compile
gcc evdev.cpp -std=c++0x -lstdc++ -o evdevtest
and then
sudo evdevtest /dev/input/event*
-Enjoy

Transfert successful

I have moved my blog from my (now dead) server to wordpress.com. I don’t have all the plug-in I have installed on my server but I think I can survive with basic latex support and no syntax highligth for the code.
Now that the site is up I’ll upgrade more frequently.