qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] input-linux: improve device handling
@ 2016-06-16  9:03 Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 1/3] input-linux: factor out input_linux_handle_mouse Gerd Hoffmann
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2016-06-16  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Patches 1+2 just factor out code to make patch 3 smaller and easier to
review.  Patch 3 refines the device detection and also allows devices
to be treated as both mouse and keyboard.  The later should improve
handling of programmable mice which can also send keyboard events.

cheers,
  Gerd

Gerd Hoffmann (3):
  input-linux: factor out input_linux_handle_mouse
  input-linux: factor out input_linux_handle_keyboard
  input-linux: better capability checks, merge
    input_linux_event_{mouse,keyboard}

 ui/input-linux.c | 269 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 140 insertions(+), 129 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 1/3] input-linux: factor out input_linux_handle_mouse
  2016-06-16  9:03 [Qemu-devel] [PATCH 0/3] input-linux: improve device handling Gerd Hoffmann
@ 2016-06-16  9:03 ` Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 2/3] input-linux: factor out input_linux_handle_keyboard Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 3/3] input-linux: better capability checks, merge input_linux_event_{mouse, keyboard} Gerd Hoffmann
  2 siblings, 0 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2016-06-16  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

No functional change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/input-linux.c | 102 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 53 insertions(+), 49 deletions(-)

diff --git a/ui/input-linux.c b/ui/input-linux.c
index 1d33b5c..a932290 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -265,6 +265,58 @@ static void input_linux_event_mouse_button(int button)
     qemu_input_event_sync();
 }
 
+static void input_linux_handle_mouse(InputLinux *il, struct input_event *event)
+{
+    if (!il->grab_active) {
+        return;
+    }
+
+    switch (event->type) {
+    case EV_KEY:
+        switch (event->code) {
+        case BTN_LEFT:
+            qemu_input_queue_btn(NULL, INPUT_BUTTON_LEFT, event->value);
+            break;
+        case BTN_RIGHT:
+            qemu_input_queue_btn(NULL, INPUT_BUTTON_RIGHT, event->value);
+            break;
+        case BTN_MIDDLE:
+            qemu_input_queue_btn(NULL, INPUT_BUTTON_MIDDLE, event->value);
+            break;
+        case BTN_GEAR_UP:
+            qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_UP, event->value);
+            break;
+        case BTN_GEAR_DOWN:
+            qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN,
+                                 event->value);
+            break;
+        };
+        break;
+    case EV_REL:
+        switch (event->code) {
+        case REL_X:
+            qemu_input_queue_rel(NULL, INPUT_AXIS_X, event->value);
+            break;
+        case REL_Y:
+            qemu_input_queue_rel(NULL, INPUT_AXIS_Y, event->value);
+            break;
+        case REL_WHEEL:
+            il->wheel = event->value;
+            break;
+        }
+        break;
+    case EV_SYN:
+        qemu_input_event_sync();
+        if (il->wheel != 0) {
+            input_linux_event_mouse_button((il->wheel > 0)
+                                           ? INPUT_BUTTON_WHEEL_UP
+                                           : INPUT_BUTTON_WHEEL_DOWN);
+            il->wheel = 0;
+        }
+        break;
+    }
+}
+
 static void input_linux_event_mouse(void *opaque)
 {
     InputLinux *il = opaque;
@@ -282,55 +334,7 @@ static void input_linux_event_mouse(void *opaque)
             break;
         }
 
-        /* only send event to guest when grab is active */
-        if (!il->grab_active) {
-            continue;
-        }
-
-        switch (event.type) {
-        case EV_KEY:
-            switch (event.code) {
-            case BTN_LEFT:
-                qemu_input_queue_btn(NULL, INPUT_BUTTON_LEFT, event.value);
-                break;
-            case BTN_RIGHT:
-                qemu_input_queue_btn(NULL, INPUT_BUTTON_RIGHT, event.value);
-                break;
-            case BTN_MIDDLE:
-                qemu_input_queue_btn(NULL, INPUT_BUTTON_MIDDLE, event.value);
-                break;
-            case BTN_GEAR_UP:
-                qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_UP, event.value);
-                break;
-            case BTN_GEAR_DOWN:
-                qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN,
-                                     event.value);
-                break;
-            };
-            break;
-        case EV_REL:
-            switch (event.code) {
-            case REL_X:
-                qemu_input_queue_rel(NULL, INPUT_AXIS_X, event.value);
-                break;
-            case REL_Y:
-                qemu_input_queue_rel(NULL, INPUT_AXIS_Y, event.value);
-                break;
-            case REL_WHEEL:
-                il->wheel = event.value;
-                break;
-            }
-            break;
-        case EV_SYN:
-            qemu_input_event_sync();
-            if (il->wheel != 0) {
-                input_linux_event_mouse_button((il->wheel > 0)
-                                               ? INPUT_BUTTON_WHEEL_UP
-                                               : INPUT_BUTTON_WHEEL_DOWN);
-                il->wheel = 0;
-            }
-            break;
-        }
+        input_linux_handle_mouse(il, &event);
     }
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 2/3] input-linux: factor out input_linux_handle_keyboard
  2016-06-16  9:03 [Qemu-devel] [PATCH 0/3] input-linux: improve device handling Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 1/3] input-linux: factor out input_linux_handle_mouse Gerd Hoffmann
@ 2016-06-16  9:03 ` Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 3/3] input-linux: better capability checks, merge input_linux_event_{mouse, keyboard} Gerd Hoffmann
  2 siblings, 0 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2016-06-16  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

