1 dawes 1.64 /* $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c,v 1.63 2002/12/15 01:15:04 dawes Exp $ */
|
2 dawes 1.1 /*
3 *
4 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
5 * Copyright 1993 by David Dawes <dawes@xfree86.org>
|
6 eich 1.52 * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich
7 * Copyright 1994-2002 by The XFree86 Project, Inc.
|
8 dawes 1.64 * Copyright 2002 by Paul Elliott
|
9 dawes 1.1 *
10 * Permission to use, copy, modify, distribute, and sell this software and its
11 * documentation for any purpose is hereby granted without fee, provided that
12 * the above copyright notice appear in all copies and that both that
13 * copyright notice and this permission notice appear in supporting
14 * documentation, and that the names of copyright holders not be
15 * used in advertising or publicity pertaining to distribution of the
16 * software without specific, written prior permission. The copyright holders
17 * make no representations about the suitability of this
18 * software for any purpose. It is provided "as is" without express or
19 * implied warranty.
20 *
21 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
22 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
23 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
25 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
26 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
27 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 *
29 */
30 dawes 1.1 /* Patch for PS/2 Intellimouse - Tim Goodwin 1997-11-06. */
31
32 /*
33 * [JCH-96/01/21] Added fourth button support for PROT_GLIDEPOINT mouse
34 * protocol.
35 */
36
37 /*
38 * [TVO-97/03/05] Added microsoft IntelliMouse support
39 */
40
|
41 dawes 1.64 /*
42 * [PME-02/08/11] Added suport for drag lock buttons
43 * for use with 4 button trackballs for convenience
44 * and to help limited dexterity persons
45 */
46
|
47 dawes 1.1 #define NEED_EVENTS
48 #include "X.h"
49 #include "Xproto.h"
50
51 #include "xf86.h"
52
53 #ifdef XINPUT
54 #include "XI.h"
55 #include "XIproto.h"
56 #include "extnsionst.h"
57 #include "extinit.h"
58 #else
59 #include "inputstr.h"
60 #endif
61
62 #include "xf86Xinput.h"
63 #include "xf86_OSproc.h"
64 #include "xf86OSmouse.h"
|
65 dawes 1.4 #define NEED_XF86_TYPES /* for xisb.h when !XFree86LOADER */
|
66 dawes 1.1 #include "xf86_ansic.h"
|
67 tsi 1.34 #include "compiler.h"
68
|
69 dawes 1.1 #include "xisb.h"
70 #include "mouse.h"
|
71 eich 1.30 #include "mousePriv.h"
|
72 dawes 1.1 #include "mipointer.h"
73
|
74 dawes 1.64 enum {
75 /* number of bits in mapped nibble */
76 NIB_BITS=4,
77 /* size of map of nibbles to bitmask */
78 NIB_SIZE= (1 << NIB_BITS),
79 /* mask for map */
80 NIB_MASK= (NIB_SIZE -1),
81 /* number of maps to map all the buttons */
82 NIB_COUNT = ((MSE_MAXBUTTONS+NIB_BITS-1)/NIB_BITS)
83 };
84
85 /*data to be used in implementing trackball drag locks.*/
86 typedef struct _DragLockRec {
87
88 /* Fields used to implement trackball drag locks. */
89 /* mask for those buttons that are ordinary drag lock buttons */
90 int lockButtonsM;
91
92 /* mask for the master drag lock button if any */
93 int masterLockM;
94
95 dawes 1.64 /* button state up/down from last time adjusted for drag locks */
96 int lockLastButtons;
97
98 /*
99 * true if master lock state i.e. master drag lock
100 * button has just been pressed
101 */
102 int masterTS;
103
104 /* simulate these buttons being down although they are not */
105 int simulatedDown;
106
107 /*
108 * data to map bits for drag lock buttons to corresponding
109 * bits for the target buttons
110 */
111 int nib_table[NIB_COUNT][NIB_SIZE];
112
113 } DragLockRec, *DragLockPtr;
114
115
116 dawes 1.64
|
117 tsi 1.57 #ifdef XFree86LOADER
|
118 paulo 1.42 static const OptionInfoRec *MouseAvailableOptions(void *unused);
|
119 tsi 1.57 #endif
|
120 dawes 1.1 static InputInfoPtr MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags);
121 #if 0
122 static void MouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
123 #endif
124
125 static int MouseProc(DeviceIntPtr device, int what);
126 static Bool MouseConvert(LocalDevicePtr local, int first, int num, int v0,
127 int v1, int v2, int v3, int v4, int v5, int *x,
128 int *y);
|
129 dawes 1.7
130 static void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
|
131 dawes 1.8 static void MousePostEvent(InputInfoPtr pInfo, int buttons,
|
132 dawes 1.25 int dx, int dy, int dz, int dw);
|
133 robin 1.22 static void MouseReadInput(InputInfoPtr pInfo);
|
134 eich 1.52 static void MouseBlockHandler(pointer data, struct timeval **waitTime,
135 pointer LastSelectMask);
136 static void MouseWakeupHandler(pointer data, int i, pointer LastSelectMask);
137 static void FlushButtons(MouseDevPtr pMse);
138
139 static Bool SetupMouse(InputInfoPtr pInfo);
140 static Bool initMouseHW(InputInfoPtr pInfo);
141 #ifdef SUPPORT_MOUSE_RESET
142 static Bool mouseReset(InputInfoPtr pInfo, unsigned char val);
143 static void ps2WakeupHandler(pointer data, int i, pointer LastSelectMask);
144 static void ps2BlockHandler(pointer data, struct timeval **waitTime,
145 pointer LastSelectMask);
146 #endif
147
148 /* mouse autoprobe stuff */
149 static const char *autoOSProtocol(InputInfoPtr pInfo, int *protoPara);
150 static void autoProbeMouse(InputInfoPtr pInfo, Bool inSync, Bool lostSync);
151 static void checkForErraticMovements(InputInfoPtr pInfo, int dx, int dy);
152 static Bool collectData(MouseDevPtr pMse, unsigned char u);
153 static void SetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID);
|
154 eich 1.55 static Bool autoGood(MouseDevPtr pMse);
|
155 dawes 1.1
|
156 dawes 1.6 #undef MOUSE
157 InputDriverRec MOUSE = {
|
158 dawes 1.1 1,
159 "mouse",
160 NULL,
161 MousePreInit,
162 /*MouseUnInit,*/NULL,
163 NULL,
164 0
165 };
166
|
167 paulo 1.42 typedef enum {
168 OPTION_ALWAYS_CORE,
169 OPTION_SEND_CORE_EVENTS,
170 OPTION_CORE_POINTER,
171 OPTION_SEND_DRAG_EVENTS,
172 OPTION_HISTORY_SIZE,
173 OPTION_DEVICE,
174 OPTION_PROTOCOL,
175 OPTION_BUTTONS,
176 OPTION_EMULATE_3_BUTTONS,
177 OPTION_EMULATE_3_TIMEOUT,
178 OPTION_CHORD_MIDDLE,
179 OPTION_FLIP_XY,
180 OPTION_INV_X,
181 OPTION_INV_Y,
|
182 dawes 1.63 OPTION_ANGLE_OFFSET,
|
183 paulo 1.42 OPTION_Z_AXIS_MAPPING,
184 OPTION_SAMPLE_RATE,
185 OPTION_RESOLUTION,
|
186 eich 1.52 OPTION_EMULATE_WHEEL,
187 OPTION_EMU_WHEEL_BUTTON,
188 OPTION_EMU_WHEEL_INERTIA,
189 OPTION_X_AXIS_MAPPING,
190 OPTION_Y_AXIS_MAPPING,
191 OPTION_AUTO_SOFT,
|
192 paulo 1.42 OPTION_CLEAR_DTR,
193 OPTION_CLEAR_RTS,
194 OPTION_BAUD_RATE,
195 OPTION_DATA_BITS,
196 OPTION_STOP_BITS,
197 OPTION_PARITY,
198 OPTION_FLOW_CONTROL,
199 OPTION_VTIME,
|
200 dawes 1.64 OPTION_VMIN,
201 OPTION_DRAGLOCKBUTTONS
|
202 paulo 1.42 } MouseOpts;
203
|
204 eich 1.48 static const OptionInfoRec mouseOptions[] = {
|
205 paulo 1.42 { OPTION_ALWAYS_CORE, "AlwaysCore", OPTV_BOOLEAN, {0}, FALSE },
206 { OPTION_SEND_CORE_EVENTS, "SendCoreEvents", OPTV_BOOLEAN, {0}, FALSE },
207 { OPTION_CORE_POINTER, "CorePointer", OPTV_BOOLEAN, {0}, FALSE },
208 { OPTION_SEND_DRAG_EVENTS, "SendDragEvents", OPTV_BOOLEAN, {0}, FALSE },
209 { OPTION_HISTORY_SIZE, "HistorySize", OPTV_INTEGER, {0}, FALSE },
210 { OPTION_DEVICE, "Device", OPTV_STRING, {0}, FALSE },
211 { OPTION_PROTOCOL, "Protocol", OPTV_STRING, {0}, FALSE },
212 { OPTION_BUTTONS, "Buttons", OPTV_INTEGER, {0}, FALSE },
213 { OPTION_EMULATE_3_BUTTONS, "Emulate3Buttons",OPTV_BOOLEAN, {0}, FALSE },
214 { OPTION_EMULATE_3_TIMEOUT, "Emulate3Timeout",OPTV_INTEGER, {0}, FALSE },
215 { OPTION_CHORD_MIDDLE, "ChordMiddle", OPTV_BOOLEAN, {0}, FALSE },
216 { OPTION_FLIP_XY, "FlipXY", OPTV_BOOLEAN, {0}, FALSE },
217 { OPTION_INV_X, "InvX", OPTV_BOOLEAN, {0}, FALSE },
218 { OPTION_INV_Y, "InvY", OPTV_BOOLEAN, {0}, FALSE },
|
219 dawes 1.63 { OPTION_ANGLE_OFFSET, "AngleOffset", OPTV_INTEGER, {0}, FALSE },
|
220 paulo 1.42 { OPTION_Z_AXIS_MAPPING, "ZAxisMapping", OPTV_STRING, {0}, FALSE },
221 { OPTION_SAMPLE_RATE, "SampleRate", OPTV_INTEGER, {0}, FALSE },
222 { OPTION_RESOLUTION, "Resolution", OPTV_INTEGER, {0}, FALSE },
|
223 eich 1.52 { OPTION_EMULATE_WHEEL, "EmulateWheel", OPTV_BOOLEAN, {0}, FALSE },
224 { OPTION_EMU_WHEEL_BUTTON, "EmulateWheelButton", OPTV_INTEGER, {0}, FALSE },
225 { OPTION_EMU_WHEEL_INERTIA, "EmulateWheelInertia", OPTV_INTEGER, {0}, FALSE },
226 { OPTION_X_AXIS_MAPPING, "XAxisMapping", OPTV_STRING, {0}, FALSE },
227 { OPTION_Y_AXIS_MAPPING, "YAxisMapping", OPTV_STRING, {0}, FALSE },
228 { OPTION_AUTO_SOFT, "AutoSoft", OPTV_BOOLEAN, {0}, FALSE },
229 /* serial options */
|
230 paulo 1.42 { OPTION_CLEAR_DTR, "ClearDTR", OPTV_BOOLEAN, {0}, FALSE },
231 { OPTION_CLEAR_RTS, "ClearRTS", OPTV_BOOLEAN, {0}, FALSE },
232 { OPTION_BAUD_RATE, "BaudRate", OPTV_INTEGER, {0}, FALSE },
233 { OPTION_DATA_BITS, "DataBits", OPTV_INTEGER, {0}, FALSE },
234 { OPTION_STOP_BITS, "StopBits", OPTV_INTEGER, {0}, FALSE },
235 { OPTION_PARITY, "Parity", OPTV_STRING, {0}, FALSE },
236 { OPTION_FLOW_CONTROL, "FlowControl", OPTV_STRING, {0}, FALSE },
237 { OPTION_VTIME, "VTime", OPTV_INTEGER, {0}, FALSE },
238 { OPTION_VMIN, "VMin", OPTV_INTEGER, {0}, FALSE },
|
239 dawes 1.64 { OPTION_DRAGLOCKBUTTONS, "DragLockButtons",OPTV_STRING, {0}, FALSE },
|
240 eich 1.52 /* end serial options */
|
241 paulo 1.42 { -1, NULL, OPTV_NONE, {0}, FALSE }
242 };
243
|
244 dawes 1.1 /*
245 * Microsoft (all serial models), Logitech MouseMan, First Mouse, etc,
246 * ALPS GlidePoint, Thinking Mouse.
247 */
248 static const char *msDefaults[] = {
249 "BaudRate", "1200",
250 "DataBits", "7",
251 "StopBits", "1",
252 "Parity", "None",
253 "FlowControl", "None",
254 "VTime", "0",
255 "VMin", "1",
256 NULL
257 };
258 /* MouseSystems */
|
259 eich 1.52 static const char *mlDefaults[] = {
|
260 dawes 1.1 "BaudRate", "1200",
261 "DataBits", "8",
262 "StopBits", "2",
263 "Parity", "None",
264 "FlowControl", "None",
265 "VTime", "0",
266 "VMin", "1",
267 NULL
268 };
269 /* MMSeries */
270 static const char *mmDefaults[] = {
271 "BaudRate", "1200",
272 "DataBits", "8",
273 "StopBits", "1",
274 "Parity", "Odd",
275 "FlowControl", "None",
276 "VTime", "0",
277 "VMin", "1",
278 NULL
279 };
|
280 eich 1.52 #if 0
281 /* Logitech series 9 *//* same as msc: now mlDefaults */
|
282 dawes 1.1 static const char *logiDefaults[] = {
283 "BaudRate", "1200",
284 "DataBits", "8",
285 "StopBits", "2",
286 "Parity", "None",
287 "FlowControl", "None",
288 "VTime", "0",
289 "VMin", "1",
290 NULL
291 };
|
292 eich 1.52 #endif
|
293 dawes 1.1 /* Hitachi Tablet */
294 static const char *mmhitDefaults[] = {
295 "BaudRate", "1200",
296 "DataBits", "8",
297 "StopBits", "1",
298 "Parity", "None",
299 "FlowControl", "None",
300 "VTime", "0",
301 "VMin", "1",
302 NULL
303 };
304 /* AceCad Tablet */
305 static const char *acecadDefaults[] = {
306 "BaudRate", "9600",
307 "DataBits", "8",
308 "StopBits", "1",
309 "Parity", "Odd",
310 "FlowControl", "None",
311 "VTime", "0",
312 "VMin", "1",
313 NULL
314 dawes 1.1 };
315
316 static MouseProtocolRec mouseProtocols[] = {
317
318 /* Serial protocols */
319 { "Microsoft", MSE_SERIAL, msDefaults, PROT_MS },
|
320 eich 1.52 { "MouseSystems", MSE_SERIAL, mlDefaults, PROT_MSC },
|
321 dawes 1.1 { "MMSeries", MSE_SERIAL, mmDefaults, PROT_MM },
|
322 eich 1.52 { "Logitech", MSE_SERIAL, mlDefaults, PROT_LOGI },
|
323 dawes 1.1 { "MouseMan", MSE_SERIAL, msDefaults, PROT_LOGIMAN },
324 { "MMHitTab", MSE_SERIAL, mmhitDefaults, PROT_MMHIT },
325 { "GlidePoint", MSE_SERIAL, msDefaults, PROT_GLIDE },
326 { "IntelliMouse", MSE_SERIAL, msDefaults, PROT_IMSERIAL },
327 { "ThinkingMouse", MSE_SERIAL, msDefaults, PROT_THINKING },
328 { "AceCad", MSE_SERIAL, acecadDefaults, PROT_ACECAD },
329
330 /* Standard PS/2 */
331 { "PS/2", MSE_PS2, NULL, PROT_PS2 },
|
332 eich 1.55 { "GenericPS/2", MSE_PS2, NULL, PROT_GENPS2 },
|
333 dawes 1.1
334 /* Extended PS/2 */
335 { "ImPS/2", MSE_XPS2, NULL, PROT_IMPS2 },
|
336 dawes 1.25 { "ExplorerPS/2", MSE_XPS2, NULL, PROT_EXPPS2 },
|
337 dawes 1.1 { "ThinkingMousePS/2", MSE_XPS2, NULL, PROT_THINKPS2 },
338 { "MouseManPlusPS/2", MSE_XPS2, NULL, PROT_MMPS2 },
339 { "GlidePointPS/2", MSE_XPS2, NULL, PROT_GLIDEPS2 },
340 { "NetMousePS/2", MSE_XPS2, NULL, PROT_NETPS2 },
341 { "NetScrollPS/2", MSE_XPS2, NULL, PROT_NETSCPS2 },
342
343 /* Bus Mouse */
344 { "BusMouse", MSE_BUS, NULL, PROT_BM },
345
346 /* Auto-detect (PnP) */
347 { "Auto", MSE_AUTO, NULL, PROT_AUTO },
348
|
349 dawes 1.2 /* Misc (usually OS-specific) */
|
350 eich 1.52 { "SysMouse", MSE_MISC, mlDefaults, PROT_SYSMOUSE },
|
351 dawes 1.2
|
352 dawes 1.1 /* end of list */
353 { NULL, MSE_NONE, NULL, PROT_UNKNOWN }
354 };
355
|
356 tsi 1.57 #ifdef XFree86LOADER
|
357 paulo 1.42 /*ARGSUSED*/
358 static const OptionInfoRec *
359 MouseAvailableOptions(void *unused)
360 {
|
361 eich 1.48 return (mouseOptions);
|
362 paulo 1.42 }
|
363 tsi 1.57 #endif
|
364 paulo 1.42
|
365 dawes 1.8 /* Process options common to all mouse types. */
366 static void
367 MouseCommonOptions(InputInfoPtr pInfo)
368 {
369 MouseDevPtr pMse;
370 MessageType from = X_DEFAULT;
|
371 dawes 1.10 char *s;
|
372 dawes 1.45 int origButtons;
|
373 dawes 1.8
374 pMse = pInfo->private;
375
376 pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
377 from = X_CONFIG;
378 if (!pMse->buttons) {
379 pMse->buttons = MSE_DFLTBUTTONS;
380 from = X_DEFAULT;
381 }
|
382 dawes 1.45 origButtons = pMse->buttons;
383
|
384 dawes 1.8 pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options,
385 "Emulate3Buttons", FALSE);
|
386 eich 1.55 if (!xf86FindOptionValue(pInfo->options,"Emulate3Buttons"))
387 pMse->emulate3ButtonsSoft = TRUE;
|
388 eich 1.52
|
389 eich 1.55 pMse->emulate3Timeout = xf86SetIntOption(pInfo->options,
390 "Emulate3Timeout", 50);
|
391 eich 1.52 if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) {
|
392 dawes 1.8 xf86Msg(X_CONFIG, "%s: Emulate3Buttons, Emulate3Timeout: %d\n",
393 pInfo->name, pMse->emulate3Timeout);
394 }
395
396 pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE);
397 if (pMse->chordMiddle)
398 xf86Msg(X_CONFIG, "%s: ChordMiddle\n", pInfo->name);
|
399 dawes 1.45 pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE);
|
400 eich 1.24 if (pMse->flipXY)
|
401 dawes 1.45 xf86Msg(X_CONFIG, "%s: FlipXY\n", pInfo->name);
402 if (xf86SetBoolOption(pInfo->options, "InvX", FALSE)) {
|
403 eich 1.24 pMse->invX = -1;
|
404 dawes 1.45 xf86Msg(X_CONFIG, "%s: InvX\n", pInfo->name);
405 } else
|
406 eich 1.24 pMse->invX = 1;
|
407 dawes 1.45 if (xf86SetBoolOption(pInfo->options, "InvY", FALSE)) {
|
408 eich 1.24 pMse->invY = -1;
|
409 dawes 1.45 xf86Msg(X_CONFIG, "%s: InvY\n", pInfo->name);
410 } else
|
411 eich 1.24 pMse->invY = 1;
|
412 dawes 1.63 pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0);
|
413 eich 1.24
|
414 dawes 1.64
415 if (pMse->pDragLock)
416 xfree(pMse->pDragLock);
417 pMse->pDragLock = NULL;
418
419 s = xf86SetStrOption(pInfo->options, "DragLockButtons", NULL);
420
421 if (s) {
422 int lock; /* lock button */
423 int target; /* target button */
424 int lockM,targetM; /* bitmasks for drag lock, target */
425 int i, j; /* indexes */
426 char *s1; /* parse input string */
427 DragLockPtr pLock;
428
429 pLock = pMse->pDragLock = xcalloc(1, sizeof(DragLockRec));
430 /* init code */
431
432 /* initial string to be taken apart */
433 s1 = s;
434
435 dawes 1.64 /* keep getting numbers which are buttons */
436 while ((s1 != NULL) && (lock = strtol(s1, &s1, 10)) != 0) {
437
438 /* check sanity for a button */
439 if ((lock < 0) || (lock > MSE_MAXBUTTONS)) {
440 xf86Msg(X_WARNING, "DragLock: Invalid button number = %d\n",
441 lock);
442 break;
443 };
444 /* turn into a button mask */
445 lockM = 1 << (lock - 1);
446
447 /* try to get drag lock button */
448 if ((s1 == NULL) || ((target=strtol(s1, &s1, 10)) == 0)) {
449 /*if no target, must be a master drag lock button */
450 /* save master drag lock mask */
451 pLock->masterLockM = lockM;
452 xf86Msg(X_CONFIG,
453 "DragLock button %d is master drag lock",
454 lock);
455 } else {
456 dawes 1.64 /* have target button number*/
457 /* check target button number for sanity */
458 if ((target < 0) || (target > MSE_MAXBUTTONS)) {
459 xf86Msg(X_WARNING,
460 "DragLock: Invalid button number for target=%d\n",
461 target);
462 break;
463 }
464
465 /* target button mask */
466 targetM = 1 << (target - 1);
467
468 xf86Msg(X_CONFIG,
469 "DragLock: button %d is drag lock for button %d\n",
470 lock,target);
471 lock--;
472
473 /* initialize table that maps drag lock mask to target mask */
474 pLock->nib_table[lock / NIB_SIZE][1 << (lock % NIB_BITS)] =
475 targetM;
476
477 dawes 1.64 /* add new drag lock to mask of drag locks */
478 pLock->lockButtonsM |= lockM;
479 }
480
481 }
482
483 /*
484 * fill out rest of map that maps sets of drag lock buttons
485 * to sets of target buttons, in the form of masks
486 */
487
488 /* for each nibble */
489 for (i = 0; i < NIB_COUNT; i++) {
490 /* for each possible set of bits for that nibble */
491 for (j = 0; j < NIB_SIZE; j++) {
492 int ff, fM, otherbits;
493
494 /* get first bit set in j*/
495 ff = ffs(j) - 1;
496 /* if 0 bits set nothing to do */
497 if (ff >= 0) {
498 dawes 1.64 /* form mask for fist bit set */
499 fM = 1 << ff;
500 /* mask off first bit set to get remaining bits set*/
501 otherbits = j & ~fM;
502 /*
503 * if otherbits =0 then only 1 bit set
504 * so j=fM
505 * nib_table[i][fM] already calculated if fM has
506 * only 1 bit set.
507 * nib_table[i][j] has already been filled in
508 * by previous loop. otherwise
509 * otherbits < j so nibtable[i][otherbits]
510 * has already been calculated.
511 */
512 if (otherbits)
513 pLock->nib_table[i][j] =
514 pLock->nib_table[i][fM] |
515 pLock->nib_table[i][otherbits];
516
517 }
518 }
519 dawes 1.64 }
520 }
521
|
522 dawes 1.10 s = xf86SetStrOption(pInfo->options, "ZAxisMapping", NULL);
523 if (s) {
|
524 dawes 1.25 int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
|
525 dawes 1.10 char *msg = NULL;
526
527 if (!xf86NameCmp(s, "x")) {
528 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
|
529 dawes 1.25 pMse->negativeW = pMse->positiveW = MSE_MAPTOX;
|
530 dawes 1.10 msg = xstrdup("X axis");
531 } else if (!xf86NameCmp(s, "y")) {
532 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY;
|
533 dawes 1.25 pMse->negativeW = pMse->positiveW = MSE_MAPTOY;
|
534 dawes 1.10 msg = xstrdup("Y axis");
|
535 dawes 1.25 } else if (sscanf(s, "%d %d %d %d", &b1, &b2, &b3, &b4) >= 2 &&
|
536 dawes 1.10 b1 > 0 && b1 <= MSE_MAXBUTTONS &&
537 b2 > 0 && b2 <= MSE_MAXBUTTONS) {
538 msg = xstrdup("buttons XX and YY");
539 if (msg)
540 sprintf(msg, "buttons %d and %d", b1, b2);
|
541 dawes 1.25 pMse->negativeZ = pMse->negativeW = 1 << (b1-1);
542 pMse->positiveZ = pMse->positiveW = 1 << (b2-1);
543 if (b3 > 0 && b3 <= MSE_MAXBUTTONS &&
544 b4 > 0 && b4 <= MSE_MAXBUTTONS) {
545 if (msg)
546 xfree(msg);
547 msg = xstrdup("buttons XX, YY, ZZ and WW");
548 if (msg)
549 sprintf(msg, "buttons %d, %d, %d and %d", b1, b2, b3, b4);
550 pMse->negativeW = 1 << (b3-1);
551 pMse->positiveW = 1 << (b4-1);
552 }
|
553 dawes 1.45 if (b1 > pMse->buttons) pMse->buttons = b1;
554 if (b2 > pMse->buttons) pMse->buttons = b2;
555 if (b3 > pMse->buttons) pMse->buttons = b3;
556 if (b4 > pMse->buttons) pMse->buttons = b4;
|
557 dawes 1.10 } else {
558 pMse->negativeZ = pMse->positiveZ = MSE_NOZMAP;
|
559 dawes 1.25 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
|
560 dawes 1.10 }
561 if (msg) {
562 xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg);
563 xfree(msg);
564 } else {
565 xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n",
566 pInfo->name, s);
567 }
568 }
|
569 dawes 1.45 if (xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE)) {
570 Bool yFromConfig = FALSE;
571 int wheelButton;
572
573 pMse->emulateWheel = TRUE;
574 wheelButton = xf86SetIntOption(pInfo->options,
575 "EmulateWheelButton", 4);
576 if (wheelButton < 0 || wheelButton > MSE_MAXBUTTONS) {
577 xf86Msg(X_WARNING, "%s: Invalid EmulateWheelButton value: %d\n",
578 pInfo->name, wheelButton);
579 wheelButton = 4;
580 }
581 pMse->wheelButtonMask = 1 << (wheelButton - 1);
582
583 pMse->wheelInertia = xf86SetIntOption(pInfo->options,
|
584 dawes 1.49 "EmulateWheelInertia", 10);
|
585 dawes 1.45 if (pMse->wheelInertia <= 0) {
586 xf86Msg(X_WARNING, "%s: Invalid EmulateWheelInertia value: %d\n",
587 pInfo->name, pMse->wheelInertia);
588 pMse->wheelInertia = 50;
589 }
590
591 pMse->negativeX = MSE_NOAXISMAP;
592 pMse->positiveX = MSE_NOAXISMAP;
593 s = xf86SetStrOption(pInfo->options, "XAxisMapping", NULL);
594 if (s) {
595 int b1 = 0, b2 = 0;
596 char *msg = NULL;
597
598 if ((sscanf(s, "%d %d", &b1, &b2) == 2) &&
599 b1 > 0 && b1 <= MSE_MAXBUTTONS &&
600 b2 > 0 && b2 <= MSE_MAXBUTTONS) {
601 msg = xstrdup("buttons XX and YY");
602 if (msg)
603 sprintf(msg, "buttons %d and %d", b1, b2);
604 pMse->negativeX = b1;
605 pMse->positiveX = b2;
606 dawes 1.45 if (b1 > pMse->buttons) pMse->buttons = b1;
607 if (b2 > pMse->buttons) pMse->buttons = b2;
608 } else {
609 xf86Msg(X_WARNING, "%s: Invalid XAxisMapping value: \"%s\"\n",
610 pInfo->name, s);
611 }
612 if (msg) {
613 xf86Msg(X_CONFIG, "%s: XAxisMapping: %s\n", pInfo->name, msg);
614 xfree(msg);
615 }
616 }
617 s = xf86SetStrOption(pInfo->options, "YAxisMapping", NULL);
618 if (s) {
619 int b1 = 0, b2 = 0;
620 char *msg = NULL;
621
622 if ((sscanf(s, "%d %d", &b1, &b2) == 2) &&
623 b1 > 0 && b1 <= MSE_MAXBUTTONS &&
624 b2 > 0 && b2 <= MSE_MAXBUTTONS) {
625 msg = xstrdup("buttons XX and YY");
626 if (msg)
627 dawes 1.45 sprintf(msg, "buttons %d and %d", b1, b2);
628 pMse->negativeY = b1;
629 pMse->positiveY = b2;
630 if (b1 > pMse->buttons) pMse->buttons = b1;
631 if (b2 > pMse->buttons) pMse->buttons = b2;
632 yFromConfig = TRUE;
633 } else {
634 xf86Msg(X_WARNING, "%s: Invalid YAxisMapping value: \"%s\"\n",
635 pInfo->name, s);
636 }
637 if (msg) {
638 xf86Msg(X_CONFIG, "%s: YAxisMapping: %s\n", pInfo->name, msg);
639 xfree(msg);
640 }
641 }
642 if (!yFromConfig) {
643 pMse->negativeY = 4;
644 pMse->positiveY = 5;
645 if (pMse->negativeY > pMse->buttons)
646 pMse->buttons = pMse->negativeY;
647 if (pMse->positiveY > pMse->buttons)
648 dawes 1.45 pMse->buttons = pMse->positiveY;
649 xf86Msg(X_DEFAULT, "%s: YAxisMapping: buttons %d and %d\n",
650 pInfo->name, pMse->negativeY, pMse->positiveY);
651 }
652 xf86Msg(X_CONFIG, "%s: EmulateWheel, EmulateWheelButton: %d, "
653 "EmulateWheelInertia: %d\n",
654 pInfo->name, wheelButton, pMse->wheelInertia);
655 }
656 if (origButtons != pMse->buttons)
657 from = X_CONFIG;
658 xf86Msg(from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons);
659
|
660 dawes 1.8 }
|
661 dawes 1.64 /*
662 * map bits corresponding to lock buttons.
663 * for each bit for a lock button,
664 * turn on bit corresponding to button button that the lock
665 * button services.
666 */
667
668 static int
669 lock2targetMap(DragLockPtr pLock, int lockMask)
670 {
671 int result,i;
672 result = 0;
673
674 /*
675 * for each nibble group of bits, use
676 * map for that group to get corresponding
677 * bits, turn them on.
678 * if 4 or less buttons only first map will
679 * need to be used.
680 */
681 for (i = 0; (i < NIB_COUNT) && lockMask; i++) {
682 dawes 1.64 result |= pLock->nib_table[i][lockMask& NIB_MASK];
683
684 lockMask &= ~NIB_MASK;
685 lockMask >>= NIB_BITS;
686 }
687 return result;
688 }
|
689 dawes 1.8
|
690 eich 1.52 static void
691 MouseHWOptions(InputInfoPtr pInfo)
|
692 dawes 1.1 {
|
693 eich 1.52 MouseDevPtr pMse = pInfo->private;
694 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
695
|
696 herrb 1.53 if (mPriv == NULL)
697 return;
698
|
699 eich 1.52 if ((mPriv->soft
700 = xf86SetBoolOption(pInfo->options, "AutoSoft", FALSE))) {
701 xf86Msg(X_CONFIG, "Don't initialize mouse when auto-probing\n");
702 }
703 pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0);
704 if (pMse->sampleRate) {
705 xf86Msg(X_CONFIG, "%s: SampleRate: %d\n", pInfo->name,
706 pMse->sampleRate);
707 }
708 pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0);
709 if (pMse->resolution) {
710 xf86Msg(X_CONFIG, "%s: Resolution: %d\n", pInfo->name,
711 pMse->resolution);
712 }
713 }
|
714 dawes 1.1
|
715 eich 1.52 static void
716 MouseSerialOptions(InputInfoPtr pInfo)
717 {
718 MouseDevPtr pMse = pInfo->private;
719 Bool clearDTR, clearRTS;
720
721
722 pMse->baudRate = xf86SetIntOption(pInfo->options, "BaudRate", 0);
723 if (pMse->baudRate) {
724 xf86Msg(X_CONFIG, "%s: BaudRate: %d\n", pInfo->name,
725 pMse->baudRate);
726 }
|
727 dawes 1.1
|
728 eich 1.52 if ((clearDTR = xf86SetBoolOption(pInfo->options, "ClearDTR",FALSE)))
729 pMse->mouseFlags |= MF_CLEAR_DTR;
730
731
732 if ((clearRTS = xf86SetBoolOption(pInfo->options, "ClearRTS",FALSE)))
733 pMse->mouseFlags |= MF_CLEAR_RTS;
734
735 if (clearDTR || clearRTS) {
736 xf86Msg(X_CONFIG, "%s: ", pInfo->name);
737 if (clearDTR) {
738 xf86ErrorF("ClearDTR");
739 if (clearRTS)
740 xf86ErrorF(", ");
741 }
742 if (clearRTS) {
743 xf86ErrorF("ClearRTS");
|
744 dawes 1.1 }
|
745 eich 1.52 xf86ErrorF("\n");
|
746 dawes 1.1 }
|
747 eich 1.52 }
|
748 dawes 1.1
|
749 eich 1.52 static MouseProtocolID
750 ProtocolNameToID(const char *name)
751 {
752 int i;
|
753 tsi 1.51
|
754 eich 1.52 for (i = 0; mouseProtocols[i].name; i++)
755 if (xf86NameCmp(name, mouseProtocols[i].name) == 0)
756 return mouseProtocols[i].id;
757 return PROT_UNKNOWN;
758 }
759
760 static const char *
761 ProtocolIDToName(MouseProtocolID id)
762 {
763 int i;
764
765 switch (id) {
766 case PROT_UNKNOWN:
767 return "Unknown";
768 break;
769 case PROT_UNSUP:
770 return "Unsupported";
771 break;
772 default:
773 for (i = 0; mouseProtocols[i].name; i++)
774 if (id == mouseProtocols[i].id)
775 eich 1.52 return mouseProtocols[i].name;
776 return "Invalid";
777 }
778 }
779
780 const char *
781 xf86MouseProtocolIDToName(MouseProtocolID id)
782 {
783 return ProtocolIDToName(id);
784 }
785
786 MouseProtocolID
787 xf86MouseProtocolNameToID(const char *name)
788 {
789 return ProtocolNameToID(name);
790 }
791
792 static int
793 ProtocolIDToClass(MouseProtocolID id)
794 {
795 int i;
796 eich 1.52
797 switch (id) {
798 case PROT_UNKNOWN:
799 case PROT_UNSUP:
800 return MSE_NONE;
801 break;
802 default:
803 for (i = 0; mouseProtocols[i].name; i++)
804 if (id == mouseProtocols[i].id)
805 return mouseProtocols[i].class;
806 return MSE_NONE;
807 }
808 }
809
810 static MouseProtocolPtr
811 GetProtocol(MouseProtocolID id) {
812 int i;
813
814 switch (id) {
815 case PROT_UNKNOWN:
816 case PROT_UNSUP:
817 eich 1.52 return NULL;
818 break;
819 default:
820 for (i = 0; mouseProtocols[i].name; i++)
|
821 eich 1.55 if (id == mouseProtocols[i].id) {
|
822 eich 1.52 return &mouseProtocols[i];
|
823 eich 1.55 }
|
824 eich 1.52 return NULL;
825 }
826 }
827
828 static OSMouseInfoPtr osInfo = NULL;
829
830 static Bool
831 InitProtocols(void)
832 {
833 int classes;
834 int i;
835 const char *osname = NULL;
836
837 if (osInfo)
838 return TRUE;
839
840 osInfo = xf86OSMouseInit(0);
841 if (!osInfo)
842 return FALSE;
843 if (!osInfo->SupportedInterfaces)
844 return FALSE;
845 eich 1.52
846 classes = osInfo->SupportedInterfaces();
847 if (!classes)
848 return FALSE;
849
850 /* Mark unsupported interface classes. */
851 for (i = 0; mouseProtocols[i].name; i++)
852 if (!(mouseProtocols[i].class & classes))
853 mouseProtocols[i].id = PROT_UNSUP;
854
855 for (i = 0; mouseProtocols[i].name; i++)
856 if (mouseProtocols[i].class & MSE_MISC)
857 if (!osInfo->CheckProtocol ||
858 !osInfo->CheckProtocol(mouseProtocols[i].name))
859 mouseProtocols[i].id = PROT_UNSUP;
860
861 /* NetBSD uses PROT_BM for "PS/2". */
862 xf86GetOS(&osname, NULL, NULL, NULL);
863 if (osname && xf86NameCmp(osname, "netbsd") == 0)
864 for (i = 0; mouseProtocols[i].name; i++)
865 if (mouseProtocols[i].id == PROT_PS2)
866 eich 1.52 mouseProtocols[i].id = PROT_BM;
867
868 return TRUE;
869 }
870
871 static InputInfoPtr
872 MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
873 {
874 InputInfoPtr pInfo;
875 MouseDevPtr pMse;
876 mousePrivPtr mPriv;
877 MessageType from = X_DEFAULT;
878 const char *protocol, *osProt = NULL;
879 MouseProtocolID protocolID;
880 MouseProtocolPtr pProto;
881 Bool detected;
882
883 if (!InitProtocols())
884 return NULL;
885
886 if (!(pInfo = xf86AllocateInput(drv, 0)))
887 eich 1.52 return NULL;
888
889 /* Initialise the InputInfoRec. */
890 pInfo->name = dev->identifier;
891 pInfo->type_name = XI_MOUSE;
892 pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
893 pInfo->device_control = MouseProc;
894 pInfo->read_input = MouseReadInput;
895 pInfo->motion_history_proc = xf86GetMotionEvents;
896 pInfo->history_size = 0;
897 pInfo->control_proc = NULL;
898 pInfo->close_proc = NULL;
899 pInfo->switch_mode = NULL;
900 pInfo->conversion_proc = MouseConvert;
901 pInfo->reverse_conversion_proc = NULL;
902 pInfo->fd = -1;
903 pInfo->dev = NULL;
904 pInfo->private_flags = 0;
905 pInfo->always_core_feedback = 0;
906 pInfo->conf_idev = dev;
907
908 eich 1.52 /* Allocate the MouseDevRec and initialise it. */
909 /*
910 * XXX This should be done by a function in the core server since the
911 * MouseDevRec is defined in the os-support layer.
912 */
913 if (!(pMse = xcalloc(sizeof(MouseDevRec), 1)))
914 return pInfo;
915 pInfo->private = pMse;
916 pMse->Ctrl = MouseCtrl;
917 pMse->PostEvent = MousePostEvent;
918 pMse->CommonOptions = MouseCommonOptions;
919
920 /* Find the protocol type. */
921 protocol = xf86SetStrOption(dev->commonOptions, "Protocol", NULL);
922 if (protocol) {
923 from = X_CONFIG;
924 } else if (osInfo->DefaultProtocol) {
925 protocol = osInfo->DefaultProtocol();
926 from = X_DEFAULT;
927 }
928 if (!protocol) {
929 eich 1.52 xf86Msg(X_ERROR, "%s: No Protocol specified\n", pInfo->name);
930 return pInfo;
931 }
932
933 protocolID = ProtocolNameToID(protocol);
934 do {
935 detected = TRUE;
936 switch (protocolID) {
937 case PROT_AUTO:
938 if (osInfo->SetupAuto) {
939 if ((osProt = osInfo->SetupAuto(pInfo,NULL))) {
940 int id = ProtocolNameToID(osProt);
941 if (id == PROT_UNKNOWN || id == PROT_UNSUP) {
942 protocolID = id;
943 protocol = osProt;
944 detected = FALSE;
945 }
946 }
947 }
948 break;
949 case PROT_UNKNOWN:
950 eich 1.52 /* Check for a builtin OS-specific protocol,
951 * and call its PreInit. */
952 if (osInfo->CheckProtocol
953 && osInfo->CheckProtocol(protocol)) {
954 if (osInfo->PreInit) {
955 osInfo->PreInit(pInfo, protocol, 0);
956 }
957 return pInfo;
958 }
959 xf86Msg(X_ERROR, "%s: Unknown protocol \"%s\"\n",
960 pInfo->name, protocol);
961 return pInfo;
962 break;
963 case PROT_UNSUP:
964 xf86Msg(X_ERROR,
965 "%s: Protocol \"%s\" is not supported on this "
966 "platform\n", pInfo->name, protocol);
967 return pInfo;
968 break;
969 default:
970 break;
971 eich 1.52
972 }
973 } while (!detected);
974
975
976 xf86Msg(from, "%s: Protocol: \"%s\"\n", pInfo->name, protocol);
|
977 dawes 1.1 if (!(pProto = GetProtocol(protocolID)))
|
978 dawes 1.4 return pInfo;
|
979 dawes 1.1
980 pMse->protocolID = protocolID;
|
981 eich 1.35 pMse->oldProtocolID = protocolID; /* hack */
|
982 eich 1.52
983 pMse->autoProbe = FALSE;
|
984 dawes 1.1
|
985 dawes 1.7 /* Collect the options, and process the common options. */
986 xf86CollectInputOptions(pInfo, pProto->defaults, NULL);
987 xf86ProcessCommonOptions(pInfo, pInfo->options);
988
|
989 dawes 1.29 /* XXX should handle this OS dependency elsewhere. */
990 #ifndef __OS2ELF__
991 /* OS/2 has a mouse handled by the OS - it cannot fail here */
992
|
993 dawes 1.1 /* Check if the device can be opened. */
994 pInfo->fd = xf86OpenSerial(pInfo->options);
995 if (pInfo->fd == -1) {
996 if (xf86GetAllowMouseOpenFail())
997 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
998 else {
999 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
|
1000 eich 1.48 if (pMse->mousePriv)
1001 xfree(pMse->mousePriv);
|
1002 dawes 1.1 xfree(pMse);
|
1003 dawes 1.13 pInfo->private = NULL;
|
1004 dawes 1.4 return pInfo;
|
1005 dawes 1.1 }
1006 }
1007 xf86CloseSerial(pInfo->fd);
|
1008 dawes 1.29 #endif
|
1009 dawes 1.1 pInfo->fd = -1;
1010
|
1011 eich 1.52 if (!(mPriv = (pointer) xcalloc(sizeof(mousePrivRec), 1)))
1012 return pInfo;
1013 pMse->mousePriv = mPriv;
|
1014 dawes 1.8 pMse->CommonOptions(pInfo);
|
1015 eich 1.52 pMse->checkMovements = checkForErraticMovements;
1016 pMse->autoProbeMouse = autoProbeMouse;
1017 pMse->collectData = collectData;
|
1018 eich 1.55 pMse->dataGood = autoGood;
|
1019 eich 1.52
1020 MouseHWOptions(pInfo);
1021 MouseSerialOptions(pInfo);
1022
|
1023 dawes 1.4 pInfo->flags |= XI86_CONFIGURED;
|
1024 dawes 1.1 return pInfo;
1025 }
1026
1027
|
1028 eich 1.52 static void
1029 MouseReadInput(InputInfoPtr pInfo)
|
1030 dawes 1.1 {
|
1031 eich 1.52 MouseDevPtr pMse;
1032 int j, buttons, dx, dy, dz, dw, baddata;
1033 int pBufP;
1034 int c;
1035 unsigned char *pBuf, u;
1036
|
1037 eich 1.55
|
1038 eich 1.52 pMse = pInfo->private;
1039 pBufP = pMse->protoBufTail;
1040 pBuf = pMse->protoBuf;
1041
|
1042 dawes 1.1 /*
|
1043 eich 1.52 * Set blocking to -1 on the first call because we know there is data to
1044 * read. Xisb automatically clears it after one successful read so that
1045 * succeeding reads are preceeded by a select with a 0 timeout to prevent
1046 * read from blocking indefinitely.
1047 */
1048 XisbBlockDuration(pMse->buffer, -1);
1049
1050 while ((c = XisbRead(pMse->buffer)) >= 0) {
1051 u = (unsigned char)c;
|
1052 eich 1.55 #if 1
|
1053 eich 1.52 /* if we do autoprobing collect the data */
1054 if (pMse->collectData && pMse->autoProbe)
1055 if (pMse->collectData(pMse,u))
1056 continue;
|
1057 eich 1.55 #endif
1058 #ifdef SUPPORT_MOUSE_RESET
|
1059 eich 1.52 if (mouseReset(pInfo,u)) {
1060 pBufP = 0;
1061 continue;
1062 }
1063 #endif
1064 if (pBufP >= pMse->protoPara[4]) {
|
1065 eich 1.55
|
1066 eich 1.52 /*
1067 * Buffer contains a full packet, which has already been processed:
1068 * Empty the buffer and check for optional 4th byte, which will be
1069 * processed directly, without being put into the buffer first.
1070 */
1071 pBufP = 0;
|
1072 dawes 1.1
|
1073 eich 1.52 if ((u & pMse->protoPara[0]) != pMse->protoPara[1] &&
1074 (u & pMse->protoPara[5]) == pMse->protoPara[6]) {
1075 /*
1076 * Hack for Logitech MouseMan Mouse - Middle button
1077 *
1078 * Unfortunately this mouse has variable length packets: the
1079 * standard Microsoft 3 byte packet plus an optional 4th byte
1080 * whenever the middle button status changes.
1081 *
1082 * We have already processed the standard packet with the
1083 * movement and button info. Now post an event message with
1084 * the old status of the left and right buttons and the
1085 * updated middle button.
1086 */
1087 /*
1088 * Even worse, different MouseMen and TrackMen differ in the
1089 * 4th byte: some will send 0x00/0x20, others 0x01/0x21, or
1090 * even 0x02/0x22, so I have to strip off the lower bits.
1091 * [CHRIS-211092]
1092 *
1093 * [JCH-96/01/21]
1094 eich 1.52 * HACK for ALPS "fourth button". (It's bit 0x10 of the
1095 * "fourth byte" and it is activated by tapping the glidepad
1096 * with the finger! 8^) We map it to bit bit3, and the
1097 * reverse map in xf86Events just has to be extended so that
1098 * it is identified as Button 4. The lower half of the
1099 * reverse-map may remain unchanged.
1100 */
1101 /*
1102 * [KAZU-030897]
1103 * Receive the fourth byte only when preceeding three bytes
1104 * have been detected (pBufP >= pMse->protoPara[4]). In the
1105 * previous versions, the test was pBufP == 0; we may have
1106 * mistakingly received a byte even if we didn't see anything
1107 * preceeding the byte.
1108 */
|
1109 dawes 1.1
|
1110 eich 1.52 #ifdef EXTMOUSEDEBUG
1111 ErrorF("mouse 4th byte %02x\n",u);
1112 #endif
1113 dx = dy = dz = dw = 0;
1114 buttons = 0;
1115 switch (pMse->protocolID) {
|
1116 dawes 1.1
|
1117 eich 1.52 /*
1118 * [KAZU-221197]
1119 * IntelliMouse, NetMouse (including NetMouse Pro) and Mie
1120 * Mouse always send the fourth byte, whereas the fourth byte
1121 * is optional for GlidePoint and ThinkingMouse. The fourth
1122 * byte is also optional for MouseMan+ and FirstMouse+ in
1123 * their native mode. It is always sent if they are in the
1124 * IntelliMouse compatible mode.
1125 */
1126 case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse,
1127 MouseMan+ */
1128 dz = (u & 0x08) ?
1129 (u & 0x0f) - 16 : (u & 0x0f);
1130 if ((dz >= 7) || (dz <= -7))
1131 dz = 0;
1132 buttons |= ((int)(u & 0x10) >> 3)
1133 | ((int)(u & 0x20) >> 2)
1134 | (pMse->lastButtons & 0x05);
|
1135 dawes 1.1 break;
|
1136 eich 1.52
1137 case PROT_GLIDE:
1138 case PROT_THINKING:
1139 buttons |= ((int)(u & 0x10) >> 1);
1140 /* fall through */
1141
|
1142 dawes 1.1 default:
|
1143 eich 1.52 buttons |= ((int)(u & 0x20) >> 4) |
1144 (pMse->lastButtons & 0x05);
|
1145 dawes 1.1 break;
1146 }
|
1147 eich 1.52 goto post_event;
|
1148 dawes 1.1 }
1149 }
|
1150 eich 1.52 /* End of packet buffer flush and 4th byte hack. */
1151
1152 /*
1153 * Append next byte to buffer (which is empty or contains an
1154 * incomplete packet); iterate if packet (still) not complete.
1155 */
1156 pBuf[pBufP++] = u;
1157 if (pBufP != pMse->protoPara[4]) continue;
1158 #ifdef EXTMOUSEDEBUG2
1159 {
1160 int i;
1161 ErrorF("received %d bytes",pBufP);
1162 for ( i=0; i < pBufP; i++)
1163 ErrorF(" %02x",pBuf[i]);
1164 ErrorF("\n");
|
1165 dawes 1.1 }
1166 #endif
|
1167 eich 1.52
1168 /*
1169 * Hack for resyncing: We check here for a package that is:
1170 * a) illegal (detected by wrong data-package header)
1171 * b) invalid (0x80 == -128 and that might be wrong for MouseSystems)
1172 * c) bad header-package
1173 *
1174 * NOTE: b) is a violation of the MouseSystems-Protocol, since values
1175 * of -128 are allowed, but since they are very seldom we can
1176 * easily use them as package-header with no button pressed.
1177 * NOTE/2: On a PS/2 mouse any byte is valid as a data byte.
1178 * Furthermore, 0x80 is not valid as a header byte. For a PS/2
1179 * mouse we skip checking data bytes. For resyncing a PS/2
1180 * mouse we require the two most significant bits in the header
1181 * byte to be 0. These are the overflow bits, and in case of
1182 * an overflow we actually lose sync. Overflows are very rare,
1183 * however, and we quickly gain sync again after an overflow
1184 * condition. This is the best we can do. (Actually, we could
1185 * use bit 0x08 in the header byte for resyncing, since that
1186 * bit is supposed to be always on, but nobody told Microsoft...)
1187 */
|
1188 eich 1.30
|
1189 eich 1.52 /*
1190 * [KAZU,OYVIND-120398]
1191 * The above hack is wrong! Because of b) above, we shall see
1192 * erroneous mouse events so often when the MouseSystem mouse is
1193 * moved quickly. As for the PS/2 and its variants, we don't need
1194 * to treat them as special cases, because protoPara[2] and
1195 * protoPara[3] are both 0x00 for them, thus, any data bytes will
1196 * never be discarded. 0x80 is rejected for MMSeries, Logitech
1197 * and MMHittab protocols, because protoPara[2] and protoPara[3]
1198 * are 0x80 and 0x00 respectively. The other protocols are 7-bit
1199 * protocols; there is no use checking 0x80.
1200 *
1201 * All in all we should check the condition a) only.
1202 */
1203
1204 /*
1205 * [OYVIND-120498]
1206 * Check packet for valid data:
1207 * If driver is in sync with datastream, the packet is considered
1208 * bad if any byte (header and/or data) contains an invalid value.
1209 *
1210 eich 1.52 * If packet is bad, we discard the first byte and shift the buffer.
1211 * Next iteration will then check the new situation for validity.
1212 *
1213 * If flag MF_SAFE is set in proto[7] and the driver
1214 * is out of sync, the packet is also considered bad if
1215 * any of the data bytes contains a valid header byte value.
1216 * This situation could occur if the buffer contains
1217 * the tail of one packet and the header of the next.
1218 *
1219 * Note: The driver starts in out-of-sync mode (pMse->inSync = 0).
1220 */
1221
1222 baddata = 0;
1223
1224 /* All databytes must be valid. */
1225 for (j = 1; j < pBufP; j++ )
1226 if ((pBuf[j] & pMse->protoPara[2]) != pMse->protoPara[3])
1227 baddata = 1;
1228
1229 /* If out of sync, don't mistake a header byte for data. */
1230 if ((pMse->protoPara[7] & MPF_SAFE) && !pMse->inSync)
1231 eich 1.52 for (j = 1; j < pBufP; j++ )
1232 if ((pBuf[j] & pMse->protoPara[0]) == pMse->protoPara[1])
1233 baddata = 1;
1234
1235 /* Accept or reject the packet ? */
1236 if ((pBuf[0] & pMse->protoPara[0]) != pMse->protoPara[1] || baddata) {
1237 if (pMse->inSync) {
1238 #ifdef EXTMOUSEDEBUG
1239 ErrorF("mouse driver lost sync\n");
1240 #endif
|
1241 eich 1.55 }
|
1242 eich 1.52 #ifdef EXTMOUSEDEBUG
1243 ErrorF("skipping byte %02x\n",*pBuf);
1244 #endif
1245 /* Tell auto probe that we are out of sync */
|
1246 eich 1.55 if (pMse->autoProbeMouse && pMse->autoProbe)
|
1247 eich 1.52 pMse->autoProbeMouse(pInfo, FALSE, pMse->inSync);
1248 pMse->protoBufTail = --pBufP;
1249 for (j = 0; j < pBufP; j++)
1250 pBuf[j] = pBuf[j+1];
1251 pMse->inSync = 0;
1252 continue;
|
1253 eich 1.30 }
|
1254 eich 1.52 /* Tell auto probe that we were successful */
|
1255 eich 1.55 if (pMse->autoProbeMouse && pMse->autoProbe)
|
1256 eich 1.52 pMse->autoProbeMouse(pInfo, TRUE, FALSE);
|
1257 eich 1.55
|
1258 eich 1.52 if (!pMse->inSync) {
1259 #ifdef EXTMOUSEDEBUG
1260 ErrorF("mouse driver back in sync\n");
1261 #endif
1262 pMse->inSync = 1;
1263 }
|
1264 eich 1.48
|
1265 eich 1.55 if (!pMse->dataGood(pMse))
1266 continue;
1267
|
1268 eich 1.52 /*
1269 * Packet complete and verified, now process it ...
|
1270 dawes 1.1 */
|
1271 eich 1.52 REDO_INTERPRET:
1272 dz = dw = 0;
1273 switch (pMse->protocolID) {
1274 case PROT_LOGIMAN: /* MouseMan / TrackMan [CHRIS-211092] */
1275 case PROT_MS: /* Microsoft */
1276 if (pMse->chordMiddle)
1277 buttons = (((int) pBuf[0] & 0x30) == 0x30) ? 2 :
1278 ((int)(pBuf[0] & 0x20) >> 3)
1279 | ((int)(pBuf[0] & 0x10) >> 4);
1280 else
1281 buttons = (pMse->lastButtons & 2)
1282 | ((int)(pBuf[0] & 0x20) >> 3)
1283 | ((int)(pBuf[0] & 0x10) >> 4);
1284 dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F));
1285 dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F));
|
1286 dawes 1.1 break;
|
1287 eich 1.52
1288 case PROT_GLIDE: /* ALPS GlidePoint */
1289 case PROT_THINKING: /* ThinkingMouse */
1290 case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse, MouseMan+ */
1291 buttons = (pMse->lastButtons & (8 + 2))
1292 | ((int)(pBuf[0] & 0x20) >> 3)
1293 | ((int)(pBuf[0] & 0x10) >> 4);
1294 dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F));
1295 dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F));
|
1296 dawes 1.1 break;
|
1297 eich 1.52
1298 case PROT_MSC: /* Mouse Systems Corp */
1299 buttons = (~pBuf[0]) & 0x07;
1300 dx = (char)(pBuf[1]) + (char)(pBuf[3]);
1301 dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
|
1302 dawes 1.1 break;
|
1303 eich 1.52
1304 case PROT_MMHIT: /* MM_HitTablet */
1305 buttons = pBuf[0] & 0x07;
1306 if (buttons != 0)
1307 buttons = 1 << (buttons - 1);
1308 dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
1309 dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
|
1310 dawes 1.1 break;
1311
|
1312 eich 1.52 case PROT_ACECAD: /* ACECAD */
1313 /* ACECAD is almost exactly like MM but the buttons are different */
1314 buttons = (pBuf[0] & 0x02) | ((pBuf[0] & 0x04) >> 2) |
1315 ((pBuf[0] & 1) << 2);
1316 dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
1317 dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
1318 break;
|
1319 dawes 1.1
|
1320 eich 1.52 case PROT_MM: /* MM Series */
1321 case PROT_LOGI: /* Logitech Mice */
1322 buttons = pBuf[0] & 0x07;
1323 dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
1324 dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
1325 break;
|
1326 dawes 1.1
|
1327 eich 1.52 case PROT_BM: /* BusMouse */
1328 buttons = (~pBuf[0]) & 0x07;
1329 dx = (char)pBuf[1];
1330 dy = - (char)pBuf[2];
|
1331 dawes 1.1 break;
|
1332 eich 1.52
1333 case PROT_PS2: /* PS/2 mouse */
|
1334 eich 1.55 case PROT_GENPS2: /* generic PS/2 mouse */
|
1335 eich 1.52 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1336 (pBuf[0] & 0x02) >> 1 | /* Right */
1337 (pBuf[0] & 0x01) << 2; /* Left */
1338 dx = (pBuf[0] & 0x10) ? (int)pBuf[1]-256 : (int)pBuf[1];
1339 dy = (pBuf[0] & 0x20) ? -((int)pBuf[2]-256) : -(int)pBuf[2];
|
1340 dawes 1.1 break;
1341
|
1342 eich 1.52 /* PS/2 mouse variants */
1343 case PROT_IMPS2: /* IntelliMouse PS/2 */
1344 case PROT_NETPS2: /* NetMouse PS/2 */
1345 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1346 (pBuf[0] & 0x02) >> 1 | /* Right */
1347 (pBuf[0] & 0x01) << 2 | /* Left */
1348 (pBuf[0] & 0x40) >> 3 | /* button 4 */
1349 (pBuf[0] & 0x80) >> 3; /* button 5 */
1350 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
1351 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
1352 dz = (char)pBuf[3];
1353 if ((dz >= 7) || (dz <= -8)) {
1354 if (pMse->autoProbe && !(pBuf[3] & 0xC0)) {
1355 SetMouseProto(pMse, PROT_EXPPS2);
1356 xf86Msg(X_INFO,
1357 "Mouse autoprobe: Changing protocol to %s\n",
1358 pMse->protocol);
|
1359 dawes 1.1
|
1360 eich 1.52 goto REDO_INTERPRET;
1361 } else
1362 dz = 0;
1363 }
1364 break;
|
1365 dawes 1.1
|
1366 eich 1.52 case PROT_EXPPS2: /* IntelliMouse Explorer PS/2 */
1367 if (pMse->autoProbe && (pBuf[3] & 0xC0)) {
1368 SetMouseProto(pMse, PROT_IMPS2);
1369 xf86Msg(X_INFO,"Mouse autoprobe: Changing protocol to %s\n",
1370 pMse->protocol);
1371 goto REDO_INTERPRET;
1372 }
1373 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1374 (pBuf[0] & 0x02) >> 1 | /* Right */
1375 (pBuf[0] & 0x01) << 2 | /* Left */
1376 (pBuf[3] & 0x10) >> 1 | /* button 4 */
1377 (pBuf[3] & 0x20) >> 1; /* button 5 */
1378 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
1379 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
1380 dz = (pBuf[3] & 0x08) ? (pBuf[3] & 0x0f) - 16 : (pBuf[3] & 0x0f);
1381 break;
|
1382 dawes 1.1
|
1383 eich 1.52 case PROT_MMPS2: /* MouseMan+ PS/2 */
1384 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1385 (pBuf[0] & 0x02) >> 1 | /* Right */
1386 (pBuf[0] & 0x01) << 2; /* Left */
1387 dx = (pBuf[0] & 0x10) ? pBuf[1] - 256 : pBuf[1];
1388 if (((pBuf[0] & 0x48) == 0x48) &&
1389 (abs(dx) > 191) &&
1390 ((((pBuf[2] & 0x03) << 2) | 0x02) == (pBuf[1] & 0x0f))) {
1391 /* extended data packet */
1392 switch ((((pBuf[0] & 0x30) >> 2) | ((pBuf[1] & 0x30) >> 4))) {
1393 case 1: /* wheel data packet */
1394 buttons |= ((pBuf[2] & 0x10) ? 0x08 : 0) | /* 4th button */
1395 ((pBuf[2] & 0x20) ? 0x10 : 0); /* 5th button */
1396 dx = dy = 0;
1397 dz = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 :
1398 (pBuf[2] & 0x0f);
1399 break;
1400 case 2: /* Logitech reserves this packet type */
1401 /*
1402 * IBM ScrollPoint uses this packet to encode its
1403 * stick movement.
1404 eich 1.52 */
1405 buttons |= (pMse->lastButtons & ~0x07);
1406 dx = dy = 0;
1407 dz = (pBuf[2] & 0x80) ? ((pBuf[2] >> 4) & 0x0f) - 16 :
1408 ((pBuf[2] >> 4) & 0x0f);
1409 dw = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 :
1410 (pBuf[2] & 0x0f);
1411 break;
1412 case 0: /* device type packet - shouldn't happen */
1413 default:
1414 buttons |= (pMse->lastButtons & ~0x07);
1415 dx = dy = 0;
1416 dz = 0;
1417 break;
1418 }
1419 } else {
1420 buttons |= (pMse->lastButtons & ~0x07);
1421 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
1422 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
1423 }
1424 break;
1425 eich 1.52
1426 case PROT_GLIDEPS2: /* GlidePoint PS/2 */
1427 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1428 (pBuf[0] & 0x02) >> 1 | /* Right */
1429 (pBuf[0] & 0x01) << 2 | /* Left */
1430 ((pBuf[0] & 0x08) ? 0 : 0x08);/* fourth button */
1431 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
1432 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
1433 break;
|
1434 dawes 1.1
|
1435 eich 1.52 case PROT_NETSCPS2: /* NetScroll PS/2 */
1436 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1437 (pBuf[0] & 0x02) >> 1 | /* Right */
1438 (pBuf[0] & 0x01) << 2 | /* Left */
1439 ((pBuf[3] & 0x02) ? 0x08 : 0) | /* button 4 */
1440 ((pBuf[3] & 0x01) ? 0x10 : 0); /* button 5 */
1441 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
1442 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
1443 dz = (pBuf[3] & 0x10) ? pBuf[4] - 256 : pBuf[4];
1444 break;
|
1445 dawes 1.1
|
1446 eich 1.52 case PROT_THINKPS2: /* ThinkingMouse PS/2 */
1447 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
1448 (pBuf[0] & 0x02) >> 1 | /* Right */
1449 (pBuf[0] & 0x01) << 2 | /* Left */
1450 ((pBuf[0] & 0x08) ? 0x08 : 0);/* fourth button */
1451 pBuf[1] |= (pBuf[0] & 0x40) ? 0x80 : 0x00;
1452 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
1453 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
1454 break;
|
1455 dawes 1.2
|
1456 eich 1.52 case PROT_SYSMOUSE: /* sysmouse */
1457 buttons = (~pBuf[0]) & 0x07;
1458 dx = (char)(pBuf[1]) + (char)(pBuf[3]);
1459 dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
1460 /* FreeBSD sysmouse sends additional data bytes */
1461 if (pMse->protoPara[4] >= 8) {
|
1462 dawes 1.54 dz = ((signed char)(pBuf[5] << 1) +
1463 (signed char)(pBuf[6] << 1)) >> 1;
|
1464 eich 1.52 buttons |= (int)(~pBuf[7] & 0x07) << 3;
1465 }
1466 break;
|
1467 dawes 1.1
|
1468 eich 1.52 default: /* There's a table error */
1469 #ifdef EXTMOUSEDEBUG
1470 ErrorF("mouse table error\n");
1471 #endif
1472 continue;
1473 }
1474 #ifdef EXTMOUSEDEBUG
1475 ErrorF("packet");
1476 for ( j=0; j < pBufP; j++)
1477 ErrorF(" %02x",pBuf[j]);
1478 ErrorF("\n");
1479 #endif
|
1480 dawes 1.1
|
1481 eich 1.52 post_event:
1482 #ifdef EXTMOUSEDEBUG
1483 ErrorF("dx=%i dy=%i dz=%i dw=%i buttons=%x\n",dx,dy,dz,dw,buttons);
1484 #endif
1485 /* When auto-probing check if data makes sense */
1486 if (pMse->checkMovements && pMse->autoProbe)
1487 pMse->checkMovements(pInfo,dx,dy);
1488 /* post an event */
1489 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
|
1490 dawes 1.1
|
1491 eich 1.52 /*
1492 * We don't reset pBufP here yet, as there may be an additional data
1493 * byte in some protocols. See above.
1494 */
1495 }
1496 pMse->protoBufTail = pBufP;
|
1497 dawes 1.1 }
|
1498 eich 1.52
1499 /*
1500 * MouseCtrl --
1501 * Alter the control parameters for the mouse. Note that all special
1502 * protocol values are handled by dix.
1503 */
1504
|
1505 dawes 1.1 static void
|
1506 eich 1.52 MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
|
1507 dawes 1.1 {
|
1508 eich 1.52 InputInfoPtr pInfo;
|
1509 dawes 1.1 MouseDevPtr pMse;
1510
|
1511 eich 1.52 pInfo = device->public.devicePrivate;
|
1512 dawes 1.1 pMse = pInfo->private;
1513
1514 #ifdef EXTMOUSEDEBUG
|
1515 eich 1.52 ErrorF("MouseCtrl pMse=%p\n", pMse);
|
1516 dawes 1.1 #endif
|
1517 eich 1.52
1518 pMse->num = ctrl->num;
1519 pMse->den = ctrl->den;
1520 pMse->threshold = ctrl->threshold;
1521 }
|
1522 dawes 1.1
|
1523 eich 1.52 /*
1524 ***************************************************************************
1525 *
1526 * MouseProc --
1527 *
1528 ***************************************************************************
1529 */
|
1530 dawes 1.1
|
1531 eich 1.52 static int
1532 MouseProc(DeviceIntPtr device, int what)
1533 {
1534 InputInfoPtr pInfo;
1535 MouseDevPtr pMse;
1536 mousePrivPtr mPriv;
1537 unsigned char map[MSE_MAXBUTTONS + 1];
1538 int i;
1539
1540 pInfo = device->public.devicePrivate;
1541 pMse = pInfo->private;
1542 pMse->device = device;
1543 mPriv = (mousePrivPtr)pMse->mousePriv;
|
1544 dawes 1.1
|
1545 eich 1.52 switch (what)
1546 {
1547 case DEVICE_INIT:
1548 device->public.on = FALSE;
|
1549 dawes 1.1 /*
|
1550 eich 1.52 * [KAZU-241097] We don't know exactly how many buttons the
1551 * device has, so setup the map with the maximum number.
|
1552 dawes 1.1 */
|
1553 eich 1.52 for (i = 0; i < MSE_MAXBUTTONS; i++)
1554 map[i + 1] = i + 1;
|
1555 dawes 1.1
|
1556 eich 1.52 InitPointerDeviceStruct((DevicePtr)device, map,
1557 min(pMse->buttons, MSE_MAXBUTTONS),
1558 miPointerGetMotionEvents, pMse->Ctrl,
1559 miPointerGetMotionBufferSize());
|
1560 dawes 1.1
|
1561 eich 1.52 /* X valuator */
1562 xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1);
1563 xf86InitValuatorDefaults(device, 0);
1564 /* Y valuator */
1565 xf86InitValuatorAxisStruct(device, 1, 0, -1, 1, 0, 1);
1566 xf86InitValuatorDefaults(device, 1);
1567 xf86MotionHistoryAllocate(pInfo);
|
1568 dawes 1.1
1569 #ifdef EXTMOUSEDEBUG
|
1570 eich 1.52 ErrorF("assigning %p atom=%d name=%s\n", device, pInfo->atom,
1571 pInfo->name);
|
1572 dawes 1.1 #endif
|
1573 eich 1.52 break;
1574
1575 case DEVICE_ON:
1576 pInfo->fd = xf86OpenSerial(pInfo->options);
1577 if (pInfo->fd == -1)
1578 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
1579 else {
1580 pMse->buffer = XisbNew(pInfo->fd, 64);
1581 if (!pMse->buffer) {
1582 xf86CloseSerial(pInfo->fd);
1583 pInfo->fd = -1;
1584 } else {
1585 if (!SetupMouse(pInfo)) {
1586 xf86CloseSerial(pInfo->fd);
1587 pInfo->fd = -1;
1588 XisbFree(pMse->buffer);
1589 pMse->buffer = NULL;
1590 } else {
1591 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
|
1592 herrb 1.53 if (mPriv != NULL) {
|
1593 eich 1.55 if ( pMse->protocolID != PROT_AUTO) {
1594 pMse->inSync = TRUE; /* @@@ */
|
1595 herrb 1.53 if (mPriv->soft)
1596 mPriv->autoState = AUTOPROBE_GOOD;
1597 else
1598 mPriv->autoState = AUTOPROBE_H_GOOD;
1599 } else {
1600 if (mPriv->soft)
1601 mPriv->autoState = AUTOPROBE_NOPROTO;
1602 else
1603 mPriv->autoState = AUTOPROBE_H_NOPROTO;
1604 }
|
1605 eich 1.52 }
1606 xf86FlushInput(pInfo->fd);
1607 xf86AddEnabledDevice(pInfo);
1608 }
1609 }
1610 }
1611 pMse->lastButtons = 0;
1612 pMse->emulateState = 0;
1613 pMse->emulate3Pending = FALSE;
1614 device->public.on = TRUE;
1615 FlushButtons(pMse);
1616 if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft)
1617 {
1618 RegisterBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler,
1619 (pointer) pInfo);
1620 }
1621 break;
1622
1623 case DEVICE_OFF:
1624 case DEVICE_CLOSE:
1625 if (pInfo->fd != -1) {
1626 eich 1.52 xf86RemoveEnabledDevice(pInfo);
1627 if (pMse->buffer) {
1628 XisbFree(pMse->buffer);
1629 pMse->buffer = NULL;
1630 }
1631 xf86CloseSerial(pInfo->fd);
1632 pInfo->fd = -1;
1633 if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft)
1634 {
1635 RemoveBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler,
1636 (pointer) pInfo);
1637 }
|
1638 dawes 1.1 }
|
1639 eich 1.52 device->public.on = FALSE;
1640 usleep(300000);
1641 break;
1642 }
1643 return Success;
1644 }
1645
1646 /*
1647 ***************************************************************************
1648 *
1649 * MouseConvert --
1650 * Convert valuators to X and Y.
1651 *
1652 ***************************************************************************
1653 */
1654 static Bool
1655 MouseConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
1656 int v3, int v4, int v5, int *x, int *y)
1657 {
1658 if (first != 0 || num != 2)
1659 return FALSE;
|
1660 dawes 1.1
|
1661 eich 1.52 *x = v0;
1662 *y = v1;
|
1663 dawes 1.1
|
1664 eich 1.52 return TRUE;
1665 }
|
1666 dawes 1.1
|
1667 eich 1.52 /**********************************************************************
1668 *
1669 * FlushButtons -- send button up events for sanity.
1670 *
1671 **********************************************************************/
|
1672 dawes 1.1
|
1673 eich 1.52 static void
1674 FlushButtons(MouseDevPtr pMse)
1675 {
|
1676 dawes 1.1
|
1677 eich 1.52 /* If no button down is pending xf86PostButtonEvent()
1678 * will discard them. So we are on the safe side. */
|
1679 dawes 1.1
|
1680 eich 1.52 int i, blocked;
|
1681 dawes 1.1
|
1682 eich 1.52 pMse->lastButtons = 0;
|
1683 dawes 1.1
|
1684 eich 1.52 blocked = xf86BlockSIGIO ();
1685 for (i = 1; i <= 5; i++)
1686 xf86PostButtonEvent(pMse->device,0,i,0,0,0);
1687 xf86UnblockSIGIO (blocked);
1688 }
|
1689 dawes 1.1
|
1690 eich 1.52 /**********************************************************************
1691 *
1692 * Emulate3Button support code
1693 *
1694 **********************************************************************/
|
1695 dawes 1.1
|
1696 dawes 1.25
|
1697 eich 1.52 /*
1698 * Lets create a simple finite-state machine for 3 button emulation:
1699 *
1700 * We track buttons 1 and 3 (left and right). There are 11 states:
1701 * 0 ground - initial state
1702 * 1 delayed left - left pressed, waiting for right
1703 * 2 delayed right - right pressed, waiting for left
1704 * 3 pressed middle - right and left pressed, emulated middle sent
1705 * 4 pressed left - left pressed and sent
1706 * 5 pressed right - right pressed and sent
1707 * 6 released left - left released after emulated middle
1708 * 7 released right - right released after emulated middle
1709 * 8 repressed left - left pressed after released left
1710 * 9 repressed right - right pressed after released right
1711 * 10 pressed both - both pressed, not emulating middle
1712 *
1713 * At each state, we need handlers for the following events
1714 * 0: no buttons down
1715 * 1: left button down
1716 * 2: right button down
1717 * 3: both buttons down
1718 eich 1.52 * 4: emulate3Timeout passed without a button change
1719 * Note that button events are not deltas, they are the set of buttons being
1720 * pressed now. It's possible (ie, mouse hardware does it) to go from (eg)
1721 * left down to right down without anything in between, so all cases must be
1722 * handled.
1723 *
1724 * a handler consists of three values:
1725 * 0: action1
1726 * 1: action2
1727 * 2: new emulation state
1728 *
1729 * action > 0: ButtonPress
1730 * action = 0: nothing
1731 * action < 0: ButtonRelease
1732 *
1733 * The comment preceeding each section is the current emulation state.
1734 * The comments to the right are of the form
1735 * <button state> (<events>) -> <new emulation state>
1736 * which should be read as
1737 * If the buttons are in <button state>, generate <events> then go to
1738 * <new emulation state>.
1739 eich 1.52 */
1740 static signed char stateTab[11][5][3] = {
1741 /* 0 ground */
1742 {
1743 { 0, 0, 0 }, /* nothing -> ground (no change) */
1744 { 0, 0, 1 }, /* left -> delayed left */
1745 { 0, 0, 2 }, /* right -> delayed right */
1746 { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */
1747 { 0, 0, -1 } /* timeout N/A */
1748 },
1749 /* 1 delayed left */
1750 {
1751 { 1, -1, 0 }, /* nothing (left event) -> ground */
1752 { 0, 0, 1 }, /* left -> delayed left (no change) */
1753 { 1, -1, 2 }, /* right (left event) -> delayed right */
1754 { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */
1755 { 1, 0, 4 }, /* timeout (left press) -> pressed left */
1756 },
1757 /* 2 delayed right */
1758 {
1759 { 3, -3, 0 }, /* nothing (right event) -> ground */
1760 eich 1.52 { 3, -3, 1 }, /* left (right event) -> delayed left (no change) */
1761 { 0, 0, 2 }, /* right -> delayed right (no change) */
1762 { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */
1763 { 3, 0, 5 }, /* timeout (right press) -> pressed right */
1764 },
1765 /* 3 pressed middle */
1766 {
1767 { -2, 0, 0 }, /* nothing (middle release) -> ground */
1768 { 0, 0, 7 }, /* left -> released right */
1769 { 0, 0, 6 }, /* right -> released left */
1770 { 0, 0, 3 }, /* left & right -> pressed middle (no change) */
1771 { 0, 0, -1 }, /* timeout N/A */
1772 },
1773 /* 4 pressed left */
1774 {
1775 { -1, 0, 0 }, /* nothing (left release) -> ground */
1776 { 0, 0, 4 }, /* left -> pressed left (no change) */
1777 { -1, 0, 2 }, /* right (left release) -> delayed right */
1778 { 3, 0, 10 }, /* left & right (right press) -> pressed both */
1779 { 0, 0, -1 }, /* timeout N/A */
1780 },
1781 eich 1.52 /* 5 pressed right */
1782 {
1783 { -3, 0, 0 }, /* nothing (right release) -> ground */
1784 { -3, 0, 1 }, /* left (right release) -> delayed left */
1785 { 0, 0, 5 }, /* right -> pressed right (no change) */
1786 { 1, 0, 10 }, /* left & right (left press) -> pressed both */
1787 { 0, 0, -1 }, /* timeout N/A */
1788 },
1789 /* 6 released left */
1790 {
1791 { -2, 0, 0 }, /* nothing (middle release) -> ground */
1792 { -2, 0, 1 }, /* left (middle release) -> delayed left */
1793 { 0, 0, 6 }, /* right -> released left (no change) */
1794 { 1, 0, 8 }, /* left & right (left press) -> repressed left */
1795 { 0, 0, -1 }, /* timeout N/A */
1796 },
1797 /* 7 released right */
1798 {
1799 { -2, 0, 0 }, /* nothing (middle release) -> ground */
1800 { 0, 0, 7 }, /* left -> released right (no change) */
1801 { -2, 0, 2 }, /* right (middle release) -> delayed right */
1802 eich 1.52 { 3, 0, 9 }, /* left & right (right press) -> repressed right */
1803 { 0, 0, -1 }, /* timeout N/A */
1804 },
1805 /* 8 repressed left */
1806 {
1807 { -2, -1, 0 }, /* nothing (middle release, left release) -> ground */
1808 { -2, 0, 4 }, /* left (middle release) -> pressed left */
1809 { -1, 0, 6 }, /* right (left release) -> released left */
1810 { 0, 0, 8 }, /* left & right -> repressed left (no change) */
1811 { 0, 0, -1 }, /* timeout N/A */
1812 },
1813 /* 9 repressed right */
1814 {
1815 { -2, -3, 0 }, /* nothing (middle release, right release) -> ground */
1816 { -3, 0, 7 }, /* left (right release) -> released right */
1817 { -2, 0, 5 }, /* right (middle release) -> pressed right */
1818 { 0, 0, 9 }, /* left & right -> repressed right (no change) */
1819 { 0, 0, -1 }, /* timeout N/A */
1820 },
1821 /* 10 pressed both */
1822 {
1823 eich 1.52 { -1, -3, 0 }, /* nothing (left release, right release) -> ground */
1824 { -3, 0, 4 }, /* left (right release) -> pressed left */
1825 { -1, 0, 5 }, /* right (left release) -> pressed right */
1826 { 0, 0, 10 }, /* left & right -> pressed both (no change) */
1827 { 0, 0, -1 }, /* timeout N/A */
1828 },
1829 };
|
1830 dawes 1.1
|
1831 eich 1.52 /*
1832 * Table to allow quick reversal of natural button mapping to correct mapping
1833 */
|
1834 dawes 1.1
|
1835 eich 1.52 /*
1836 * [JCH-96/01/21] The ALPS GlidePoint pad extends the MS protocol
1837 * with a fourth button activated by tapping the PAD.
1838 * The 2nd line corresponds to 4th button on; the drv sends
1839 * the buttons in the following map (MSBit described first) :
1840 * 0 | 4th | 1st | 2nd | 3rd
1841 * And we remap them (MSBit described first) :
1842 * 0 | 4th | 3rd | 2nd | 1st
1843 */
1844 static char reverseMap[32] = { 0, 4, 2, 6, 1, 5, 3, 7,
1845 8, 12, 10, 14, 9, 13, 11, 15,
1846 16, 20, 18, 22, 17, 21, 19, 23,
1847 24, 28, 26, 30, 25, 29, 27, 31};
|
1848 dawes 1.1
1849
|
1850 eich 1.52 static char hitachMap[16] = { 0, 2, 1, 3,
1851 8, 10, 9, 11,
1852 4, 6, 5, 7,
1853 12, 14, 13, 15 };
|
1854 dawes 1.2
|
1855 eich 1.52 #define reverseBits(map, b) (((b) & ~0x0f) | map[(b) & 0x0f])
|
1856 dawes 1.1
|
1857 eich 1.52 static CARD32
1858 buttonTimer(InputInfoPtr pInfo)
1859 {
1860 MouseDevPtr pMse;
1861 int sigstate;
1862 int id;
|
1863 dawes 1.1
|
1864 eich 1.52 pMse = pInfo->private;
|
1865 dawes 1.1
|
1866 eich 1.52 sigstate = xf86BlockSIGIO ();
|
1867 dawes 1.1
|
1868 eich 1.52 pMse->emulate3Pending = FALSE;
1869 if ((id = stateTab[pMse->emulateState][4][0]) != 0) {
1870 xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
1871 pMse->emulateState = stateTab[pMse->emulateState][4][2];
1872 } else {
1873 ErrorF("Got unexpected buttonTimer in state %d\n", pMse->emulateState);
|
1874 dawes 1.1 }
|
1875 eich 1.52
1876 xf86UnblockSIGIO (sigstate);
1877 return 0;
|
1878 hohndel 1.21 }
1879
|
1880 eich 1.52 static Bool
1881 Emulate3ButtonsSoft(InputInfoPtr pInfo)
1882 {
1883 MouseDevPtr pMse = pInfo->private;
1884
1885 if (!pMse->emulate3ButtonsSoft)
1886 return TRUE;
1887
1888 pMse->emulate3Buttons = FALSE;
1889
1890 if (pMse->emulate3Pending)
1891 buttonTimer(pInfo);
1892
1893 xf86Msg(X_INFO,"3rd Button detected: disabling emulate3Button\n");
1894
1895 return FALSE;
1896 }
|
1897 dawes 1.1
|
1898 eich 1.52 static void MouseBlockHandler(pointer data,
1899 struct timeval **waitTime,
1900 pointer LastSelectMask)
|
1901 dawes 1.1 {
|
1902 eich 1.52 InputInfoPtr pInfo = (InputInfoPtr) data;
1903 MouseDevPtr pMse = (MouseDevPtr) pInfo->private;
1904 int ms;
|
1905 dawes 1.1
|
1906 eich 1.52 if (pMse->emulate3Pending)
1907 {
1908 ms = pMse->emulate3Expires - GetTimeInMillis ();
1909 if (ms <= 0)
1910 ms = 0;
1911 AdjustWaitForDelay (waitTime, ms);
1912 }
1913 }
|
1914 dawes 1.1
|
1915 eich 1.52 static void MouseWakeupHandler(pointer data,
1916 int i,
1917 pointer LastSelectMask)
1918 {
1919 InputInfoPtr pInfo = (InputInfoPtr) data;
1920 MouseDevPtr pMse = (MouseDevPtr) pInfo->private;
1921 int ms;
|
1922 dawes 1.1
|
1923 eich 1.52 if (pMse->emulate3Pending)
1924 {
1925 ms = pMse->emulate3Expires - GetTimeInMillis ();
1926 if (ms <= 0)
1927 buttonTimer (pInfo);
1928 }
|
1929 dawes 1.1 }
1930
|
1931 eich 1.52 /*******************************************************************
|
1932 dawes 1.1 *
|
1933 eich 1.52 * Post mouse events
|
1934 dawes 1.1 *
|
1935 eich 1.52 *******************************************************************/
1936
1937 static void
1938 MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
|
1939 dawes 1.1 {
1940 MouseDevPtr pMse;
|
1941 eich 1.52 int truebuttons, emulateButtons;
1942 int id, change;
1943 int emuWheelDelta, emuWheelButton, emuWheelButtonMask;
|
1944 dawes 1.1
1945 pMse = pInfo->private;
1946
|
1947 eich 1.52 truebuttons = buttons;
1948 if (pMse->protocolID == PROT_MMHIT)
1949 buttons = reverseBits(hitachMap, buttons);
1950 else
1951 buttons = reverseBits(reverseMap, buttons);
|
1952 dawes 1.1
|
1953 eich 1.52 /* Intercept wheel emulation. */
1954 if (pMse->emulateWheel && (buttons & pMse->wheelButtonMask)) {
1955 /* Y axis movement */
1956 if (pMse->negativeY != MSE_NOAXISMAP) {
1957 pMse->wheelYDistance += dy;
1958 if (pMse->wheelYDistance < 0) {
1959 emuWheelDelta = -pMse->wheelInertia;
1960 emuWheelButton = pMse->negativeY;
1961 } else {
1962 emuWheelDelta = pMse->wheelInertia;
1963 emuWheelButton = pMse->positiveY;
1964 }
1965 emuWheelButtonMask = 1 << (emuWheelButton - 1);
1966 while (abs(pMse->wheelYDistance) > pMse->wheelInertia) {
1967 pMse->wheelYDistance -= emuWheelDelta;
|
1968 dawes 1.1
|
1969 eich 1.52 /*
1970 * Synthesize the press and release, but not when the button
1971 * to be synthesized is already pressed "for real".
1972 */
1973 if (!(emuWheelButtonMask & buttons) ||
1974 (emuWheelButtonMask & pMse->wheelButtonMask)) {
1975 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 1, 0, 0);
1976 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 0, 0, 0);
|
1977 dawes 1.9 }
|
1978 dawes 1.4 }
|
1979 dawes 1.1 }
|
1980 eich 1.52
1981 /* X axis movement */
1982 if (pMse->negativeX != MSE_NOAXISMAP) {
1983 pMse->wheelXDistance += dx;
1984 if (pMse->wheelXDistance < 0) {
1985 emuWheelDelta = -pMse->wheelInertia;
1986 emuWheelButton = pMse->negativeX;
1987 } else {
1988 emuWheelDelta = pMse->wheelInertia;
1989 emuWheelButton = pMse->positiveX;
|
1990 dawes 1.4 }
|
1991 eich 1.52 emuWheelButtonMask = 1 << (emuWheelButton - 1);
1992 while (abs(pMse->wheelXDistance) > pMse->wheelInertia) {
1993 pMse->wheelXDistance -= emuWheelDelta;
1994
1995 /*
1996 * Synthesize the press and release, but not when the button
1997 * to be synthesized is already pressed "for real".
1998 */
1999 if (!(emuWheelButtonMask & buttons) ||
2000 (emuWheelButtonMask & pMse->wheelButtonMask)) {
2001 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 1, 0, 0);
2002 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 0, 0, 0);
2003 }
|
2004 keithp 1.47 }
|
2005 dawes 1.1 }
|
2006 eich 1.52
2007 /* Absorb the mouse movement and the wheel button press. */
2008 dx = 0;
2009 dy = 0;
2010 buttons &= ~pMse->wheelButtonMask;
|
2011 dawes 1.1 }
2012
|
2013 eich 1.52 if (dx || dy)
2014 xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
2015
2016 if (truebuttons != pMse->lastButtons) {
2017
2018 if (pMse->protocolID == PROT_MMHIT)
2019 change = buttons ^ reverseBits(hitachMap, pMse->lastButtons);
2020 else
2021 change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
|
2022 dawes 1.64
2023 /*
2024 * adjust buttons state for drag locks!
2025 * if there is drag locks
2026 */
2027 if (pMse->pDragLock) {
2028 DragLockPtr pLock;
2029 int tarOfGoingDown, tarOfDown;
2030 int realbuttons;
2031
2032 /* get drag lock block */
2033 pLock = pMse->pDragLock;
2034 /* save real buttons */
2035 realbuttons = buttons;
2036
2037 /* if drag lock used */
2038
2039 /* state of drag lock buttons not seen always up */
2040
2041 buttons &= ~pLock->lockButtonsM;
2042
2043 dawes 1.64 /*
2044 * if lock buttons being depressed changes state of
2045 * targets simulatedDown.
2046 */
2047 tarOfGoingDown = lock2targetMap(pLock,
2048 realbuttons & change & pLock->lockButtonsM);
2049 pLock->simulatedDown ^= tarOfGoingDown;
2050
2051 /* targets of drag locks down */
2052 tarOfDown = lock2targetMap(pLock,
2053 realbuttons & pLock->lockButtonsM);
2054
2055 /*
2056 * when simulatedDown set and target pressed,
2057 * simulatedDown goes false
2058 */
2059 pLock->simulatedDown &= ~(realbuttons & change);
2060
2061 /*
2062 * if master drag lock released
2063 * then master drag lock state on
2064 dawes 1.64 */
2065 pLock->masterTS |= (~realbuttons & change) & pLock->masterLockM;
2066
2067 /* if master state, buttons going down are simulatedDown */
2068 if (pLock->masterTS)
2069 pLock->simulatedDown |= (realbuttons & change);
2070
2071 /* if any button pressed, no longer in master drag lock state */
2072 if (realbuttons & change)
2073 pLock->masterTS = 0;
2074
2075 /* if simulatedDown or drag lock down, simulate down */
2076 buttons |= (pLock->simulatedDown | tarOfDown);
2077
2078 /* master button not seen */
2079 buttons &= ~(pLock->masterLockM);
2080
2081 /* buttons changed since last time */
2082 change = buttons ^ pLock->lockLastButtons;
2083
2084 /* save this time for next last time. */
2085 dawes 1.64 pLock->lockLastButtons = buttons;
2086 }
|
2087 eich 1.52
2088 if (pMse->emulate3Buttons
2089 && (!(buttons & 0x02) || Emulate3ButtonsSoft(pInfo))) {
|
2090 dawes 1.1
|
2091 eich 1.52 /* handle all but buttons 1 & 3 normally */
|
2092 dawes 1.1
|
2093 eich 1.52 change &= ~05;
|
2094 dawes 1.4
|
2095 eich 1.52 /* emulate the third button by the other two */
2096
2097 emulateButtons = (buttons & 01) | ((buttons &04) >> 1);
2098
2099 if ((id = stateTab[pMse->emulateState][emulateButtons][0]) != 0)
2100 xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
2101 if ((id = stateTab[pMse->emulateState][emulateButtons][1]) != 0)
2102 xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
2103
2104 pMse->emulateState =
2105 stateTab[pMse->emulateState][emulateButtons][2];
2106
2107 if (stateTab[pMse->emulateState][4][0] != 0) {
2108 pMse->emulate3Expires = GetTimeInMillis () + pMse->emulate3Timeout;
2109 pMse->emulate3Pending = TRUE;
2110 } else {
2111 pMse->emulate3Pending = FALSE;
2112 }
2113 }
2114
2115 while (change) {
2116 eich 1.52 id = ffs(change);
2117 change &= ~(1 << (id - 1));
2118 xf86PostButtonEvent(pInfo->dev, 0, id,
2119 (buttons & (1 << (id - 1))), 0, 0);
2120 }
2121
2122 pMse->lastButtons = truebuttons;
2123 }
2124 }
2125
2126 static void
2127 MousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw)
2128 {
2129 MouseDevPtr pMse;
2130 int zbutton = 0;
2131
2132 pMse = pInfo->private;
2133
2134 /* Map the Z axis movement. */
2135 /* XXX Could this go in the conversion_proc? */
2136 switch (pMse->negativeZ) {
2137 eich 1.52 case MSE_NOZMAP: /* do nothing */
2138 break;
2139 case MSE_MAPTOX:
2140 if (dz != 0) {
2141 dx = dz;
2142 dz = 0;
2143 }
2144 break;
2145 case MSE_MAPTOY:
2146 if (dz != 0) {
2147 dy = dz;
2148 dz = 0;
2149 }
2150 break;
2151 default: /* buttons */
2152 buttons &= ~(pMse->negativeZ | pMse->positiveZ
2153 | pMse->negativeW | pMse->positiveW);
2154 if (dw < 0 || dz < -1)
2155 zbutton = pMse->negativeW;
2156 else if (dz < 0)
2157 zbutton = pMse->negativeZ;
2158 eich 1.52 else if (dw > 0 || dz > 1)
2159 zbutton = pMse->positiveW;
2160 else if (dz > 0)
2161 zbutton = pMse->positiveZ;
2162 buttons |= zbutton;
2163 dz = 0;
2164 break;
2165 }
|
2166 dawes 1.63
2167 /* Apply angle offset */
2168 if (pMse->angleOffset != 0) {
2169 double rad = 3.141592653 * pMse->angleOffset / 180.0;
2170 int ndx = dx;
2171 dx = (int)((dx * cos(rad)) + (dy * sin(rad)) + 0.5);
2172 dy = (int)((dy * cos(rad)) - (ndx * sin(rad)) + 0.5);
2173 }
2174
|
2175 eich 1.52 dx = pMse->invX * dx;
2176 dy = pMse->invY * dy;
2177 if (pMse->flipXY) {
2178 int tmp = dx;
2179 dx = dy;
2180 dy = tmp;
2181 }
2182 MouseDoPostEvent(pInfo, buttons, dx, dy);
2183
2184 /*
2185 * If dz has been mapped to a button `down' event, we need to cook up
2186 * a corresponding button `up' event.
2187 */
2188 if (zbutton) {
2189 buttons &= ~zbutton;
2190 MouseDoPostEvent(pInfo, buttons, 0, 0);
2191 }
2192 }
2193 /******************************************************************
|
2194 paulo 1.41 *
|
2195 eich 1.52 * Mouse Setup Code
|
2196 dawes 1.4 *
|
2197 eich 1.52 ******************************************************************/
2198 /*
2199 * This array is indexed by the MouseProtocolID values, so the order of the entries
2200 * must match that of the MouseProtocolID enum in mouse.h.
2201 */
2202 static unsigned char proto[PROT_NUMPROTOS][8] = {
2203 /* --header-- ---data--- packet -4th-byte- mouse */
2204 /* mask id mask id bytes mask id flags */
2205 /* Serial mice */
2206 { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MicroSoft */
2207 { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_SAFE }, /* MouseSystems */
2208 { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MMSeries */
2209 { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* Logitech */
2210 { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MouseMan */
2211 { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MM_HitTablet */
2212 { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* GlidePoint */
2213 { 0x40, 0x40, 0x40, 0x00, 3, ~0x3f, 0x00, MPF_NONE }, /* IntelliMouse */
2214 { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* ThinkingMouse */
2215 { 0x80, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ACECAD */
2216 /* PS/2 variants */
2217 { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* PS/2 mouse */
|
2218 eich 1.55 { 0xc8, 0x08, 0x00, 0x00, 3, 0x08, 0x00, MPF_NONE }, /* genericPS/2 mouse*/
|
2219 eich 1.52 { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* IntelliMouse */
2220 { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* Explorer */
2221 { 0x80, 0x80, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ThinkingMouse */
2222 { 0x08, 0x08, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MouseMan+ */
2223 { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* GlidePoint */
2224 { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* NetMouse */
2225 { 0xc0, 0x00, 0x00, 0x00, 6, 0x00, 0xff, MPF_NONE }, /* NetScroll */
2226 /* Bus Mouse */
2227 { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* BusMouse */
2228 { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* Auto (dummy) */
2229 { 0xf8, 0x80, 0x00, 0x00, 8, 0x00, 0xff, MPF_NONE }, /* SysMouse */
2230 };
2231
2232
2233 /*
2234 * SetupMouse --
2235 * Sets up the mouse parameters
2236 */
2237 static Bool
2238 SetupMouse(InputInfoPtr pInfo)
2239 {
2240 eich 1.52 MouseDevPtr pMse;
2241 mousePrivPtr mPriv;
2242 int i;
2243 int protoPara[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
2244 const char *name = NULL;
2245 Bool automatic = FALSE;
2246
2247 pMse = pInfo->private;
2248 mPriv = (mousePrivPtr)pMse->mousePriv;
|
2249 eich 1.55
|
2250 eich 1.52 /* Handle the "Auto" protocol. */
2251 if (pMse->protocolID == PROT_AUTO) {
2252 /*
2253 * We come here when user specifies protocol "auto" in
2254 * the configuration file or thru the xf86misc extensions.
2255 * So we initialize autoprobing here.
2256 * Probe for PnP/OS mouse first. If unsuccessful
2257 * try to guess protocol from incoming data.
2258 */
2259 automatic = TRUE;
2260 pMse->autoProbe = TRUE;
2261 name = autoOSProtocol(pInfo,protoPara);
|
2262 eich 1.55 if (name) {
|
2263 eich 1.52 #ifdef EXTMOUSEDEBUG
|
2264 eich 1.55 ErrorF("PnP/OS Mouse detected: %s\n",name);
|
2265 eich 1.52 #endif
|
2266 eich 1.55 }
|
2267 eich 1.52 }
2268
2269 SetMouseProto(pMse, pMse->protocolID);
2270
2271 if (automatic) {
2272 if (name) {
2273 /* Possible protoPara overrides from SetupAuto. */
2274 for (i = 0; i < sizeof(pMse->protoPara); i++)
2275 if (protoPara[i] != -1)
2276 pMse->protoPara[i] = protoPara[i];
2277 /* if we come here PnP/OS mouse probing was successful */
2278 } else {
2279 #if 1
2280 /* PnP/OS mouse probing wasn't successful; we look at data */
2281 #else
2282 xf86Msg(X_ERROR, "%s: cannot determine the mouse protocol\n",
2283 pInfo->name);
2284 return FALSE;
2285 #endif
2286 }
2287 }
2288 eich 1.52
2289 /*
2290 * If protocol has changed fetch the default options
2291 * for the new protocol.
2292 */
2293 if (pMse->oldProtocolID != pMse->protocolID) {
2294 pointer tmp = NULL;
2295 if ((pMse->protocolID >= 0)
2296 && (pMse->protocolID < PROT_NUMPROTOS)
2297 && mouseProtocols[pMse->protocolID].defaults)
2298 tmp = xf86OptionListCreate(
2299 mouseProtocols[pMse->protocolID].defaults, -1, 0);
2300 pInfo->options = xf86OptionListMerge(pInfo->options, tmp);
2301 /*
2302 * If baudrate is set write it back to the option
2303 * list so that the serial interface code can access
2304 * the new value. Not set means default.
2305 */
2306 if (pMse->baudRate)
2307 xf86ReplaceIntOption(pInfo->options, "BaudRate", pMse->baudRate);
2308 pMse->oldProtocolID = pMse->protocolID; /* hack */
2309 eich 1.52 }
2310
2311
2312 /* Set the port parameters. */
2313 if (!automatic)
2314 xf86SetSerial(pInfo->fd, pInfo->options);
2315
2316 if (!initMouseHW(pInfo))
2317 return FALSE;
2318
2319 pMse->protoBufTail = 0;
2320 pMse->inSync = 0;
2321
2322 return TRUE;
2323 }
2324
2325 /********************************************************************
|
2326 dawes 1.4 *
|
2327 eich 1.52 * Mouse HW setup code
|
2328 dawes 1.4 *
|
2329 eich 1.52 ********************************************************************/
2330
2331 /*
2332 ** The following lines take care of the Logitech MouseMan protocols.
2333 ** The "Logitech" protocol is for the old "series 9" Logitech products.
2334 ** All products since then use the "MouseMan" protocol. Some models
2335 ** were programmable, but most (all?) of the current models are not.
2336 **
2337 ** NOTE: There are different versions of both MouseMan and TrackMan!
2338 ** Hence I add another protocol PROT_LOGIMAN, which the user can
2339 ** specify as MouseMan in his XF86Config file. This entry was
2340 ** formerly handled as a special case of PROT_MS. However, people
2341 ** who don't have the middle button problem, can still specify
2342 ** Microsoft and use PROT_MS.
2343 **
2344 ** By default, these mice should use a 3 byte Microsoft protocol
2345 ** plus a 4th byte for the middle button. However, the mouse might
2346 ** have switched to a different protocol before we use it, so I send
2347 ** the proper sequence just in case.
2348 **
2349 ** NOTE: - all commands to (at least the European) MouseMan have to
2350 eich 1.52 ** be sent at 1200 Baud.
2351 ** - each command starts with a '*'.
2352 ** - whenever the MouseMan receives a '*', it will switch back
2353 ** to 1200 Baud. Hence I have to select the desired protocol
2354 ** first, then select the baud rate.
2355 **
2356 ** The protocols supported by the (European) MouseMan are:
2357 ** - 5 byte packed binary protocol, as with the Mouse Systems
2358 ** mouse. Selected by sequence "*U".
2359 ** - 2 button 3 byte MicroSoft compatible protocol. Selected
2360 ** by sequence "*V".
2361 ** - 3 button 3+1 byte MicroSoft compatible protocol (default).
2362 ** Selected by sequence "*X".
2363 **
2364 ** The following baud rates are supported:
2365 ** - 1200 Baud (default). Selected by sequence "*n".
2366 ** - 9600 Baud. Selected by sequence "*q".
2367 **
2368 ** Selecting a sample rate is no longer supported with the MouseMan!
2369 ** [CHRIS-211092]
2370 */
2371 eich 1.52
|
2372 eich 1.62 #define do_ps2Reset(x) { \
2373 int i = 10;\
2374 while (i-- > 0) { \
2375 xf86FlushInput(x->fd); \
2376 if (ps2Reset(x)) break; \
2377 } \
2378 }
2379
2380
|
2381 eich 1.52 static Bool
2382 initMouseHW(InputInfoPtr pInfo)
2383 {
2384 MouseDevPtr pMse = pInfo->private;
2385 const char *s;
2386 unsigned char c;
2387 int speed;
2388 pointer options;
2389 unsigned char *param = NULL;
2390 int paramlen = 0;
|
2391 eich 1.62
|
2392 eich 1.52 switch (pMse->protocolID) {
|
2393 eich 1.62 case PROT_LOGI: /* Logitech Mice */
2394 /*
2395 * The baud rate selection command must be sent at the current
2396 * baud rate; try all likely settings.
2397 */
2398 speed = pMse->baudRate;
2399 switch (speed) {
2400 case 9600:
2401 s = "*q";
2402 break;
2403 case 4800:
2404 s = "*p";
2405 break;
2406 case 2400:
2407 s = "*o";
2408 break;
2409 case 1200:
2410 s = "*n";
2411 break;
2412 default:
2413 /* Fallback value */
2414 eich 1.62 speed = 1200;
2415 s = "*n";
2416 }
2417 xf86SetSerialSpeed(pInfo->fd, 9600);
2418 xf86WriteSerial(pInfo->fd, s, 2);
2419 usleep(100000);
2420 xf86SetSerialSpeed(pInfo->fd, 4800);
2421 xf86WriteSerial(pInfo->fd, s, 2);
2422 usleep(100000);
2423 xf86SetSerialSpeed(pInfo->fd, 2400);
2424 xf86WriteSerial(pInfo->fd, s, 2);
2425 usleep(100000);
2426 xf86SetSerialSpeed(pInfo->fd, 1200);
2427 xf86WriteSerial(pInfo->fd, s, 2);
2428 usleep(100000);
2429 xf86SetSerialSpeed(pInfo->fd, speed);
2430
2431 /* Select MM series data format. */
2432 xf86WriteSerial(pInfo->fd, "S", 1);
2433 usleep(100000);
2434 /* Set the parameters up for the MM series protocol. */
2435 eich 1.62 options = pInfo->options;
2436 xf86CollectInputOptions(pInfo, mmDefaults, NULL);
2437 xf86SetSerial(pInfo->fd, pInfo->options);
2438 pInfo->options = options;
2439
2440 /* Select report rate/frequency. */
2441 if (pMse->sampleRate <= 0) c = 'O'; /* 100 */
2442 else if (pMse->sampleRate <= 15) c = 'J'; /* 10 */
2443 else if (pMse->sampleRate <= 27) c = 'K'; /* 20 */
2444 else if (pMse->sampleRate <= 42) c = 'L'; /* 35 */
2445 else if (pMse->sampleRate <= 60) c = 'R'; /* 50 */
2446 else if (pMse->sampleRate <= 85) c = 'M'; /* 67 */
2447 else if (pMse->sampleRate <= 125) c = 'Q'; /* 100 */
2448 else c = 'N'; /* 150 */
2449 xf86WriteSerial(pInfo->fd, &c, 1);
2450 break;
2451
2452 case PROT_LOGIMAN:
2453 speed = pMse->baudRate;
2454 switch (speed) {
2455 case 9600:
2456 eich 1.62 s = "*q";
2457 break;
2458 case 1200:
2459 s = "*n";
2460 break;
2461 default:
2462 /* Fallback value */
2463 speed = 1200;
2464 s = "*n";
2465 }
2466 xf86SetSerialSpeed(pInfo->fd, 1200);
2467 xf86WriteSerial(pInfo->fd, "*n", 2);
2468 xf86WriteSerial(pInfo->fd, "*X", 2);
2469 xf86WriteSerial(pInfo->fd, s, 2);
2470 usleep(100000);
2471 xf86SetSerialSpeed(pInfo->fd, speed);
2472 break;
2473
2474 case PROT_MMHIT: /* MM_HitTablet */
2475 /*
2476 * Initialize Hitachi PUMA Plus - Model 1212E to desired settings.
2477 eich 1.62 * The tablet must be configured to be in MM mode, NO parity,
2478 * Binary Format. pMse->sampleRate controls the sensitivity
2479 * of the tablet. We only use this tablet for it's 4-button puck
2480 * so we don't run in "Absolute Mode".
2481 */
2482 xf86WriteSerial(pInfo->fd, "z8", 2); /* Set Parity = "NONE" */
2483 usleep(50000);
2484 xf86WriteSerial(pInfo->fd, "zb", 2); /* Set Format = "Binary" */
2485 usleep(50000);
2486 xf86WriteSerial(pInfo->fd, "@", 1); /* Set Report Mode = "Stream" */
2487 usleep(50000);
2488 xf86WriteSerial(pInfo->fd, "R", 1); /* Set Output Rate = "45 rps" */
2489 usleep(50000);
2490 xf86WriteSerial(pInfo->fd, "I\x20", 2); /* Set Incrememtal Mode "20" */
2491 usleep(50000);
2492 xf86WriteSerial(pInfo->fd, "E", 1); /* Set Data Type = "Relative */
2493 usleep(50000);
2494 /*
2495 * These sample rates translate to 'lines per inch' on the Hitachi
2496 * tablet.
2497 */
2498 eich 1.62 if (pMse->sampleRate <= 40) c = 'g';
2499 else if (pMse->sampleRate <= 100) c = 'd';
2500 else if (pMse->sampleRate <= 200) c = 'e';
2501 else if (pMse->sampleRate <= 500) c = 'h';
2502 else if (pMse->sampleRate <= 1000) c = 'j';
2503 else c = 'd';
2504 xf86WriteSerial(pInfo->fd, &c, 1);
2505 usleep(50000);
2506 xf86WriteSerial(pInfo->fd, "\021", 1); /* Resume DATA output */
2507 break;
2508
2509 case PROT_THINKING: /* ThinkingMouse */
2510 /* This mouse may send a PnP ID string, ignore it. */
2511 usleep(200000);
2512 xf86FlushInput(pInfo->fd);
2513 /* Send the command to initialize the beast. */
2514 for (s = "E5E5"; *s; ++s) {
2515 xf86WriteSerial(pInfo->fd, s, 1);
2516 if ((xf86WaitForInput(pInfo->fd, 1000000) <= 0))
2517 break;
2518 xf86ReadSerial(pInfo->fd, &c, 1);
2519 eich 1.62 if (c != *s)
2520 break;
2521 }
2522 break;
2523
2524 case PROT_MSC: /* MouseSystems Corp */
2525 usleep(100000);
2526 xf86FlushInput(pInfo->fd);
2527 break;
2528
2529 case PROT_ACECAD:
2530 /* initialize */
2531 /* A nul character resets. */
2532 xf86WriteSerial(pInfo->fd, "", 1);
2533 usleep(50000);
2534 /* Stream out relative mode high resolution increments of 1. */
2535 xf86WriteSerial(pInfo->fd, "@EeI!", 5);
2536 break;
2537
2538 case PROT_BM: /* bus/InPort mouse */
2539 if (osInfo->SetBMRes)
2540 eich 1.62 osInfo->SetBMRes(pInfo, pMse->protocol, pMse->sampleRate,
2541 pMse->resolution);
2542 break;
2543
2544 case PROT_GENPS2:
2545 break;
2546
2547 case PROT_PS2:
2548 case PROT_GLIDEPS2:
2549 do_ps2Reset(pInfo);
|
2550 eich 1.52 break;
|
2551 eich 1.62
2552 case PROT_IMPS2: /* IntelliMouse */
2553 {
2554 static unsigned char seq[] = { 243, 200, 243, 100, 243, 80, 242 };
2555 do_ps2Reset(pInfo);
2556 param = seq;
2557 paramlen = sizeof(seq);
2558 }
|
2559 eich 1.52 break;
2560
|
2561 eich 1.62 case PROT_EXPPS2: /* IntelliMouse Explorer */
2562 {
2563 static unsigned char seq[] = { 243, 200, 243, 100, 243, 80,
2564 243, 200, 243, 200, 243, 80, 242 };
2565
2566 do_ps2Reset(pInfo);
2567 param = seq;
2568 paramlen = sizeof(seq);
|
2569 eich 1.52 }
2570 break;
2571
|
2572 eich 1.62 case PROT_NETPS2: /* NetMouse, NetMouse Pro, Mie Mouse */
2573 case PROT_NETSCPS2: /* NetScroll */
2574 {
2575 static unsigned char seq[] = { 232, 3, 230, 230, 230, };
|
2576 eich 1.52
|
2577 eich 1.62 do_ps2Reset(pInfo);
2578 param = seq;
2579 paramlen = sizeof(seq);
2580 }
2581 break;
|
2582 eich 1.52
|
2583 eich 1.62 case PROT_MMPS2: /* MouseMan+, FirstMouse+ */
2584 {
2585 static unsigned char seq[] = { 230, 232, 0, 232, 3, 232, 2, 232, 1,
2586 230, 232, 3, 232, 1, 232, 2, 232, 3, };
2587 do_ps2Reset(pInfo);
2588 param = seq;
2589 paramlen = sizeof(seq);
2590 }
2591 break;
|
2592 eich 1.52
|
2593 eich 1.62 case PROT_THINKPS2: /* ThinkingMouse */
2594 {
2595 static unsigned char seq[] = { 243, 10, 232, 0, 243, 20, 243, 60,
2596 243, 40, 243, 20, 243, 20, 243, 60,
2597 243, 40, 243, 20, 243, 20, };
2598 do_ps2Reset(pInfo);
2599 param = seq;
2600 paramlen = sizeof(seq);
2601 }
|
2602 eich 1.52 break;
|
2603 eich 1.62 case PROT_SYSMOUSE:
2604 if (osInfo->SetMiscRes)
2605 osInfo->SetMiscRes(pInfo, pMse->protocol, pMse->sampleRate,
2606 pMse->resolution);
2607 break;
|
2608 dawes 1.4
|
2609 eich 1.62 default:
2610 /* Nothing to do. */
2611 break;
|
2612 eich 1.52 }
|
2613 eich 1.62
|
2614 eich 1.52 if (paramlen > 0) {
|
2615 eich 1.55 int count = 10;
|
2616 eich 1.62
|
2617 eich 1.55 while (count--) {
2618 if (ps2SendPacket(pInfo,param,paramlen))
2619 break;
|
2620 eich 1.52 usleep(30000);
2621 }
|
2622 eich 1.62 if (!count)
|
2623 eich 1.55 xf86Msg(X_ERROR, "%s: Mouse initialization failed\n", pInfo->name);
|
2624 eich 1.52 usleep(30000);
2625 xf86FlushInput(pInfo->fd);
2626 }
|
2627 dawes 1.4
|
2628 eich 1.52 if (pMse->class & (MSE_PS2 | MSE_XPS2)) {
2629
2630 if (osInfo->SetPS2Res) {
2631 osInfo->SetPS2Res(pInfo, pMse->protocol, pMse->sampleRate,
2632 pMse->resolution);
2633 } else {
|
2634 eich 1.55 int count = 10;
|
2635 eich 1.52 unsigned char c2[2];
2636
2637 c = 230; /* 1:1 scaling */
2638 xf86WriteSerial(pInfo->fd, &c, 1);
2639 c = 244; /* enable mouse */
2640 xf86WriteSerial(pInfo->fd, &c, 1);
2641 c2[0] = 243; /* set sampling rate */
2642 if (pMse->sampleRate > 0) {
2643 if (pMse->sampleRate >= 200)
2644 c2[1] = 200;
2645 else if (pMse->sampleRate >= 100)
2646 c2[1] = 100;
2647 else if (pMse->sampleRate >= 80)
2648 c2[1] = 80;
2649 else if (pMse->sampleRate >= 60)
2650 c2[1] = 60;
2651 else if (pMse->sampleRate >= 40)
2652 c2[1] = 40;
2653 else
2654 c2[1] = 20;
2655 } else {
2656 eich 1.52 c2[1] = 100;
2657 }
2658 xf86WriteSerial(pInfo->fd, c2, 2);
2659 c2[0] = 232; /* set device resolution */
2660 if (pMse->resolution > 0) {
2661 if (pMse->resolution >= 200)
2662 c2[1] = 3;
2663 else if (pMse->resolution >= 100)
2664 c2[1] = 2;
2665 else if (pMse->resolution >= 50)
2666 c2[1] = 1;
2667 else
2668 c2[1] = 0;
2669 } else {
2670 c2[1] = 2;
2671 }
2672 xf86WriteSerial(pInfo->fd, c2, 2);
2673 usleep(30000);
2674 xf86FlushInput(pInfo->fd);
|
2675 eich 1.55 do {
2676 if (!ps2EnableDataReporting(pInfo)) {
|
2677 dawes 1.60 xf86Msg(X_INFO, "%s: ps2EnableDataReporting: failed\n",
2678 pInfo->name);
|
2679 eich 1.55 xf86FlushInput(pInfo->fd);
2680 } else {
|
2681 dawes 1.60 xf86Msg(X_INFO, "%s: ps2EnableDataReporting: succeeded\n",
2682 pInfo->name);
|
2683 eich 1.55 break;
2684 }
2685 } while (count --);
|
2686 eich 1.52 }
2687 }
2688 return TRUE;
2689 }
|
2690 dawes 1.4
|
2691 eich 1.55 #ifdef SUPPORT_MOUSE_RESET
|
2692 eich 1.52 static Bool
2693 mouseReset(InputInfoPtr pInfo, unsigned char val)
|
2694 paulo 1.41 {
|
2695 eich 1.52 MouseDevPtr pMse = pInfo->private;
2696 mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv;
2697 CARD32 prevEvent = mousepriv->lastEvent;
2698 Bool expectReset = FALSE;
2699 Bool ret = FALSE;
|
2700 paulo 1.41
|
2701 eich 1.52 mousepriv->lastEvent = GetTimeInMillis();
|
2702 paulo 1.41
|
2703 eich 1.52 #ifdef EXTMOUSEDEBUG
2704 ErrorF("byte: 0x%x time: %li\n",val,mousepriv->lastEvent);
2705 #endif
2706 /*
2707 * We believe that the following is true:
2708 * When the mouse is replugged it will send a reset package
2709 * It takes several seconds to replug a mouse: We don't see
2710 * events for several seconds before we see the replug event package.
2711 * There is no significant delay between consecutive bytes
2712 * of a replug event package.
2713 * There are no bytes sent after the replug event package until
2714 * the mouse is reset.
2715 */
2716
2717 if (mousepriv->current == 0
2718 && (mousepriv->lastEvent - prevEvent) < 4000)
2719 return FALSE;
|
2720 paulo 1.41
|
2721 eich 1.52 if (mousepriv->current > 0
2722 && (mousepriv->lastEvent - prevEvent) >= 1000) {
2723 mousepriv->inReset = FALSE;
2724 mousepriv->current = 0;
2725 return FALSE;
|
2726 paulo 1.41 }
2727
|
2728 eich 1.52 if (mousepriv->inReset)
2729 mousepriv->inReset = FALSE;
2730
2731 #ifdef EXTMOUSEDEBUG
2732 ErrorF("Mouse Current: %i 0x%x\n",mousepriv->current, val);
2733 #endif
2734
2735 /* here we put the mouse specific reset detction */
2736 /* They need to do three things: */
2737 /* Check if byte may be a reset byte */
2738 /* If so: Set expectReset TRUE */
2739 /* If convinced: Set inReset TRUE */
2740 /* Register BlockAndWakeupHandler */
2741
2742 /* PS/2 */
2743 {
2744 unsigned char seq[] = { 0xaa, 0x00 };
2745 int len = sizeof(seq);
2746
2747 if (seq[mousepriv->current] == val)
2748 expectReset = TRUE;
2749 eich 1.52
2750 if (len == mousepriv->current + 1) {
2751 mousepriv->inReset = TRUE;
2752 mousepriv->expires = GetTimeInMillis() + 1000;
2753
2754 #ifdef EXTMOUSEDEBUG
2755 ErrorF("Found PS/2 Reset string\n");
2756 #endif
2757 RegisterBlockAndWakeupHandlers (ps2BlockHandler,
2758 ps2WakeupHandler, (pointer) pInfo);
2759 ret = TRUE;
2760 }
2761 }
2762
2763 if (!expectReset)
2764 mousepriv->current = 0;
2765 else
2766 mousepriv->current++;
2767 return ret;
|
2768 paulo 1.41 }
2769
|
2770 eich 1.52 static void
2771 ps2BlockHandler(pointer data, struct timeval **waitTime,
2772 pointer LastSelectMask)
|
2773 keithp 1.44 {
2774 InputInfoPtr pInfo = (InputInfoPtr) data;
2775 MouseDevPtr pMse = (MouseDevPtr) pInfo->private;
|
2776 eich 1.52 mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv;
|
2777 keithp 1.44 int ms;
2778
|
2779 eich 1.52 if (mousepriv->inReset) {
2780 ms = mousepriv->expires - GetTimeInMillis ();
|
2781 keithp 1.44 if (ms <= 0)
2782 ms = 0;
2783 AdjustWaitForDelay (waitTime, ms);
|
2784 eich 1.52 } else
2785 RemoveBlockAndWakeupHandlers (ps2BlockHandler, ps2WakeupHandler,
2786 (pointer) pInfo);
|
2787 keithp 1.44 }
2788
|
2789 eich 1.52 static void
2790 ps2WakeupHandler(pointer data, int i, pointer LastSelectMask)
|
2791 keithp 1.44 {
2792 InputInfoPtr pInfo = (InputInfoPtr) data;
2793 MouseDevPtr pMse = (MouseDevPtr) pInfo->private;
|
2794 eich 1.52 mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv;
|
2795 keithp 1.44 int ms;
2796
|
2797 eich 1.52 if (mousepriv->inReset) {
2798 unsigned char val;
2799 int blocked;
2800
2801 ms = mousepriv->expires - GetTimeInMillis();
2802 if (ms > 0)
2803 return;
|
2804 keithp 1.44
|
2805 eich 1.52 blocked = xf86BlockSIGIO ();
|
2806 dawes 1.4
|
2807 eich 1.52 xf86MsgVerb(X_INFO,3,
2808 "Got reinsert event: reinitializing PS/2 mouse\n");
2809 val = 0xf4;
2810 if (xf86WriteSerial(pInfo->fd, &val, 1) != 1)
2811 xf86Msg(X_ERROR, "%s: Write to mouse failed\n",
2812 pInfo->name);
2813 xf86UnblockSIGIO(blocked);
|
2814 dawes 1.45 }
|
2815 eich 1.52 RemoveBlockAndWakeupHandlers (ps2BlockHandler, ps2WakeupHandler,
2816 (pointer) pInfo);
2817 }
|
2818 eich 1.55 #endif /* SUPPORT_MOUSE_RESET */
|
2819 dawes 1.4
|
2820 eich 1.52 /************************************************************
2821 *
2822 * Autoprobe stuff
2823 *
2824 ************************************************************/
2825 #ifdef EXTMOUSEDEBUG
2826 # define AP_DBG(x) { ErrorF("Autoprobe: "); ErrorF x; }
2827 # define AP_DBGC(x) ErrorF x ;
2828 # else
2829 # define AP_DBG(x)
2830 # define AP_DBGC(x)
2831 #endif
|
2832 paulo 1.41
|
2833 eich 1.52 MouseProtocolID hardProtocolList[] = { PROT_MSC, PROT_MM, PROT_LOGI,
2834 PROT_LOGIMAN, PROT_MMHIT,
2835 PROT_GLIDE, PROT_IMSERIAL,
2836 PROT_THINKING, PROT_ACECAD,
2837 PROT_THINKPS2, PROT_MMPS2,
2838 PROT_GLIDEPS2,
2839 PROT_NETSCPS2, PROT_EXPPS2,PROT_IMPS2,
|
2840 eich 1.55 PROT_GENPS2, PROT_NETPS2,
|
2841 eich 1.52 PROT_MS,
2842 PROT_UNKNOWN
2843 };
|
2844 paulo 1.41
|
2845 eich 1.52 MouseProtocolID softProtocolList[] = { PROT_MSC, PROT_MM, PROT_LOGI,
2846 PROT_LOGIMAN, PROT_MMHIT,
2847 PROT_GLIDE, PROT_IMSERIAL,
2848 PROT_THINKING, PROT_ACECAD,
2849 PROT_THINKPS2, PROT_MMPS2,
2850 PROT_GLIDEPS2,
2851 PROT_NETSCPS2 ,PROT_IMPS2,
|
2852 eich 1.55 PROT_GENPS2,
|
2853 eich 1.52 PROT_MS,
2854 PROT_UNKNOWN
2855 };
|
2856 paulo 1.41
|
2857 eich 1.52 static const char *
2858 autoOSProtocol(InputInfoPtr pInfo, int *protoPara)
2859 {
2860 MouseDevPtr pMse = pInfo->private;
2861 const char *name = NULL;
2862 MouseProtocolID protocolID = PROT_UNKNOWN;
|
2863 dawes 1.4
|
2864 eich 1.52 /* Check if the OS has a detection mechanism. */
2865 if (osInfo->SetupAuto) {
2866 name = osInfo->SetupAuto(pInfo, protoPara);
2867 if (name) {
2868 protocolID = ProtocolNameToID(name);
2869 switch (protocolID) {
2870 case PROT_UNKNOWN:
2871 /* Check for a builtin OS-specific protocol. */
2872 if (osInfo->CheckProtocol && osInfo->CheckProtocol(name)) {
2873 /* We can only come here if the protocol has been
2874 * changed to auto thru the xf86misc extension
2875 * and we have detected an OS specific builtin
2876 * protocol. Currently we cannot handle this */
2877 name = NULL;
2878 } else
2879 name = NULL;
2880 break;
2881 case PROT_UNSUP:
2882 name = NULL;
2883 break;
2884 default:
2885 eich 1.52 break;
2886 }
2887 }
2888 }
2889 #ifdef PNP_MOUSE
2890 if (!name) {
2891 /* A PnP serial mouse? */
2892 protocolID = MouseGetPnpProtocol(pInfo);
2893 if (protocolID >= 0 && protocolID < PROT_NUMPROTOS) {
2894 name = ProtocolIDToName(protocolID);
2895 xf86Msg(X_PROBED, "%s: PnP-detected protocol: \"%s\"\n",
2896 pInfo->name, name);
|
2897 dawes 1.4 }
2898 }
|
2899 eich 1.52 #endif
2900 if (name) {
2901 pMse->protocolID = protocolID;
2902 }
2903
2904 return name;
|
2905 dawes 1.8 }
2906
|
2907 eich 1.52 /*
2908 * createProtocolList() -- create a list of protocols which may
2909 * match on the incoming data stream.
2910 */
|
2911 dawes 1.8 static void
|
2912 eich 1.52 createProtoList(MouseDevPtr pMse, MouseProtocolID *protoList)
|
2913 dawes 1.8 {
|
2914 eich 1.52 int i, j, k = 0;
2915 MouseProtocolID prot;
2916 unsigned char *para;
2917 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
2918 MouseProtocolID *tmplist = NULL;
2919 int blocked;
2920
2921 AP_DBGC(("Autoprobe: "));
2922 for (i = 0; i < mPriv->count; i++)
2923 AP_DBGC(("%2.2x ", (unsigned char) mPriv->data[i]));
2924 AP_DBGC(("\n"));
2925
2926 blocked = xf86BlockSIGIO ();
2927
2928 /* create a private copy first so we can write in the old list */
2929 if ((tmplist = xalloc(sizeof(MouseProtocolID) * NUM_AUTOPROBE_PROTOS))){
2930 for (i = 0; protoList[i] != PROT_UNKNOWN; i++) {
2931 tmplist[i] = protoList[i];
2932 }
2933 tmplist[i] = PROT_UNKNOWN;
2934 protoList = tmplist;
2935 eich 1.52 } else
2936 return;
|
2937 dawes 1.8
|
2938 eich 1.52 for (i = 0; ((prot = protoList[i]) != PROT_UNKNOWN
2939 && (k < NUM_AUTOPROBE_PROTOS - 1)) ; i++) {
2940 Bool bad = TRUE;
2941 unsigned char byte = 0;
2942 int count = 0;
2943 int next_header_candidate = 0;
2944 int header_count = 0;
2945
2946 if (!GetProtocol(prot))
2947 continue;
2948 para = proto[prot];
|
2949 dawes 1.8
|
2950 eich 1.52 AP_DBG(("Protocol: %s ", ProtocolIDToName(prot)));
|
2951 dawes 1.8
|
2952 eich 1.52 #ifdef EXTMOUSEDEBUG
2953 for (j = 0; j < 7; j++)
2954 AP_DBGC(("%2.2x ", (unsigned char) para[j]));
2955 AP_DBGC(("\n"));
2956 #endif
2957 j = 0;
2958 while (1) {
2959 /* look for header */
2960 while (j < mPriv->count) {
2961 if (((byte = mPriv->data[j++]) & para[0]) == para[1]){
2962 AP_DBG(("found header %2.2x\n",byte));
2963 next_header_candidate = j;
2964 count = 1;
2965 break;
2966 } else {
2967 /*
2968 * Bail ot if number of bytes per package have
2969 * been tested for header.
2970 * Take bytes per package of leading garbage into
2971 * account.
2972 */
2973 eich 1.52 if (j > para[4] && ++header_count > para[4]) {
2974 j = mPriv->count;
2975 break;
2976 }
2977 }
2978 }
2979 /* check if remaining data matches protocol */
2980 while (j < mPriv->count) {
2981 byte = mPriv->data[j++];
2982 if (count == para[4]) {
2983 count = 0;
2984 /* check and eat excess byte */
2985 if (((byte & para[0]) != para[1])
2986 && ((byte & para[5]) == para[6])) {
2987 AP_DBG(("excess byte found\n"));
2988 continue;
2989 }
2990 }
2991 if (count == 0) {
2992 /* validate next header */
2993 bad = FALSE;
2994 eich 1.52 AP_DBG(("Complete set found\n"));
2995 if ((byte & para[0]) != para[1]) {
2996 AP_DBG(("Autoprobe: header bad\n"));
2997 bad = TRUE;
2998 break;
2999 } else {
3000 count++;
3001 continue;
3002 }
3003 }
3004 /* validate data */
3005 else if (((byte & para[2]) != para[3])
3006 || ((para[7] & MPF_SAFE)
3007 && ((byte & para[0]) == para[1]))) {
3008 AP_DBG(("data bad\n"));
3009 bad = TRUE;
3010 break;
3011 } else {
3012 count ++;
3013 continue;
3014 }
3015 eich 1.52 }
3016 if (!bad) {
3017 /* this is a matching protocol */
3018 mPriv->protoList[k++] = prot;
|
3019 eich 1.55 AP_DBG(("Autoprobe: Adding protocol %s to list (entry %i)\n",
3020 ProtocolIDToName(prot),k-1));
|
3021 eich 1.52 break;
3022 }
3023 j = next_header_candidate;
3024 next_header_candidate = 0;
3025 /* we have tested number of bytes per package for header */
3026 if (j > para[4] && ++header_count > para[4])
3027 break;
3028 /* we have not found anything that looks like a header */
3029 if (!next_header_candidate)
3030 break;
3031 AP_DBG(("Looking for new header\n"));
|
3032 dawes 1.8 }
3033 }
3034
|
3035 eich 1.52 xf86UnblockSIGIO(blocked);
3036
3037 mPriv->protoList[k] = PROT_UNKNOWN;
3038
3039 xfree(tmplist);
|
3040 eich 1.48 }
3041
|
3042 eich 1.52
3043 /* This only needs to be done once */
3044 void **serialDefaultsList = NULL;
3045
3046 /*
3047 * createSerialDefaultsLists() - create a list of the different default
3048 * settings for the serial interface of the known protocols.
3049 */
|
3050 eich 1.48 static void
|
3051 eich 1.52 createSerialDefaultsList(void)
|
3052 eich 1.48 {
|
3053 eich 1.52 int i = 0, j, k;
3054
3055 serialDefaultsList = (void **)xnfalloc(sizeof(void*));
3056 serialDefaultsList[0] = NULL;
|
3057 eich 1.48
|
3058 eich 1.52 for (j = 0; mouseProtocols[j].name; j++) {
3059 if (!mouseProtocols[j].defaults)
3060 continue;
3061 for (k = 0; k < i; k++)
3062 if (mouseProtocols[j].defaults == serialDefaultsList[k])
3063 continue;
3064 i++;
3065 serialDefaultsList = (void**)xnfrealloc(serialDefaultsList,
3066 sizeof(void*)*(i+1));
3067 serialDefaultsList[i-1] = mouseProtocols[j].defaults;
3068 serialDefaultsList[i] = NULL;
|
3069 eich 1.48 }
|
3070 eich 1.52 }
|
3071 eich 1.48
|
3072 eich 1.52 typedef enum {
3073 STATE_INVALID,
3074 STATE_UNCERTAIN,
3075 STATE_VALID
3076 } validState;
3077
3078 /* Probing threshold values */
3079 #define PROBE_UNCERTAINTY 50
3080 #define BAD_CERTAINTY 6
3081 #define BAD_INC_CERTAINTY 1
3082 #define BAD_INC_CERTAINTY_WHEN_SYNC_LOST 2
3083
3084 static validState
3085 validCount(mousePrivPtr mPriv, Bool inSync, Bool lostSync)
3086 {
3087 if (inSync) {
3088 if (!--mPriv->goodCount) {
3089 /* we are sure to have found the correct protocol */
3090 mPriv->badCount = 0;
3091 return STATE_VALID;
3092 }
3093 eich 1.52 AP_DBG(("%i successful rounds to go\n",
3094 mPriv->goodCount));
3095 return STATE_UNCERTAIN;
3096 }
|
3097 eich 1.48
3098
|
3099 eich 1.52 /* We are out of sync again */
3100 mPriv->goodCount = PROBE_UNCERTAINTY;
3101 /* We increase uncertainty of having the correct protocol */
3102 mPriv->badCount+= lostSync ? BAD_INC_CERTAINTY_WHEN_SYNC_LOST
3103 : BAD_INC_CERTAINTY;
3104
3105 if (mPriv->badCount < BAD_CERTAINTY) {
3106 /* We are not convinced yet to have the wrong protocol */
3107 AP_DBG(("Changing protocol after: %i rounds\n",
3108 BAD_CERTAINTY - mPriv->badCount));
3109 return STATE_UNCERTAIN;
3110 }
3111 return STATE_INVALID;
3112 }
3113
3114 #define RESET_VALIDATION mPriv->goodCount = PROBE_UNCERTAINTY;\
3115 mPriv->badCount = 0;\
3116 mPriv->prevDx = 0;\
3117 mPriv->prevDy = 0;\
3118 mPriv->accDx = 0;\
3119 mPriv->accDy = 0;\
3120 eich 1.52 mPriv->acc = 0;
|
3121 eich 1.48
|
3122 eich 1.52 static void
3123 autoProbeMouse(InputInfoPtr pInfo, Bool inSync, Bool lostSync)
3124 {
3125 MouseDevPtr pMse = pInfo->private;
3126 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
|
3127 eich 1.48
|
3128 eich 1.52 MouseProtocolID *protocolList = NULL;
3129
3130 while (1) {
3131 switch (mPriv->autoState) {
3132 case AUTOPROBE_GOOD:
|
3133 eich 1.55 if (inSync)
|
3134 eich 1.52 return;
3135 AP_DBG(("State GOOD\n"));
3136 RESET_VALIDATION;
3137 mPriv->autoState = AUTOPROBE_VALIDATE1;
3138 return;
3139 case AUTOPROBE_H_GOOD:
3140 if (inSync)
3141 return;
3142 AP_DBG(("State H_GOOD\n"));
3143 RESET_VALIDATION;
3144 mPriv->autoState = AUTOPROBE_H_VALIDATE2;
3145 return;
3146 case AUTOPROBE_H_NOPROTO:
3147 AP_DBG(("State H_NOPROTO\n"));
3148 mPriv->protocolID = 0;
3149 mPriv->autoState = AUTOPROBE_H_SETPROTO;
3150 break;
3151 case AUTOPROBE_H_SETPROTO:
3152 AP_DBG(("State H_SETPROTO\n"));
3153 if ((pMse->protocolID = hardProtocolList[mPriv->protocolID++])
3154 == PROT_UNKNOWN) {
3155 eich 1.52 mPriv->protocolID = 0;
3156 break;
3157 } else if (GetProtocol(pMse->protocolID) && SetupMouse(pInfo)) {
3158 FlushButtons(pMse);
3159 RESET_VALIDATION;
3160 AP_DBG(("Autoprobe: Trying Protocol: %s\n",
3161 ProtocolIDToName(pMse->protocolID)));
3162 mPriv->autoState = AUTOPROBE_H_VALIDATE1;
3163 return;
3164 }
3165 break;
3166 case AUTOPROBE_H_VALIDATE1:
3167 AP_DBG(("State H_VALIDATE1\n"));
3168 switch (validCount(mPriv,inSync,lostSync)) {
3169 case STATE_INVALID:
3170 mPriv->autoState = AUTOPROBE_H_SETPROTO;
3171 break;
3172 case STATE_VALID:
3173 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n",
3174 ProtocolIDToName(pMse->protocolID));
3175 mPriv->autoState = AUTOPROBE_H_GOOD;
3176 eich 1.52 return;
3177 case STATE_UNCERTAIN:
3178 return;
3179 default:
3180 break;
3181 }
3182 break;
3183 case AUTOPROBE_H_VALIDATE2:
3184 AP_DBG(("State H_VALIDATE2\n"));
3185 switch (validCount(mPriv,inSync,lostSync)) {
3186 case STATE_INVALID:
3187 mPriv->autoState = AUTOPROBE_H_AUTODETECT;
3188 break;
3189 case STATE_VALID:
3190 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n",
3191 ProtocolIDToName(pMse->protocolID));
3192 mPriv->autoState = AUTOPROBE_H_GOOD;
3193 return;
3194 case STATE_UNCERTAIN:
3195 return;
3196 }
3197 eich 1.52 break;
3198 case AUTOPROBE_H_AUTODETECT:
3199 AP_DBG(("State H_AUTODETECT\n"));
3200 pMse->protocolID = PROT_AUTO;
3201 AP_DBG(("Looking for PnP/OS mouse\n"));
3202 mPriv->count = 0;
3203 SetupMouse(pInfo);
3204 if (pMse->protocolID != PROT_AUTO)
3205 mPriv->autoState = AUTOPROBE_H_GOOD;
3206 else
3207 mPriv->autoState = AUTOPROBE_H_NOPROTO;
3208 break;
3209 case AUTOPROBE_NOPROTO:
3210 AP_DBG(("State NOPROTO\n"));
3211 mPriv->count = 0;
3212 mPriv->serialDefaultsNum = -1;
3213 mPriv->autoState = AUTOPROBE_COLLECT;
3214 break;
3215 case AUTOPROBE_COLLECT:
3216 AP_DBG(("State COLLECT\n"));
3217 if (mPriv->count <= NUM_MSE_AUTOPROBE_BYTES)
3218 eich 1.52 return;
3219 protocolList = softProtocolList;
3220 mPriv->autoState = AUTOPROBE_CREATE_PROTOLIST;
3221 break;
3222 case AUTOPROBE_CREATE_PROTOLIST:
3223 AP_DBG(("State CREATE_PROTOLIST\n"));
3224 createProtoList(pMse, protocolList);
3225 mPriv->protocolID = 0;
3226 mPriv->autoState = AUTOPROBE_SWITCH_PROTOCOL;
3227 break;
3228 case AUTOPROBE_AUTODETECT:
3229 AP_DBG(("State AUTODETECT\n"));
3230 pMse->protocolID = PROT_AUTO;
3231 AP_DBG(("Looking for PnP/OS mouse\n"));
3232 mPriv->count = 0;
3233 SetupMouse(pInfo);
3234 if (pMse->protocolID != PROT_AUTO)
3235 mPriv->autoState = AUTOPROBE_GOOD;
3236 else
3237 mPriv->autoState = AUTOPROBE_NOPROTO;
3238 break;
3239 eich 1.52 case AUTOPROBE_VALIDATE1:
3240 AP_DBG(("State VALIDATE1\n"));
3241 switch (validCount(mPriv,inSync,lostSync)) {
3242 case STATE_INVALID:
3243 mPriv->autoState = AUTOPROBE_AUTODETECT;
3244 break;
3245 case STATE_VALID:
3246 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n",
3247 ProtocolIDToName(pMse->protocolID));
3248 mPriv->autoState = AUTOPROBE_GOOD;
3249 break;
3250 case STATE_UNCERTAIN:
3251 return;
3252 }
3253 break;
3254 case AUTOPROBE_VALIDATE2:
3255 AP_DBG(("State VALIDATE2\n"));
3256 switch (validCount(mPriv,inSync,lostSync)) {
3257 case STATE_INVALID:
3258 protocolList = &mPriv->protoList[mPriv->protocolID];
3259 mPriv->autoState = AUTOPROBE_CREATE_PROTOLIST;
3260 eich 1.52 break;
3261 case STATE_VALID:
3262 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n",
3263 ProtocolIDToName(pMse->protocolID));
3264 mPriv->autoState = AUTOPROBE_GOOD;
3265 break;
3266 case STATE_UNCERTAIN:
3267 return;
3268 }
3269 break;
3270 case AUTOPROBE_SWITCHSERIAL:
|
3271 eich 1.48 {
|
3272 eich 1.52 pointer serialDefaults;
3273 AP_DBG(("State SWITCHSERIAL\n"));
3274
3275 if (!serialDefaultsList)
3276 createSerialDefaultsList();
3277
3278 AP_DBG(("Switching serial params\n"));
3279 if ((serialDefaults =
3280 serialDefaultsList[++mPriv->serialDefaultsNum]) == NULL) {
3281 mPriv->serialDefaultsNum = 0;
3282 } else {
3283 pointer tmp = xf86OptionListCreate(serialDefaults, -1, 0);
3284 xf86SetSerial(pInfo->fd, tmp);
3285 xf86OptionListFree(tmp);
3286 mPriv->count = 0;
3287 mPriv->autoState = AUTOPROBE_COLLECT;
3288 }
3289 break;
|
3290 eich 1.48 }
|
3291 eich 1.52 case AUTOPROBE_SWITCH_PROTOCOL:
|
3292 eich 1.48 {
|
3293 eich 1.52 MouseProtocolID proto;
|
3294 eich 1.55 void *defaults;
|
3295 eich 1.52 AP_DBG(("State SWITCH_PROTOCOL\n"));
3296 proto = mPriv->protoList[mPriv->protocolID++];
|
3297 tsi 1.56 if (proto == PROT_UNKNOWN)
|
3298 eich 1.52 mPriv->autoState = AUTOPROBE_SWITCHSERIAL;
|
3299 tsi 1.56 else if (!(defaults = GetProtocol(proto)->defaults)
|
3300 eich 1.55 || (mPriv->serialDefaultsNum == -1
3301 && (defaults == msDefaults))
3302 || (mPriv->serialDefaultsNum != -1
3303 && serialDefaultsList[mPriv->serialDefaultsNum]
3304 == defaults)) {
|
3305 eich 1.52 AP_DBG(("Changing Protocol to %s\n",
3306 ProtocolIDToName(proto)));
3307 SetMouseProto(pMse,proto);
3308 FlushButtons(pMse);
3309 RESET_VALIDATION;
3310 mPriv->autoState = AUTOPROBE_VALIDATE2;
3311 return;
|
3312 eich 1.55 }
|
3313 eich 1.52 break;
|
3314 eich 1.48 }
3315 }
3316 }
|
3317 eich 1.52 }
3318
|
3319 eich 1.55 static Bool
3320 autoGood(MouseDevPtr pMse)
3321 {
3322 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
3323
3324 if (!pMse->autoProbe)
3325 return TRUE;
3326
3327 switch (mPriv->autoState) {
3328 case AUTOPROBE_GOOD:
3329 case AUTOPROBE_H_GOOD:
3330 return TRUE;
3331 case AUTOPROBE_VALIDATE1: /* @@@ */
3332 case AUTOPROBE_H_VALIDATE1: /* @@@ */
3333 case AUTOPROBE_VALIDATE2:
3334 case AUTOPROBE_H_VALIDATE2:
3335 if (mPriv->goodCount < PROBE_UNCERTAINTY/2)
3336 return TRUE;
3337 default:
3338 return FALSE;
3339 }
3340 eich 1.55 }
3341
|
3342 eich 1.52
3343 #define TOT_THRESHOLD 3000
3344 #define VAL_THRESHOLD 40
|
3345 eich 1.48
|
3346 eich 1.52 /*
3347 * checkForErraticMovements() -- check if mouse 'jumps around'.
3348 */
3349 static void
3350 checkForErraticMovements(InputInfoPtr pInfo, int dx, int dy)
3351 {
3352 MouseDevPtr pMse = pInfo->private;
3353 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
3354 #if 1
3355 if (!mPriv->goodCount)
3356 return;
3357 #endif
3358 #if 0
3359 if (abs(dx - mPriv->prevDx) > 300
3360 || abs(dy - mPriv->prevDy) > 300)
3361 AP_DBG(("erratic1 behaviour\n"));
|
3362 eich 1.48 #endif
|
3363 eich 1.52 if (abs(dx) > VAL_THRESHOLD) {
3364 if (sign(dx) == sign(mPriv->prevDx)) {
3365 mPriv->accDx += dx;
3366 if (abs(mPriv->accDx) > mPriv->acc) {
3367 mPriv->acc = abs(mPriv->accDx);
3368 AP_DBG(("acc=%i\n",mPriv->acc));
3369 }
|
3370 eich 1.48 else
|
3371 eich 1.52 AP_DBG(("accDx=%i\n",mPriv->accDx));
|
3372 eich 1.48 } else {
|
3373 eich 1.52 mPriv->accDx = 0;
|
3374 eich 1.48 }
|
3375 eich 1.52 }
3376
3377 if (abs(dy) > VAL_THRESHOLD) {
3378 if (sign(dy) == sign(mPriv->prevDy)) {
3379 mPriv->accDy += dy;
3380 if (abs(mPriv->accDy) > mPriv->acc) {
3381 mPriv->acc = abs(mPriv->accDy);
3382 AP_DBG(("acc: %i\n",mPriv->acc));
3383 } else
3384 AP_DBG(("accDy=%i\n",mPriv->accDy));
|
3385 eich 1.48 } else {
|
3386 eich 1.52 mPriv->accDy = 0;
|
3387 eich 1.48 }
3388 }
|
3389 eich 1.52 mPriv->prevDx = dx;
3390 mPriv->prevDy = dy;
3391 if (mPriv->acc > TOT_THRESHOLD) {
3392 mPriv->goodCount = PROBE_UNCERTAINTY;
3393 mPriv->prevDx = 0;
3394 mPriv->prevDy = 0;
3395 mPriv->accDx = 0;
3396 mPriv->accDy = 0;
3397 mPriv->acc = 0;
3398 AP_DBG(("erratic2 behaviour\n"));
3399 autoProbeMouse(pInfo, FALSE,TRUE);
3400 }
3401 }
3402
3403 static void
3404 SetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID)
3405 {
3406 pMse->protocolID = protocolID;
3407 pMse->protocol = ProtocolIDToName(pMse->protocolID);
3408 pMse->class = ProtocolIDToClass(pMse->protocolID);
3409 if ((pMse->protocolID >= 0) && (pMse->protocolID < PROT_NUMPROTOS))
3410 eich 1.52 memcpy(pMse->protoPara, proto[pMse->protocolID],
3411 sizeof(pMse->protoPara));
3412
3413 if (pMse->emulate3ButtonsSoft)
3414 pMse->emulate3Buttons = TRUE;
|
3415 eich 1.48 }
3416
|
3417 eich 1.52 /*
3418 * collectData() -- collect data bytes sent by mouse.
3419 */
|
3420 eich 1.48 static Bool
|
3421 eich 1.52 collectData(MouseDevPtr pMse, unsigned char u)
|
3422 eich 1.48 {
|
3423 eich 1.52 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
3424 if (mPriv->count < NUM_MSE_AUTOPROBE_TOTAL) {
3425 mPriv->data[mPriv->count++] = u;
3426 if (mPriv->count <= NUM_MSE_AUTOPROBE_BYTES) {
|
3427 eich 1.55 return TRUE;
|
3428 eich 1.52 }
|
3429 dawes 1.8 }
|
3430 eich 1.52 return FALSE;
|
3431 dawes 1.1 }
3432
|
3433 eich 1.52 /**************** end of autoprobe stuff *****************/
3434
3435
3436
|
3437 alanh 1.23 #ifdef XFree86LOADER
|
3438 paulo 1.42 ModuleInfoRec MouseInfo = {
3439 1,
3440 "MOUSE",
3441 NULL,
3442 0,
3443 MouseAvailableOptions,
3444 };
3445
|
3446 alanh 1.23 static void
3447 xf86MouseUnplug(pointer p)
3448 {
3449 }
3450 static pointer
3451 xf86MousePlug(pointer module,
3452 pointer options,
3453 int *errmaj,
3454 int *errmin)
3455 {
|
3456 paulo 1.42 static Bool Initialised = FALSE;
3457
3458 if (!Initialised) {
3459 Initialised = TRUE;
3460 #ifndef REMOVE_LOADER_CHECK_MODULE_INFO
3461 if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
3462 #endif
3463 xf86AddModuleInfo(&MouseInfo, module);
3464 }
3465
|
3466 alanh 1.23 xf86AddInputDriver(&MOUSE, module, 0);
3467
3468 return module;
3469 }
3470
3471 static XF86ModuleVersionInfo xf86MouseVersionRec =
3472 {
3473 "mouse",
3474 MODULEVENDORSTRING,
3475 MODINFOSTRING1,
3476 MODINFOSTRING2,
3477 XF86_VERSION_CURRENT,
3478 1, 0, 0,
3479 ABI_CLASS_XINPUT,
3480 ABI_XINPUT_VERSION,
3481 MOD_CLASS_XINPUT,
3482 {0, 0, 0, 0} /* signature, to be patched into the file by */
3483 /* a tool */
3484 };
3485
3486 XF86ModuleData mouseModuleData = {&xf86MouseVersionRec,
3487 alanh 1.23 xf86MousePlug,
3488 xf86MouseUnplug};
3489
|
3490 eich 1.52 /*
3491 Look at hitachi device stuff.
3492 */
|
3493 alanh 1.23 #endif /* XFree86LOADER */
|
3494 eich 1.52
3495
|