| From 8c3c283e6bf463ab498d6e7823aff6c4762314b6 Mon Sep 17 00:00:00 2001 |
| From: Olaf Hering <olaf@aepfle.de> |
| Date: Wed, 16 Mar 2011 22:11:46 -0700 |
| Subject: Input: xen-kbdfront - advertise either absolute or relative coordinates |
| |
| From: Olaf Hering <olaf@aepfle.de> |
| |
| commit 8c3c283e6bf463ab498d6e7823aff6c4762314b6 upstream. |
| |
| A virtualized display device is usually viewed with the vncviewer |
| application, either by 'xm vnc domU' or with vncviewer localhost:port. |
| vncviewer and the RFB protocol provides absolute coordinates to the |
| virtual display. These coordinates are either passed through to a PV |
| guest or converted to relative coordinates for a HVM guest. |
| |
| A PV guest receives these coordinates and passes them to the kernels |
| evdev driver. There it can be picked up by applications such as the |
| xorg-input drivers. Using absolute coordinates avoids issues such as |
| guest mouse pointer not tracking host mouse pointer due to wrong mouse |
| acceleration settings in the guests X display. |
| |
| Advertise either absolute or relative coordinates to the input system |
| and the evdev driver, depending on what dom0 provides. The xorg-input |
| driver prefers relative coordinates even if a devices provides both. |
| |
| Signed-off-by: Olaf Hering <olaf@aepfle.de> |
| Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> |
| Signed-off-by: Dmitry Torokhov <dtor@mail.ru> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/input/xen-kbdfront.c | 45 ++++++++++++++++++++++--------------------- |
| 1 file changed, 24 insertions(+), 21 deletions(-) |
| |
| --- a/drivers/input/xen-kbdfront.c |
| +++ b/drivers/input/xen-kbdfront.c |
| @@ -108,7 +108,7 @@ static irqreturn_t input_handler(int rq, |
| static int __devinit xenkbd_probe(struct xenbus_device *dev, |
| const struct xenbus_device_id *id) |
| { |
| - int ret, i; |
| + int ret, i, abs; |
| struct xenkbd_info *info; |
| struct input_dev *kbd, *ptr; |
| |
| @@ -126,6 +126,11 @@ static int __devinit xenkbd_probe(struct |
| if (!info->page) |
| goto error_nomem; |
| |
| + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-abs-pointer", "%d", &abs) < 0) |
| + abs = 0; |
| + if (abs) |
| + xenbus_printf(XBT_NIL, dev->nodename, "request-abs-pointer", "1"); |
| + |
| /* keyboard */ |
| kbd = input_allocate_device(); |
| if (!kbd) |
| @@ -135,11 +140,12 @@ static int __devinit xenkbd_probe(struct |
| kbd->id.bustype = BUS_PCI; |
| kbd->id.vendor = 0x5853; |
| kbd->id.product = 0xffff; |
| - kbd->evbit[0] = BIT(EV_KEY); |
| + |
| + __set_bit(EV_KEY, kbd->evbit); |
| for (i = KEY_ESC; i < KEY_UNKNOWN; i++) |
| - set_bit(i, kbd->keybit); |
| + __set_bit(i, kbd->keybit); |
| for (i = KEY_OK; i < KEY_MAX; i++) |
| - set_bit(i, kbd->keybit); |
| + __set_bit(i, kbd->keybit); |
| |
| ret = input_register_device(kbd); |
| if (ret) { |
| @@ -158,12 +164,20 @@ static int __devinit xenkbd_probe(struct |
| ptr->id.bustype = BUS_PCI; |
| ptr->id.vendor = 0x5853; |
| ptr->id.product = 0xfffe; |
| - ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); |
| + |
| + if (abs) { |
| + __set_bit(EV_ABS, ptr->evbit); |
| + input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); |
| + input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); |
| + } else { |
| + input_set_capability(ptr, EV_REL, REL_X); |
| + input_set_capability(ptr, EV_REL, REL_Y); |
| + } |
| + input_set_capability(ptr, EV_REL, REL_WHEEL); |
| + |
| + __set_bit(EV_KEY, ptr->evbit); |
| for (i = BTN_LEFT; i <= BTN_TASK; i++) |
| - set_bit(i, ptr->keybit); |
| - ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); |
| - input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); |
| - input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); |
| + __set_bit(i, ptr->keybit); |
| |
| ret = input_register_device(ptr); |
| if (ret) { |
| @@ -270,7 +284,7 @@ static void xenkbd_backend_changed(struc |
| enum xenbus_state backend_state) |
| { |
| struct xenkbd_info *info = dev_get_drvdata(&dev->dev); |
| - int ret, val; |
| + int val; |
| |
| switch (backend_state) { |
| case XenbusStateInitialising: |
| @@ -281,17 +295,6 @@ static void xenkbd_backend_changed(struc |
| |
| case XenbusStateInitWait: |
| InitWait: |
| - ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend, |
| - "feature-abs-pointer", "%d", &val); |
| - if (ret < 0) |
| - val = 0; |
| - if (val) { |
| - ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, |
| - "request-abs-pointer", "1"); |
| - if (ret) |
| - printk(KERN_WARNING |
| - "xenkbd: can't request abs-pointer"); |
| - } |
| xenbus_switch_state(dev, XenbusStateConnected); |
| break; |
| |