No functional change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/input-linux.c | 103 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 54 insertions(+), 49 deletions(-)

diff --git a/ui/input-linux.c b/ui/input-linux.c
index a932290..ffff97f 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -188,6 +188,59 @@ static void input_linux_toggle_grab(InputLinux *il)
     }
 }
 
+static void input_linux_handle_keyboard(InputLinux *il,
+                                        struct input_event *event)
+{
+    if (event->type == EV_KEY) {
+        if (event->value > 2 || (event->value > 1 && !il->repeat)) {
+            /*
+             * ignore autorepeat + unknown key events
+             * 0 == up, 1 == down, 2 == autorepeat, other == undefined
+             */
+            return;
+        }
+        if (event->code >= KEY_CNT) {
+            /*
+             * Should not happen.  But better safe than sorry,
+             * and we make Coverity happy too.
+             */
+            return;
+        }
+
+        /* keep track of key state */
+        if (!il->keydown[event->code] && event->value) {
+            il->keydown[event->code] = true;
+            il->keycount++;
+        }
+        if (il->keydown[event->code] && !event->value) {
+            il->keydown[event->code] = false;
+            il->keycount--;
+        }
+
+        /* send event to guest when grab is active */
+        if (il->grab_active) {
+            int qcode = qemu_input_linux_to_qcode(event->code);
+            qemu_input_event_send_key_qcode(NULL, qcode, event->value);
+        }
+
+        /* hotkey -> record switch request ... */
+        if (il->keydown[KEY_LEFTCTRL] &&
+            il->keydown[KEY_RIGHTCTRL]) {
+            il->grab_request = true;
+        }
+
+        /*
+         * ... and do the switch when all keys are lifted, so we
+         * confuse neither guest nor host with keys which seem to
+         * be stuck due to missing key-up events.
+         */
+        if (il->grab_request && !il->keycount) {
+            il->grab_request = false;
+            input_linux_toggle_grab(il);
+        }
+    }
+}
+
 static void input_linux_event_keyboard(void *opaque)
 {
     InputLinux *il = opaque;
@@ -205,55 +258,7 @@ static void input_linux_event_keyboard(void *opaque)
             break;
         }
 
