Ich schreibe ein Key Board Emulator Programm in Linux, als Start war ich in der Lage, Tastenstriche in X11 Fenster zu rendern, aber dies funktioniert nicht in virtuellen Terminals und probieren Sie ein anderes aus Weg. Ich bezog mich auf http://thiemonge.org/getting-started-with-uinput und versuchte mit uinput Kernel-Modul. Entsprechend dem Tutorial können Schlüsselstriche als ein Eingabe-Ereignis eingegeben werden und ich schrieb entsprechend unter Code.Wie erzeugt man Tastenanschläge mit dem Input Subsystem
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <iostream>
#include <time.h>
#include <string>
#define die(str, args...) do { \
perror(str); \
exit(EXIT_FAILURE); \
} while(0)
int main(void)
{
int fd_keyEmulator;
struct uinput_user_dev uidev;
struct input_event ev;
int dx, dy;
int i;
fd_keyEmulator = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if(fd_keyEmulator < 0)
{
std::cout << "error: open : " << strerror(errno) << std::endl;
}
int ret;
//ret = ioctl(fd_keyEmulator, UI_SET_EVBIT, EV_KEY);
//ret = ioctl(fd_keyEmulator, UI_SET_KEYBIT, KEY_D);
//ret = ioctl(fd_keyEmulator, UI_SET_EVBIT, EV_SYN);
sleep(5);
if (ioctl(fd_keyEmulator, UI_SET_EVBIT, EV_KEY) < 0)
{
std::cout << "test 1 ..." << std::endl;
die("error: ioctl");
}
if (ioctl(fd_keyEmulator, UI_SET_KEYBIT, KEY_D) < 0)
{
std::cout << "test 2 ..." << std::endl;
die("error: ioctl");
}
if (ioctl(fd_keyEmulator, UI_SET_EVBIT, EV_REL) < 0)
{
std::cout << "test 3 ..." << std::endl;
die("error: ioctl");
}
memset(&uidev, 0, sizeof(uidev));
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "keyboard-emulator");
uidev.id.bustype = BUS_USB;
uidev.id.vendor = 0x1;
uidev.id.product = 0x1;
uidev.id.version = 1;
std::cout << "Writing key press..." << std::endl;
if(write(fd_keyEmulator, &uidev, sizeof(uidev)) < 0)
std::cout << "error: write" << strerror(errno) << std::endl;
if(ioctl(fd_keyEmulator, UI_DEV_CREATE) < 0)
std::cout << "error: ioctl" << strerror(errno) << std::endl;
memset(&ev, 0, sizeof(ev));
ev.type = EV_REL;
ev.code = KEY_D;
ev.value = 1;
//ret = write(fd_keyEmulator, &ev, sizeof(ev));
if (write(fd_keyEmulator, &ev, sizeof (struct input_event)) < 0)
die("error: write");
if (write(fd_keyEmulator, &ev, sizeof (struct input_event)) < 0)
die("error: write");
if (write(fd_keyEmulator, &ev, sizeof (struct input_event)) < 0)
die("error: write");
if (write(fd_keyEmulator, &ev, sizeof (struct input_event)) < 0)
die("error: write");
if(ioctl(fd_keyEmulator, UI_DEV_DESTROY) < 0)
std::cout << "error: ioctl" << strerror(errno) << std::endl;
close(fd_keyEmulator);
}
in diesem Fall ist das, was ich versuche, ein uinput Ereignisse für Tastenhub ‚d‘ zu erzeugen. aber mit der Programmausführung kann ich nichts sehen. kann mir jemand helfen, dieses Programm zu überprüfen. Es ist nicht klar, wie ein Schlüsselstrich mit dem uinput-Subsystem auch im Tutorial eingefügt wird.
EDIT: Ich schrieb ein anderes Programm, aber ich kann keine Ausgabe sehen. Ich habe mich verlaufen und jede Hilfe zu schätzen wissen.
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <iostream>
#include <time.h>
#include <string>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
// create uinput file descriptor
int fd_key_emulator;
// open file descriptor
fd_key_emulator = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if(fd_key_emulator < 0)
{
std::cout << "error in open : " << strerror(errno) << std::endl;
}
// uinput_user_dev struct for fake keyboard
struct uinput_user_dev dev_fake_keyboard;
memset(&dev_fake_keyboard, 0, sizeof(uinput_user_dev));
snprintf(dev_fake_keyboard.name, UINPUT_MAX_NAME_SIZE, "kb-emulator");
dev_fake_keyboard.id.bustype = BUS_USB;
dev_fake_keyboard.id.vendor = 0x01;
dev_fake_keyboard.id.product = 0x01;
dev_fake_keyboard.id.version = 1;
/**configure the input device to send type of events, inform to subsystem which
* type of input events we are using via ioctl calls.
* UI_SET_EVBIT ioctl request is used to applied on uinput descriptor to enable a type of event.
**/
// enable key press/release event
if(ioctl(fd_key_emulator, UI_SET_EVBIT, EV_KEY))
{
std::cout << "Error in ioctl : UI_SET_EVBIT : EV_KEY : " << strerror(errno) << std::endl;
}
// enable set of KEY events here
if(ioctl(fd_key_emulator, UI_SET_KEYBIT, KEY_A))
{
std::cout << "Error in ioctl : UI_SET_KEYBIT : KEY_A : " << strerror(errno) << std::endl;
}
// enable synchronization event
if(ioctl(fd_key_emulator, UI_SET_EVBIT, EV_SYN))
{
std::cout << "Error in ioctl : UI_SET_EVBIT : EV_SYN : " << strerror(errno) << std::endl;
}
// now write the uinput_user_dev structure into uinput file descriptor
if(write(fd_key_emulator, &dev_fake_keyboard, sizeof(uinput_user_dev)) < 0)
{
std::cout << "Error in write(): uinput_user_dev struct into uinput file descriptor: " << strerror(errno) << std::endl;
}
// create the device via an IOCTL call
if(ioctl(fd_key_emulator, UI_DEV_CREATE))
{
std::cout << "Error in ioctl : UI_DEV_CREATE : " << strerror(errno) << std::endl;
}
// now fd_key_emulator represents the end-point file descriptor of the new input device.
// struct member for input events
struct input_event key_input_event;
memset(&key_input_event, 0, sizeof(input_event));
// key press event for 'a'
key_input_event.type = EV_KEY;
key_input_event.code = KEY_A;
key_input_event.value = 1;
// now write to the file descriptor
if(write(fd_key_emulator, &key_input_event, sizeof(input_event)) < 0)
{
std::cout << "Error write : KEY_A press : " << strerror(errno) << std::endl;
}
memset(&key_input_event, 0, sizeof(input_event));
// EV_SYN for key press event
key_input_event.type = EV_SYN;
key_input_event.code = SYN_REPORT;
key_input_event.value = 0;
// now write to the file descriptor
if(write(fd_key_emulator, &key_input_event, sizeof(input_event)) < 0)
{
std::cout << "Error write : EV_SYN for key press : " << strerror(errno) << std::endl;
}
memset(&key_input_event, 0, sizeof(input_event));
// key release event for 'a'
key_input_event.type = EV_KEY;
key_input_event.code = KEY_A;
key_input_event.value = 0;
// now write to the file descriptor
if(write(fd_key_emulator, &key_input_event, sizeof(input_event)) < 0)
{
std::cout << "Error write : KEY_A release : " << strerror(errno) << std::endl;
}
memset(&key_input_event, 0, sizeof(input_event));
// EV_SYN for key press event
key_input_event.type = EV_SYN;
key_input_event.code = SYN_REPORT;
key_input_event.value = 0;
// now write to the file descriptor
if(write(fd_key_emulator, &key_input_event, sizeof(input_event)) < 0)
{
std::cout << "Error write : EV_SYN for key release : " << strerror(errno) << std::endl;
}
return 0;
}