Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "u.h"
2
#include "../port/lib.h"
3
#include "mem.h"
4
#include "dat.h"
5
#include "fns.h"
6
#include "../port/error.h"
7
#include "io.h"
8
 
9
#define	Image	IMAGE
10
#include <draw.h>
11
#include <memdraw.h>
12
#include <cursor.h>
13
#include "screen.h"
14
 
15
/*
16
 *  mouse types
17
 */
18
enum
19
{
20
	Mouseother=	0,
21
	Mouseserial=	1,
22
	MousePS2=	2,
23
};
24
 
25
extern int mouseshifted;
26
 
27
static QLock mousectlqlock;
28
static int mousetype;
29
static int intellimouse;
30
static int packetsize;
31
static int resolution;
32
static int accelerated;
33
static int mousehwaccel;
34
static char mouseport[5];
35
 
36
enum
37
{
38
	CMaccelerated,
39
	CMhwaccel,
40
	CMintellimouse,
41
	CMlinear,
42
	CMps2,
43
	CMps2intellimouse,
44
	CMres,
45
	CMreset,
46
	CMserial,
47
};
48
 
49
static Cmdtab mousectlmsg[] =
50
{
51
	CMaccelerated,		"accelerated",		0,
52
	CMhwaccel,		"hwaccel",		2,
53
	CMintellimouse,		"intellimouse",		1,
54
	CMlinear,		"linear",		1,
55
	CMps2,			"ps2",			1,
56
	CMps2intellimouse,	"ps2intellimouse",	1,
57
	CMres,			"res",			0,
58
	CMreset,		"reset",		1,
59
	CMserial,		"serial",		0,
60
};
61
 
62
/*
63
 *  ps/2 mouse message is three bytes
64
 *
65
 *	byte 0 -	0 0 SDY SDX 1 M R L
66
 *	byte 1 -	DX
67
 *	byte 2 -	DY
68
 *
69
 *  shift & right button is the same as middle button
70
 *
71
 * Intellimouse and AccuPoint with extra buttons deliver
72
 *	byte 3 -	00 or 01 or FF according to extra button state.
73
 * extra buttons are mapped in this code to buttons 4 and 5.
74
 * AccuPoint generates repeated events for these buttons;
75
*  it and Intellimouse generate 'down' events only, so
76
 * user-level code is required to generate button 'up' events
77
 * if they are needed by the application.
78
 * Also on laptops with AccuPoint AND external mouse, the
79
 * controller may deliver 3 or 4 bytes according to the type
80
 * of the external mouse; code must adapt.
81
 *
82
 * On the NEC Versa series (and perhaps others?) we seem to
83
 * lose a byte from the packet every once in a while, which
84
 * means we lose where we are in the instruction stream.
85
 * To resynchronize, if we get a byte more than two seconds
86
 * after the previous byte, we assume it's the first in a packet.
87
 */
88
static void
89
ps2mouseputc(int c, int shift)
90
{
91
	static short msg[4];
92
	static int nb;
93
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 };
94
	static ulong lasttick;
95
	ulong m;
96
	int buttons, dx, dy;
97
 
98
	shift |= mouseshifted;
99
	m = MACHP(0)->ticks;
100
	if(TK2SEC(m - lasttick) > 2)
101
		nb = 0;
102
	lasttick = m;
103
	if(nb==0 && (c&0xc8)!=0x08)
104
		if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){
105
			packetsize = 4;
106
			return;
107
		}
108
 
109
	msg[nb] = c;
110
	if(++nb == packetsize){
111
		nb = 0;
112
		if(msg[0] & 0x10)
113
			msg[1] |= 0xFF00;
114
		if(msg[0] & 0x20)
115
			msg[2] |= 0xFF00;
116
 
117
		buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
118
		if(intellimouse && packetsize==4){
119
			if((msg[3]&0xc8) == 0x08){
120
				packetsize = 3;
121
				msg[0] = msg[3];
122
				nb = 1;
123
			}else{
124
				if((msg[3] >> 3) & 1)
125
					buttons |= 1<<3;
126
				else if(msg[3] & 0x7)
127
					buttons |= 1<<4;
128
			}
129
		}
130
		dx = msg[1];
131
		dy = -msg[2];
132
		mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks));
133
	}
134
}
135
 
136
/*
137
 *  set up a ps2 mouse
138
 */
139
static void
140
ps2mouse(void)
141
{
142
	if(mousetype == MousePS2)
143
		return;
144
 
145
//	i8042auxenable(ps2mouseputc);
146
//	i8042auxcmd(0xEA);	// TODO
147
//	i8042auxcmd(0xF4);
148
 
149
	mousetype = MousePS2;
150
	packetsize = 3;
151
	mousehwaccel = 1;
152
}
153
 
154
/*
155
 * The PS/2 Trackpoint multiplexor on the IBM Thinkpad T23 ignores
156
 * acceleration commands.  It is supposed to pass them on
157
 * to the attached device, but my Logitech mouse is simply
158
 * not behaving any differently.  For such devices, we allow
159
 * the user to use "hwaccel off" to tell us to back off to
160
 * software acceleration even if we're using the PS/2 port.
161
 * (Serial mice are always software accelerated.)
162
 * For more information on the Thinkpad multiplexor, see
163
 * http://wwwcssrv.almaden.ibm.com/trackpoint/
164
 */
165
static void
166
setaccelerated(int x)
167
{
168
	accelerated = x;
169
	mouseaccelerate(x);
170
}
171
 
172
static void
173
setlinear(void)
174
{
175
	accelerated = 0;
176
	mouseaccelerate(0);
177
}
178
 
179
static void
180
setres(int n)
181
{
182
	resolution = n;
183
}
184
 
185
static void
186
setintellimouse(void)
187
{
188
	intellimouse = 1;
189
	packetsize = 4;
190
}
191
 
192
static void
193
resetmouse(void)
194
{
195
	packetsize = 3;
196
}
197
 
198
void
199
mousectl(Cmdbuf *cb)
200
{
201
	Cmdtab *ct;
202
 
203
	qlock(&mousectlqlock);
204
	if(waserror()){
205
		qunlock(&mousectlqlock);
206
		nexterror();
207
	}
208
 
209
	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
210
	switch(ct->index){
211
	case CMaccelerated:
212
		setaccelerated(cb->nf == 1? 1: atoi(cb->f[1]));
213
		break;
214
	case CMintellimouse:
215
		setintellimouse();
216
		break;
217
	case CMlinear:
218
		setlinear();
219
		break;
220
	case CMps2:
221
		intellimouse = 0;
222
		break;
223
	case CMps2intellimouse:
224
		setintellimouse();
225
		break;
226
	case CMres:
227
		if(cb->nf >= 2)
228
			setres(atoi(cb->f[1]));
229
		else
230
			setres(1);
231
		break;
232
	case CMreset:
233
		resetmouse();
234
		if(accelerated)
235
			setaccelerated(accelerated);
236
		if(resolution)
237
			setres(resolution);
238
		if(intellimouse)
239
			setintellimouse();
240
		break;
241
	case CMserial:
242
		error("serial mice not supported");
243
		break;
244
	case CMhwaccel:
245
		if(strcmp(cb->f[1], "on")==0)
246
			mousehwaccel = 1;
247
		else if(strcmp(cb->f[1], "off")==0)
248
			mousehwaccel = 0;
249
		else
250
			cmderror(cb, "bad mouse control message");
251
	}
252
 
253
	qunlock(&mousectlqlock);
254
	poperror();
255
}