-        switch (event.type) {
-        case EV_KEY:
-            if (event.value > 2 || (event.value > 1 && !il->repeat)) {
-                /*
-                 * ignore autorepeat + unknown key events
-                 * 0 == up, 1 == down, 2 == autorepeat, other == undefined
-                 */
-                continue;
-            }
-            if (event.code >= KEY_CNT) {
-                /*
-                 * Should not happen.  But better safe than sorry,
-                 * and we make Coverity happy too.
-                 */
-                continue;
-            }
-            /* keep track of key state */
-            if (!il->keydown[event.code] && event.value) {
-                il->keydown[event.code] = true;
-                il->keycount++;
-            }
-            if (il->keydown[event.code] && !event.value) {
-                il->keydown[event.code] = false;
-                il->keycount--;
-            }
-
-            /* send event to guest when grab is active */
-            if (il->grab_active) {
-                int qcode = qemu_input_linux_to_qcode(event.code);
-                qemu_input_event_send_key_qcode(NULL, qcode, event.value);
-            }
-
-            /* hotkey -> record switch request ... */
-            if (il->keydown[KEY_LEFTCTRL] &&
-                il->keydown[KEY_RIGHTCTRL]) {
-                il->grab_request = true;
-            }
-
-            /*
-             * ... and do the switch when all keys are lifted, so we
-             * confuse neither guest nor host with keys which seem to
-             * be stuck due to missing key-up events.
-             */
-            if (il->grab_request && !il->keycount) {
-                il->grab_request = false;
-                input_linux_toggle_grab(il);
-            }
-            break;
-        }
+        input_linux_handle_keyboard(il, &event);
     }
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 3/3] input-linux: better capability checks, merge input_linux_event_{mouse, keyboard}
  2016-06-16  9:03 [Qemu-devel] [PATCH 0/3] input-linux: improve device handling Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 1/3] input-linux: factor out input_linux_handle_mouse Gerd Hoffmann
  2016-06-16  9:03 ` [Qemu-devel] [PATCH 2/3] input-linux: factor out input_linux_handle_keyboard Gerd Hoffmann
@ 2016-06-16  9:03 ` Gerd Hoffmann
  2 siblings, 0 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2016-06-16  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Improve capability checks (count keys and buttons), store results.

Merge the input_linux_event_mouse and input_linux_event_keyboard
functions into one, dispatch into input_linux_handle_mouse and
input_linux_handle_keyboard depending on device capabilities.

Allow calling both handle functions, so we can handle mice which
also send key events, by routing those key events to the keyboard.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/input-linux.c | 92 +++++++++++++++++++++++++++++---------------------------
 1 file changed, 47 insertions(+), 45 deletions(-)

diff --git a/ui/input-linux.c b/ui/input-linux.c
index ffff97f..0e230ce 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -129,6 +129,17 @@ static int qemu_input_linux_to_qcode(unsigned int lnx)
     return linux_to_qcode[lnx];
 }
 
+static bool linux_is_button(unsigned int lnx)
+{
+    if (lnx < 0x100) {
+        return false;
+    }
+    if (lnx >= 0x160 && lnx < 0x2c0) {
+        return false;
+    }
+    return true;
+}
+
 #define TYPE_INPUT_LINUX "input-linux"
 #define INPUT_LINUX(obj) \
     OBJECT_CHECK(InputLinux, (obj), TYPE_INPUT_LINUX)
@@ -153,6 +164,12 @@ struct InputLinux {
     int         keycount;
     int         wheel;
     bool        initialized;
+
+    bool        has_rel_x;
+    bool        has_abs_x;
+    int         num_keys;
+    int         num_btns;
+
     QTAILQ_ENTRY(InputLinux) next;
 };
 
@@ -241,27 +258,6 @@ static void input_linux_handle_keyboard(InputLinux *il,
     }
 }
 
-static void input_linux_event_keyboard(void *opaque)
-{
-    InputLinux *il = opaque;
-    struct input_event event;
-    int rc;
-
-    for (;;) {
-        rc = read(il->fd, &event, sizeof(event));
-        if (rc != sizeof(event)) {
-            if (rc < 0 && errno != EAGAIN) {
-                fprintf(stderr, "%s: read: %s\n", __func__, strerror(errno));
-                qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
-                close(il->fd);
-            }
-            break;
-        }
-
-        input_linux_handle_keyboard(il, &event);
-    }
-}
-
 static void input_linux_event_mouse_button(int button)
 {
     qemu_input_queue_btn(NULL, button, true);
@@ -322,7 +318,7 @@ static void input_linux_handle_mouse(InputLinux *il, struct input_event *event)
     }
 }
 
