1 
2 /* Based on:
3  * simple driver for serial mouse
4  * Andrew Haylett, 14th December 1992
5  * and on the driver in XFree86.
6  * Edited for svgalib (hhanemaa@cs.ruu.nl).
7  * This probably doesn't work with all types of bus mouse.
8  * HH: Added PS/2 mouse support.
9  * Fixed Logitech support thanks to Daniel Jackson.
10  * MouseSystems movement overflow fixed by Steve VanDevender.
11  * Logitech fixed again.
12  * Michael: Added support for controlling DTR and RTS.
13  * Added mouse acceleration 3/97 - Mike Chapman mike@paranoia.com
14  * Added Intellimouse support 5/98 - Brion Vibber brion@pobox.com
15  * Totally customisable mouse behaviour 28 Mar 1998 - by 101; 101@kempelen.inf.bme.hu
16  * Added rx-axis support for IntelliMouse wheel and improved fake keyboard
17  *  event scancode setting 7/98 - Brion
18  */
19 
20 /* This file is included by mouse.c. */
21 
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <termios.h>
26 #include <sys/ioctl.h>
27 #include <fcntl.h>
28 #include <time.h>
29 #include <vga.h>
30 #include <string.h>
31 #include <math.h>
32 #include "driver.h"
33 
34 /* #define DEBUG */
35 /* #define DEBUG_ACCEL */
36 /* #define DEBUG_WHEEL */
37 
38 static int    m_type;
39 static int    m_baud = 1200;		/* Should be 1200. */
40 static int    m_sample;
41 static char*  m_dev;
42        int    __svgalib_mouse_fd = -1;
43 static int    m_fdmode = 0;		/* 0 means don't wait (NDELAY) */
44 static int    m_modem_ctl = 0;
45 
46 /* Settings found on mouse open.. Probably std termios should be restored as well */
47 static unsigned long m_old_modem_info;	/*  original state of DTR/RTS */
48 static char m_modem_info_valid = 0;	/*  ==0 means: couldn't get it: old kernel? */
49 
50 unsigned char __svgalib_m_ignore_dx = 0; /* These are flags set by keyboard.c */
51 unsigned char __svgalib_m_ignore_dy = 0;
52 unsigned char __svgalib_m_ignore_dz = 0;
53 
54 static char   m_accel_type   = DEFAULT_ACCEL_TYPE;	/* don't accelerate mouse */
55 static int    m_accel_thresh = DEFAULT_ACCEL_THRESH;	/* movement threshold */
56 static float  m_accel_mult   = DEFAULT_ACCEL_MULT;	/* multiply */
57 static int    m_maxdelta     = DEFAULT_MAXDELTA;	/* before acceleration; no limit by default */
58 static int    m_accel_maxdelta = DEFAULT_ACCEL_MAXDELTA;/* after acceleration; no limit by default */
59 static float* m_accel_powertable = 0;   		/* precalculated table for power mode */
60 static float  m_accel_power  = DEFAULT_ACCEL_POWER;
61 static float  m_accel_offset = DEFAULT_ACCEL_OFFSET;
62 static int    m_force	     = 0;			/* Don't force parameters */
63 
64 static int m_wheel_steps = DEFAULT_WHEEL_STEPS;         /* Number of steps that make up a full turn of the wheel (for IntelliMouse & co) */
65 static int m_wheel_delta = DEFAULT_WHEEL_DELTA;         /* Amount to change rotation about the X axis when wheel is turned */
66 static int m_fake_kbd_events = 0;                       /* Create fake keyboard events for turning the wheel */
67 static int m_fake_upscancode = 0;                       /* Scan code to produce for turning up */
68 static int m_fake_downscancode = 0;                     /* Scan code to produce for turning down */
69 static char *m_fake_upkeyname = NULL;                   /* Symbolic key name from which scancode is determined */
70 static char *m_fake_downkeyname = NULL;
71 
72 static const unsigned short cflag[] = {
73     (CS7 | CREAD | CLOCAL | HUPCL),			/* MicroSoft */
74     (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL),		/* MouseSystems */
75     (CS8 | PARENB | PARODD | CREAD | CLOCAL | HUPCL),	/* MMSeries */
76     (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL),		/* Logitech */
77     0,							/* BusMouse */
78     0,							/* PS/2 */
79     (CS7 | CREAD | CLOCAL | HUPCL),			/* MouseMan */
80     (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL),		/* GPM (MouseSystems) */
81     (CS8 | CLOCAL | CREAD | IXON | IXOFF ),		/* Spaceball */
82     0,							/* Dummy entry for MOUSE_NONE */
83     (CS7 | CREAD | CLOCAL | HUPCL),			/* IntelliMouse (Serial) */
84     CS7,       						/* IntelliMouse (PS/2) */
85     (CS7 | CREAD | CLOCAL | HUPCL),			/* plug'n'pray */
86     (CS8 | CREAD | CLOCAL | HUPCL),			/* Wacom Graphire tablet/mouse */
87 };
88 
89 static const unsigned char proto[][5] =
90 {
91     /*  hd_mask hd_id   dp_mask dp_id   nobytes */
92     {0x40, 0x40, 0x40, 0x00, 3},	/* MicroSoft */
93     {0xf8, 0x80, 0x00, 0x00, 5},	/* MouseSystems */
94     {0xe0, 0x80, 0x80, 0x00, 3},	/* MMSeries */
95     {0xe0, 0x80, 0x00, 0x00, 3},	/* Logitech */
96     {0xf8, 0x80, 0x00, 0x00, 5},	/* BusMouse */
97     {0xc0, 0x00, 0x00, 0x00, 3},	/* PS/2 mouse */
98     {0x40, 0x40, 0x40, 0x00, 3},	/* Mouseman */
99     {0xf8, 0x80, 0x00, 0x00, 5},	/* gpm (MouseSystems) */
100     {0xe0, 0x40, 0x00, 0x00, 6},	/* Spaceball */
101     {0, 0, 0, 0, 0},			/* Dummy entry for MOUSE_NONE */
102     {0xc0, 0x40, 0xc0, 0x00, 4},	/* IntelliMouse (Serial) */
103     {0xc8, 0x08, 0x00, 0x00, 4},	/* IntelliMouse (PS/2) */
104     {0x40, 0x40, 0x40, 0x00, 3},	/* pnp */
105     {0x80, 0x80, 0x80, 0x00, 7},	/* Wacom Graphire */
106     {0xc8, 0x08, 0x00, 0x00, 4},	/* DRMOUSE4DS (Digital Research 2-wheel PS/2) */
107 };
108 
ms_setspeed(const int old,const int new,const unsigned short c_cflag)109 static void ms_setspeed(const int old, const int new,
110 			const unsigned short c_cflag)
111 {
112     struct termios tty;
113     char *c;
114 
115     tcgetattr(__svgalib_mouse_fd, &tty);
116 
117     tty.c_iflag = IGNBRK | IGNPAR;
118     tty.c_oflag = 0;
119     tty.c_lflag = 0;
120 /*    tty.c_line  = 0;*/
121     tty.c_cc[VTIME] = 0;
122     tty.c_cc[VMIN]  = 1;
123 
124     switch (old) {
125     case 9600:
126 	tty.c_cflag = c_cflag | B9600;
127 	break;
128     case 4800:
129 	tty.c_cflag = c_cflag | B4800;
130 	break;
131     case 2400:
132 	tty.c_cflag = c_cflag | B2400;
133 	break;
134     case 1200:
135     default:
136 	tty.c_cflag = c_cflag | B1200;
137 	break;
138     }
139 
140     tcsetattr(__svgalib_mouse_fd, TCSAFLUSH, &tty);
141 
142     switch (new) {
143     case 9600:
144 	c = "*q";
145 	tty.c_cflag = c_cflag | B9600;
146 	break;
147     case 4800:
148 	c = "*p";
149 	tty.c_cflag = c_cflag | B4800;
150 	break;
151     case 2400:
152 	c = "*o";
153 	tty.c_cflag = c_cflag | B2400;
154 	break;
155     case 1200:
156     default:
157 	c = "*n";
158 	tty.c_cflag = c_cflag | B1200;
159 	break;
160     }
161 
162     write(__svgalib_mouse_fd, c, 2);
163     usleep(10000);
164     tcsetattr(__svgalib_mouse_fd, TCSAFLUSH, &tty);
165 }
166 
167 static char *mouse_config_options[] = {
168   "mouse_accel_type", "mouse_accel_mult", "mouse_accel_thresh",
169   "mouse_accel_power", "mouse_accel_maxdelta", "mouse_maxdelta",
170   "mouse_accel_offset", "mouse_override", "mouse_force",
171   "mouse_fake_kbd_event", "mouse_wheel_steps", NULL
172 };
173 
mouse_process_option(int option,int mode)174 static char* mouse_process_option(int option, int mode) {
175 
176  char *ptr;
177  int newmtype;
178 
179 #ifdef DEBUG_ACCEL
180   printf("Processing option %ld (%s)\n", (long)option, mouse_config_options[option]);
181 #endif
182 
183    switch (option) {
184     float *fptr;
185     int   *iptr;
186     char  **cptr;
187 
188      case 0: /* mouse_accel_type */
189 	if ( (ptr = strtok(NULL, " ")) == 0 ) {
190      param_needed:
191 	  fprintf(stderr, "svgalib: mouse-config: \'%s\' requires a parameter\n",
192 	  				mouse_config_options[option]);
193 	  return ptr;
194 	} else if (!strcasecmp(ptr, "normal")) {
195 	  m_accel_type = MOUSE_ACCEL_TYPE_NORMAL;
196 	} else if (!strcasecmp(ptr, "power")) {
197 	  m_accel_type = MOUSE_ACCEL_TYPE_POWER;
198 	} else if (!strcasecmp(ptr, "off")) {
199 	  m_accel_type = 0;
200 	} else {
201 	  fprintf(stderr, "svgalib: mouse-config: ignoring unknown mouse acceleration \'%s\'\n", ptr);
202 	  m_accel_type = 0;
203 	}
204      	break;
205 
206      case 1: /* mouse_accel_mult */
207 	fptr = &m_accel_mult;
208 
209    process_float:
210 	if ( (ptr = strtok((NULL), " ")) == 0) {
211 	  goto param_needed;
212 	} else {
213 	 char *endptr;
214 	 double dtmp = strtod(ptr, &endptr);
215 	  if (endptr == ptr) {
216 	    fprintf(stderr, "svgalib: mouse-config: illegal float \'%s\' %s\n",
217 					ptr,  mouse_config_options[option]);
218 	    return ptr;
219 	  } else {
220 	    *fptr = dtmp;
221 	  }
222 	}
223 	break;
224 
225 
226      case 2: /* mouse_accel_thresh */
227 	iptr = &m_accel_thresh;
228 
229    process_int:
230 	if ( (ptr = strtok((NULL), " ")) == 0) {
231 	  goto param_needed;
232 	} else {
233 	 char *endptr;
234 	 long ltmp = strtol(ptr, &endptr, 10);
235 	  if (ptr == endptr) {
236 	    fprintf(stderr, "svgalib: mouse-config: illegal number \'%s\' for %s\n",
237 					ptr,  mouse_config_options[option]);
238 	    return ptr;
239 	  } else {
240 	    *iptr = ltmp;
241 	  }
242 	}
243 	break;
244 
245      case 3: /* mouse_accel_power */
246 	fptr = &m_accel_power;
247 	goto process_float;
248 
249      case 4: /* mouse_accel_maxdelta */
250 	iptr = &m_accel_maxdelta;
251 	goto process_int;
252 
253      case 5: /* mouse_maxdelta */
254 	iptr = &m_maxdelta;
255 	goto process_int;
256 
257      case 6: /* mouse_accel_offset */
258 	fptr = &m_accel_offset;
259 	goto process_float;
260 
261      case 7: /* mouse_override */
262 #ifdef ALLOW_MOUSE_OVERRIDE
263 	newmtype = vga_getmousetype();
264 	if (m_type != newmtype) {
265 	    printf("svgalib: mouse-init: mouse type override %d to %d\n",
266 		   m_type, newmtype);
267 	    m_type = newmtype;
268 	}
269 #else				/* ALLOW_MOUSE_OVERRIDE */
270 	fputs("svgalib: was compiled with SVGA_MOUSE_OVERRIDE disabled !", stderr);
271 #endif				/* ALLOW_MOUSE_OVERRIDE */
272 	break;
273 
274      case 8: /* mouse_force */
275 	m_force = 1;
276         break;
277 
278      case 9: /* mouse_fake_kbd_event */
279          /* Set fake keyboard events for mouse wheel...
280             Turn them off temporarily in case the params are bad */
281          m_fake_kbd_events = 0;
282 
283 #ifdef DEBUG_WHEEL
284          fprintf(stderr, " Setting up fake keyboard events");
285 #endif
286 
287          /* Parse the config for the scancodes */
288          cptr = &m_fake_upkeyname;
289          iptr = &m_fake_upscancode;
290          while(cptr) {
291              if ( (ptr = strtok(NULL, " ")) == 0 )
292                  goto param_needed;
293 
294 #ifdef DEBUG_WHEEL
295              fprintf(stderr, "; keyname %s", ptr);
296 #endif
297 
298              /* Keep the name in case the keyboard gets remapped later */
299              if(*cptr)
300                  free(*cptr);
301              *cptr = (char *)malloc(strlen(ptr) + 1);
302              strcpy(*cptr, ptr);
303 
304              /* Determine the scancode */
305              *iptr = __svgalib_mapkeyname(*cptr);
306 
307 #ifdef DEBUG_WHEEL
308              fprintf(stderr, " = scancode %d", *iptr);
309 #endif
310 
311              /* Move on to the next */
312              iptr = ((cptr == &m_fake_upkeyname)?(&m_fake_downscancode):NULL);
313              cptr = ((cptr == &m_fake_upkeyname)?(&m_fake_downkeyname):NULL);
314          }
315 
316 #ifdef DEBUG_WHEEL
317          fprintf(stderr, "; done.\n");
318 #endif
319 
320          /* Now that we've survived all that, turn on fake events */
321          m_fake_kbd_events = 1;
322 
323          break;
324 
325    case 10: /* mouse_wheel_steps */
326        /* Set the number of steps that make up a complete turn of
327           the wheel on an IntelliMouse or other wheel mouse. Zero
328           disables X-axis rotation but not fake keyboard events. */
329 	iptr = &m_wheel_steps;
330 	goto process_int;
331 
332    }
333    return strtok(NULL, " ");
334 }
335 
ms_init(void)336 static int ms_init(void)
337 {
338 /*------------------------------------------------------------------*/
339 /* Define ALLOW_MOUSE_OVERRIDE to recognize the SVGA_MOUSE_OVERRIDE */
340 /* environment variable.  If this environment variable is set       */
341 /* then ignore the program's specified mouse type and use           */
342 /* the configuration file's type.                                   */
343 /* In particular, DOOM does not understand "MouseMan" as a valid    */
344 /* mouse type and so defaults the mouse type to "MouseSystems".     */
345 /*------------------------------------------------------------------*/
346     __svgalib_read_options(mouse_config_options, mouse_process_option);
347 
348     if (m_maxdelta < 0  &&  !m_force) {
349       fprintf(stderr, "svgalib: mouse_maxdelta value '%ld' is invalid, should be > 0\n", (long)m_maxdelta);
350       m_maxdelta = DEFAULT_MAXDELTA;
351     }
352 
353     if (m_accel_maxdelta < 0  &&  !m_force) {
354       fprintf(stderr, "svgalib: mouse_accel_maxdelta value '%ld' is invalid, should be > 0\n", (long)m_accel_maxdelta);
355       m_accel_maxdelta = DEFAULT_ACCEL_MAXDELTA;
356     }
357 
358     if (m_accel_type) {
359 
360       if ((m_accel_mult <= 0  ||  m_accel_mult > 200.0)  &&  !m_force) {
361         fprintf(stderr, "svgalib: mouse_accel_mult value '%.2f' is invalid, should be between 0 and 200.0\n", (double)m_accel_mult);
362         m_accel_mult = DEFAULT_ACCEL_MULT;
363       }
364 
365       if ((m_accel_power < -200.0  ||  m_accel_power > 200.0)  &&  !m_force) {
366         fprintf(stderr, "svgalib: mouse_accel_power value '%.2f' is invalid, should be between -200.0 and 200.0\n", m_accel_power);
367 	m_accel_power = DEFAULT_ACCEL_POWER;
368       }
369 
370       if ((m_accel_offset < -100.0  ||  m_accel_offset > 100.0)  &&  !m_force) {
371         fprintf(stderr, "svgalib: mouse_accel_offset value '%.2f' is invalid, should be between -100.0 and 100.0\n", m_accel_offset);
372 	m_accel_offset = DEFAULT_ACCEL_OFFSET;
373       }
374 
375       if (!m_force) {
376          if (m_accel_thresh <= 0  ||  m_accel_thresh > 200) {
377             fprintf(stderr, "svgalib: mouse_accel_thresh value '%ld' is invalid, should be between 0 and 200\n", (long)m_accel_thresh);
378 	    m_accel_thresh = DEFAULT_ACCEL_THRESH;
379          }
380       } else if (m_accel_thresh < 0) {
381 	 fputs("svgalib: mouse_accel_thresh musn't be negative !\n", stderr);
382 	 m_accel_thresh = DEFAULT_ACCEL_THRESH;
383       }
384 
385       if (m_accel_offset >= m_accel_mult) {
386          fputs("svgalib: warning: accel_offset should be less then accel_mult !", stderr);
387       }
388 
389       if (m_accel_thresh > 1 && m_accel_type == MOUSE_ACCEL_TYPE_POWER) {
390         if ((m_accel_powertable = malloc(m_accel_thresh * sizeof(float))) == 0 ) {
391   	  fputs("svgalib: out of memory in mouse init ! (Check SVGA_MOUSE_ACCEL_THRESH size) !", stderr);
392 	  fflush(stderr);
393 	  return 1;
394         } else {
395          int i;
396 #ifdef DEBUG_ACCEL
397 	  printf("m_accel_powertable:\n");
398 #endif
399           for (i = 1; i < m_accel_thresh; i++) {
400             m_accel_powertable[i] = pow((double)(i-1)/(m_accel_thresh-1), m_accel_power)
401               * (m_accel_mult - m_accel_offset) + m_accel_offset;
402 
403 #ifdef DEBUG_ACCEL
404 	    printf("  %ld => %f (%f)\n", (long)i, (double)m_accel_powertable[i] * i,
405 	  			     (double)m_accel_powertable[i]);
406 #endif
407           }
408         }
409       }
410     }
411 
412 #ifdef DEBUG_ACCEL
413     printf("m_accel_type: %ld\n",	(long)m_accel_type);
414     printf("m_force: %ld\n",		(long)m_force);
415     printf("m_accel_thresh: %ld\n",	(long)m_accel_thresh);
416     printf("m_accel_offset: %ld\n",	(long)m_accel_offset);
417     printf("m_accel_mult: %f\n",	(double)m_accel_mult);
418     printf("m_accel_power: %f\n",	(double)m_accel_power);
419     printf("m_maxdelta: %ld\n",		(long)m_maxdelta);
420     printf("m_accel_maxdelta: %ld\n",	(long)m_accel_maxdelta);
421 #endif
422 
423     /*  Ensure that the open will get a file descriptor greater
424      *  than 2, else problems can occur with stdio functions
425      *  under certain strange conditions:  */
426     if (fcntl(0,F_GETFD) < 0) open("/dev/null", O_RDONLY);
427     if (fcntl(1,F_GETFD) < 0) open("/dev/null", O_WRONLY);
428     if (fcntl(2,F_GETFD) < 0) open("/dev/null", O_WRONLY);
429 
430     /* Set the proper wheel delta */
431     if(m_wheel_steps)
432         m_wheel_delta = (360 / m_wheel_steps);
433     else
434         m_wheel_delta = 0;
435 
436     /* Added O_NDELAY here. */
437 /*
438     if(__svgalib_mouse_fd!=-1)close(__svgalib_mouse_fd);
439 */
440     if ((__svgalib_mouse_fd = open(m_dev, O_RDWR | O_NDELAY )) < 0)
441 	return -1;
442 
443     if (m_type == MOUSE_BUSMOUSE || m_type == MOUSE_PS2
444     		|| m_type == MOUSE_IMPS2 || m_type == MOUSE_GPM || m_type == MOUSE_DRMOUSE4DS)
445 	m_modem_ctl = 0;
446 
447     /* If no signal will change there is no need to restore
448        or safe original settings. */
449     if (!m_modem_ctl)
450 	m_modem_info_valid = 0;
451     else {
452 	/* Get current modem signals; keep silent on errors.. */
453 	m_modem_info_valid = !ioctl(__svgalib_mouse_fd,
454 				   TIOCMGET, &m_old_modem_info);
455 
456 	if (m_modem_info_valid) {
457 	    unsigned long param = m_old_modem_info;
458 
459 	    /* Prepare new stat: */
460 
461 	    /*set DTR as ordered.. */
462 	    if (m_modem_ctl & MOUSE_CHG_DTR) {
463 		param &= ~TIOCM_DTR;
464 		if (m_modem_ctl & MOUSE_DTR_HIGH)
465 		    param |= TIOCM_DTR;
466 	    }
467 	    /*set RTS as ordered.. */
468 	    if (m_modem_ctl & MOUSE_CHG_RTS) {
469 		param &= ~TIOCM_RTS;
470 		if (m_modem_ctl & MOUSE_RTS_HIGH)
471 		    param |= TIOCM_RTS;
472 	    }
473 	    if (ioctl(__svgalib_mouse_fd, TIOCMSET, &param))
474 		m_modem_info_valid = 0;	/* No try to restore if this failed */
475 	}
476     }
477 
478     if (m_type == MOUSE_SPACEBALL) {
479       m_baud = 9600;
480       ms_setspeed(1200, m_baud, cflag[m_type]);
481     } else if (m_type == MOUSE_LOGIMAN) {
482 	ms_setspeed(9600, 1200, cflag[m_type]);
483 	ms_setspeed(4800, 1200, cflag[m_type]);
484 	ms_setspeed(2400, 1200, cflag[m_type]);
485 	ms_setspeed(1200, 1200, cflag[m_type]);
486 	write(__svgalib_mouse_fd, "*X", 2);
487 	ms_setspeed(1200, m_baud, cflag[m_type]);
488     } else if (m_type == MOUSE_WACOM_GRAPHIRE) {
489     	m_baud = 9600;
490     	ms_setspeed(1200, m_baud, cflag[m_type]);
491     	/* Reset baud rate */
492     	write(__svgalib_mouse_fd, "\r$", 2);
493     	usleep(250000);
494     	/* Reset tablet */
495     	write(__svgalib_mouse_fd, "\r#", 2);
496     	usleep(75000);
497     	/* Set hardware filtering */
498     	write(__svgalib_mouse_fd, "\rSU3", 4);
499     	usleep(75000);
500     	/* Start sending coordinates */
501     	write(__svgalib_mouse_fd, "\rST\r", 4);
502     } else if (m_type == MOUSE_IMPS2 || m_type == MOUSE_DRMOUSE4DS) {
503 	/* Initialize the mouse into wheel mode */
504 	write(__svgalib_mouse_fd, "\363\310\363\144\363\120", 6);
505     } else if (m_type == MOUSE_PNP) {
506     	/* Need to do this termios stuff here, by hand, ms_setspeed won't
507 	   work with pnp */
508 	struct termios tty;
509  	m_baud = 1200;
510 	tcgetattr(__svgalib_mouse_fd, &tty);
511 	tty.c_iflag = IGNBRK | IGNPAR;
512 	tty.c_oflag = 0;
513 	tty.c_lflag = 0;
514 /*	tty.c_line = 0;*/
515 	tty.c_cc[VTIME] = 0;
516 	tty.c_cc[VMIN] = 1;
517 	tty.c_cflag = cflag[m_type] | B1200;
518 	tcsetattr(__svgalib_mouse_fd, TCSAFLUSH, &tty);
519     } else if (m_type != MOUSE_BUSMOUSE && m_type != MOUSE_PS2) {
520 	ms_setspeed(9600, m_baud, cflag[m_type]);
521 	ms_setspeed(4800, m_baud, cflag[m_type]);
522 	ms_setspeed(2400, m_baud, cflag[m_type]);
523 	ms_setspeed(1200, m_baud, cflag[m_type]);
524 
525 	if (m_type == MOUSE_LOGITECH) {
526 	    write(__svgalib_mouse_fd, "S", 1);
527 	    ms_setspeed(m_baud, m_baud, cflag[MOUSE_MMSERIES]);
528 	}
529 	if (m_sample <= 0)
530 	    write(__svgalib_mouse_fd, "O", 1);
531 	else if (m_sample <= 15)
532 	    write(__svgalib_mouse_fd, "J", 1);
533 	else if (m_sample <= 27)
534 	    write(__svgalib_mouse_fd, "K", 1);
535 	else if (m_sample <= 42)
536 	    write(__svgalib_mouse_fd, "L", 1);
537 	else if (m_sample <= 60)
538 	    write(__svgalib_mouse_fd, "R", 1);
539 	else if (m_sample <= 85)
540 	    write(__svgalib_mouse_fd, "M", 1);
541 	else if (m_sample <= 125)
542 	    write(__svgalib_mouse_fd, "Q", 1);
543 	else
544 	    write(__svgalib_mouse_fd, "N", 1);
545     }
546 
547     /* Set the mouse caps */
548     mouse_caps.key = MOUSE_GOTCAPS;
549 
550     /* Zero out first to be sure... */
551     mouse_caps.buttons = mouse_caps.axes = mouse_caps.info =
552         mouse_caps.reserved0 = mouse_caps.reserved1 = 0;
553 
554     switch(m_type) {
555     case MOUSE_SPACEBALL:
556         /* 6 axes, many buttons */
557         mouse_caps.buttons =
558             MOUSE_LEFTBUTTON | MOUSE_MIDDLEBUTTON | MOUSE_RIGHTBUTTON |
559             MOUSE_FOURTHBUTTON | MOUSE_FIFTHBUTTON | MOUSE_SIXTHBUTTON |
560             MOUSE_RESETBUTTON;
561         mouse_caps.axes = MOUSE_6DIM;
562         break;
563 
564     case MOUSE_DRMOUSE4DS:
565     	/* X, Y, RX and RY (two wheels), 3 buttons */
566 	mouse_caps.axes = MOUSE_2DIM | MOUSE_RXDIM | MOUSE_RYDIM;
567 	mouse_caps.buttons = MOUSE_LEFTBUTTON | MOUSE_RIGHTBUTTON | MOUSE_MIDDLEBUTTON;
568 	mouse_caps.info = MOUSE_INFO_WHEEL;
569 	break;
570 
571     case MOUSE_INTELLIMOUSE:
572     case MOUSE_IMPS2:
573     case MOUSE_WACOM_GRAPHIRE:
574         /* X, Y, RX (wheel), 3 buttons, wheel */
575         mouse_caps.axes = MOUSE_RXDIM;
576         mouse_caps.info = MOUSE_INFO_WHEEL;
577 
578     case MOUSE_LOGIMAN:		/* Some TrackMen have 4 buttons */
579 	mouse_caps.buttons = MOUSE_FOURTHBUTTON;
580 
581     case MOUSE_MOUSESYSTEMS:
582     case MOUSE_MMSERIES:
583     case MOUSE_LOGITECH:
584     case MOUSE_BUSMOUSE:
585     case MOUSE_PS2:
586     case MOUSE_GPM:
587         /* Any of these _can_ have 3 buttons, but may not */
588         mouse_caps.buttons |= MOUSE_MIDDLEBUTTON;
589 
590     case MOUSE_MICROSOFT: /* Two buttons only */
591         mouse_caps.buttons |= MOUSE_LEFTBUTTON | MOUSE_RIGHTBUTTON;
592         mouse_caps.axes |= MOUSE_2DIM;
593         break;
594     }
595 
596     return 0;
597 }
598 
599 /* Scooped from X driver. */
ms_close(void)600 static inline void ms_close(void)
601 {
602     if (m_accel_powertable)
603         free(m_accel_powertable);
604     if (__svgalib_mouse_fd == -1)
605 	return;
606     if (m_type == MOUSE_LOGITECH) {
607 	write(__svgalib_mouse_fd, "U", 1);
608 	ms_setspeed(m_baud, 1200, cflag[MOUSE_LOGITECH]);
609     }
610     /* Try to restore modem signals if we could get them. */
611     if (m_modem_info_valid)
612 	ioctl(__svgalib_mouse_fd, TIOCMSET, &m_old_modem_info);
613 
614     close(__svgalib_mouse_fd);
615     __svgalib_mouse_fd = -1;
616 }
617 
618 #define MOUSEBUFFERSIZE 256
619 
get_ms_event(int wait)620 static int get_ms_event(int wait) {
621 /*
622    Changed to process multiple packets.
623    wait value:
624    0    Process any mouse events, and return status.
625    1    Wait for mouse event, then return.
626 
627    Status indicates whether an event was processed.
628  */
629 
630     static unsigned char buf[MOUSEBUFFERSIZE];
631     static int nu_bytes = 0;
632     int nu_packets = 0;
633     char event_handled = 0;
634     int bytesread;
635     int i, wheel;
636 /*  int but; */
637     static int but = 0;		/* static is hack for MouseMan */
638     static int mouse_orientation = 0;
639     int dx=0, dy=0, dz=0, drx=0, dry=0, drz=0;
640     int ax=0, ay=0;
641     static int oldax=0, olday=0, nodev = 0;
642     int j;
643     char SpaceWare[] = "SpaceWare!";
644 
645     if (__svgalib_mouse_fd == -1)
646 	return -1;
647 
648   again:
649 
650     if (m_fdmode == 1) {
651 	/* We don't want to wait, set NDELAY mode. */
652 	fcntl(__svgalib_mouse_fd, F_SETFL, O_RDONLY | O_NDELAY );
653 	m_fdmode = 0;
654     }
655 #ifdef BACKGROUND
656     /* No need to read mouse while background. */
657     if (vga_oktowrite()) {
658 #endif
659         bytesread = read(__svgalib_mouse_fd,
660 		     &buf[nu_bytes], MOUSEBUFFERSIZE - nu_bytes);
661 #ifdef BACKGROUND
662        }
663      else
664        bytesread=0;
665 #endif
666     i = 0;
667 
668     if (bytesread >= 1)
669 	nu_bytes += bytesread;
670 
671 #ifdef DEBUG
672     printf("#bytes in buffer: %d\n", nu_bytes);
673 #endif
674 
675   handle_packets:
676 
677     /* Handle packets in buffer. */
678 
679 #ifdef DEBUG
680     printf("Bytes left in buffer: %d at %d, packet is %d bytes\n",
681 	   nu_bytes - i, i, proto[m_type][4]);
682     if (nu_bytes - i > 0 )
683       printf("Header byte: %c %d\n", (buf[i] & 0177), buf[i]);
684 
685 #endif
686 
687     if ((m_type == MOUSE_LOGIMAN) &&
688 	((nu_bytes - i) >= 1) &&
689 	((buf[i] & proto[m_type][0]) != proto[m_type][1]) &&
690 	((char) (buf[i] & ~0x33) == 0)) { /* s/23/33/, for 4-but trackman */
691 	/* Hack-o-matic, stolen from xf86_Mouse.c */
692 	but = ((buf[i] & 0x20) >> 4) | ((buf[i] & 0x10) >> 1) | (but & 0x05);
693 	__svgalib_mouse_eventhandler(but, 0, 0, 0, 0, 0, 0);
694 	event_handled++;
695 	i++;
696     }
697     if ((m_type == MOUSE_SPACEBALL)) {
698       j=i;
699       while ((nu_bytes - j > 0) && (buf[j]!=13))
700         j++;
701       nu_packets=(buf[j]==13);
702     } else {
703       nu_packets=1;
704     }
705     if ((nu_packets==0)||(nu_bytes - i < proto[m_type][4])) {
706 	/* No full packet available. */
707 	if (wait == 0 || (wait == 1 && event_handled)) {
708 	    if (i >= nu_bytes) {
709 		nu_bytes = 0;
710 		i = 0;
711 	    } else {
712 		/* Move partial packet to front of buffer. */
713 		for (j = i; j < nu_bytes; j++)
714 		    buf[j - i] = buf[j];
715 		nu_bytes -= i;
716 	    }
717 	    return event_handled;
718 	} else {		/* (wait == 1 && !event_handled) */
719 	    if (i >= nu_bytes) {
720 		nu_bytes = 0;
721 		i = 0;
722 	    }
723 	    /* Wait mode, we'll sleep on reads. */
724 	    fcntl(__svgalib_mouse_fd, F_SETFL, O_RDONLY);
725 	    m_fdmode = 1;
726 #ifdef BACKGROUND
727             /* Waits while foreground again. No reading in background. */
728 	    while(!vga_oktowrite()) sleep(0);
729 #endif
730 	    read(__svgalib_mouse_fd, &buf[nu_bytes], 1);
731             if ((m_type == MOUSE_SPACEBALL)) {
732               nu_packets=(buf[nu_bytes]==13);
733             } else {
734               nu_packets=1;
735             }
736 	    nu_bytes++;
737 	    if ((nu_packets==0)||(nu_bytes - i < proto[m_type][4]))
738 		/* Not a complete packet. */
739 		goto again;
740 	}
741     }
742 
743     /* Check header byte. */
744     if ((buf[i] & proto[m_type][0]) != proto[m_type][1]) {
745 	/* Not a header byte. */
746 #ifdef DEBUG
747     printf("Bad header byte: %c %d\n", (buf[i] & 0177), buf[i]);
748 #endif
749 	i++;
750 	goto handle_packets;
751     }
752     /* Check whether it's a valid data packet. */
753     if ((m_type != MOUSE_PS2)&&(m_type != MOUSE_IMPS2)&&(m_type != MOUSE_SPACEBALL)
754     	&&(m_type != MOUSE_WACOM_GRAPHIRE) && (m_type != MOUSE_DRMOUSE4DS) )
755 	for (j = 1; j < proto[m_type][4]; j++)
756 	    if ((buf[i + j] & proto[m_type][2]) != proto[m_type][3]
757 		|| buf[i + j] == 0x80) {
758 		i = i + j + 1;
759 		goto handle_packets;
760 	    }
761     /* Construct the event. */
762     switch (m_type) {
763     case MOUSE_MICROSOFT:	/* Microsoft */
764     case MOUSE_LOGIMAN:	/* MouseMan / TrackMan */
765     case MOUSE_PNP:
766     default:
767 	but = (but & 0x0A) | ((buf[i] & 0x20) >> 3) | ((buf[i] & 0x10) >> 4);
768 	dx = (char) (((buf[i] & 0x03) << 6) | (buf[i + 1] & 0x3F));
769 	dy = (char) (((buf[i] & 0x0C) << 4) | (buf[i + 2] & 0x3F));
770         break;
771     case MOUSE_WACOM_GRAPHIRE: /* Wacom Graphire Tablet */
772         if (!(buf[i] & 0x40)) { /* no device on tablet */
773         	nodev = 1;
774         	break;
775         }
776         but =   (buf[i+3] & 0x08) ? MOUSE_LEFTBUTTON : 0 |
777         	(buf[i+3] & 0x10) ? MOUSE_RIGHTBUTTON : 0 |
778         	(buf[i+3] & 0x20) ? MOUSE_MIDDLEBUTTON : 0;
779 
780         /* The absolute position is returned, not the change in position, so
781            we convert it. */
782         ax = ((buf[i+0] & 0x03) << 14) | (buf[i+1] << 7) | buf[i+2];
783         ay = ((buf[i+3] & 0x03) << 14) | (buf[i+4] << 7) | buf[i+5];
784 
785         if (nodev) {
786         	oldax = ax;
787         	olday = ay;
788         	nodev = 0;
789         }
790 
791 	dx = ax - oldax;
792 	dy = ay - olday;
793 
794 	dz = (((buf[i+6] & 0x3f) << 1) | ((buf[i+3] & 0x04) >> 2));
795 
796 	if (buf[i+6] & 0x40)
797 		dz = -dz;
798 
799 	/* The tablet has *very* high resolution, so we normalize
800 	   that a bit. */
801 	dx /= 2;
802 	dy /= 2;
803 
804 	oldax = ax;
805 	olday = ay;
806 
807 	if (buf[i] & 0x20 && dz) /* stylus has pressure */
808 		but |= MOUSE_LEFTBUTTON;
809 	else if (buf[i+6] & 0x30) { /* roller is being turned */
810 		wheel = (buf[i+6] & 0x30) >> 3;
811 		if (buf[i+6] & 0x40)
812 			wheel = -wheel;
813 #ifdef DEBUG_WHEEL
814             fprintf(stderr, " Wheel turned (0x%02x)", wheel);
815 #endif
816             /* RX-axis */
817             if(m_wheel_delta) {
818                 drx = ((wheel < 0) ? (-m_wheel_delta) : m_wheel_delta);
819 #ifdef DEBUG_WHEEL
820                 fprintf(stderr, "; RX axis delta = %d", drx);
821 #endif
822             }
823 
824             /* Are fake keyboard events enabled? */
825             if(m_fake_kbd_events && __svgalib_keyboard_eventhandler) {
826                 /* Fake keypresses... */
827                 int key = ((wheel < 0) ? m_fake_upscancode : m_fake_downscancode);
828 #ifdef DEBUG_WHEEL
829                 fprintf(stderr, "; pressing scancode %d", key);
830 #endif
831                 __svgalib_keyboard_eventhandler(key, 1); /* press */
832                 /* todo: delay */
833 #ifdef DEBUG_WHEEL
834                 fprintf(stderr, ", releasing scancode %d", key);
835 #endif
836                 __svgalib_keyboard_eventhandler(key, 0); /* release */
837 #ifdef DEBUG_WHEEL
838             fprintf(stderr, ".\n");
839 #endif
840             }
841         }
842 	break;
843 
844     case MOUSE_INTELLIMOUSE:    /* Serial IntelliMouse */
845         /* This bit modified from gpm 1.13 */
846         but = ((buf[i] & 0x20) >> 3)         /* left */
847                | ((buf[i + 3] & 0x10) >> 3)  /* middle */
848                | ((buf[i] & 0x10) >> 4);     /* right */
849         dx = (char) (((buf[i] & 0x03) << 6) | (buf[i + 1] & 0x3F));
850         dy = (char) (((buf[i] & 0x0C) << 4) | (buf[i + 2] & 0x3F));
851 
852         /* Did we turn the wheel? */
853         if((wheel = buf[i + 3] & 0x0f) != 0) {
854 #ifdef DEBUG_WHEEL
855             fprintf(stderr, " Wheel turned (0x%02x)", wheel);
856 #endif
857             /* RX-axis */
858             if(m_wheel_delta) {
859                 drx = ((wheel > 7) ? (-m_wheel_delta) : m_wheel_delta);
860 #ifdef DEBUG_WHEEL
861                 fprintf(stderr, "; RX axis delta = %d", drx);
862 #endif
863             }
864 
865             /* Are fake keyboard events enabled? */
866             if(m_fake_kbd_events && __svgalib_keyboard_eventhandler) {
867                 /* Fake keypresses... */
868                 int key = ((wheel > 7) ? m_fake_upscancode : m_fake_downscancode);
869 #ifdef DEBUG_WHEEL
870                 fprintf(stderr, "; pressing scancode %d", key);
871 #endif
872                 __svgalib_keyboard_eventhandler(key, 1); /* press */
873                 /* todo: delay */
874 #ifdef DEBUG_WHEEL
875                 fprintf(stderr, ", releasing scancode %d", key);
876 #endif
877                 __svgalib_keyboard_eventhandler(key, 0); /* release */
878 #ifdef DEBUG_WHEEL
879             fprintf(stderr, ".\n");
880 #endif
881             }
882         }
883         break;
884     case MOUSE_MOUSESYSTEMS:	/* Mouse Systems Corp */
885     case MOUSE_GPM:
886 	but = (~buf[i]) & 0x07;
887 	dx = (char) (buf[i + 1]);
888 	dx += (char) (buf[i + 3]);
889 	dy = -((char) (buf[i + 2]));
890 	dy -= (char) (buf[i + 4]);
891 	break;
892     case MOUSE_MMSERIES:	/* MM Series */
893     case MOUSE_LOGITECH:	/* Logitech */
894 	but = buf[i] & 0x07;
895 	dx = (buf[i] & 0x10) ? buf[i + 1] : -buf[i + 1];
896 	dy = (buf[i] & 0x08) ? -buf[i + 2] : buf[i + 2];
897 	break;
898     case MOUSE_BUSMOUSE:	/* BusMouse */
899 	but = (~buf[i]) & 0x07;
900 	dx = (char) buf[i + 1];
901 	dy = -(char) buf[i + 2];
902 	break;
903     case MOUSE_PS2:		/* PS/2 mouse */
904 	but = (buf[i] & 0x04) >> 1 |	/* Middle */
905 	    (buf[i] & 0x02) >> 1 |	/* Right */
906 	    (buf[i] & 0x01) << 2;	/* Left */
907 	dx = (buf[i] & 0x10) ? buf[i + 1] - 256 : buf[i + 1];
908 	dy = (buf[i] & 0x20) ? -(buf[i + 2] - 256) : -buf[i + 2];
909 	break;
910     case MOUSE_DRMOUSE4DS:
911     /* Digital Research 4-Axis mouse - like the PS/2 IntelliMouse, but
912        has two wheels.  */
913         /* This bit modified from the gpm 1.13 imps2 patch by Tim Goodwin */
914         but = ((buf[i] & 1) << 2) /* left */
915             | ((buf[i] & 6) >> 1); /* middle and right */
916         dx = (buf[i] & 0x10) ? buf[i + 1] - 256 : buf[i + 1];
917         dy = (buf[i] & 0x20) ? -(buf[i + 2] - 256) : -buf[i + 2];
918 
919         /* Did we turn the wheel? */
920         if((wheel = buf[i + 3]) != 0) {
921 #ifdef DEBUG_WHEEL
922             fprintf(stderr, " Wheel turned (0x%02x)", wheel);
923 #endif
924 	/* RX reports as 1 or F, RY reports as 2 or E */
925 	/* both never report at the same time, which makes life easier */
926 	if (m_wheel_delta)
927 	{
928 		switch (wheel & 0x0F)
929 		{
930 		case 1:		drx = m_wheel_delta; break;
931 		case 15:	drx = -m_wheel_delta; break;
932 		case 2:		dry = -m_wheel_delta; break;
933 		case 14:	dry = m_wheel_delta; break;
934 		};
935 #ifdef DEBUG_WHEEL
936                 fprintf(stderr, "; RX axis delta = %d : RY axis delta = %d", drx, dry);
937 #endif
938 
939             /* Are fake keyboard events enabled? */
940             if(m_fake_kbd_events && __svgalib_keyboard_eventhandler) {
941                 /* Fake keypresses... */
942                 int key = ((drx+dry < 0) ? m_fake_upscancode : m_fake_downscancode);
943 #ifdef DEBUG_WHEEL
944                 fprintf(stderr, "; pressing scancode %d", key);
945 #endif
946                  __svgalib_keyboard_eventhandler(key, 1); /* press */
947                 /* todo: delay */
948 #ifdef DEBUG_WHEEL
949                 fprintf(stderr, ", releasing scancode %d", key);
950 #endif
951                 __svgalib_keyboard_eventhandler(key, 0); /* release */
952             }
953 #ifdef DEBUG_WHEEL
954             fprintf(stderr, ".\n");
955 #endif
956 
957 
958 	}
959     }
960     break;
961 
962     case MOUSE_IMPS2:           /* PS/2 IntelliMouse */
963         /* This bit modified from the gpm 1.13 imps2 patch by Tim Goodwin */
964         but = ((buf[i] & 1) << 2) /* left */
965             | ((buf[i] & 6) >> 1); /* middle and right */
966         dx = (buf[i] & 0x10) ? buf[i + 1] - 256 : buf[i + 1];
967         dy = (buf[i] & 0x20) ? -(buf[i + 2] - 256) : -buf[i + 2];
968 
969         /* Did we turn the wheel? */
970         if((wheel = buf[i + 3]) != 0) {
971 #ifdef DEBUG_WHEEL
972             fprintf(stderr, " Wheel turned (0x%02x)", wheel);
973 #endif
974             /* RX-axis */
975             if(m_wheel_delta) {
976                 drx = ((wheel > 0x7f) ? (-m_wheel_delta) : m_wheel_delta);
977 #ifdef DEBUG_WHEEL
978                 fprintf(stderr, "; RX axis delta = %d", drx);
979 #endif
980             }
981 
982             /* Are fake keyboard events enabled? */
983             if(m_fake_kbd_events && __svgalib_keyboard_eventhandler) {
984                 /* Fake keypresses... */
985                 int key = ((wheel > 0x7f) ? m_fake_upscancode : m_fake_downscancode);
986 #ifdef DEBUG_WHEEL
987                 fprintf(stderr, "; pressing scancode %d", key);
988 #endif
989                  __svgalib_keyboard_eventhandler(key, 1); /* press */
990                 /* todo: delay */
991 #ifdef DEBUG_WHEEL
992                 fprintf(stderr, ", releasing scancode %d", key);
993 #endif
994                 __svgalib_keyboard_eventhandler(key, 0); /* release */
995             }
996 #ifdef DEBUG_WHEEL
997             fprintf(stderr, ".\n");
998 #endif
999         }
1000         break;
1001     case MOUSE_SPACEBALL:
1002 
1003 	switch (buf[i]) {
1004 	  case 'D':
1005 
1006 	    but=0177 & buf[i+1];
1007 
1008 	    /* Strip the MSB, which is a parity bit */
1009 	    for (j = 2; j < 11; ++j) {
1010 	        buf[i+j] &= 0177;           /* Make sure everything is 7bit */
1011 	        buf[i+j] ^= SpaceWare[j-2]; /* What's this doing in the data? */
1012 	    }
1013 
1014 	    /* Turn chars into 10 bit integers */
1015 	    if (mouse_orientation == MOUSE_ORIENTATION_VERTICAL) {
1016 	      dx = ((buf[i+2] & 0177)<<3)|((buf[i+3] & 0160)>>4);
1017 	      dy = ((buf[i+3] & 0017)<<6)|((buf[i+4] & 0176)>>1);
1018 	      dz = ((buf[i+4] & 0001)<<9)|((buf[i+5] & 0177)<<2)|
1019                     ((buf[i+6] & 0140)>>5);
1020 	      drx = ((buf[i+6] & 0037)<<5)|((buf[i+7] & 0174)>>2);
1021 	      dry = ((buf[i+7] & 0003)<<8)|((buf[i+8] & 0177)<<1)|
1022                      ((buf[i+9] & 0100)>>6);
1023 	      drz = ((buf[i+9] & 0077)<<4)|((buf[i+10] & 0170)>>3);
1024 	    } else {
1025 	      dx = ((buf[i+2] & 0177)<<3)|((buf[i+3] & 0160)>>4);
1026 	      dz = ((buf[i+3] & 0017)<<6)|((buf[i+4] & 0176)>>1);
1027 	      dy = ((buf[i+4] & 0001)<<9)|((buf[i+5] & 0177)<<2)|
1028                     ((buf[i+6] & 0140)>>5);
1029 	      drx = ((buf[i+6] & 0037)<<5)|((buf[i+7] & 0174)>>2);
1030 	      drz = ((buf[i+7] & 0003)<<8)|((buf[i+8] & 0177)<<1)|
1031                      ((buf[i+9] & 0100)>>6);
1032 	      dry = ((buf[i+9] & 0077)<<4)|((buf[i+10] & 0170)>>3);
1033 	    }
1034 
1035 	    /* Get the sign right. */
1036 	    if (dx > 511) dx -= 1024;
1037 	    if (dy > 511) dy -= 1024;
1038 	    if (dz > 511) dz -= 1024;
1039 	    if (drx > 511) drx -= 1024;
1040 	    if (dry > 511) dry -= 1024;
1041 	    if (drz > 511) drz -= 1024;
1042             if (mouse_orientation == MOUSE_ORIENTATION_HORIZONTAL)
1043               { dz *= -1;
1044                 drz *= -1;
1045               }
1046 	    /*    if (fabs(dx) < sorb_trans_thresh[1]) dx = 0; */
1047             i+=13;
1048 #ifdef DEBUG
1049     printf("Got D packet! but=%d, x=%d y=%d z=%d rx=%d ry=%d rz=%d\n",
1050             but,dx,dy,dz,drx,dry,drz);
1051 #endif
1052             break;
1053 	  case 'K':
1054 	/* Button press/release w/out motion */
1055 	    but=0177 & buf[i+2];
1056 	    if (but==MOUSE_RESETBUTTON)
1057 	      mouse_orientation=1-mouse_orientation;
1058 #ifdef DEBUG
1059     printf("Got K packet! but=%d, x=%d y=%d z=%d rx=%d ry=%d rz=%d\n",
1060             but,dx,dy,dz,drx,dry,drz);
1061 #endif
1062 	    i+=6;
1063 	    break;
1064 	  case 'R':
1065 #ifdef DEBUG
1066     printf("Got init string!\n");
1067 #endif
1068 	    for (j=i;((buf[j] !=13)&&(j<nu_bytes));j++)
1069               printf("%c",(buf[j] & 0177));
1070             printf("\n\n");
1071             i=j+1;
1072             break;
1073 	  default:
1074 #ifdef DEBUG
1075     printf("Got unknown packet!\n");
1076 #endif
1077             i++;
1078             break;
1079 	}
1080 
1081 	break;
1082     }
1083 
1084     if (m_type != MOUSE_SPACEBALL)
1085       i += proto[m_type][4];
1086 
1087     /* Try to snag that optional mouseman fourth byte, if present */
1088     if ((m_type == MOUSE_LOGIMAN) &&
1089 	((nu_bytes - i) >= 1) &&
1090 	((buf[i] & proto[m_type][0]) != proto[m_type][1]) &&
1091 	((char) (buf[i] & ~0x23) == 0)) {
1092 	/* Hack-o-matic, stolen from xf86_Mouse.c */
1093 	but = ((buf[i] & 0x20) >> 4) | (but & 0x05);
1094 	i++;
1095     }
1096 
1097     if (__svgalib_m_ignore_dx)  dx = 0;
1098     if (__svgalib_m_ignore_dy)  dy = 0;
1099     if (__svgalib_m_ignore_dz)  dz = 0;
1100 
1101 
1102     if (m_maxdelta) {
1103       if (abs(dx) > m_maxdelta)
1104         dx = (dx > 0) ? m_maxdelta : -m_maxdelta;
1105       if (abs(dy) > m_maxdelta)
1106         dy = (dy > 0) ? m_maxdelta : -m_maxdelta;
1107       if (abs(dz) > m_maxdelta)
1108         dz = (dz > 0) ? m_maxdelta : -m_maxdelta;
1109     }
1110 
1111 
1112     switch (m_accel_type) {
1113       int delta;
1114 
1115       case MOUSE_ACCEL_TYPE_NORMAL:
1116 #ifdef DEBUG_ACCEL
1117   printf("%ld\t", (long)dx);
1118 #endif
1119 	if (abs(dx) > m_accel_thresh) dx = (int) ((float)dx * m_accel_mult);
1120 	if (abs(dy) > m_accel_thresh) dy = (int) ((float)dy * m_accel_mult);
1121 	if (abs(dz) > m_accel_thresh) dz = (int) ((float)dz * m_accel_mult);
1122 #ifdef DEBUG_ACCEL
1123   printf("%ld\n", (long)dx);
1124 #endif
1125         break;
1126 
1127 
1128       case MOUSE_ACCEL_TYPE_POWER:
1129 #ifdef DEBUG_ACCEL
1130   printf("%ld\t", (long)dx);
1131 #endif
1132 	delta = abs(dx);
1133 	dx = (delta >= m_accel_thresh)  ?  (float)dx * m_accel_mult :
1134 	     (float)dx * m_accel_powertable[delta];
1135 
1136 	delta = abs(dy);
1137 	dy = (delta >= m_accel_thresh)  ?  (float)dy * m_accel_mult :
1138 	     (float)dy * m_accel_powertable[delta];
1139 
1140 	delta = abs(dz);
1141 	dz = (delta >= m_accel_thresh)  ?  (float)dz * m_accel_mult :
1142 	     (float)dz * m_accel_powertable[delta];
1143 
1144 #ifdef DEBUG_ACCEL
1145   printf("%ld\n", (long)dx);
1146 #endif
1147         break;
1148     }
1149 
1150     if (m_accel_maxdelta  &&  m_accel_type) {
1151       if (abs(dx) > m_accel_maxdelta)
1152         dx = (dx > 0) ? m_accel_maxdelta : -m_accel_maxdelta;
1153       if (abs(dy) > m_accel_maxdelta)
1154         dy = (dy > 0) ? m_accel_maxdelta : -m_accel_maxdelta;
1155       if (abs(dz) > m_accel_maxdelta)
1156         dz = (dz > 0) ? m_accel_maxdelta : -m_accel_maxdelta;
1157     }
1158 
1159     __svgalib_mouse_eventhandler(but, dx, dy, dz, drx, dry, drz);
1160 
1161     event_handled = 1;
1162 
1163     goto handle_packets;
1164 }
1165 
__svgalib_mouse_update_keymap(void)1166 void __svgalib_mouse_update_keymap(void)
1167 {
1168     /*
1169      The keyboard has been remapped, and we should accordingly remap any
1170      symbolically-specified scancodes for fake keyboard events.
1171      */
1172 #ifdef DEBUG_WHEEL
1173     fprintf(stderr, " Remapping fake keyboard event scancodes... ");
1174 #endif
1175     if(m_fake_upkeyname)
1176         m_fake_upscancode = __svgalib_mapkeyname(m_fake_upkeyname);
1177     if(m_fake_downkeyname)
1178         m_fake_downscancode = __svgalib_mapkeyname(m_fake_downkeyname);
1179 #ifdef DEBUG_WHEEL
1180     fprintf(stderr, "done.\n");
1181 #endif
1182 }
1183