Sending simulated mouse events using uinput

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Greetings oh Linux input wranglers,

At Nuvation we are building a driver for multiple input devices, all of which need to appear as mouse events in userland.  We've tried several approaches without any good results.  Lately I've been looking at the uinput module, especially after finding an article in January 2007 Dashboard about how to do it:

   www.einfochips.com/download/dash_jan_tip.pdf

I made a slightly modified version of the sample code from that article.  I enabled uinput, verified that it is in place, did chmod a+rw on it so I could open it for writing, and compiled this:

===================================

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/time.h>
#include <unistd.h>

// Test the uinput module

struct uinput_user_dev   uinp;
struct input_event       event;

int main(void) {

            int ufile, retcode, i;

            ufile = open("/dev/input/uinput", O_WRONLY | O_NDELAY );
            printf("open /dev/input/uinput returned %d.\n", ufile);
            if (ufile == 0) {
                        printf("Could not open uinput.\n");
                        return -1;
            }

            memset(&uinp, 0, sizeof(uinp));
            strncpy(uinp.name, "simulated mouse", 20);
            uinp.id.version = 4;
            uinp.id.bustype = BUS_USB;

            ioctl(ufile, UI_SET_EVBIT, EV_KEY);
            ioctl(ufile, UI_SET_EVBIT, EV_REL);
            ioctl(ufile, UI_SET_RELBIT, REL_X);
            ioctl(ufile, UI_SET_RELBIT, REL_Y);

            for (i=0; i<256; i++) {
                        ioctl(ufile, UI_SET_KEYBIT, i);
            }

            ioctl(ufile, UI_SET_KEYBIT, BTN_MOUSE);

            // create input device in input subsystem
            retcode = write(ufile, &uinp, sizeof(uinp));
            printf("First write returned %d.\n", retcode);

            retcode = (ioctl(ufile, UI_DEV_CREATE));
            printf("ioctl UI_DEV_CREATE returned %d.\n", retcode);
            if (retcode) {
                        printf("Error create uinput device %d.\n", retcode);
                        return -1;
            }

            // NOW DO STUFF !!!!

            for (i=0; i<100; i++) {

                        struct timeval tv1;

                        // move pointer upleft by 5 pixels
                        memset(&event, 0, sizeof(event));
                        gettimeofday(&event.time, NULL);
                        event.type = EV_REL;
                        event.code = REL_X;
                        event.value = -5;
                        write(ufile, &event, sizeof(event));
            
                        memset(&event, 0, sizeof(event));
                        gettimeofday(&event.time, NULL);
                        event.type = EV_REL;
                        event.code = REL_Y;
                        event.value = -5;
                        write(ufile, &event, sizeof(event));
            
                        memset(&event, 0, sizeof(event));
                        gettimeofday(&event.time, NULL);
                        event.type = EV_SYN;
                        event.code = SYN_REPORT;
                        event.value = 0;
                        write(ufile, &event, sizeof(event));

                        // wait just a moment
                        do { gettimeofday(&tv1, NULL); } while ((tv1.tv_usec & 0x3FFF) != 0);
                        do { gettimeofday(&tv1, NULL); } while ((tv1.tv_usec & 0x3FFF) == 0);
            }

            // destroy the device
            ioctl(ufile, UI_DEV_DESTROY);

            close(ufile);

}

==============

As I understand it, this ought to cause the mouse to move slowly upleft for a few seconds - but nothing happens!  It is not clear to me what is wrong.

The output on the command line is thus:

[fedorauser@localhost uinputtest]$ gcc uinputtest.c
[fedorauser@localhost uinputtest]$ ./a.out
open /dev/input/uinput returned 3.
First write returned 1116.
ioctl UI_DEV_CREATE returned 0.
[fedorauser@localhost uinputtest]$

I am running Fedora on a VM (using VMWare Player) on a Windows XP machine.  Here is /etc/X11/xorg.conf:



# Xorg configuration created by system-config-display

Section "ServerLayout"
            Identifier     "single head configuration"
            Screen      0  "Screen0" 0 0
            InputDevice    "Keyboard0" "CoreKeyboard"
            InputDevice    "VMMouse" "CorePointer"
EndSection

Section "InputDevice"
            Identifier  "Keyboard0"
            Driver      "kbd"
            Option     "XkbModel" "pc105"
            Option     "XkbLayout" "us"
EndSection

Section "InputDevice"
            Identifier  "VMMouse"
            Driver      "vmmouse"
            Option     "Device" "/dev/input/mice"
            Option     "Emulate3Buttons" "yes"
EndSection

Section "Monitor"
            Identifier   "Monitor0"
            ModelName    "LCD Panel 1680x1050"
            HorizSync    31.5 - 90.0
            VertRefresh  59.9 - 60.1
            Option     "dpms"
EndSection

Section "Device"
            Identifier  "Videocard0"
            Driver      "vmware"
EndSection

Section "Screen"
            Identifier "Screen0"
            Device     "Videocard0"
            Monitor    "Monitor0"
            DefaultDepth     24
            SubSection "Display"
                        Viewport   0 0
                        Depth     24
            EndSubSection
EndSection



Can anyone offer some advice?  Are we forgetting something terribly obvious?  Is the fact of running under a VM somehow messing us up?

Thanks, people.  I'm new to Linux - it's great to find out what a large group of humans are actively supporting it.

Looking forward to any replies,

Nick Turner
Design Engineer
Nuvation, inc.
San Jose, CA
408-228-5580 x258

-
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux