static void dom0_driver_command(const char *path, void *opaque);
static void dom0_driver_leave_done(void);
-#define DEBUG_DOM0_DRIVER 1
-#define XS_REFRESH_INTERVAL 5000
+#define DEBUG_DOM0_DRIVER 1
+#define XS_REFRESH_INTERVAL 1000
+#define DOM0_DRIVER_SWITCH_TIMEOUT 2
#define DOM0_MOUSE 1
#define DOM0_KEYBOARD 2
#if DEBUG_DOM0_DRIVER
# define DEBUG(_format_, args...) \
do { \
- char *str = get_time(); \
- fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, str, domid, __LINE__, ## args);\
+ char *__str = get_time(); \
+ fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, __str, domid, __LINE__, ## args);\
+ free(__str); \
} while (false)
#else
# define DEBUG(_format_, args...) (void)0
blank = strtol(str, NULL, 10);
free(str);
if (blank == 2)
+ {
+ usleep(100 * 1000); /* 100 ms */
dom0_driver_leave_done();
+ }
}
static int dom0_driver_blank(void)
{
static int dom0_dom_alive(int id)
{
- int *domids;
- int len, i;
+ xc_dominfo_t info;
+ int rc;
- domids = xenstore_get_domids(&len);
- if (domids == NULL)
- return 0;
- for (i = 0; i < len; i++)
- if (domids[i] == id)
- break;
- free(domids);
- return (i < len);
+ rc = xc_domain_getinfo(xc_handle, id, 1, &info);
+ return rc == 1 && info.domid == id;
}
uint32_t t = time(NULL);
struct dom0_driver_xs_info mouse, keyboard;
- if (!vga_passthrough)
- return 0;
-
dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
-
if (mouse.domid == domid)
dom0_driver_handler->probe(1);
else
dom0_driver_handler->probe(0);
- if (mouse.state == -1)
+ if (!vga_passthrough)
+ return 0;
+
+ if (mouse.state == -1)
{
DEBUG("No state grab the device\n");
dom0_gr_devices(1, DOM0_KEYBOARD);
goto out;
}
+ if ( keyboard.state == 2 &&
+ (t - keyboard.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
+ {
+ DEBUG("Keyboard in state 2 for to long, take it back\n");
+ dom0_gr_devices(1, DOM0_KEYBOARD);
+ }
+
+ if (mouse.state == 2 &&
+ (t - mouse.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
+ {
+ DEBUG("Mouse in state 2 for to long, take it back\n");
+ dom0_gr_devices(1, DOM0_MOUSE);
+ DEBUG("Get the focus now !\n");
+ driver.enter();
+ goto out;
+ }
+
ret = 0;
out:
qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
int positions[NB_SLOTS];
char *str;
int len;
+ int ready;
+ struct dom0_driver_xs_info info;
dom0_get_positions(positions);
if (positions[slot] == 0)
}
str = xenstore_dom_read(positions[slot], "dom0_input/ready", &len);
- if (strcmp(str, "1") == 0)
+ ready = strtol(str, NULL, 10);
+ free(str);
+ if (ready != 1)
{
- dom0_driver_xs_write("new-slot", slot, controller);
- dom0_driver_xs_write("timestamp", time(NULL), controller);
- dom0_driver_xs_write("state", 0, controller);
+ DEBUG("Cannot switch controller %d to %d slot not ready\n", controller, slot);
+ return;
}
- free(str);
+
+ dom0_driver_read_xs_info(&info, controller);
+ if (info.state != 1)
+ {
+ DEBUG("Cannot switch controller %d to %d, unstable state\n", controller, slot);
+ return;
+ }
+
+ dom0_driver_xs_write("new-slot", slot, controller);
+ dom0_driver_xs_write("timestamp", time(NULL), controller);
+ dom0_driver_xs_write("state", 0, controller);
}
void dom0_driver_command(const char *path, void *opaque)
#define HID_LINUX_XS_PATH "/local/domain/0/hid_linux"
#define ABS(x) ((x) > 0 ? (x) : -(x))
-#define EVENT_PATH "/dev/input/event"
+#define EVENT_PATH "/dev/input/event"
+#define HID_LINUX_MAX_DEV 16
#define DEBUG_HID_LINUX
# define DEBUG(_format_, args...) \
do \
{ \
- char *str = get_time(); \
- fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, str, domid, __LINE__, ## args);\
- free(str);\
+ char *__str = get_time(); \
+ fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, (__str), domid, __LINE__, ## args);\
+ free(__str);\
} \
while (0);
#else
static struct hid_linux_driver
{
- int keyboard_fds[4];
- int mouse_fds[4];
- char *controller_paths[8];
+ int keyboard_fds[HID_LINUX_MAX_DEV / 2];
+ int mouse_fds[HID_LINUX_MAX_DEV / 2];
+ char *controller_paths[HID_LINUX_MAX_DEV];
int mouse_button_state;
int key_status[256];
} hid_linux_driver;
hid_linux_binding[i + 1].cb = NULL;
hid_linux_binding[i].cb = cb;
hid_linux_binding[i].payload = payload;
- printf("binding payload %d\n", (int)(payload));
hid_linux_binding[i].binding = NULL;
j = 0;
}
static int hid_linux_grab_devices(int grab, int *fd)
-{
- assert(fd != NULL);
+{
+ int rc = 0;
+
+ assert(fd != NULL && *fd != -1);
for (; *fd != -1; fd++)
{
- if (ioctl(*fd, EVIOCGRAB, grab) == -1)
+ if ((rc = ioctl(*fd, EVIOCGRAB, grab)) == -1)
+ {
+ char *er;
+ er = strerror(errno);
+ DEBUG("ioctl(%d, EVOCGRAB) failed, %s\n", *fd, er);
return 0;
+ }
+
+ DEBUG("ioctl(%d, EVOCGRAB) succed\n", *fd);
if (grab)
qemu_set_fd_handler(*fd, hid_linux_read, NULL, fd);
{
sprintf(path, "%s%i", EVENT_PATH, i++);
- if ((fd = open(path, O_RDONLY)) == -1)
+ if (stat(path, &st) == -1)
break;
- for ( c = 0; c < 8 && hid_linux_driver.controller_paths[c]; c++)
+ for ( c = 0; c < HID_LINUX_MAX_DEV && hid_linux_driver.controller_paths[c]; c++)
if (!strcmp(hid_linux_driver.controller_paths[c], path))
break;
- assert(c != 8);
+ assert(c != HID_LINUX_MAX_DEV);
if (hid_linux_driver.controller_paths[c])
continue;
-
+
+ if ((fd = open(path, O_RDONLY)) == -1)
+ break;
+
if (ioctl(fd, EVIOCGNAME(128), name) == -1)
{
DEBUG("Input get name failed on %s\n", path);
if (strcasestr(name, "keyboard"))
{
- DEBUG("Add %s as a keyboard\n", name);
+ DEBUG("Add %s %s as a keyboard, fd=%d\n", path, name, fd);
controllers = hid_linux_driver.keyboard_fds;
}
else
{
- DEBUG("Add %s as a mouse\n", name);
+ DEBUG("Add %s %s as a mouse, fd=%d\n", path, name, fd);
controllers = hid_linux_driver.mouse_fds;
}
- for ( j = 0; j < 4 && controllers[j] != -1; j++)
+ for ( j = 0; j < (HID_LINUX_MAX_DEV / 2) && controllers[j] != -1; j++)
;
- assert(j != 4);
-
+ assert(j != (HID_LINUX_MAX_DEV / 2));
+
controllers[j] = fd;
controllers[j + 1] = -1;
- hid_linux_driver.controller_paths[c] = strdup(path);
- hid_linux_driver.controller_paths[c + 1] = NULL;
if (grab)
{
- DEBUG("Grab device %s\n", name);
- hid_linux_grab_devices(0, controllers);
+ if (!hid_linux_grab_devices(1, controllers + j))
+ {
+ DEBUG("Grabing failed, try next time...\n");
+ controllers[j] = -1;
+ break;
+ }
}
+
+ hid_linux_driver.controller_paths[c] = strdup(path);
+ hid_linux_driver.controller_paths[c + 1] = NULL;
+
fd = -1;
}
- close(fd);
+ if (fd != -1)
+ close(fd);
}
void hid_linux_init(void)