diff --git a/hid-linux.c b/hid-linux.c
-index f2e0bce..039a8ab 100644
+index f2e0bce..10c7ad8 100644
--- a/hid-linux.c
+++ b/hid-linux.c
-@@ -43,11 +43,8 @@
+@@ -42,12 +42,11 @@
+ #include <assert.h>
#include <time.h>
#include <sys/time.h>
++#include <utime.h>
-#define HID_LINUX_XS_PATH "/local/domain/0/hid_linux"
++#define HID_LINUX_ACTIVITY_FILE "/tmp/.qemu.hid-linux.stamp"
+#define HID_LINUX_XS_PATH "/local/domain/0/linux_hid_driver"
#define ABS(x) ((x) > 0 ? (x) : -(x))
-#define EVENT_PATH "/dev/input/event"
#define DEBUG_HID_LINUX
-@@ -64,468 +61,605 @@ while (0);
+@@ -64,468 +63,629 @@ while (0);
# define DEBUG(_format_, args...) (void)0
#endif
+ int fds[N_DEVS];
+ int mouse_button_state;
+ int key_status[256];
++ time_t last_activity;
+ void (*secure_key) (int ascii);
+} linux_hid_driver;
+
+ kbd_put_keycode (keycode & 0x7f);
}
-
-
+-
+-
-static void hid_linux_key_event(int code, uint32_t keycode)
+static void
+linux_hid_key_event (int code, uint32_t keycode)
- if (hid_linux_detect_binding())
- return;
- hid_linux_key_inject(code, keycode);
++ int fd;
++
+ if (code == 1)
+ if (hid_linux_detect_binding ())
+ return;
+ struct input_event event[5];
+ int i = 0;
+ int read_sz = 0;
-+
-+ read_sz = read (fd, event, sizeof (event));
-+ if (read_sz <= 0)
-+ return -1;
- read_sz = read(fd, event, sizeof (event));
- for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
++ read_sz = read (fd, event, sizeof (event));
++ if (read_sz <= 0)
++ return -1;
++
++ close(creat(HID_LINUX_ACTIVITY_FILE, S_IRUSR | S_IRWXU));
++ utime(HID_LINUX_ACTIVITY_FILE, NULL);
++
+ for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
{
- if (event[i].type == EV_KEY)
+ int read_sz = 0;
+
+ assert (linux_hid_driver.secure_key);
-+
+
+-static void hid_linux_redirect_fds(int *fd, IOHandler *cb)
+ read_sz = read (fd, event, sizeof (event));
+
+ if (read_sz <= 0)
+ return -1;
-
--static void hid_linux_redirect_fds(int *fd, IOHandler *cb)
++
+ for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
+ if (event[i].type == EV_KEY && event[i].code < BTN_MOUSE &&
+ event[i].value > 0)
- assert(fd != NULL);
+ int result;
+ int slot = (int) opaque;
-
-- while (*fd != -1)
++
+ if (slot < 0)
+ return 0;
+ if (slot >= N_DEVS)
+ result = hid_linux_secure_read (linux_hid_driver.fds[slot]);
+ else
+ result = hid_linux_read (linux_hid_driver.fds[slot]);
-+
+
+- while (*fd != -1)
+ if (result)
{
- qemu_set_fd_handler(*fd, cb, NULL, fd);
+
+
+ if (strcasestr (name, "keyboard"))
- {
-- if (fd != -1)
-- close(fd);
++ {
+ fprintf (stderr, "/dev/input/event%d added keyboard on fd %d (%s)\n",
+ slot, fd, name);
+ linux_hid_driver.types[slot] = HID_TYPE_KEYBOARD;
-
-- sprintf(path, "%s%i", EVENT_PATH, i++);
++
+ set_handler (slot, linux_hid_driver.keyboard_grabbed);
-
-- if (i>=HID_LINUX_MAX_DEV_NO)
-- break;
++
+ }
+ else
-+ {
+ {
+- if (fd != -1)
+- close(fd);
+ fprintf (stderr, "/dev/input/event%d added mouse on fd %d (%s)\n",
+ slot, fd, name);
+ linux_hid_driver.types[slot] = HID_TYPE_MOUSE;
+ set_handler (slot, linux_hid_driver.mouse_grabbed);
+ }
+- sprintf(path, "%s%i", EVENT_PATH, i++);
+
+- if (i>=HID_LINUX_MAX_DEV_NO)
+- break;
++ return 0;
++}
+
- if (stat(path, &st) == -1)
- continue;
- assert(c != HID_LINUX_MAX_DEV);
- if (hid_linux_driver.controller_paths[c])
- continue;
-+ return 0;
-+}
- if ((fd = open(path, O_RDONLY)) == -1)
- break;
- DEBUG("Input get name failed on %s\n", path);
- break;
- }
++static void
++hid_linux_scan (void *opaque)
++{
++ char name[128];
++ int i;
++ struct stat s;
- if (ioctl(fd, EVIOCGID, &id) == -1)
- {
- DEBUG("Input get id failed on %s\n", path);
- continue;
- }
++// fprintf (stderr, "hid_linux_scan()\n");
- /* Only get devices on usb and i8042 */
- if (id.bustype != BUS_I8042 && id.bustype != BUS_USB)
- continue;
-+static void
-+hid_linux_scan (void *opaque)
-+{
-+ char name[128];
-+ int i;
- if (strcasestr(name, "keyboard"))
- {
- controllers = hid_linux_driver.keyboard_fds;
- }
- else
-- {
-- DEBUG("Add %s %s as a mouse, fd=%d, bus=%d\n", path, name, fd, id.bustype);
-- controllers = hid_linux_driver.mouse_fds;
-- }
-+// fprintf (stderr, "hid_linux_scan()\n");
-
-- for ( j = 0; j < (HID_LINUX_MAX_DEV / 2) && controllers[j] != -1; j++)
-- ;
-- assert(j != (HID_LINUX_MAX_DEV / 2));
-
-- controllers[j] = fd;
-- controllers[j + 1] = -1;
+ for (i = 0; i < N_DEVS; ++i)
+ {
+
+ continue;
+
+ sprintf (name, "/dev/input/event%d", i);
-
-- if (grab)
-- {
-- if (!hid_linux_grab_devices(1, controllers + j))
-- {
-- DEBUG("Grabing failed, try next time...\n");
-- controllers[j] = -1;
-- break;
-- }
-- }
++
+/* Check to see if we can open it */
+ linux_hid_driver.fds[i] = open (name, O_RDONLY);
+ if (linux_hid_driver.fds[i] < 0)
+ continue; /* No */
-
-- hid_linux_driver.controller_paths[c] = strdup(path);
-- hid_linux_driver.controller_paths[c + 1] = NULL;
++
+/* Switch to NBIO*/
+ {
+ long arg = 0;
+
+/* See if we like it and set up input notify if we do*/
+ if (consider_device (i))
-+ {
+ {
+- DEBUG("Add %s %s as a mouse, fd=%d, bus=%d\n", path, name, fd, id.bustype);
+- controllers = hid_linux_driver.mouse_fds;
+ close (linux_hid_driver.fds[i]);
+ linux_hid_driver.fds[i] = -1;
+ continue;
-+ }
+ }
-- fd = -1;
- }
-- if (fd != -1)
-- close(fd);
-+
+- for ( j = 0; j < (HID_LINUX_MAX_DEV / 2) && controllers[j] != -1; j++)
+- ;
+- assert(j != (HID_LINUX_MAX_DEV / 2));
++ }
+
+- controllers[j] = fd;
+- controllers[j + 1] = -1;
++/* Check the activity file */
++ if (!linux_hid_driver.mouse_grabbed)
++ {
++ if (stat(HID_LINUX_ACTIVITY_FILE, &s) == -1)
++ {
++ fprintf (stderr, "cannot stat %s\n", HID_LINUX_ACTIVITY_FILE);
++ return;
++ }
++ if (linux_hid_driver.last_activity &&
++ s.st_mtime > linux_hid_driver.last_activity)
++ {
++ /* simulated a key press (down and up) on LEFTCTRL */
++ linux_hid_key_event(KEY_LEFTCTRL, 1);
++ linux_hid_key_event(KEY_LEFTCTRL, 0);
++ }
++ linux_hid_driver.last_activity = s.st_mtime;
++ }
+
+- if (grab)
+- {
+- if (!hid_linux_grab_devices(1, controllers + j))
+- {
+- DEBUG("Grabing failed, try next time...\n");
+- controllers[j] = -1;
+- break;
+- }
+- }
+/* Kick off the periodic scan for devices */
+ if (!linux_hid_driver.scan_timer)
+ linux_hid_driver.scan_timer =
+ qemu_new_timer (rt_clock, hid_linux_scan, NULL);
-+
+
+- hid_linux_driver.controller_paths[c] = strdup(path);
+- hid_linux_driver.controller_paths[c + 1] = NULL;
+/* Schedule ourselves */
+ qemu_mod_timer (linux_hid_driver.scan_timer,
+ qemu_get_clock (rt_clock) + 4000);
-+
+
+- fd = -1;
+- }
+- if (fd != -1)
+- close(fd);
}
-void hid_linux_init(void)
+ linux_hid_driver.fds[i] = -1;
+ linux_hid_driver.keyboard_grabbed = 0;
+ linux_hid_driver.mouse_grabbed = 0;
++ linux_hid_driver.last_activity = 0;
+ hid_linux_scan (NULL);
}