Cihazlar büyük olasılıkla /dev/input/adlandırılmış bir dosya alır, eventNburada 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 Sysfsdeğ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/eventNKullanılan cevaba dayanarak bu cevabı genişletiyorum .
Bunun bir yolu olabilir:
Başlangıç döngüsünde bulunan tüm eventdosyalar /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- KEY9ve KEY_KP0iç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_KEYgüç düğmesi bu biti ayarlayacağından kontrol edemezsiniz , ama açıkçası KEY_Avb.
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.hprogramları gibi, dumpkeysharitalama 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/devicesher satırın başında bir harf olduğunu unutmayın . İşte Bbit 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_devin tanımına bakın .input.hledbit
LED'lerin durumunu kontrol etmek için şunları söyleyin:
ioctl(fd, EVIOCGLED(sizeof(ledbit)), &ledbit);
Bit 1 girişi 1 ise ledbitnum-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_SYNhakkı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.