-static void input_linux_event_mouse(void *opaque)
+static void input_linux_event(void *opaque)
 {
     InputLinux *il = opaque;
     struct input_event event;
@@ -339,14 +335,20 @@ static void input_linux_event_mouse(void *opaque)
             break;
         }
 
-        input_linux_handle_mouse(il, &event);
+        if (il->num_keys) {
+            input_linux_handle_keyboard(il, &event);
+        }
+        if (il->has_rel_x && il->num_btns) {
+            input_linux_handle_mouse(il, &event);
+        }
     }
 }
 
 static void input_linux_complete(UserCreatable *uc, Error **errp)
 {
     InputLinux *il = INPUT_LINUX(uc);
-    uint32_t evtmap, relmap, absmap;
+    uint8_t evtmap, relmap, absmap, keymap[KEY_CNT / 8];
+    unsigned int i;
     int rc, ver;
 
     if (!il->evdev) {
@@ -374,36 +376,36 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
     }
 
     if (evtmap & (1 << EV_REL)) {
+        relmap = 0;
         rc = ioctl(il->fd, EVIOCGBIT(EV_REL, sizeof(relmap)), &relmap);
-        if (rc < 0) {
-            relmap = 0;
+        if (relmap & (1 << REL_X)) {
+            il->has_rel_x = true;
         }
     }
 
     if (evtmap & (1 << EV_ABS)) {
-        ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
-        if (rc < 0) {
-            absmap = 0;
+        absmap = 0;
+        rc = ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
+        if (absmap & (1 << ABS_X)) {
+            il->has_abs_x = true;
         }
     }
 
-    if ((evtmap & (1 << EV_REL)) &&
-        (relmap & (1 << REL_X))) {
-        /* has relative x axis -> assume mouse */
-        qemu_set_fd_handler(il->fd, input_linux_event_mouse, NULL, il);
-    } else if ((evtmap & (1 << EV_ABS)) &&
-               (absmap & (1 << ABS_X))) {
-        /* has absolute x axis -> not supported */
-        error_setg(errp, "tablet/touchscreen not supported");
-        goto err_close;
-    } else if (evtmap & (1 << EV_KEY)) {
-        /* has keys/buttons (and no x axis) -> assume keyboard */
-        qemu_set_fd_handler(il->fd, input_linux_event_keyboard, NULL, il);
-    } else {
-        /* Huh? What is this? */
-        error_setg(errp, "unknown kind of input device");
-        goto err_close;
+    if (evtmap & (1 << EV_KEY)) {
+        memset(keymap, 0, sizeof(keymap));
+        rc = ioctl(il->fd, EVIOCGBIT(EV_KEY, sizeof(keymap)), keymap);
+        for (i = 0; i < KEY_CNT; i++) {
+            if (keymap[i / 8] & (1 << (i % 8))) {
+                if (linux_is_button(i)) {
+                    il->num_btns++;
+                } else {
+                    il->num_keys++;
+                }
+            }
+        }
     }
+
+    qemu_set_fd_handler(il->fd, input_linux_event, NULL, il);
     input_linux_toggle_grab(il);
     QTAILQ_INSERT_TAIL(&inputs, il, next);
     il->initialized = true;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-06-16  9:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-16  9:03 [Qemu-devel] [PATCH 0/3] input-linux: improve device handling Gerd Hoffmann
2016-06-16  9:03 ` [Qemu-devel] [PATCH 1/3] input-linux: factor out input_linux_handle_mouse Gerd Hoffmann
2016-06-16  9:03 ` [Qemu-devel] [PATCH 2/3] input-linux: factor out input_linux_handle_keyboard Gerd Hoffmann
2016-06-16  9:03 ` [Qemu-devel] [PATCH 3/3] input-linux: better capability checks, merge input_linux_event_{mouse, keyboard} Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).