Fixed bug #102
authorSam Lantinga <slouken@libsdl.org>
Sun, 07 May 2006 06:20:39 +0000
changeset 17725115185b6e3c
parent 1771 8d3ca155c396
child 1773 3776702e1fb9
Fixed bug #102

Improved GPM mouse protocol detection.
The original patch had a bunch of bugs, so I completely rewrote it to hopefully fix them, and to support more protocols.
src/video/fbcon/SDL_fbevents.c
     1.1 --- a/src/video/fbcon/SDL_fbevents.c	Sun May 07 04:02:48 2006 +0000
     1.2 +++ b/src/video/fbcon/SDL_fbevents.c	Sun May 07 06:20:39 2006 +0000
     1.3 @@ -55,6 +55,7 @@
     1.4  #define GPM_NODE_FIFO	"/dev/gpmdata"
     1.5  #endif
     1.6  
     1.7 +/*#define DEBUG_MOUSE*/
     1.8  
     1.9  /* The translation tables from a console scancode to a SDL keysym */
    1.10  #define NUM_VGAKEYMAPS	(1<<KG_CAPSSHIFT)
    1.11 @@ -360,7 +361,7 @@
    1.12  }
    1.13  
    1.14  /* Returns true if /dev/gpmdata is being written to by gpm */
    1.15 -static int gpm_available(void)
    1.16 +static int gpm_available(char *proto, size_t protolen)
    1.17  {
    1.18  	int available;
    1.19  	DIR *proc;
    1.20 @@ -370,6 +371,9 @@
    1.21  	char args[PATH_MAX], *arg;
    1.22  
    1.23  	/* Don't bother looking if the fifo isn't there */
    1.24 +#ifdef DEBUG_MOUSE 
    1.25 +	fprintf(stderr,"testing gpm\n");
    1.26 +#endif
    1.27  	if ( access(GPM_NODE_FIFO, F_OK) < 0 ) {
    1.28  		return(0);
    1.29  	}
    1.30 @@ -377,17 +381,37 @@
    1.31  	available = 0;
    1.32  	proc = opendir("/proc");
    1.33  	if ( proc ) {
    1.34 -		while ( (pid=find_pid(proc, "gpm")) > 0 ) {
    1.35 +		char raw_proto[10] = { '\0' };
    1.36 +		char repeat_proto[10] = { '\0' };
    1.37 +		while ( !available && (pid=find_pid(proc, "gpm")) > 0 ) {
    1.38  			SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid);
    1.39  			cmdline = open(path, O_RDONLY, 0);
    1.40  			if ( cmdline >= 0 ) {
    1.41  				len = read(cmdline, args, sizeof(args));
    1.42  				arg = args;
    1.43  				while ( len > 0 ) {
    1.44 -					if ( SDL_strcmp(arg, "-R") == 0 ) {
    1.45 +					arglen = SDL_strlen(arg)+1;
    1.46 +#ifdef DEBUG_MOUSE 
    1.47 +				        fprintf(stderr,"gpm arg %s len %d\n",arg,arglen);
    1.48 +#endif
    1.49 +					if ( SDL_strcmp(arg, "-t") == 0) {
    1.50 +						/* protocol string, keep it for later */
    1.51 +						char *t, *s;
    1.52 +						t = arg + arglen;
    1.53 +						s = SDL_strchr(t, ' ');
    1.54 +						if (s) *s = 0;
    1.55 +						SDL_strncpy(raw_proto, t, SDL_arraysize(raw_proto));
    1.56 +						if (s) *s = ' ';
    1.57 +					}
    1.58 +					if ( SDL_strncmp(arg, "-R", 2) == 0 ) {
    1.59 +						char *t, *s;
    1.60  						available = 1;
    1.61 +						t = arg + 2;
    1.62 +						s = SDL_strchr(t, ' ');
    1.63 +						if (s) *s = 0;
    1.64 +						SDL_strncpy(repeat_proto, t, SDL_arraysize(repeat_proto));
    1.65 +						if (s) *s = ' ';
    1.66  					}
    1.67 -					arglen = SDL_strlen(arg)+1;
    1.68  					len -= arglen;
    1.69  					arg += arglen;
    1.70  				}
    1.71 @@ -395,6 +419,16 @@
    1.72  			}
    1.73  		}
    1.74  		closedir(proc);
    1.75 +
    1.76 +		if ( available ) {
    1.77 +			if ( SDL_strcmp(repeat_proto, "raw") == 0 ) {
    1.78 +				SDL_strlcpy(proto, raw_proto, protolen);
    1.79 +			} else if ( *repeat_proto ) {
    1.80 +				SDL_strlcpy(proto, repeat_proto, protolen);
    1.81 +			} else {
    1.82 +				SDL_strlcpy(proto, "msc", protolen);
    1.83 +			}
    1.84 +		}
    1.85  	}
    1.86  	return available;
    1.87  }
    1.88 @@ -552,14 +586,35 @@
    1.89  		};
    1.90  		/* First try to use GPM in repeater mode */
    1.91  		if ( mouse_fd < 0 ) {
    1.92 -			if ( gpm_available() ) {
    1.93 +			char proto[10];
    1.94 +			if ( gpm_available(proto, SDL_arraysize(proto)) ) {
    1.95  				mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0);
    1.96  				if ( mouse_fd >= 0 ) {
    1.97 +					if ( SDL_strcmp(proto, "msc") == 0 ) {
    1.98 +						mouse_drv = MOUSE_MSC;
    1.99 +					} else if ( SDL_strcmp(proto, "ps2") == 0 ) {
   1.100 +						mouse_drv = MOUSE_PS2;
   1.101 +					} else if ( SDL_strcmp(proto, "imps2") == 0 ) {
   1.102 +						mouse_drv = MOUSE_IMPS2;
   1.103 +					} else if ( SDL_strcmp(proto, "ms") == 0 ||
   1.104 +					            SDL_strcmp(proto, "bare") == 0 ) {
   1.105 +						mouse_drv = MOUSE_MS;
   1.106 +					} else if ( SDL_strcmp(proto, "bm") == 0 ) {
   1.107 +						mouse_drv = MOUSE_BM;
   1.108 +					} else {
   1.109 +						/* Unknown protocol... */
   1.110  #ifdef DEBUG_MOUSE
   1.111 -fprintf(stderr, "Using GPM mouse\n");
   1.112 +						fprintf(stderr, "GPM mouse using unknown protocol = %s\n", proto);
   1.113  #endif
   1.114 -					mouse_drv = MOUSE_MSC;
   1.115 +						close(mouse_fd);
   1.116 +						mouse_fd = -1;
   1.117 +					}
   1.118  				}
   1.119 +#ifdef DEBUG_MOUSE
   1.120 +				if ( mouse_fd >= 0 ) {
   1.121 +					fprintf(stderr, "Using GPM mouse, protocol = %s\n", proto);
   1.122 +				}
   1.123 +#endif /* DEBUG_MOUSE */
   1.124  			}
   1.125  		}
   1.126  		/* Now try to use a modern PS/2 mouse */