Subversion Repositories shark

Rev

Rev 519 | Rev 538 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
519 mauro 1
/*
523 mauro 2
 * $Id: mouse.c,v 1.2 2004-03-25 10:37:48 mauro Exp $
519 mauro 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
 
523 mauro 31
//#define DEBUG_MOUSE
519 mauro 32
 
33
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
34
MODULE_DESCRIPTION("Input driver event debug module");
35
MODULE_LICENSE("GPL");
36
 
523 mauro 37
extern void shark_mouse_exec(void);
519 mauro 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;
523 mauro 97
        *dz      = mbuffer[mtail].dz;
519 mauro 98
        *buttons = mbuffer[mtail].buttons;
99
 
523 mauro 100
#ifdef DEBUG_MOUSE
101
        printk(KERN_DEBUG "mouse.c: ( %3d %3d %3d - %6x)\n", mbuffer[mtail].dx, mbuffer[mtail].dy, mbuffer[mtail].dz, (int)mbuffer[mtail].buttons);
102
        printk(KERN_DEBUG "mouse.c: ( %3d %3d %3d - %6x)\n", *dx, *dy, *dz, *(int *)buttons);
103
#endif
519 mauro 104
        return 0;
105
}
106
 
107
static void mouse_abs_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
108
{
109
        int size;
110
 
111
        /* Ignore joysticks */
112
        if (test_bit(BTN_TRIGGER, handle->dev->keybit))
113
                return;
114
 
115
        /* Handle touchpad data */
116
        if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
117
 
118
                if (list->finger && list->finger < 3)
119
                        list->finger++;
120
 
121
                switch (code) {
122
                        case ABS_X:
123
                                if (list->finger == 3)
124
                                        list->dx += (value - list->oldx) / 8;
125
                                list->oldx = value;
126
                                return;
127
                        case ABS_Y:
128
                                if (list->finger == 3)
129
                                        list->dy -= (value - list->oldy) / 8;
130
                                list->oldy = value;
131
                                return;
132
                }
133
                return;
134
        }
135
 
136
        /* Handle tablet data */
137
        switch (code) {
138
                case ABS_X:
139
                        size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
140
                        if (size == 0) size = xres;
141
                        list->dx += (value * xres - list->oldx) / size;
142
                        list->oldx += list->dx * size;
143
                        return;
144
                case ABS_Y:
145
                        size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
146
                        if (size == 0) size = yres;
147
                        list->dy -= (value * yres - list->oldy) / size;
148
                        list->oldy -= list->dy * size;
149
                        return;
150
        }
151
}
152
 
153
static void mouse_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
154
{
155
        int index;
156
 
157
#ifdef DEBUG_MOUSE
158
        printk(KERN_DEBUG "mouse.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
159
#endif
160
 
161
        switch (type) {
162
                case EV_ABS:
163
                        mouse_abs_event(handle, type, code, value);
164
                        break;
165
 
166
                case EV_REL:
167
                        switch (code) {
168
                                case REL_X:     list->dx += value; break;
169
                                case REL_Y:     list->dy -= value; break;
170
                                case REL_WHEEL: list->dz -= value; break;
171
                        }
172
                        break;
173
 
174
                case EV_KEY:
175
                        switch (code) {
176
                                case BTN_TOUCH: /* Handle touchpad data */
177
                                        if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
178
                                                list->finger = value;
179
                                                return;
180
                                        }
181
                                case BTN_0:
182
                                case BTN_FORWARD:
183
                                case BTN_LEFT:   index = 0; break;
184
                                case BTN_4:
185
                                case BTN_EXTRA:  index = 4; break;
186
                                case BTN_STYLUS:
187
                                case BTN_1:
188
                                case BTN_RIGHT:  index = 1; break;
189
                                case BTN_3:
190
                                case BTN_BACK:
191
                                case BTN_SIDE:   index = 3; break;
192
                                case BTN_2:
193
                                case BTN_STYLUS2:
194
                                case BTN_MIDDLE: index = 2; break;     
195
                                default: return;
196
                        }
197
                        switch (value) {
198
                                case 0: clear_bit(index, &list->buttons); break;
199
                                case 1: set_bit(index, &list->buttons); break;
200
                                case 2: return;
201
                        }
202
                        break;
203
 
204
                case EV_SYN:
205
                        switch (code) {
206
                                case SYN_REPORT:
207
                                        if (mtail != mhead) {
208
                                                mbuffer[mhead].buttons = list->buttons;
209
                                                mbuffer[mhead].dx = list->dx;
210
                                                mbuffer[mhead].dy = list->dy;
211
                                                mbuffer[mhead].dz = list->dz;
212
                                                mhead = (mhead+1) & MOUSE_BUFFERMASK;
523 mauro 213
                                                list->dx = list->dy = list->dz = 0;
519 mauro 214
                                        }
523 mauro 215
                                        shark_mouse_exec();
519 mauro 216
                                        break;
217
                        }
218
        }
219
}
220
 
221
static struct input_handle *mouse_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
222
{
223
        struct input_handle *handle;
224
 
225
        if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
226
                return NULL;
227
        memset(handle, 0, sizeof(struct input_handle));
228
 
229
        handle->dev = dev;
230
        handle->handler = handler;
231
        handle->name = mouse_name;
232
 
233
        input_open_device(handle);
234
 
235
#ifdef DEBUG_MOUSE
236
        printk(KERN_DEBUG "mouse.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
237
#endif
238
 
239
        return handle;
240
}
241
 
242
static void mouse_disconnect(struct input_handle *handle)
243
{
244
#ifdef DEBUG_MOUSE
245
        printk(KERN_DEBUG "mouse.c: Disconnected device: %s\n", handle->dev->phys);
246
#endif
247
 
248
        input_close_device(handle);
249
 
250
        kfree(handle);
251
}
252
 
253
static struct input_device_id mouse_ids[] = {
254
        {
255
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
256
                .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
257
                .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
258
                .relbit = { BIT(REL_X) | BIT(REL_Y) },
259
        },      // A mouse like device, at least one button, two relative axes
260
        {
261
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
262
                .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
263
                .relbit = { BIT(REL_WHEEL) },
264
        },      // A separate scrollwheel
265
        {
266
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
267
                .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
268
                .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
269
                .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
270
        },      // A tablet like device, at least touch detection, two absolute axes
271
        {
272
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
273
                .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
274
                .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) },
275
                .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) },
276
        },      // A touchpad
277
 
278
        { },    // Terminating entry
279
};
280
 
281
MODULE_DEVICE_TABLE(input, mouse_ids);
282
 
283
static struct input_handler mouse_handler = {
284
        .event =        mouse_event,
285
        .connect =      mouse_connect,
286
        .disconnect =   mouse_disconnect,
287
        .name =         "mouse",
288
        .id_table =     mouse_ids,
289
};
290
 
291
int __init mouse_init(void)
292
{
523 mauro 293
        /* Initialize Buffer Variables */
294
        mhead=1;
295
        mtail=0;
296
 
519 mauro 297
        input_register_handler(&mouse_handler);
298
        return 0;
299
}
300
 
301
void __exit mouse_exit(void)
302
{
303
        input_unregister_handler(&mouse_handler);
304
}
305
 
306
module_init(mouse_init);
307
module_exit(mouse_exit);