it's no effect when using uinput
http://www.linuxforums.org/forum/ubuntu-linux/161718-its-no-effect-when-using-uinput.html
-
t's no effect when using uinput
Hi,
I am learning to use uinput to send event on user space.I modprobe uinput and can see the uinput mod through lsmod | grep uinput.I use a example test code to send the event.However,it's no effect when i run the program.I just run dmesg and can see the output below
[ 2062.084146] input: Virtual Keyboard Device as /devices/virtual/input/input31
[ 2067.918824] input: Virtual Keyboard Device as /devices/virtual/input/input32
Except this,no things happen.Can anyone tell me what's wrong with my program?
Or is there some way to capture the event?
Thank you.
My source code below:
#include <linux/input.h>
#include<linux/uinput.h>
#include <sys/time.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
/* Setup the uinput device */
int setup_uinput_device() {
int uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
if (uinp_fd == 0) {
printf("Unable to open /dev/uinput\n");
return -1;
}
struct uinput_user_dev uinp;
memset(&uinp, 0, sizeof(uinp)); // Intialize the uInput device to NULL
strncpy(uinp.name, "Virtual Keyboard Device", strlen(
"Virtual Keyboard Device"));
uinp.id.version = 4;
uinp.id.bustype = BUS_USB;
uinp.id.product = 1;
uinp.id.vendor = 1;
// Setup the uinput device
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
int i = 0;
for (i = 0; i < 256; i++) {
ioctl(uinp_fd, UI_SET_KEYBIT, i);
}
/* Create input device into input sub-system */
write(uinp_fd, &uinp, sizeof(uinp));
if (ioctl(uinp_fd, UI_DEV_CREATE)) {
printf("Unable to create UINPUT device.");
return -1;
}
return uinp_fd;
}
void send_key_event(int fd, unsigned int keycode, int keyvalue) {
struct input_event event;
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = keycode;
event.value = keyvalue;
if (write(fd, &event, sizeof(event)) < 0) {
printf("simulate key error\n");
} else {
printf("simuate key %d, %d\n", keycode, keyvalue);
}
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(fd, &event, sizeof(event));
if (write(fd, &event, sizeof(event)) < 0) {
printf("simulate key error\n");
} else {
printf("simuate key %d, %d\n", keycode, keyvalue);
}
}
int main(int argc, char *argv[]) {
unsigned int key_code = 15;
if (argc >= 2) {
key_code = atoi(argv[1]);
}
int uinp_fd;
if ((uinp_fd = setup_uinput_device()) < 0) {
printf("Unable to find uinput device\n");
return -1;
}
send_key_event(uinp_fd, key_code, 1);
send_key_event(uinp_fd, key_code, 0);
/* Destroy the input device */
ioctl(uinp_fd, UI_DEV_DESTROY);
/* Close the UINPUT device */
close(uinp_fd);
}
-
08-18-2010 #2Just Joined!
- Join Date
- Feb 2009
- Posts
- 45
I know this might be a bit late, but I'm putting the answer here for people who have the same problem and might stumble upon this page.
I base my answer on the assumption that the basic code you posted is the one that can be found at http://www.einfochips.com/download/dash_jan_tip.pdf with the exception of some personal changes.
In fact nothing is wrong with your program, rather with the response time of X. Let's say you call the product of the compilation of this code "messwithinput". Had you tried "sleep 2; ./messwithinput 30" and switched to another non-X terminal (i.e. via STRG+ALT+F2) you would in fact have seen an "a" appear (*1).
Originally Posted by bennymoo
The problem here is, that this program creates a new input device (probably somewhere in "/dev/input") and that X cannot register the input device fast enough so that it can fetch the input. A simple "sleep(1);" (with the appropriate "#include <unistd.h>") after the creation of the input device solves the problem. To be (probably unnecessary) specific, if you change
toCode:if ((uinp_fd = setup_uinput_device()) < 0) {
printf("Unable to find uinput device\n");
return -1;
}
send_key_event(uinp_fd, key_code, 1);
send_key_event(uinp_fd, key_code, 0);
the program will behave as expected because now X had ample time to realize there's a new input device.Code:if ((uinp_fd = setup_uinput_device()) < 0) {
printf("Unable to find uinput device\n");
return -1;
}
sleep(1);
send_key_event(uinp_fd, key_code, 1);
send_key_event(uinp_fd, key_code, 0);
P.S.:
I don't think this has anything to do with Ubuntu. This topic might be better off in programming, X or something related.
---
(*1): The input event code 30 corresponds to the key code of the character "a", as stated in <linux/input.h>:
Code:$> egrep 'KEY_A\W' /usr/include/linux/input.h
#define KEY_A 30

Reply With Quote
浙公网安备 33010602011771号