lkml.org 
[lkml]   [2004]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 35/39] input: Mousedev - better multiplex absolute and relative devices
    You can pull this changeset from:
    bk://kernel.bkbits.net/vojtech/input-for-linus

    ===================================================================

    ChangeSet@1.1587.27.15, 2004-05-10 01:44:03-05:00, dtor_core@ameritech.net
    Input: mousedev - better multiplex absolute and relative devices;
    cleanups


    mousedev.c | 260 ++++++++++++++++++++++++++++++++++---------------------------
    1 files changed, 146 insertions(+), 114 deletions(-)

    ===================================================================

    diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
    --- a/drivers/input/mousedev.c 2004-06-07 13:10:38 +02:00
    +++ b/drivers/input/mousedev.c 2004-06-07 13:10:38 +02:00
    @@ -2,6 +2,7 @@
    * Input driver to ExplorerPS/2 device driver module.
    *
    * Copyright (c) 1999-2002 Vojtech Pavlik
    + * Copyright (c) 2004 Dmitry Torokhov
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as published by
    @@ -47,15 +48,24 @@
    module_param(yres, uint, 0);
    MODULE_PARM_DESC(yres, "Vertical screen resolution");

    +struct mousedev_motion {
    + int dx, dy, dz;
    +};
    +
    struct mousedev {
    int exist;
    int open;
    int minor;
    - int misc;
    char name[16];
    wait_queue_head_t wait;
    struct list_head list;
    struct input_handle handle;
    +
    + struct mousedev_motion packet;
    + unsigned long buttons;
    + unsigned int pkt_count;
    + int old_x[4], old_y[4];
    + unsigned int touch;
    };

    struct mousedev_list {
    @@ -63,13 +73,10 @@
    struct mousedev *mousedev;
    struct list_head node;
    int dx, dy, dz;
    - int old_x[4], old_y[4];
    unsigned long buttons;
    signed char ps2[6];
    unsigned char ready, buffer, bufsiz;
    unsigned char mode, imexseq, impsseq;
    - unsigned int pkt_count;
    - unsigned char touch;
    };

    #define MOUSEDEV_SEQ_LEN 6
    @@ -82,135 +89,157 @@
    static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
    static struct mousedev mousedev_mix;

    -#define fx(i) (list->old_x[(list->pkt_count - (i)) & 03])
    -#define fy(i) (list->old_y[(list->pkt_count - (i)) & 03])
    +#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
    +#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])

    -static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
    +static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
    {
    - int size;
    - int touchpad;
    + if (mousedev->touch) {
    + switch (code) {
    + case ABS_X:
    + fx(0) = value;
    + if (mousedev->pkt_count >= 2)
    + mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
    + break;

    - /* Ignore joysticks */
    - if (test_bit(BTN_TRIGGER, handle->dev->keybit))
    - return;
    + case ABS_Y:
    + fy(0) = value;
    + if (mousedev->pkt_count >= 2)
    + mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
    + break;
    + }
    + }
    +}

    - touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
    +static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
    +{
    + int size;

    switch (code) {
    case ABS_X:
    - if (touchpad) {
    - if (list->touch) {
    - fx(0) = value;
    - if (list->pkt_count >= 2)
    - list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
    - }
    - } else {
    - size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
    - if (size == 0) size = xres;
    - list->dx += (value * xres - list->old_x[0]) / size;
    - list->old_x[0] += list->dx * size;
    - }
    + size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
    + if (size == 0) size = xres;
    + mousedev->packet.dx = (value * xres - mousedev->old_x[0]) / size;
    + mousedev->old_x[0] = mousedev->packet.dx * size;
    break;
    +
    case ABS_Y:
    - if (touchpad) {
    - if (list->touch) {
    - fy(0) = value;
    - if (list->pkt_count >= 2)
    - list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
    - }
    - } else {
    - size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
    - if (size == 0) size = yres;
    - list->dy -= (value * yres - list->old_y[0]) / size;
    - list->old_y[0] -= list->dy * size;
    - }
    + size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
    + if (size == 0) size = yres;
    + mousedev->packet.dy = (value * yres - mousedev->old_y[0]) / size;
    + mousedev->old_y[0] = mousedev->packet.dy * size;
    break;
    }
    }

    -static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
    +static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
    +{
    + switch (code) {
    + case REL_X: mousedev->packet.dx += value; break;
    + case REL_Y: mousedev->packet.dy -= value; break;
    + case REL_WHEEL: mousedev->packet.dz -= value; break;
    + }
    +}
    +
    +static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
    +{
    + int index;
    +
    + switch (code) {
    + case BTN_TOUCH:
    + case BTN_0:
    + case BTN_FORWARD:
    + case BTN_LEFT: index = 0; break;
    + case BTN_STYLUS:
    + case BTN_1:
    + case BTN_RIGHT: index = 1; break;
    + case BTN_2:
    + case BTN_STYLUS2:
    + case BTN_MIDDLE: index = 2; break;
    + case BTN_3:
    + case BTN_BACK:
    + case BTN_SIDE: index = 3; break;
    + case BTN_4:
    + case BTN_EXTRA: index = 4; break;
    + default: return;
    + }
    +
    + if (value) {
    + set_bit(index, &mousedev->buttons);
    + set_bit(index, &mousedev_mix.buttons);
    + } else {
    + clear_bit(index, &mousedev->buttons);
    + clear_bit(index, &mousedev_mix.buttons);
    + }
    +}
    +
    +static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
    {
    - struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL };
    - struct mousedev **mousedev = mousedevs;
    struct mousedev_list *list;
    - int index, wake;

    - while (*mousedev) {
    + list_for_each_entry(list, &mousedev->list, node) {
    + list->dx += packet->dx;
    + list->dy += packet->dy;
    + list->dz += packet->dz;
    + list->buttons = mousedev->buttons;
    + list->ready = 1;
    + kill_fasync(&list->fasync, SIGIO, POLL_IN);
    + }
    +
    + wake_up_interruptible(&mousedev->wait);
    +}
    +
    +static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
    +{
    + struct mousedev *mousedev = handle->private;
    +
    + switch (type) {
    + case EV_ABS:
    + /* Ignore joysticks */
    + if (test_bit(BTN_TRIGGER, handle->dev->keybit))
    + return;
    +
    + if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
    + mousedev_touchpad_event(mousedev, code, value);
    + else
    + mousedev_abs_event(handle->dev, mousedev, code, value);

    - wake = 0;
    + break;
    +
    + case EV_REL:
    + mousedev_rel_event(mousedev, code, value);
    + break;

    - list_for_each_entry(list, &(*mousedev)->list, node)
    - switch (type) {
    - case EV_ABS:
    - mousedev_abs_event(handle, list, code, value);
    - break;
    -
    - case EV_REL:
    - switch (code) {
    - case REL_X: list->dx += value; break;
    - case REL_Y: list->dy -= value; break;
    - case REL_WHEEL: if (list->mode) list->dz -= value; break;
    - }
    - break;
    -
    - case EV_KEY:
    - if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
    - /* Handle touchpad data */
    - list->touch = value;
    - if (!list->touch)
    - list->pkt_count = 0;
    - break;
    - }
    -
    - switch (code) {
    - case BTN_TOUCH:
    - case BTN_0:
    - case BTN_FORWARD:
    - case BTN_LEFT: index = 0; break;
    - case BTN_4:
    - case BTN_EXTRA: if (list->mode == 2) { index = 4; break; }
    - case BTN_STYLUS:
    - case BTN_1:
    - case BTN_RIGHT: index = 1; break;
    - case BTN_3:
    - case BTN_BACK:
    - case BTN_SIDE: if (list->mode == 2) { index = 3; break; }
    - case BTN_2:
    - case BTN_STYLUS2:
    - case BTN_MIDDLE: index = 2; break;
    - default: return;
    - }
    - switch (value) {
    - case 0: clear_bit(index, &list->buttons); break;
    - case 1: set_bit(index, &list->buttons); break;
    - case 2: return;
    - }
    - break;
    -
    - case EV_SYN:
    - switch (code) {
    - case SYN_REPORT:
    - if (list->touch) {
    - list->pkt_count++;
    - /* Input system eats duplicate events,
    - * but we need all of them to do correct
    - * averaging so apply present one forward
    - */
    - fx(0) = fx(1);
    - fy(0) = fy(1);
    - }
    -
    - list->ready = 1;
    - kill_fasync(&list->fasync, SIGIO, POLL_IN);
    - wake = 1;
    - break;
    - }
    + case EV_KEY:
    + if (value != 2) {
    + if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
    + /* Handle touchpad data */
    + mousedev->touch = value;
    + if (!mousedev->touch)
    + mousedev->pkt_count = 0;
    + }
    + else
    + mousedev_key_event(mousedev, code, value);
    }
    + break;
    +
    + case EV_SYN:
    + if (code == SYN_REPORT) {
    + if (mousedev->touch) {
    + mousedev->pkt_count++;
    + /* Input system eats duplicate events, but we need all of them
    + * to do correct averaging so apply present one forward
    + */
    + fx(0) = fx(1);
    + fy(0) = fy(1);
    + }

    - if (wake)
    - wake_up_interruptible(&((*mousedev)->wait));
    + mousedev_notify_readers(mousedev, &mousedev->packet);
    + mousedev_notify_readers(&mousedev_mix, &mousedev->packet);

    - mousedev++;
    + memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
    + }
    + break;
    }
    }

    @@ -326,6 +355,8 @@
    list->dz -= list->ps2[off + 3];
    list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
    list->bufsiz++;
    + } else {
    + list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
    }

    if (list->mode == 1) {
    @@ -553,6 +584,7 @@
    static struct miscdevice psaux_mouse = {
    PSMOUSE_MINOR, "psaux", &mousedev_fops
    };
    +static int psaux_registered;
    #endif

    static int __init mousedev_init(void)
    @@ -572,7 +604,7 @@
    NULL, "mice");

    #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
    - if (!(mousedev_mix.misc = !misc_register(&psaux_mouse)))
    + if (!(psaux_registered = !misc_register(&psaux_mouse)))
    printk(KERN_WARNING "mice: could not misc_register the device\n");
    #endif

    @@ -584,7 +616,7 @@
    static void __exit mousedev_exit(void)
    {
    #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
    - if (mousedev_mix.misc)
    + if (psaux_registered)
    misc_deregister(&psaux_mouse);
    #endif
    devfs_remove("input/mice");
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:03    [W:0.037 / U:123.028 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site