Cihazlar büyük olasılıkla /dev/input/
adlandırılmış bir dosya alır, eventN
burada N fare, klavye, jak, güç düğmeleri vb.
ls -l /dev/input/by-{path,id}/
size bir ipucu vermeli.
Ayrıca bakınız:
cat /proc/bus/input/devices
Nerede Sysfs
değer yolu altındadır /sys
.
Örneğin ile test edebilirsiniz
cat /dev/input/event2 # if 2 is kbd.
Uygulamak için ioctl kullanın ve cihazları + monitörü kontrol edin.
DÜZENLEME 2:
TAMAM. /dev/input/eventN
Kullanılan cevaba dayanarak bu cevabı genişletiyorum .
Bunun bir yolu olabilir:
Başlangıç döngüsünde bulunan tüm event
dosyalar /dev/input/
. ioctl()
Etkinlik bitleri istemek için kullanın :
ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
sonra EV_KEY
-bit'in ayarlanıp ayarlanmadığını kontrol edin .
IFF ayarlandıktan sonra anahtarları kontrol edin:
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
Örneğin sayı tuşları ilginçse, bitlerin KEY_0
- KEY9
ve KEY_KP0
için olup olmadığını kontrol edin KEY_KP9
.
Daha sonra bulunan IFF anahtarları olay dosyasını iş parçacığında izlemeye başlar.
1'e geri dön.
Bu şekilde, istenen kriterleri karşılayan tüm cihazları izlemelisiniz. Sadece EV_KEY
güç düğmesi bu biti ayarlayacağından kontrol edemezsiniz , ama açıkçası KEY_A
vb.
Egzotik anahtarlar için yanlış pozitifler gördünüz, ancak normal anahtarlar için bu yeterli olmalıdır. İzlemede doğrudan bir zarar yoktur, örneğin güç düğmesi veya jak için olay dosyası, ancak söz konusu olayları (yani kötü kod) yaymazsınız.
Aşağıda daha ayrıntılı olarak.
DÜZENLEME 1:
Gelince "o son açıklama açıklayın ..." . Stackoverflow diyarında buraya gidiyoruz … ama:
C'de hızlı ve kirli bir örnek. Doğru cihazı aldığınızdan, olay türünü, kodu ve değeri çevirdiğinizden emin olmak için çeşitli kodlar uygulamanız gerekir. Genellikle tuş açma, tuş açma, tuş tekrarı, anahtar kodu vb.
Gerisini eklemek için zamanınız yok (ve burada çok fazla).
Check out linux/input.h
programları gibi, dumpkeys
haritalama kodları için vb çekirdek kodlarını. Örneğindumpkeys -l
Her neyse:
Örnek olarak çalıştırın:
# ./testprog /dev/input/event2
Kod:
#include <stdio.h>
#include <string.h> /* strerror() */
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <unistd.h> /* close() */
#include <sys/ioctl.h> /* ioctl() */
#include <linux/input.h> /* EVIOCGVERSION ++ */
#define EV_BUF_SIZE 16
int main(int argc, char *argv[])
{
int fd, sz;
unsigned i;
/* A few examples of information to gather */
unsigned version;
unsigned short id[4]; /* or use struct input_id */
char name[256] = "N/A";
struct input_event ev[EV_BUF_SIZE]; /* Read up to N events ata time */
if (argc < 2) {
fprintf(stderr,
"Usage: %s /dev/input/eventN\n"
"Where X = input device number\n",
argv[0]
);
return EINVAL;
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
fprintf(stderr,
"ERR %d:\n"
"Unable to open `%s'\n"
"%s\n",
errno, argv[1], strerror(errno)
);
}
/* Error check here as well. */
ioctl(fd, EVIOCGVERSION, &version);
ioctl(fd, EVIOCGID, id);
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
fprintf(stderr,
"Name : %s\n"
"Version : %d.%d.%d\n"
"ID : Bus=%04x Vendor=%04x Product=%04x Version=%04x\n"
"----------\n"
,
name,
version >> 16,
(version >> 8) & 0xff,
version & 0xff,
id[ID_BUS],
id[ID_VENDOR],
id[ID_PRODUCT],
id[ID_VERSION]
);
/* Loop. Read event file and parse result. */
for (;;) {
sz = read(fd, ev, sizeof(struct input_event) * EV_BUF_SIZE);
if (sz < (int) sizeof(struct input_event)) {
fprintf(stderr,
"ERR %d:\n"
"Reading of `%s' failed\n"
"%s\n",
errno, argv[1], strerror(errno)
);
goto fine;
}
/* Implement code to translate type, code and value */
for (i = 0; i < sz / sizeof(struct input_event); ++i) {
fprintf(stderr,
"%ld.%06ld: "
"type=%02x "
"code=%02x "
"value=%02x\n",
ev[i].time.tv_sec,
ev[i].time.tv_usec,
ev[i].type,
ev[i].code,
ev[i].value
);
}
}
fine:
close(fd);
return errno;
}
DÜZENLEME 2 (devam):
Eğer bakarsanız, /proc/bus/input/devices
her satırın başında bir harf olduğunu unutmayın . İşte B
bit haritası. Örneğin:
B: PROP=0
B: EV=120013
B: KEY=20000 200 20 0 0 0 0 500f 2100002 3803078 f900d401 feffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7
Bu bitlerin her biri cihazın bir özelliğine karşılık gelir. Hangi bit eşleme aracıyla, 1, tanımlandığı gibi bir özelliğin mevcut olduğunu gösterir linux/input.h
. :
B: PROP=0 => 0000 0000
B: EV=120013 => 0001 0010 0000 0000 0001 0011 (Event types sup. in this device.)
| | | ||
| | | |+-- EV_SYN (0x00)
| | | +--- EV_KEY (0x01)
| | +------- EV_MSC (0x04)
| +----------------------- EV_LED (0x11)
+--------------------------- EV_REP (0x14)
B: KEY=20... => OK, I'm not writing out this one as it is a bit huge.
B: MSC=10 => 0001 0000
|
+------- MSC_SCAN
B: LED=7 => 0000 0111 , indicates what LED's are present
|||
||+-- LED_NUML
|+--- LED_CAPSL
+---- LED_SCROLL
/drivers/input/input.{h,c}
Çekirdek kaynak ağacına bir göz atın . Orada çok iyi kod. (Örneğin, cihaz özellikleri bu işlev tarafından üretilir .)
Bu mülk haritalarının her birine tarafından ulaşılabilir ioctl
. Örneğin, hangi LED özelliklerinin kullanılabilir olduğunu kontrol etmek istiyorsanız şunları söyleyin:
ioctl(fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), &ledbit);
Nasıl tanımlandığına ilişkin olarak struct input_dev
in tanımına bakın .input.h
ledbit
LED'lerin durumunu kontrol etmek için şunları söyleyin:
ioctl(fd, EVIOCGLED(sizeof(ledbit)), &ledbit);
Bit 1 girişi 1 ise ledbit
num-lock yanar. Bit 2 1 ise büyük harf kilidi yanar vb.
input.h
çeşitli tanımları vardır.
Etkinlik izleme söz konusu olduğunda notlar:
İzleme için sözde kod şu yönde bir şey olabilir:
WHILE TRUE
READ input_event
IF event->type == EV_SYN THEN
IF event->code == SYN_DROPPED THEN
Discard all events including next EV_SYN
ELSE
This marks EOF current event.
FI
ELSE IF event->type == EV_KEY THEN
SWITCH ev->value
CASE 0: Key Release (act accordingly)
CASE 1: Key Press (act accordingly)
CASE 2: Key Autorepeat (act accordingly)
END SWITCH
FI
END WHILE
İlgili bazı belgeler:
Documentation/input/input.txt
, esp. not bölüm 5.
Documentation/input/event-codes.txt
Çeşitli olayların açıklaması vb örn altındaki açıklamalara göre dikkate alın EV_SYN
hakkındaSYN_DROPPED
Documentation/input
... isterseniz diğerlerini okuyun.
/dev/disk/by-id/
tarafından oluşturulurudev
- soru bu parçalı durumda (gömülü platform) kullanılabilir olup olmadığıdır.