2 #include "../port/lib.h"
6 #include "../port/error.h"
25 static QLock mousectlqlock;
27 static int intellimouse;
28 static int packetsize;
29 static int resolution;
30 static int accelerated;
31 static int mousehwaccel;
32 static char mouseport[5];
47 static Cmdtab mousectlmsg[] =
49 CMaccelerated, "accelerated", 0,
50 CMhwaccel, "hwaccel", 2,
51 CMintellimouse, "intellimouse", 1,
52 CMlinear, "linear", 1,
54 CMps2intellimouse, "ps2intellimouse", 1,
57 CMserial, "serial", 0,
61 * ps/2 mouse message is three bytes
63 * byte 0 - 0 0 SDY SDX 1 M R L
67 * shift & right button is the same as middle button
69 * Intellimouse and AccuPoint with extra buttons deliver
70 * byte 3 - 00 or 01 or FF according to extra button state.
71 * extra buttons are mapped in this code to buttons 4 and 5.
72 * AccuPoint generates repeated events for these buttons;
73 * it and Intellimouse generate 'down' events only, so
74 * user-level code is required to generate button 'up' events
75 * if they are needed by the application.
76 * Also on laptops with AccuPoint AND external mouse, the
77 * controller may deliver 3 or 4 bytes according to the type
78 * of the external mouse; code must adapt.
80 * On the NEC Versa series (and perhaps others?) we seem to
81 * lose a byte from the packet every once in a while, which
82 * means we lose where we are in the instruction stream.
83 * To resynchronize, if we get a byte more than two seconds
84 * after the previous byte, we assume it's the first in a packet.
87 ps2mouseputc(int c, int shift)
91 static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 };
92 static ulong lasttick;
97 * Resynchronize in stream with timing; see comment above.
100 if(TK2SEC(m - lasttick) > 2)
105 * check byte 0 for consistency
107 if(nb==0 && (c&0xc8)!=0x08){
108 if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){
109 /* last byte of 4-byte packet */
116 if(++nb == packetsize){
123 buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
124 if(intellimouse && packetsize==4){
125 if((msg[3]&0xc8) == 0x08){
126 /* first byte of 3-byte packet */
130 /* fall through to emit previous packet */
132 /* The AccuPoint on the Toshiba 34[48]0CT
133 * encodes extra buttons as 4 and 5. They repeat
134 * and don't release, however, so user-level
135 * timing code is required. Furthermore,
136 * intellimice with 3buttons + scroll give a
137 * two's complement number in the lower 4 bits
138 * (bit 4 is sign extension) that describes
139 * the amount the scroll wheel has moved during
140 * the last sample. Here we use only the sign to
141 * decide whether the wheel is moving up or down
142 * and generate a single button 4 or 5 click
145 if((msg[3] >> 3) & 1)
147 else if(msg[3] & 0x7)
153 mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks));
164 if(mousetype == MousePS2)
167 i8042auxenable(ps2mouseputc);
168 /* make mouse streaming, enabled */
172 mousetype = MousePS2;
178 * The PS/2 Trackpoint multiplexor on the IBM Thinkpad T23 ignores
179 * acceleration commands. It is supposed to pass them on
180 * to the attached device, but my Logitech mouse is simply
181 * not behaving any differently. For such devices, we allow
182 * the user to use "hwaccel off" to tell us to back off to
183 * software acceleration even if we're using the PS/2 port.
184 * (Serial mice are always software accelerated.)
185 * For more information on the Thinkpad multiplexor, see
186 * http://wwwcssrv.almaden.ibm.com/trackpoint/
189 setaccelerated(int x)
229 setintellimouse(void)
235 i8042auxcmd(0xF3); /* set sample */
237 i8042auxcmd(0xF3); /* set sample */
239 i8042auxcmd(0xF3); /* set sample */
243 uartsetmouseputc(mouseport, m5mouseputc);
255 i8042auxcmd(0xEA); /* streaming */
256 i8042auxcmd(0xE8); /* set resolution */
258 i8042auxcmd(0xF4); /* enabled */
268 qlock(&mousectlqlock);
270 qunlock(&mousectlqlock);
274 ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
277 setaccelerated(cb->nf == 1 ? 1 : atoi(cb->f[1]));
289 case CMps2intellimouse:
295 setres(atoi(cb->f[1]));
302 setaccelerated(accelerated);
309 if(mousetype == Mouseserial)
313 if(strcmp(cb->f[2], "M") == 0)
314 uartmouse(cb->f[1], m3mouseputc, 0);
315 else if(strcmp(cb->f[2], "MI") == 0)
316 uartmouse(cb->f[1], m5mouseputc, 0);
318 uartmouse(cb->f[1], mouseputc, cb->nf == 1);
320 uartmouse(cb->f[1], mouseputc, cb->nf == 1);
322 mousetype = Mouseserial;
323 strncpy(mouseport, cb->f[1], sizeof(mouseport)-1);
324 mouseport[sizeof(mouseport)-1] = 0;
328 if(strcmp(cb->f[1], "on")==0)
330 else if(strcmp(cb->f[1], "off")==0)
333 cmderror(cb, "bad mouse control message");
336 qunlock(&mousectlqlock);