Subversion Repositories shark

Rev

Rev 523 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
519 mauro 1
/*
2
 * $Id: mouse.c,v 1.1 2004-03-22 14:48:15 mauro Exp $
3
 *
4
 *  Copyright (c) 1999-2001 Vojtech Pavlik
5
 */
6
 
7
/*
8
 *  Input driver event debug module - dumps all events into syslog
9
 */
10
 
11
/*
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 */
22
 
23
#include <linuxcomp.h>
24
 
25
#include <linux/slab.h>
26
#include <linux/module.h>
27
#include <linux/input.h>
28
#include <linux/init.h>
29
#include <linux/device.h>
30
 
31
#define DEBUG_MOUSE
32
 
33
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
34
MODULE_DESCRIPTION("Input driver event debug module");
35
MODULE_LICENSE("GPL");
36
 
37
extern void shark_mouse_task(void);
38
 
39
#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
40
#define CONFIG_INPUT_MOUSEDEV_SCREEN_X  1024
41
#endif
42
#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_Y
43
#define CONFIG_INPUT_MOUSEDEV_SCREEN_Y  768
44
#endif
45
 
46
static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
47
static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
48
 
49
/* Buffer Ssize */
50
#define MOUSE_BUFFERSIZE 256
51
 
52
/* Buffer Mask ( i=(i+1)&MASK is better than i=(i+1)%SIZE ) */
53
#define MOUSE_BUFFERMASK 0xff
54
 
55
/* Circular Buffer */
56
static struct mouse_event {
57
        unsigned long buttons;
58
        int dx, dy, dz;
59
} mbuffer[MOUSE_BUFFERSIZE];
60
 
61
/*
62
 * Buffer Pointers
63
 * data is inserted to mhead
64
 * data is kept from mtail+1
65
 * (mhead point to mtail+1 when buffer is empty)
66
 */
67
static unsigned mtail, mhead;
68
 
69
static char mouse_name[] = "mouse";
70
 
71
struct mouse_list {
72
        int dx, dy, dz, oldx, oldy;
73
        signed char ps2[6];
74
        unsigned long buttons;
75
        /*unsigned char ready, buffer, bufsiz;
76
        unsigned char mode, imexseq, impsseq;*/
77
        int finger;
78
};
79
 
80
static struct mouse_list m_list;
81
static struct mouse_list *list = &m_list;
82
 
83
/*
84
 * Get data from the mouse
85
 *
86
 * it's follow the port_receive() semantic
87
 */
88
int mouse_get(int *dx, int *dy, int *dz, unsigned long *buttons)
89
{
90
        if ( ((mtail+1) & MOUSE_BUFFERMASK) == ((mhead) & MOUSE_BUFFERMASK) )
91
                return -1;
92
 
93
        mtail = (mtail+1) & MOUSE_BUFFERMASK;
94
 
95
        *dx      = mbuffer[mtail].dx;
96
        *dy      = mbuffer[mtail].dy;
97
        *dz      = mbuffer[mtail].dx;
98
        *buttons = mbuffer[mtail].buttons;
99
 
100
        return 0;
101
}
102
 
103
static void mouse_abs_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
104
{
105
        int size;
106
 
107
        /* Ignore joysticks */
108
        if (test_bit(BTN_TRIGGER, handle->dev->keybit))
109
                return;
110
 
111
        /* Handle touchpad data */
112
        if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
113
 
114
                if (list->finger && list->finger < 3)
115
                        list->finger++;
116
 
117
                switch (code) {
118
                        case ABS_X:
119
                                if (list->finger == 3)
120
                                        list->dx += (value - list->oldx) / 8;
121
                                list->oldx = value;
122
                                return;
123
                        case ABS_Y:
124
                                if (list->finger == 3)
125
                                        list->dy -= (value - list->oldy) / 8;
126
                                list->oldy = value;
127
                                return;
128
                }
129
                return;
130
        }
131
 
132
        /* Handle tablet data */
133
        switch (code) {
134
                case ABS_X:
135
                        size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
136
                        if (size == 0) size = xres;
137
                        list->dx += (value * xres - list->oldx) / size;
138
                        list->oldx += list->dx * size;
139
                        return;
140
                case ABS_Y:
141
                        size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
142
                        if (size == 0) size = yres;
143
                        list->dy -= (value * yres - list->oldy) / size;
144
                        list->oldy -= list->dy * size;
145
                        return;
146
        }
147
}
148
 
