Где найти максимальное разрешение для сенсорного монитора в Linux?

В приложении, которое я пишу, есть поток, который постоянно опрашивает местоположение /dev/input/eventX для событий касания, поскольку ядро ​​Linux, которое я использую, имеет ограниченную поддержку сенсорных экранов. Из-за этой ограниченной поддержки QT5 не получает никаких событий касания, и мне приходится анализировать необработанные данные о событиях с устройства.

Мой метод работает, но я получаю крайне неточные значения X и Y для точек касания, потому что мне нужно масштабировать координаты в соответствии с разрешением монитора. Например, если я использую утилиту evtest, я могу увидеть, что текущие максимальные значения X и Y для этого монитора равны (15360, 8640), а разрешение монитора — 1920x1080. Это означает, что мне нужно масштабировать значения X и Y на 0,125, чтобы получить правильные координаты.

Поскольку утилита evtest может показать мне эти максимальные значения X и Y, я предполагаю, что информацию можно где-то прочитать, но я не могу найти никакой информации о том, где получить эту информацию. Может ли кто-нибудь сказать мне, где я могу найти текущие максимальные значения координат сенсорного экрана? Кроме того, если он не находится в том же месте, где я могу получить разрешение монитора?


person Darin Beaudreau    schedule 25.06.2019    source источник
comment
Вопрос в предположениях: почему вы вообще используете QT?   -  person    schedule 25.06.2019
comment
@derik Потому что приложение моей компании написано на QT?   -  person Darin Beaudreau    schedule 25.06.2019
comment
Вы хотите сделать через командную строку?   -  person Oblivion    schedule 25.06.2019
comment
@oblivion Предпочтительно нет, так как мне нужно иметь возможность получать эти значения через C++, поэтому, если есть файл, который я могу прочитать, или заголовок Linux с функцией для извлечения этих значений, это было бы предпочтительнее.   -  person Darin Beaudreau    schedule 25.06.2019
comment
Вы смотрели исходный код evtest, чтобы увидеть, как он получает нужную информацию? С другой стороны, мне не кажется, что ваше ядро ​​​​Linux имеет ограниченную поддержку вашего сенсорного экрана, если события видны через /dev/input/eventX. Это все, что должно делать ядро. Чтобы события были видны через QT API, сначала нужно убедиться, что X11 читает из /dev/input/eventX. Я бы рекомендовал не анализировать файл устройства напрямую. Qt может рисовать на другом экране или в другой координате, чем вы ожидаете.   -  person HAL9000    schedule 25.06.2019
comment
@ HAL9000 Я использую ядро ​​​​Linux 2.6.32-754. Насколько я понимаю, поддержка сенсорных экранов в этой версии крайне минимальна, а интерфейсы Xorg не реагируют на события касания, а Qt5 никогда не вызывал событие касания даже после написания для них обработчиков событий и включения событий касания для окна.   -  person Darin Beaudreau    schedule 25.06.2019
comment
@ HAL9000 Кроме того, как мне заставить X11 читать из этого места события? Файл xorg.conf? Мне еще предстоит выяснить, как правильно настроить что-либо в этом файле.   -  person Darin Beaudreau    schedule 25.06.2019
comment
2.6.32 стар как грязь. Ваш X-сервер такой же старый? Конфигурация X зависит от версии. Более новые версии в современных дистрибутивах, как правило, работают по принципу plug-and-play. Я бы порекомендовал вам обновиться.   -  person HAL9000    schedule 25.06.2019
comment
@ HAL9000 Как я уже сказал, это технический стек моей компании, а не мой. Обновление не вариант, потому что это потребует переписать огромное количество кода. С помощью моего метода я смог заставить работать простую операцию масштабирования, но мне нужно иметь возможность касаться виджетов Qt, поэтому мне нужны точные координаты касания.   -  person Darin Beaudreau    schedule 25.06.2019
comment
утилита evtest может показать мне эти максимальные значения X и Y. Итак, прочитайте уже ее исходный код, чтобы увидеть, как она это делает.   -  person Jesper Juhl    schedule 25.06.2019
comment
Если вы не можете обновиться, то по крайней мере исправьте xorg.conf, чтобы вы могли получать доступ к сенсорному экрану через X и QT. Есть много забавных способов облажаться при сопоставлении необработанных событий с qt-виджетами. Например, удаленные рабочие столы, темы пользовательского интерфейса и т. д. И когда вы пишете в неудобных интерфейсах, ваши пользователи и системные администраторы действительно полюбят вас. Вы действительно хотите получить телефонный звонок во время отпуска, потому что кто-то купил новый сенсорный экран, настроил ОС для работы с этим экраном, и ваша программа была единственным, что перестало работать? И что, когда руководство, наконец, решит обновить свой программный стек?   -  person HAL9000    schedule 25.06.2019
comment
@ HAL9000 Вся машина и все программное обеспечение на ней принадлежат нам. Мы предоставляем сенсорный экран. На данный момент это каноническое решение, но я буду работать над тем, чтобы что-то работало лучше, если это возможно. Я не игнорирую ваши комментарии, но все доказательства, которые я видел в своих исследованиях, показывают, что эта версия Linux изначально не сможет делать то, что вы предлагаете, и обновление в данный момент невозможно, так что это мой единственный вариант.   -  person Darin Beaudreau    schedule 25.06.2019


Ответы (1)


Мне удалось найти исходный код утилиты evtest, о которой я упоминал, и смог найти максимальные значения X и Y сенсорного экрана, используя следующий фрагмент кода:

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);

Это дало мне правильное масштабирование.

Есть ли способ сделать это с помощью библиотек C++? Или нет C++, эквивалентного ioctl()?

person Darin Beaudreau    schedule 25.06.2019
comment
ioctl по своей сути специфичен для ОС. Стандарт С++ не имеет отношения к этому. Если вы предпочитаете нестандартную оболочку C++ вокруг ioctl, а не голый развернутый ioctl, просто напишите ее. Кстати, если вы хотите задать вопрос, нажмите кнопку «Задать вопрос». - person n. 1.8e9-where's-my-share m.; 25.06.2019
comment
@н.м. Хорошо. Это все еще был ответ, я просто подумал, что кто-то может ответить на этот второстепенный вопрос в комментариях, потому что это не было очень важно. - person Darin Beaudreau; 25.06.2019