diff options
author | Olaf Hering <olaf@aepfle.de> | 2011-03-17 01:11:46 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-17 02:24:02 -0400 |
commit | 8c3c283e6bf463ab498d6e7823aff6c4762314b6 (patch) | |
tree | 32a5aaf486e95afc321f4c7514129b7e48b883b6 /drivers/input | |
parent | 53a2b81c4e659d894aadc56715c8d8a9afa60d67 (diff) |
Input: xen-kbdfront - advertise either absolute or relative coordinates
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>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/xen-kbdfront.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index 7f85a862ad11..53e62732ee96 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
@@ -110,7 +110,7 @@ static irqreturn_t input_handler(int rq, void *dev_id) | |||
110 | static int __devinit xenkbd_probe(struct xenbus_device *dev, | 110 | static int __devinit xenkbd_probe(struct xenbus_device *dev, |
111 | const struct xenbus_device_id *id) | 111 | const struct xenbus_device_id *id) |
112 | { | 112 | { |
113 | int ret, i; | 113 | int ret, i, abs; |
114 | struct xenkbd_info *info; | 114 | struct xenkbd_info *info; |
115 | struct input_dev *kbd, *ptr; | 115 | struct input_dev *kbd, *ptr; |
116 | 116 | ||
@@ -128,6 +128,11 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev, | |||
128 | if (!info->page) | 128 | if (!info->page) |
129 | goto error_nomem; | 129 | goto error_nomem; |
130 | 130 | ||
131 | if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-abs-pointer", "%d", &abs) < 0) | ||
132 | abs = 0; | ||
133 | if (abs) | ||
134 | xenbus_printf(XBT_NIL, dev->nodename, "request-abs-pointer", "1"); | ||
135 | |||
131 | /* keyboard */ | 136 | /* keyboard */ |
132 | kbd = input_allocate_device(); | 137 | kbd = input_allocate_device(); |
133 | if (!kbd) | 138 | if (!kbd) |
@@ -137,11 +142,12 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev, | |||
137 | kbd->id.bustype = BUS_PCI; | 142 | kbd->id.bustype = BUS_PCI; |
138 | kbd->id.vendor = 0x5853; | 143 | kbd->id.vendor = 0x5853; |
139 | kbd->id.product = 0xffff; | 144 | kbd->id.product = 0xffff; |
140 | kbd->evbit[0] = BIT(EV_KEY); | 145 | |
146 | __set_bit(EV_KEY, kbd->evbit); | ||
141 | for (i = KEY_ESC; i < KEY_UNKNOWN; i++) | 147 | for (i = KEY_ESC; i < KEY_UNKNOWN; i++) |
142 | set_bit(i, kbd->keybit); | 148 | __set_bit(i, kbd->keybit); |
143 | for (i = KEY_OK; i < KEY_MAX; i++) | 149 | for (i = KEY_OK; i < KEY_MAX; i++) |
144 | set_bit(i, kbd->keybit); | 150 | __set_bit(i, kbd->keybit); |
145 | 151 | ||
146 | ret = input_register_device(kbd); | 152 | ret = input_register_device(kbd); |
147 | if (ret) { | 153 | if (ret) { |
@@ -160,12 +166,20 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev, | |||
160 | ptr->id.bustype = BUS_PCI; | 166 | ptr->id.bustype = BUS_PCI; |
161 | ptr->id.vendor = 0x5853; | 167 | ptr->id.vendor = 0x5853; |
162 | ptr->id.product = 0xfffe; | 168 | ptr->id.product = 0xfffe; |
163 | ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); | 169 | |
170 | if (abs) { | ||
171 | __set_bit(EV_ABS, ptr->evbit); | ||
172 | input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); | ||
173 | input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); | ||
174 | } else { | ||
175 | input_set_capability(ptr, EV_REL, REL_X); | ||
176 | input_set_capability(ptr, EV_REL, REL_Y); | ||
177 | } | ||
178 | input_set_capability(ptr, EV_REL, REL_WHEEL); | ||
179 | |||
180 | __set_bit(EV_KEY, ptr->evbit); | ||
164 | for (i = BTN_LEFT; i <= BTN_TASK; i++) | 181 | for (i = BTN_LEFT; i <= BTN_TASK; i++) |
165 | set_bit(i, ptr->keybit); | 182 | __set_bit(i, ptr->keybit); |
166 | ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); | ||
167 | input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); | ||
168 | input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); | ||
169 | 183 | ||
170 | ret = input_register_device(ptr); | 184 | ret = input_register_device(ptr); |
171 | if (ret) { | 185 | if (ret) { |
@@ -272,7 +286,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
272 | enum xenbus_state backend_state) | 286 | enum xenbus_state backend_state) |
273 | { | 287 | { |
274 | struct xenkbd_info *info = dev_get_drvdata(&dev->dev); | 288 | struct xenkbd_info *info = dev_get_drvdata(&dev->dev); |
275 | int ret, val; | 289 | int val; |
276 | 290 | ||
277 | switch (backend_state) { | 291 | switch (backend_state) { |
278 | case XenbusStateInitialising: | 292 | case XenbusStateInitialising: |
@@ -285,16 +299,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
285 | 299 | ||
286 | case XenbusStateInitWait: | 300 | case XenbusStateInitWait: |
287 | InitWait: | 301 | InitWait: |
288 | ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend, | ||
289 | "feature-abs-pointer", "%d", &val); | ||
290 | if (ret < 0) | ||
291 | val = 0; | ||
292 | if (val) { | ||
293 | ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, | ||
294 | "request-abs-pointer", "1"); | ||
295 | if (ret) | ||
296 | pr_warning("can't request abs-pointer\n"); | ||
297 | } | ||
298 | xenbus_switch_state(dev, XenbusStateConnected); | 302 | xenbus_switch_state(dev, XenbusStateConnected); |
299 | break; | 303 | break; |
300 | 304 | ||