149
static void mouse_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
150
{
151
        int index;
152
 
153
#ifdef DEBUG_MOUSE
154
        printk(KERN_DEBUG "mouse.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
155
#endif
156
 
157
        switch (type) {
158
                case EV_ABS:
159
                        mouse_abs_event(handle, type, code, value);
160
                        break;
161
 
162
                case EV_REL:
163
                        switch (code) {
164
                                case REL_X:     list->dx += value; break;
165
                                case REL_Y:     list->dy -= value; break;
166
                                case REL_WHEEL: list->dz -= value; break;
167
                        }
168
                        break;
169
 
170
                case EV_KEY:
171
                        switch (code) {
172
                                case BTN_TOUCH: /* Handle touchpad data */
173
                                        if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
174
                                                list->finger = value;
175
                                                return;
176
                                        }
177
                                case BTN_0:
178
                                case BTN_FORWARD:
179
                                case BTN_LEFT:   index = 0; break;
180
                                case BTN_4:
181
                                case BTN_EXTRA:  index = 4; break;
182
                                case BTN_STYLUS:
183
                                case BTN_1:
184
                                case BTN_RIGHT:  index = 1; break;
185
                                case BTN_3:
186
                                case BTN_BACK:
187
                                case BTN_SIDE:   index = 3; break;
188
                                case BTN_2:
189
                                case BTN_STYLUS2:
190
                                case BTN_MIDDLE: index = 2; break;     
191
                                default: return;
192
                        }
193
                        switch (value) {
194
                                case 0: clear_bit(index, &list->buttons); break;
195
                                case 1: set_bit(index, &list->buttons); break;
196
                                case 2: return;
197
                        }
198
                        break;
199
 
200
                case EV_SYN:
201
                        switch (code) {
202
                                case SYN_REPORT:
203
                                        if (mtail != mhead) {
204
                                                mbuffer[mhead].buttons = list->buttons;
205
                                                mbuffer[mhead].dx = list->dx;
206
                                                mbuffer[mhead].dy = list->dy;
207
                                                mbuffer[mhead].dz = list->dz;
208
                                                mhead = (mhead+1) & MOUSE_BUFFERMASK;
209
                                                list->dx = list->dx = list->dx = 0;
210
                                        }
211
                                        shark_mouse_task();
212
                                        break;
213
                        }
214
        }
215
}
216
 
217
static struct input_handle *mouse_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
218
{
219
        struct input_handle *handle;
220
 
221
        if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
222
                return NULL;
223
        memset(handle, 0, sizeof(struct input_handle));
224
 
225
        handle->dev = dev;
226
        handle->handler = handler;
227
        handle->name = mouse_name;
228
 
229
        input_open_device(handle);
230
 
231
#ifdef DEBUG_MOUSE
232
        printk(KERN_DEBUG "mouse.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
233
#endif
234
 
235
        return handle;
236
}
237
 
238
static void mouse_disconnect(struct input_handle *handle)
239
{
240
#ifdef DEBUG_MOUSE
241
        printk(KERN_DEBUG "mouse.c: Disconnected device: %s\n", handle->dev->phys);
242
#endif
243
 
244
        input_close_device(handle);
245
 
246
        kfree(handle);
247
}
248
 
249
/*static struct input_device_id mouse_ids[] = {
250
        { .driver_info = 1 },   // Matches all devices
251
        { },                    // Terminating zero entry
252
};*/
253
 
254
static struct input_device_id mouse_ids[] = {
255
        {
256
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
257
                .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
258
                .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
259
                .relbit = { BIT(REL_X) | BIT(REL_Y) },
260
        },      // A mouse like device, at least one button, two relative axes
261
        {
262
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
263
                .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
264
                .relbit = { BIT(REL_WHEEL) },
265
        },      // A separate scrollwheel
266
        {
267
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
268
                .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
269
                .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
270
                .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
271
        },      // A tablet like device, at least touch detection, two absolute axes
272
        {
273
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
274
                .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
275
                .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) },
276
                .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) },
277
        },      // A touchpad
278
 
279
        { },    // Terminating entry
280
};
281
 
282
MODULE_DEVICE_TABLE(input, mouse_ids);
283
 
284
static struct input_handler mouse_handler = {
285
        .event =        mouse_event,
286
        .connect =      mouse_connect,
287
        .disconnect =   mouse_disconnect,
288
        .name =         "mouse",
289
        .id_table =     mouse_ids,
290
};
291
 
292
int __init mouse_init(void)
293
{
294
        input_register_handler(&mouse_handler);
295
        return 0;
296
}
297
 
298
void __exit mouse_exit(void)
299
{
300
        input_unregister_handler(&mouse_handler);
301
}
302
 
303
module_init(mouse_init);
304
module_exit(mouse_exit);