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);