[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] pvfb: Split mouse and keyboard into separate devices.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1170864760 0
# Node ID cb50bcfcf9fafc98eb3a0c7e516f86446b463a65
# Parent  6e1b380947ee72e300ce038cbeade628f347ac6a
pvfb: Split mouse and keyboard into separate devices.

This patch creates two separate input devices for keyboard and mouse
events.  The reason for this is to separate them in the linux input
layer and allow them being routed different ways.

Use case:  Configure the X-Server like this to get the mouse
events directly from the linux input layer, which has the major
advantage that absolute coordinates work correctly:

Section "InputDevice"
  Driver       "evdev"
  Identifier   "Mouse"
  Option       "Device" "/dev/input/event<nr>"
EndSection

This makes the keyboard stop working though in case mouse and
keyboard events are coming through the same input device, at least
with older Xorg (6.9) versions.

Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxx>

Assign fake pci product identifiers down from 0xffff. This may help
clarify that the devices are not actually PCI. Also it reduces
probability of accidental conflict if further real PCI assignments
occur in future (0x0002, 0x0003, ... would be obvious next identifiers
to allocate).

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c |  103 ++++++++++++++--------
 1 files changed, 70 insertions(+), 33 deletions(-)

diff -r 6e1b380947ee -r cb50bcfcf9fa 
linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Wed Feb 07 16:08:47 
2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Wed Feb 07 16:12:40 
2007 +0000
@@ -29,10 +29,12 @@
 
 struct xenkbd_info
 {
-       struct input_dev *dev;
+       struct input_dev *kbd;
+       struct input_dev *ptr;
        struct xenkbd_page *page;
        int irq;
        struct xenbus_device *xbdev;
+       char phys[32];
 };
 
 static int xenkbd_remove(struct xenbus_device *);
@@ -56,23 +58,36 @@ static irqreturn_t input_handler(int rq,
        rmb();                  /* ensure we see ring contents up to prod */
        for (cons = page->in_cons; cons != prod; cons++) {
                union xenkbd_in_event *event;
+               struct input_dev *dev;
                event = &XENKBD_IN_RING_REF(page, cons);
 
+               dev = info->ptr;
                switch (event->type) {
                case XENKBD_TYPE_MOTION:
-                       input_report_rel(info->dev, REL_X, event->motion.rel_x);
-                       input_report_rel(info->dev, REL_Y, event->motion.rel_y);
+                       input_report_rel(dev, REL_X, event->motion.rel_x);
+                       input_report_rel(dev, REL_Y, event->motion.rel_y);
                        break;
                case XENKBD_TYPE_KEY:
-                       input_report_key(info->dev, event->key.keycode, 
event->key.pressed);
+                       dev = NULL;
+                       if (test_bit(event->key.keycode, info->kbd->keybit))
+                               dev = info->kbd;
+                       if (test_bit(event->key.keycode, info->ptr->keybit))
+                               dev = info->ptr;
+                       if (dev)
+                               input_report_key(dev, event->key.keycode,
+                                                event->key.pressed);
+                       else
+                               printk("xenkbd: unhandled keycode 0x%x\n",
+                                      event->key.keycode);
                        break;
                case XENKBD_TYPE_POS:
-                       input_report_abs(info->dev, ABS_X, event->pos.abs_x);
-                       input_report_abs(info->dev, ABS_Y, event->pos.abs_y);
+                       input_report_abs(dev, ABS_X, event->pos.abs_x);
+                       input_report_abs(dev, ABS_Y, event->pos.abs_y);
                        break;
                }
-       }
-       input_sync(info->dev);
+               if (dev)
+                       input_sync(dev);
+       }
        mb();                   /* ensure we got ring contents */
        page->in_cons = cons;
        notify_remote_via_irq(info->irq);
@@ -85,7 +100,7 @@ int __devinit xenkbd_probe(struct xenbus
 {
        int ret, i;
        struct xenkbd_info *info;
-       struct input_dev *input_dev;
+       struct input_dev *kbd, *ptr;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
@@ -94,6 +109,7 @@ int __devinit xenkbd_probe(struct xenbus
        }
        dev->dev.driver_data = info;
        info->xbdev = dev;
+       snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);
 
        info->page = (void *)__get_free_page(GFP_KERNEL);
        if (!info->page)
@@ -101,32 +117,52 @@ int __devinit xenkbd_probe(struct xenbus
        info->page->in_cons = info->page->in_prod = 0;
        info->page->out_cons = info->page->out_prod = 0;
 
-       input_dev = input_allocate_device();
-       if (!input_dev)
+       /* keyboard */
+       kbd = input_allocate_device();
+       if (!kbd)
                goto error_nomem;
-
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_MOUSE)]
-               = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       /* TODO additional buttons */
-       input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-
-       /* FIXME not sure this is quite right */
-       for (i = 0; i < 256; i++)
-               set_bit(i, input_dev->keybit);
-
-       input_dev->name = "Xen Virtual Keyboard/Mouse";
-
-       input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
-
-       ret = input_register_device(input_dev);
-       if (ret) {
-               input_free_device(input_dev);
-               xenbus_dev_fatal(dev, ret, "input_register_device");
+       kbd->name = "Xen Virtual Keyboard";
+       kbd->phys = info->phys;
+       kbd->id.bustype = BUS_PCI;
+       kbd->id.vendor = 0x5853;
+       kbd->id.product = 0xffff;
+       kbd->evbit[0] = BIT(EV_KEY);
+       for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
+               set_bit(i, kbd->keybit);
+       for (i = KEY_OK; i < KEY_MAX; i++)
+               set_bit(i, kbd->keybit);
+
+       ret = input_register_device(kbd);
+       if (ret) {
+               input_free_device(kbd);
+               xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
                goto error;
        }
-       info->dev = input_dev;
+       info->kbd = kbd;
+
+       /* pointing device */
+       ptr = input_allocate_device();
+       if (!ptr)
+               goto error_nomem;
+       ptr->name = "Xen Virtual Pointer";
+       ptr->phys = info->phys;
+       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);
+       for (i = BTN_LEFT; i <= BTN_TASK; i++)
+               set_bit(i, ptr->keybit);
+       ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
+       input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
+
+       ret = input_register_device(ptr);
+       if (ret) {
+               input_free_device(ptr);
+               xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
+               goto error;
+       }
+       info->ptr = ptr;
 
        ret = xenkbd_connect_backend(dev, info);
        if (ret < 0)
@@ -155,7 +191,8 @@ static int xenkbd_remove(struct xenbus_d
        struct xenkbd_info *info = dev->dev.driver_data;
 
        xenkbd_disconnect_backend(info);
-       input_unregister_device(info->dev);
+       input_unregister_device(info->kbd);
+       input_unregister_device(info->ptr);
        free_page((unsigned long)info->page);
        kfree(info);
        return 0;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.