2025-05-10 21:58:58 +08:00

212 lines
4.2 KiB
C++

#include <unistd.h>
#include <fcntl.h>
#include <qmessagebox.h>
#include <qsocketnotifier.h>
#include <QVBoxLayout>
#include "keytest.h"
#include "ui_keytest.h"
#include <linux/input.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"
static int is_event_device(const struct dirent *dir) {
return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}
static char* scan_devices(void)
{
struct dirent **namelist;
int i, ndev, devnum;
char *filename;
int max_device = 0;
ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, alphasort);
if (ndev <= 0)
return NULL;
fprintf(stderr, "Available devices:\n");
for (i = 0; i < ndev; i++)
{
char fname[64];
int fd = -1;
char name[256] = "???";
snprintf(fname, sizeof(fname),
"%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
fd = open(fname, O_RDONLY);
if (fd < 0)
continue;
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
close(fd);
if (strncmp(name, "adc-keys", strlen("adc-keys")) != 0)
continue;
fprintf(stderr, "%s: %s\n", fname, name);
sscanf(namelist[i]->d_name, "event%d", &devnum);
if (devnum > max_device)
max_device = devnum;
free(namelist[i]);
}
if (devnum > max_device || devnum < 0)
return NULL;
asprintf(&filename, "%s/%s%d",
DEV_INPUT_EVENT, EVENT_DEV_NAME,
devnum);
return filename;
}
Keytest::Keytest(QWidget *parent) :
QWidget(parent),
ui(new Ui::Keytest)
{
ui->setupUi(this);
ui->mainLayout;
setLayout(ui->mainLayout);
setWindowState(Qt::WindowMaximized);
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
char *event_name = scan_devices();
if (!event_name)
return ;
m_fd = open(event_name, O_RDONLY);
if (m_fd < 0)
{
QMessageBox::information(this,"Error", "Fail to open ,Please check your key device");
return;
}
memset(m_oldButtonsState, 0, sizeof(m_oldButtonsState));
m_notifyObject = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect (m_notifyObject, SIGNAL(activated(int)), this, SLOT(keyEvent()));
connect(ui->exitBtn, &QPushButton::clicked, this, [=](){
close();
});
}
Keytest::~Keytest()
{
delete m_notifyObject;
::close(m_fd);
delete ui;
}
void Keytest::keyEvent()
{
char buffer[KEYMAXNUM];
memset(buffer, 0, sizeof(buffer));
struct input_event event;
int nResult=::read(m_fd, &event, sizeof(event));
if (nResult != sizeof(event))
{
QMessageBox::information(this,"Debug","read error");
return;
}
switch(event.code)
{
case KEY_V_UP:
buffer[0]=event.value;
break;
case KEY_V_DOWN:
buffer[1]=event.value;
break;
case KEY_V_HOME:
buffer[2]=event.value;
break;
case KEY_V_ESC:
buffer[3]=event.value;
break;
default:
return;
}
for (unsigned i = 0; i < sizeof(buffer) / sizeof(buffer[0]); i++)
{
bool oldState = m_oldButtonsState[i];
bool isOn = ((buffer[i] & 0x01) | (buffer[i] & 0x02));
if (oldState != isOn)
{
m_oldButtonsState[i] = isOn;
update(); //this function will call paintEvent
}
}
}
void Keytest::paintEvent(QPaintEvent*)
{
for(unsigned i = 0; i < KEYMAXNUM; i++)
{
if(m_oldButtonsState[i])
{
switch(i)
{
case 0://up
ui->pbt_up ->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 255);"));
break;
case 1://down
ui->pbt_down->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 255);"));
break;
case 2://home
ui->pbt_home->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 255);"));
break;
case 3://esc
ui->pbt_menu->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 255);"));
break;
default:
break;
}
}
else
{
switch(i)
{
case 0://up
ui->pbt_up ->setStyleSheet(QString::fromUtf8("background-color: rgb(206, 206,206);"));
break;
case 1://down
ui->pbt_down->setStyleSheet(QString::fromUtf8("background-color: rgb(206, 206,206);"));
break;
case 2://home
ui->pbt_home->setStyleSheet(QString::fromUtf8("background-color: rgb(206, 206,206);"));
break;
case 3://menu
ui->pbt_menu->setStyleSheet(QString::fromUtf8("background-color: rgb(206, 206,206);"));
break;
default:
break;
}
}
}
}