ms.c

来自「linux 下svgalib编的一个界面程序示例」· C语言 代码 · 共 1,183 行 · 第 1/3 页

C
1,183
字号
/* Based on: * simple driver for serial mouse * Andrew Haylett, 14th December 1992 * and on the driver in XFree86. * Edited for svgalib (hhanemaa@cs.ruu.nl). * This probably doesn't work with all types of bus mouse. * HH: Added PS/2 mouse support. * Fixed Logitech support thanks to Daniel Jackson. * MouseSystems movement overflow fixed by Steve VanDevender. * Logitech fixed again. * Michael: Added support for controlling DTR and RTS. * Added mouse acceleration 3/97 - Mike Chapman mike@paranoia.com * Added Intellimouse support 5/98 - Brion Vibber brion@pobox.com * Totally customisable mouse behaviour 28 Mar 1998 - by 101; 101@kempelen.inf.bme.hu * Added rx-axis support for IntelliMouse wheel and improved fake keyboard *  event scancode setting 7/98 - Brion *//* This file is included by mouse.c. */#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <termios.h>#include <sys/ioctl.h>#include <fcntl.h>#include <time.h>#include <vga.h>#include <string.h>#include <math.h>#include "driver.h"/* #define DEBUG *//* #define DEBUG_ACCEL *//* #define DEBUG_WHEEL */static int    m_type;static int    m_baud = 1200;		/* Should be 1200. */static int    m_sample;static char*  m_dev;       int    __svgalib_mouse_fd = -1;static int    m_fdmode = 0;		/* 0 means don't wait (NDELAY) */static int    m_modem_ctl = 0;/* Settings found on mouse open.. Probably std termios should be restored as well */static unsigned long m_old_modem_info;	/*  original state of DTR/RTS */static char m_modem_info_valid = 0;	/*  ==0 means: couldn't get it: old kernel? */unsigned char __svgalib_m_ignore_dx = 0; /* These are flags set by keyboard.c */unsigned char __svgalib_m_ignore_dy = 0;unsigned char __svgalib_m_ignore_dz = 0;static char   m_accel_type   = DEFAULT_ACCEL_TYPE;	/* don't accelerate mouse */static int    m_accel_thresh = DEFAULT_ACCEL_THRESH;	/* movement threshold */static float  m_accel_mult   = DEFAULT_ACCEL_MULT;	/* multiply */static int    m_maxdelta     = DEFAULT_MAXDELTA;	/* before acceleration; no limit by default */static int    m_accel_maxdelta = DEFAULT_ACCEL_MAXDELTA;/* after acceleration; no limit by default */static float* m_accel_powertable = 0;   		/* precalculated table for power mode */static float  m_accel_power  = DEFAULT_ACCEL_POWER;static float  m_accel_offset = DEFAULT_ACCEL_OFFSET;static int    m_force	     = 0;			/* Don't force parameters */static int m_wheel_steps = DEFAULT_WHEEL_STEPS;         /* Number of steps that make up a full turn of the wheel (for IntelliMouse & co) */static int m_wheel_delta = DEFAULT_WHEEL_DELTA;         /* Amount to change rotation about the X axis when wheel is turned */static int m_fake_kbd_events = 0;                       /* Create fake keyboard events for turning the wheel */static int m_fake_upscancode = 0;                       /* Scan code to produce for turning up */static int m_fake_downscancode = 0;                     /* Scan code to produce for turning down */static char *m_fake_upkeyname = NULL;                   /* Symbolic key name from which scancode is determined */static char *m_fake_downkeyname = NULL;static const unsigned short cflag[] = {    (CS7 | CREAD | CLOCAL | HUPCL),			/* MicroSoft */    (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL),		/* MouseSystems */    (CS8 | PARENB | PARODD | CREAD | CLOCAL | HUPCL),	/* MMSeries */    (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL),		/* Logitech */    0,							/* BusMouse */    0,							/* PS/2 */    (CS7 | CREAD | CLOCAL | HUPCL),			/* MouseMan */    (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL),		/* GPM (MouseSystems) */    (CS8 | CLOCAL | CREAD | IXON | IXOFF ),		/* Spaceball */    0,							/* Dummy entry for MOUSE_NONE */    (CS7 | CREAD | CLOCAL | HUPCL),			/* IntelliMouse (Serial) */    CS7,       						/* IntelliMouse (PS/2) */    (CS7 | CREAD | CLOCAL | HUPCL),			/* plug'n'pray */    (CS8 | CREAD | CLOCAL | HUPCL),			/* Wacom Graphire tablet/mouse */};static const unsigned char proto[][5] ={    /*  hd_mask hd_id   dp_mask dp_id   nobytes */    {0x40, 0x40, 0x40, 0x00, 3},	/* MicroSoft */    {0xf8, 0x80, 0x00, 0x00, 5},	/* MouseSystems */    {0xe0, 0x80, 0x80, 0x00, 3},	/* MMSeries */    {0xe0, 0x80, 0x00, 0x00, 3},	/* Logitech */    {0xf8, 0x80, 0x00, 0x00, 5},	/* BusMouse */    {0xc0, 0x00, 0x00, 0x00, 3},	/* PS/2 mouse */    {0x40, 0x40, 0x40, 0x00, 3},	/* Mouseman */    {0xf8, 0x80, 0x00, 0x00, 5},	/* gpm (MouseSystems) */    {0xe0, 0x40, 0x00, 0x00, 6},	/* Spaceball */    {0, 0, 0, 0, 0},			/* Dummy entry for MOUSE_NONE */    {0xc0, 0x40, 0xc0, 0x00, 4},	/* IntelliMouse (Serial) */    {0xc8, 0x08, 0x00, 0x00, 4},	/* IntelliMouse (PS/2) */    {0x40, 0x40, 0x40, 0x00, 3},	/* pnp */    {0x80, 0x80, 0x80, 0x00, 7},	/* Wacom Graphire */    {0xc8, 0x08, 0x00, 0x00, 4},	/* DRMOUSE4DS (Digital Research 2-wheel PS/2) */};static void ms_setspeed(const int old, const int new,			const unsigned short c_cflag){    struct termios tty;    char *c;    tcgetattr(__svgalib_mouse_fd, &tty);    tty.c_iflag = IGNBRK | IGNPAR;    tty.c_oflag = 0;    tty.c_lflag = 0;    tty.c_line  = 0;    tty.c_cc[VTIME] = 0;    tty.c_cc[VMIN]  = 1;    switch (old) {    case 9600:	tty.c_cflag = c_cflag | B9600;	break;    case 4800:	tty.c_cflag = c_cflag | B4800;	break;    case 2400:	tty.c_cflag = c_cflag | B2400;	break;    case 1200:    default:	tty.c_cflag = c_cflag | B1200;	break;    }    tcsetattr(__svgalib_mouse_fd, TCSAFLUSH, &tty);    switch (new) {    case 9600:	c = "*q";	tty.c_cflag = c_cflag | B9600;	break;    case 4800:	c = "*p";	tty.c_cflag = c_cflag | B4800;	break;    case 2400:	c = "*o";	tty.c_cflag = c_cflag | B2400;	break;    case 1200:    default:	c = "*n";	tty.c_cflag = c_cflag | B1200;	break;    }    write(__svgalib_mouse_fd, c, 2);    usleep(10000);    tcsetattr(__svgalib_mouse_fd, TCSAFLUSH, &tty);}static char *mouse_config_options[] = {  "mouse_accel_type", "mouse_accel_mult", "mouse_accel_thresh",  "mouse_accel_power", "mouse_accel_maxdelta", "mouse_maxdelta",  "mouse_accel_offset", "mouse_override", "mouse_force",  "mouse_fake_kbd_event", "mouse_wheel_steps", NULL};static char* mouse_process_option(int option, int mode) { char *ptr; int newmtype;#ifdef DEBUG_ACCEL  printf("Processing option %ld (%s)\n", (long)option, mouse_config_options[option]);#endif   switch (option) {    float *fptr;    int   *iptr;    char  **cptr;     case 0: /* mouse_accel_type */	if ( (ptr = strtok(NULL, " ")) == 0 ) {     param_needed:	  fprintf(stderr, "svgalib: mouse-config: \'%s\' requires a parameter\n",	  				mouse_config_options[option]);	  return ptr;	} else if (!strcasecmp(ptr, "normal")) {	  m_accel_type = MOUSE_ACCEL_TYPE_NORMAL;	} else if (!strcasecmp(ptr, "power")) {	  m_accel_type = MOUSE_ACCEL_TYPE_POWER;	} else if (!strcasecmp(ptr, "off")) {	  m_accel_type = 0;	} else {	  fprintf(stderr, "svgalib: mouse-config: ignoring unknown mouse acceleration \'%s\'\n", ptr);	  m_accel_type = 0;	}     	break;     case 1: /* mouse_accel_mult */	fptr = &m_accel_mult;   process_float:	if ( (ptr = strtok((NULL), " ")) == 0) {	  goto param_needed;	} else {	 char *endptr;	 double dtmp = strtod(ptr, &endptr);	  if (endptr == ptr) {	    fprintf(stderr, "svgalib: mouse-config: illegal float \'%s\' %s\n",					ptr,  mouse_config_options[option]);	    return ptr;	  } else {	    *fptr = dtmp;	  }	}	break;     case 2: /* mouse_accel_thresh */	iptr = &m_accel_thresh;   process_int:	if ( (ptr = strtok((NULL), " ")) == 0) {	  goto param_needed;	} else {	 char *endptr;	 long ltmp = strtol(ptr, &endptr, 10);	  if (ptr == endptr) {	    fprintf(stderr, "svgalib: mouse-config: illegal number \'%s\' for %s\n",					ptr,  mouse_config_options[option]);	    return ptr;	  } else {	    *iptr = ltmp;	  }	}	break;     case 3: /* mouse_accel_power */	fptr = &m_accel_power;	goto process_float;     case 4: /* mouse_accel_maxdelta */	iptr = &m_accel_maxdelta;	goto process_int;     case 5: /* mouse_maxdelta */	iptr = &m_maxdelta;	goto process_int;     case 6: /* mouse_accel_offset */	fptr = &m_accel_offset;	goto process_float;     case 7: /* mouse_override */#ifdef ALLOW_MOUSE_OVERRIDE	newmtype = vga_getmousetype();	if (m_type != newmtype) {	    printf("svgalib: mouse-init: mouse type override %d to %d\n",		   m_type, newmtype);	    m_type = newmtype;	}#else				/* ALLOW_MOUSE_OVERRIDE */	fputs("svgalib: was compiled with SVGA_MOUSE_OVERRIDE disabled !", stderr);#endif				/* ALLOW_MOUSE_OVERRIDE */	break;     case 8: /* mouse_force */	m_force = 1;        break;     case 9: /* mouse_fake_kbd_event */         /* Set fake keyboard events for mouse wheel...            Turn them off temporarily in case the params are bad */         m_fake_kbd_events = 0;#ifdef DEBUG_WHEEL         fprintf(stderr, " Setting up fake keyboard events");#endif         /* Parse the config for the scancodes */         cptr = &m_fake_upkeyname;         iptr = &m_fake_upscancode;         while(cptr) {             if ( (ptr = strtok(NULL, " ")) == 0 )                 goto param_needed;#ifdef DEBUG_WHEEL             fprintf(stderr, "; keyname %s", ptr);#endif             /* Keep the name in case the keyboard gets remapped later */             if(*cptr)                 free(*cptr);             *cptr = (char *)malloc(strlen(ptr) + 1);             strcpy(*cptr, ptr);             /* Determine the scancode */             *iptr = __svgalib_mapkeyname(*cptr);#ifdef DEBUG_WHEEL             fprintf(stderr, " = scancode %d", *iptr);#endif             /* Move on to the next */             iptr = ((cptr == &m_fake_upkeyname)?(&m_fake_downscancode):NULL);             cptr = ((cptr == &m_fake_upkeyname)?(&m_fake_downkeyname):NULL);         }#ifdef DEBUG_WHEEL         fprintf(stderr, "; done.\n");#endif         /* Now that we've survived all that, turn on fake events */         m_fake_kbd_events = 1;         break;   case 10: /* mouse_wheel_steps */       /* Set the number of steps that make up a complete turn of          the wheel on an IntelliMouse or other wheel mouse. Zero          disables X-axis rotation but not fake keyboard events. */	iptr = &m_wheel_steps;	goto process_int;   }   return strtok(NULL, " ");}static int ms_init(void){/*------------------------------------------------------------------*//* Define ALLOW_MOUSE_OVERRIDE to recognize the SVGA_MOUSE_OVERRIDE *//* environment variable.  If this environment variable is set       *//* then ignore the program's specified mouse type and use           *//* the configuration file's type.                                   *//* In particular, DOOM does not understand "MouseMan" as a valid    *//* mouse type and so defaults the mouse type to "MouseSystems".     *//*------------------------------------------------------------------*/    __svgalib_read_options(mouse_config_options, mouse_process_option);    if (m_maxdelta < 0  &&  !m_force) {      fprintf(stderr, "svgalib: mouse_maxdelta value '%ld' is invalid, should be > 0\n", (long)m_maxdelta);      m_maxdelta = DEFAULT_MAXDELTA;    }    if (m_accel_maxdelta < 0  &&  !m_force) {      fprintf(stderr, "svgalib: mouse_accel_maxdelta value '%ld' is invalid, should be > 0\n", (long)m_accel_maxdelta);      m_accel_maxdelta = DEFAULT_ACCEL_MAXDELTA;    }    if (m_accel_type) {      if ((m_accel_mult <= 0  ||  m_accel_mult > 200.0)  &&  !m_force) {        fprintf(stderr, "svgalib: mouse_accel_mult value '%.2f' is invalid, should be between 0 and 200.0\n", (double)m_accel_mult);        m_accel_mult = DEFAULT_ACCEL_MULT;      }      if ((m_accel_power < -200.0  ||  m_accel_power > 200.0)  &&  !m_force) {        fprintf(stderr, "svgalib: mouse_accel_power value '%.2f' is invalid, should be between -200.0 and 200.0\n", m_accel_power);	m_accel_power = DEFAULT_ACCEL_POWER;      }      if ((m_accel_offset < -100.0  ||  m_accel_offset > 100.0)  &&  !m_force) {        fprintf(stderr, "svgalib: mouse_accel_offset value '%.2f' is invalid, should be between -100.0 and 100.0\n", m_accel_offset);	m_accel_offset = DEFAULT_ACCEL_OFFSET;      }      if (!m_force) {         if (m_accel_thresh <= 0  ||  m_accel_thresh > 200) {            fprintf(stderr, "svgalib: mouse_accel_thresh value '%ld' is invalid, should be between 0 and 200\n", (long)m_accel_thresh);	    m_accel_thresh = DEFAULT_ACCEL_THRESH;         }      } else if (m_accel_thresh < 0) {	 fputs("svgalib: mouse_accel_thresh musn't be negative !\n", stderr);	 m_accel_thresh = DEFAULT_ACCEL_THRESH;      }      if (m_accel_offset >= m_accel_mult) {         fputs("svgalib: warning: accel_offset should be less then accel_mult !", stderr);      }      if (m_accel_thresh > 1 && m_accel_type == MOUSE_ACCEL_TYPE_POWER) {        if ((m_accel_powertable = malloc(m_accel_thresh * sizeof(float))) == 0 ) {  	  fputs("svgalib: out of memory in mouse init ! (Check SVGA_MOUSE_ACCEL_THRESH size) !", stderr);	  fflush(stderr);	  return 1;        } else {         int i;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?