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 + -
显示快捷键?