embedeo
embedeo

Reputation: 13

How to capture legitimately and programmatically a second mouse or a trackball under linux, X?

I am designing and implementing an experimental GUI application. I wish to allow my users to ergonomically use both hands simultaneously to interact with the application. As an example, imagine GIMP and a second mouse (a trackball) in your left (other) hand: you can navigate, pan, rotate or zoom the picture with your left hand, while drawing/editing point-accurate dots, lines or figures with your right hand at the same time. Back in 2000 ~ 2002 I did some experiments with two mice: one on PS2 (USB) interface and another one on RS232 serial interface. Nowadays, many years later, I am revisiting that ancient idea, with modern software and contemporary (USB) input devices.

In an ideal case, my goal is to attach a second mouse (or a trackball) to a GNU/ Linux system with X and then be able to:

I have spent 6+ hours searching Internet for hints, but regrettably I did not go too far beyond some "dirty" partial solution, with several disadvantages:

...

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char **argv)
{
  int ret=1; /* Program's return value; 0=success. */
  int fd; /* File descriptor (handler) */
  struct input_event ev;

  if (argc != 2) {
    printf("Usage:\n rdinpdev <device>\n"
      "Print events from an input device.\n"
    );
  }
  else {
    fd = open(argv[1], O_RDONLY);
    printf("open returned %d\n",fd);
    if(fd >= 0) {
      ret=0;
      while(1) {
        read(fd, &ev, sizeof(struct input_event));
        printf("value %d, type %d, code %d\n",ev.value,ev.type,ev.code);
      }
    }
  }
  return ret;
}

Upvotes: 1

Views: 165

Answers (1)

JvO
JvO

Reputation: 3106

Short answer: The X Input Device Extension

Somewhat longer answer: X has a concept of core input devices which are usually the keyboard and mouse, and additional input devices which can be queried with the extension mentioned above. These alternative inputs can generate events if you ask them to.

Here's a short piece of code that will list all input devices:

#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>

int main (int argc, char *argv[])
{

  Display *d = XOpenDisplay (0);

  if (!d)
  {
    printf ("Failed to open display.\n");
    return 1;
  }

  int i, num;
  XDeviceInfo *dev;

  dev = XListInputDevices (d, &num);
  printf ("Found %d input devices:\n", num);

  for (i = 0; i < num; i++)
  {
    printf ("  name: %s; classes: %d; use: %d\n", dev[i].name, dev[i].num_classes, dev[i].use);
  }

  XCloseDisplay (d);
  return 0;
}

Makefile:

second-input: second-input.o
       $(CC) -o $@ $< -lX11 -lXi

.o:.c
       $(CC) -g -o $@ $<

I have a Wacom drawing tablet connected to my system but this code lists even more, some that I didn't expect:

Found 10 input devices:
  name: Virtual core pointer; classes: 2; use: 0
  name: Virtual core keyboard; classes: 1; use: 1
  name: Virtual core XTEST pointer; classes: 2; use: 4
  name: Virtual core XTEST keyboard; classes: 1; use: 3
  name: Power Button; classes: 1; use: 3
  name: Power Button; classes: 1; use: 3
  name: USB Mouse              ; classes: 2; use: 4
  name: Wacom Volito Pen; classes: 0; use: 2
  name: UVC Camera (046d:081d); classes: 1; use: 3
  name: AT Translated Set 2 keyboard; classes: 1; use: 3

Upvotes: 1

Related Questions