c++linuxrhel6

Where to find the max resolution for a touchscreen monitor in Linux?


The application that I'm writing has a thread that is constantly polling a /dev/input/eventX location for touch events since the Linux kernel I am running has limited support for touchscreens. Because of this limited support, QT5 does not receive any touch events, and I have to parse the raw event data from the device.

My method works, but I am getting wildly inaccurate X and Y values for the touch points because I need to scale the coordinates according to the resolution of the monitor. For example, if I use the evtest utility, I'm able to see that the current max X and Y values for this monitor are (15360, 8640), and the monitor resolution is 1920x1080. This would imply I need to scale both X and Y values by 0.125 to get the correct coordinates.

Since the evtest utility is able to show me these max X and Y values, I'm assuming that information can be read somewhere, but I can't find any information on where to get that info. Could someone tell me where I can find the touchscreen's current max coordinate values? Also, if it is not in the same location, where can I get the monitor resolution as well?


Solution

  • I managed to find the source code for the evtest utility that I mentioned and was able to find the max X and Y values of the touchscreen by using the following code snippet:

    const char * filename = "/dev/input/event15";
    char * absval[6] = { "Value", "Min", "Max", "Fuzz", "Flat", "Resolution" };
    int fd = open(filename, O_RDONLY);
    if((fd < 0) && (errno == EACCES) && (getuid() != 0)) {
        cout << "Could not open device file. Try running as root." << endl;
    }
    
    int absX[6] = {};
    int absY[6] = {};
    
    ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), absX);
    ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), absY);
    
    cout << "ABS_MT_POSITION_X Properties" << endl;
    for(int x = 0; x < 6; x++) {
        if((x < 3) || absX[x]) {
            cout << absval[x] << ": " << absX[x] << endl;
        }
    }
    
    cout << "ABS_MT_POSITION_Y Properties" << endl;
    for(int y = 0; y < 6; y++) {
        if((y < 3) || absX[y]) {
            cout << absval[y] << ": " << absY[y] << endl;
        }
    }
    
    SCALE_X = (1920.0f / absX[2]);
    SCALE_Y = (1080.0f / absY[2]);
    
    close(fd);
    

    This got me the correct scaling amount.

    Is there a way to do this using C++ libraries? Or is there no C++ equivalent to ioctl()?