16

I try to control the mouse in Linux. Xlib seems to work, but when I try to use it with OpenCV, it keeps returning:

Resource temporarily unavailable

So I decided to write "/dev/psaux". The code is as follows:

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main() {
    unsigned char a[5] = {0, 0xff, 0, 0x28, 0xff};
    int fp = open ("/dev/psaux", O_WRONLY);
    if(!fp)
        printf("open error:%s\n", strerror(errno));

    for(int i = 0; i < 10; i++)
        printf("write:%d\t\t%s\n", write(fp, a, 5), strerror(errno));
    close(fp);
    return 0;
}

Compile it with:

gcc  my_psaux.c -o my_psaux -std=gnu99 -g

Run

sudo ./my_psaux

and get

write:5    Success
write:5    Success
write:5    Success
write:5    Success
write:5    Success
write:5    Success
write:5    Success
write:5    Success
write:5    Success
write:5    Success

However, the mouse doesn't move. Then I open a new terminal, type in "sudo cat /dev/psaux" and run "my_psaux". But I just cat nothing. Nothing is written into "/dev/psaux"

How can I fix this?

If this is not a good method to control the mouse, is there another one?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thundertrick
  • 1,634
  • 1
  • 17
  • 22

2 Answers2

23

Great thanks to R... for reminding me of some other ways instead of /dev/psaux

I tried /dev/input/mouse* and /dev/input/event*

By using

cat /proc/bus/input/devices

I get this:

I: Bus=0003 Vendor=0461 Product=4d81 Version=0111
N: Name="USB Optical Mouse"
P: Phys=usb-0000:00:1d.0-1/input0
S: Sysfs=/devices/pci0000:00/0000:00:1d.0/usb6/6-1/6-1:1.0/input/input10
U: Uniq=
H: Handlers=mouse2 event10
B: EV=17
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=143
B: MSC=10

After testing, only /dev/input/event10 works. The code is as follows:

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

int main() {
  struct input_event event, event_end;

  int fd = open("/dev/input/event10", O_RDWR);
  if (fd < 0) {
    printf("Errro open mouse:%s\n", strerror(errno));
    return -1;
  }
  memset(&event, 0, sizeof(event));
  memset(&event, 0, sizeof(event_end));
  gettimeofday(&event.time, NULL);
  event.type = EV_REL;
  event.code = REL_X;
  event.value = 100;
  gettimeofday(&event_end.time, NULL);
  event_end.type = EV_SYN;
  event_end.code = SYN_REPORT;
  event_end.value = 0;
  for (int i=0; i<5; i++) {
    write(fd, &event, sizeof(event)); // Move the mouse
    write(fd, &event_end, sizeof(event_end)); // Show move
    sleep(1); // Wait
  }
  close(fd);
  return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thundertrick
  • 1,634
  • 1
  • 17
  • 22
2

The mouse is not a loopback/echo device. It's more like a terminal. Would you expect writing data to a terminal (which would appear on the screen) to make the same characters come back to you as input? The same applies to the mouse; the only point in writing to it is to send escape sequences that change its mode (e.g. the protocol used or the resolution).

If you want to "control" the mouse, you have to inject events some other way, or provide a fifo (named pipe) or pseudo-tty in place of /dev/psaux for the input system to read from. However this is probably a rather misguided way to do things...

If you explain why you need to control the mouse, perhaps we could offer you better alternative approaches to what you're trying to do.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Thanks for answering. Pipe sounds a good idea. I am trying to do something (like kinect) to control the mouse movement. Xlib has been tried but failed. Any suggestion? – thundertrick Oct 06 '11 at 14:49
  • @R.. Contrary to what you answered, the /dev/input/event* devices in fact do echo whatever you write to them if it's compliant with the events supported by the device. A write() call to a /dev/input/event* device injects the events written, as if the event came from the device itself: See http://lxr.free-electrons.com/source/drivers/input/evdev.c#L457 – fons May 30 '14 at 18:29
  • Interesting. I haven't verified this, but it seems like evdev-specific behavior. Certainly the `psaux` device node did not behave that way; it allowed commands that control the device settings (like dpi) to be written to the mouse. – R.. GitHub STOP HELPING ICE May 30 '14 at 19:18