import gpm from unix.schottelius.org
Signed-off-by: Nico Schottelius <nico@ikn.schottelius.org>
This commit is contained in:
parent
241d2c35b4
commit
95a46c5577
5930 changed files with 755263 additions and 0 deletions
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* disable-paste.c - trivial program to stop gpm from pasting the
|
||||
* current selection until the next user action
|
||||
*
|
||||
* Copyright (C) 1998 Ian Zimmerman <itz@rahul.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include "headers/gpm.h"
|
||||
#include "headers/gpmInt.h"
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
Gpm_Connect conn;
|
||||
const int len = sizeof(Gpm_Connect);
|
||||
int exit_status = 0;
|
||||
conn.eventMask = (unsigned short)(-1); conn.defaultMask = 0;
|
||||
conn.minMod = 0; conn.maxMod = (unsigned short)(-1);
|
||||
|
||||
if (0 > Gpm_Open(&conn,0)) {
|
||||
fprintf(stderr,"disable-paste: cannot open mouse connection\n");
|
||||
exit(1);
|
||||
}
|
||||
conn.vc = GPM_REQ_NOPASTE;
|
||||
conn.pid = 0;
|
||||
if (len > write(gpm_fd, &conn, len)) {
|
||||
fprintf(stderr,"disable-paste: cannot write request\n");
|
||||
exit_status = 2;
|
||||
}
|
||||
Gpm_Close();
|
||||
exit(exit_status);
|
||||
}
|
||||
110
software/gpm/browse_source/gpm-1.20.6/src/prog/display-buttons.c
Normal file
110
software/gpm/browse_source/gpm-1.20.6/src/prog/display-buttons.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* display-coords.c - a very simple gpm client
|
||||
*
|
||||
* Copyright 2007-2008 Nico Schottelius <nico-gpm2008 (at) schottelius.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Compile and link with: gcc -o display-buttons -lgpm display-buttons.c
|
||||
*
|
||||
********/
|
||||
|
||||
/*
|
||||
* This client is connects to gpm and displays the following values until
|
||||
* it is killed by control+c:
|
||||
*
|
||||
* left/middle/right button
|
||||
* time: when packet was recievesd
|
||||
* dtime: delta to the last packet
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* write, read, open */
|
||||
#include <stdlib.h> /* strtol() */
|
||||
#include <stdio.h> /* printf() */
|
||||
#include <time.h> /* time() */
|
||||
#include <errno.h> /* errno */
|
||||
#include <gpm.h> /* gpm information */
|
||||
|
||||
/* display resulting data */
|
||||
int display_data(Gpm_Event *event, void *data)
|
||||
{
|
||||
static time_t last = 0;
|
||||
time_t now = time(NULL);
|
||||
int delta;
|
||||
|
||||
delta = now - last;
|
||||
last = now;
|
||||
|
||||
/* display time, delta time */
|
||||
printf("[%d] delta: %ds",now,delta);
|
||||
|
||||
/* display mouse information */
|
||||
printf(": p=%d, l=%1d, m=%1d, r=%1d, clicks=%d\n",
|
||||
event->type & GPM_DOWN,
|
||||
event->buttons & GPM_B_LEFT,
|
||||
event->buttons & GPM_B_MIDDLE,
|
||||
event->buttons & GPM_B_RIGHT,
|
||||
event->clicks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int vc; /* argv: console number */
|
||||
Gpm_Connect conn; /* connection to gpm */
|
||||
fd_set fds;
|
||||
|
||||
/* select virtual console, 0 if not set */
|
||||
vc = (argc == 2) ? strtol(argv[1],NULL,10) : 0;
|
||||
|
||||
conn.eventMask = GPM_DRAG | GPM_DOWN | GPM_UP;
|
||||
conn.defaultMask = ~GPM_HARD; /* inverted GPM_HARD mask */
|
||||
conn.minMod = 0;
|
||||
conn.maxMod = ~0;
|
||||
|
||||
if(Gpm_Open(&conn,vc) == -1) {
|
||||
printf("Cannot connect to gpm!\n");
|
||||
return 1;
|
||||
}
|
||||
if(gpm_fd == -2) {
|
||||
printf("I must be run on the console\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\tp=pressed (0=release)\n\tl=left\n\tm=middle\n\tr=right\n");
|
||||
|
||||
|
||||
while(1) { /* read data */
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(gpm_fd, &fds);
|
||||
|
||||
if (select(gpm_fd+1, &fds, 0, 0, 0) < 0 && errno == EINTR)
|
||||
continue;
|
||||
if (FD_ISSET(gpm_fd, &fds)) {
|
||||
Gpm_Event evt;
|
||||
if (Gpm_GetEvent(&evt) > 0) {
|
||||
display_data(&evt, NULL);
|
||||
} else {
|
||||
printf("Gpm_GetEvent failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gpm_Close(); /* close connection */
|
||||
|
||||
return 0;
|
||||
}
|
||||
104
software/gpm/browse_source/gpm-1.20.6/src/prog/display-coords.c
Normal file
104
software/gpm/browse_source/gpm-1.20.6/src/prog/display-coords.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* display-coords.c - a very simple gpm client
|
||||
*
|
||||
* Copyright 2007-2008 Nico Schottelius <nico-gpm2008 (at) schottelius.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Compile and link with: gcc -o display-coords -lgpm display-coords.c
|
||||
*
|
||||
********/
|
||||
|
||||
/*
|
||||
* This client is connects to gpm and displays the following values until
|
||||
* it is killed by control+c:
|
||||
*
|
||||
* x/y coords on the screen
|
||||
* dx, dy: deltas
|
||||
* time: when packet was recievesd
|
||||
* dtime: delta to the last packet
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* write, read, open */
|
||||
#include <stdlib.h> /* strtol() */
|
||||
#include <stdio.h> /* printf() */
|
||||
#include <time.h> /* time() */
|
||||
#include <errno.h> /* errno */
|
||||
#include <gpm.h> /* gpm information */
|
||||
|
||||
/* display resulting data */
|
||||
int display_data(Gpm_Event *event, void *data)
|
||||
{
|
||||
static time_t last = 0;
|
||||
time_t now = time(NULL);
|
||||
int delta;
|
||||
|
||||
delta = now - last;
|
||||
last = now;
|
||||
|
||||
/* display time, delta time */
|
||||
printf("[%d] delta: %ds",now,delta);
|
||||
|
||||
/* display mouse information */
|
||||
printf(": x=%2i, y=%2i, dx=%2i, dy=%2i\n", event->x, event->y, event->dx, event->dy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int vc; /* argv: console number */
|
||||
Gpm_Connect conn; /* connection to gpm */
|
||||
fd_set fds;
|
||||
|
||||
/* select virtual console, 0 if not set */
|
||||
vc = (argc == 2) ? strtol(argv[1],NULL,10) : 0;
|
||||
|
||||
conn.eventMask = GPM_MOVE; /* read only moves */
|
||||
conn.defaultMask = ~GPM_HARD; /* inverted GPM_HARD mask */
|
||||
conn.minMod = 0;
|
||||
conn.maxMod = ~0;
|
||||
|
||||
if(Gpm_Open(&conn,vc) == -1) {
|
||||
printf("Cannot connect to gpm!\n");
|
||||
return 1;
|
||||
}
|
||||
if(gpm_fd == -2) {
|
||||
printf("I must be run on the console\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
while(1) { /* read data */
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(gpm_fd, &fds);
|
||||
|
||||
if (select(gpm_fd+1, &fds, 0, 0, 0) < 0 && errno == EINTR)
|
||||
continue;
|
||||
if (FD_ISSET(gpm_fd, &fds)) {
|
||||
Gpm_Event evt;
|
||||
if (Gpm_GetEvent(&evt) > 0) {
|
||||
display_data(&evt, NULL);
|
||||
} else {
|
||||
printf("Gpm_GetEvent failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gpm_Close(); /* close connection */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Get gpm library and server version
|
||||
*
|
||||
* Copyright 2007-2008 Nico Schottelius <nico-gpm2008 (at) schottelius.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Compile and link with: gcc -lgpm
|
||||
*
|
||||
********/
|
||||
|
||||
#include <stdio.h> /* printf() */
|
||||
#include <gpm.h> /* gpm information */
|
||||
|
||||
int main()
|
||||
{
|
||||
char *ver;
|
||||
int intver;
|
||||
|
||||
ver = Gpm_GetLibVersion(&intver);
|
||||
printf("lib: %s, %d\n",ver,intver);
|
||||
|
||||
ver = Gpm_GetServerVersion(&intver);
|
||||
printf("srv: %s, %d\n",ver,intver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
1396
software/gpm/browse_source/gpm-1.20.6/src/prog/gpm-root.y
Normal file
1396
software/gpm/browse_source/gpm-1.20.6/src/prog/gpm-root.y
Normal file
File diff suppressed because it is too large
Load diff
543
software/gpm/browse_source/gpm-1.20.6/src/prog/hltest.c
Normal file
543
software/gpm/browse_source/gpm-1.20.6/src/prog/hltest.c
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* hltest.c - a demo program for the high-level library.
|
||||
*
|
||||
* Copyright 1995 rubini@linux.it (Alessandro Rubini)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "headers/gpm.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ((a)>(b)?(b):(a))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If you happen to read this source to get insights about mouse
|
||||
* management, note that most of this file is concerned with user
|
||||
* interface and screen handling. The mouse-related part begines
|
||||
* at "MOUSE-BEGIN" (so you can use your editor capabilities to
|
||||
* look for strings).
|
||||
*
|
||||
* If you use parts of this program in your own one, I'd like some credit.
|
||||
* If you want to overcome the gnu copyleft though using parts of this
|
||||
* program, just tell me about it, and I'll change the copyright.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* this is used as clientdata */
|
||||
|
||||
typedef struct WinInfo {
|
||||
char color;
|
||||
int number;
|
||||
short hei,wid;
|
||||
Gpm_Roi *roi;
|
||||
} WinInfo;
|
||||
|
||||
WinInfo left_cldata; /* for the msg bar */
|
||||
|
||||
int colors[]={0x40,0x60,0x20,0x30,0x47,0x67,0x27,0x37};
|
||||
#define NR_COLORS 8
|
||||
#define LEFTWID 22
|
||||
/* Dirty: use escape sequences and /dev/vcs (don't want to learn curses) */
|
||||
|
||||
#define CLEAR (printf("\x1b[H\x1b[J"),fflush(stdout))
|
||||
|
||||
int dev_vcs=-1;
|
||||
int wid,hei,vcsize;
|
||||
|
||||
/*
|
||||
* These two functions are only involved in the user interface:
|
||||
* dump and restore the screen to keep things up to date.
|
||||
*/
|
||||
|
||||
unsigned short clear_sel_args[6]={0, 0,0, 0,0, 4};
|
||||
unsigned char *clear_sel_arg= (unsigned char *)clear_sel_args+1;
|
||||
|
||||
|
||||
static inline int scrdump(char *buf)
|
||||
{
|
||||
clear_sel_arg[0]=2; /* clear_selection */
|
||||
ioctl(fileno(stdin),TIOCLINUX,clear_sel_arg);
|
||||
lseek (dev_vcs, 0, SEEK_SET);
|
||||
return read(dev_vcs,buf,vcsize);
|
||||
}
|
||||
|
||||
static inline int scrrestore(char *buf)
|
||||
{
|
||||
clear_sel_arg[0]=2; /* clear_selection */
|
||||
ioctl(fileno(stdin),TIOCLINUX,clear_sel_arg);
|
||||
lseek (dev_vcs, 0, SEEK_SET);
|
||||
return write(dev_vcs,buf,vcsize);
|
||||
}
|
||||
|
||||
|
||||
/* I don't like curses, so I'm doing low level stuff here */
|
||||
static void raw(void)
|
||||
{
|
||||
struct termios it;
|
||||
|
||||
tcgetattr(fileno(stdin),&it);
|
||||
it.c_lflag &= ~(ICANON);
|
||||
it.c_lflag &= ~(ECHO);
|
||||
it.c_iflag &= ~(INPCK|ISTRIP|IXON);
|
||||
it.c_oflag &= ~(OPOST);
|
||||
it.c_cc[VMIN] = 1;
|
||||
it.c_cc[VTIME] = 0;
|
||||
|
||||
tcsetattr(fileno(stdin),TCSANOW,&it);
|
||||
|
||||
}
|
||||
|
||||
static void noraw(void)
|
||||
{
|
||||
struct termios it;
|
||||
|
||||
tcgetattr(fileno(stdin),&it);
|
||||
it.c_lflag |= ICANON;
|
||||
it.c_lflag |= ECHO;
|
||||
it.c_iflag |= IXON;
|
||||
it.c_oflag |= OPOST;
|
||||
|
||||
tcsetattr(fileno(stdin),TCSANOW,&it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* this one is the signal handler */
|
||||
|
||||
void killed(int signo)
|
||||
{
|
||||
CLEAR;
|
||||
fprintf(stderr,"hltest: killed by signal %i\r\n",signo);
|
||||
noraw();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char *dumpbuf;
|
||||
char *dumpbuf_clean;
|
||||
#define DUMPCHAR(x,y) (dumpbuf+4+2*((y)*wid+(x)))
|
||||
#define DUMPATTR(x,y) (dumpbuf+5+2*((y)*wid+(x)))
|
||||
|
||||
/*
|
||||
* This function draws one window on top of the others
|
||||
*/
|
||||
|
||||
static inline int drawwin(Gpm_Roi *which)
|
||||
{
|
||||
char *curr;
|
||||
char name[5];
|
||||
|
||||
#define GOTO(x,y) (curr=DUMPCHAR(x,y))
|
||||
#define PUTC(c,a) (*(curr++)=(c),*(curr++)=a)
|
||||
#define ULCORNER 0xc9
|
||||
#define URCORNER 0xbb
|
||||
#define LLCORNER 0xc8
|
||||
#define LRCORNER 0xbc
|
||||
#define HORLINE 0xcd
|
||||
#define VERLINE 0xba
|
||||
|
||||
int attrib=((WinInfo *)which->clientdata)->color;
|
||||
int i,j;
|
||||
|
||||
/* top border */
|
||||
GOTO(which->xMin,which->yMin);
|
||||
PUTC(ULCORNER,attrib);
|
||||
for (i=which->xMin+1; i<which->xMax; i++)
|
||||
PUTC(HORLINE,attrib);
|
||||
PUTC(URCORNER,attrib);
|
||||
|
||||
/* sides and items */
|
||||
for (j=which->yMin+1;j<which->yMax;j++)
|
||||
{
|
||||
GOTO(which->xMin,j);
|
||||
PUTC(VERLINE,attrib);
|
||||
for (i=which->xMin+1; i<which->xMax; i++)
|
||||
PUTC(' ',attrib);
|
||||
PUTC(VERLINE,attrib);
|
||||
}
|
||||
|
||||
/* bottom border */
|
||||
GOTO(which->xMin,which->yMax);
|
||||
PUTC(LLCORNER,attrib);
|
||||
for (i=which->xMin+1; i<which->xMax; i++)
|
||||
PUTC(HORLINE,attrib);
|
||||
PUTC(LRCORNER,attrib);
|
||||
|
||||
/* name */
|
||||
sprintf(name,"%3i",((WinInfo *)which->clientdata)->number);
|
||||
GOTO(which->xMin+1,which->yMin+1);
|
||||
for (i=0;name[i];i++)
|
||||
PUTC(name[i],attrib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* and finally, draw them all (recursive) */
|
||||
|
||||
int drawthemall(Gpm_Roi *this)
|
||||
{
|
||||
if (this->next)
|
||||
drawthemall(this->next);
|
||||
else
|
||||
memcpy(dumpbuf,dumpbuf_clean,vcsize);
|
||||
|
||||
return drawwin(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* This one writes all the messages in the right position
|
||||
*/
|
||||
|
||||
int newmsg(int window, char *msg)
|
||||
{
|
||||
static char *data=NULL;
|
||||
static char **strings;
|
||||
static int current, last;
|
||||
static time_t t;
|
||||
int i,j;
|
||||
|
||||
/* first time, alloc material */
|
||||
if (!data)
|
||||
{
|
||||
data=malloc((LEFTWID-2)*(hei-2));
|
||||
strings=malloc(hei*sizeof(char *));
|
||||
if(!data || !strings) { perror("malloc()"); exit(1); }
|
||||
memset(data,' ',(LEFTWID-2)*(hei-2));
|
||||
for (i=0;i<hei-2;i++)
|
||||
strings[i]=data+(LEFTWID-2)*i, strings[i][19]='\0';
|
||||
current=0;
|
||||
}
|
||||
|
||||
if (msg) /* if sth new */
|
||||
{
|
||||
time(&t);
|
||||
strftime(strings[current],15,"%M:%S ",localtime(&t));
|
||||
sprintf(strings[current]+strlen(strings[current]),"%i: ",window);
|
||||
strncat(strings[current],msg,LEFTWID-2-strlen(strings[current]));
|
||||
for (i=strlen(strings[current]);i<19;i++)
|
||||
strings[current][i]=' ';
|
||||
strings[current][i]=0;
|
||||
last=current; current++; current%=(hei-2);
|
||||
}
|
||||
else /* draw them all */
|
||||
for (i=1,j=current; j%=(hei-2), i<hei-2; i++,j++)
|
||||
printf("\x1B[%03i;%03iH%s",j+2,2,strings[j]); /* y and x */
|
||||
|
||||
/* write only the current one */
|
||||
printf("\x1B[%03i;%03iH%s\x1B[%03i;%03iH%s",
|
||||
last+2,2,strings[last],current+2,2," ");
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper: refresh the whole screen
|
||||
*/
|
||||
static inline void dorefresh(void)
|
||||
{
|
||||
static unsigned short clear_sel_args[6]={0, 0,0, 0,0, 4};
|
||||
static unsigned char *clear_sel_arg= (unsigned char *)clear_sel_args+1;
|
||||
|
||||
drawthemall(gpm_roi);
|
||||
clear_sel_arg[0]=2; /* clear_selection */
|
||||
ioctl(fileno(stdin),TIOCLINUX,clear_sel_arg);
|
||||
scrrestore(dumpbuf);
|
||||
newmsg(0,NULL);
|
||||
}
|
||||
|
||||
|
||||
/*============================================================ MOUSE-BEGIN */
|
||||
|
||||
/*
|
||||
* In this sample program, I use only one handler, which reports on the
|
||||
* screen any event it gets. The clientdata received is the one I pass to
|
||||
* Gpm_PushRoi on creation, and is used to differentiate them
|
||||
*/
|
||||
|
||||
int handler(Gpm_Event *ePtr, void *clientdata)
|
||||
{
|
||||
WinInfo *info=clientdata;
|
||||
int number=info->number;
|
||||
int delta;
|
||||
|
||||
if (ePtr->type&GPM_ENTER)
|
||||
{ newmsg(number,"enter"); return 0; }
|
||||
if (ePtr->type&GPM_LEAVE)
|
||||
{ newmsg(number,"leave"); return 0; }
|
||||
if (ePtr->type&GPM_MOVE)
|
||||
{ newmsg(number,"move"); return 0; }
|
||||
|
||||
if (ePtr->type&GPM_DOWN)
|
||||
{newmsg(number,"press"); return 0; }
|
||||
if (ePtr->type&GPM_DRAG)
|
||||
{
|
||||
newmsg(number,"drag");
|
||||
if (!(ePtr->buttons&GPM_B_LEFT)) return 0;
|
||||
|
||||
/*
|
||||
* Implement window motion
|
||||
*/
|
||||
delta=0;
|
||||
if (ePtr->dx < 0) delta=max(ePtr->dx,LEFTWID-info->roi->xMin);
|
||||
else if (ePtr->dx > 0) delta=min(ePtr->dx,wid-1 - info->roi->xMax);
|
||||
if (delta) { info->roi->xMin+=delta; info->roi->xMax+=delta; }
|
||||
|
||||
delta=0;
|
||||
if (ePtr->dy < 0) delta=max(ePtr->dy,0 - info->roi->yMin);
|
||||
else if (ePtr->dy > 0) delta=min(ePtr->dy,hei-1 - info->roi->yMax);
|
||||
if (delta) { info->roi->yMin+=delta; info->roi->yMax+=delta; }
|
||||
Gpm_RaiseRoi(info->roi,NULL);
|
||||
dorefresh(); return 0;
|
||||
}
|
||||
|
||||
newmsg(number,"release");
|
||||
|
||||
/*
|
||||
* "up" events can be double or triple,
|
||||
* moreover, they can happen out of the region
|
||||
*/
|
||||
|
||||
if (!(ePtr->type&GPM_SINGLE)) return 0;
|
||||
if (ePtr->x<0 || ePtr->y<0) return 0;
|
||||
if (ePtr->x>info->wid-1 || ePtr->y>info->hei-1) return 0;
|
||||
|
||||
/*
|
||||
* Ok, it is has been a double click, and it is within our area
|
||||
*/
|
||||
|
||||
switch(ePtr->buttons)
|
||||
{
|
||||
case GPM_B_LEFT: Gpm_RaiseRoi(info->roi,NULL); break;
|
||||
case GPM_B_MIDDLE: Gpm_LowerRoi(info->roi,NULL); break;
|
||||
case GPM_B_RIGHT:
|
||||
Gpm_PopRoi(info->roi); free(info); break;
|
||||
}
|
||||
dorefresh();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* the following function creates a window, with the four corners as
|
||||
* specified by the arguments.
|
||||
*/
|
||||
int wincreate(int x, int y, int X, int Y)
|
||||
{
|
||||
static int winno=0;
|
||||
Gpm_Roi*roi;
|
||||
WinInfo *cldata;
|
||||
int tmp;
|
||||
|
||||
if (X<x) tmp=X,X=x,x=tmp;
|
||||
if (Y<y) tmp=Y,Y=y,y=tmp;
|
||||
if (X-x<5) X=x+4;
|
||||
if (Y-y<3) Y=y+2;
|
||||
if (X>=wid) X=wid-1;
|
||||
if (Y>=hei) Y=hei-1;
|
||||
if (x<LEFTWID) x=LEFTWID;
|
||||
if (y<0) y=0;
|
||||
|
||||
cldata=malloc(sizeof(WinInfo));
|
||||
roi=Gpm_PushRoi(x,y,X,Y,
|
||||
GPM_DOWN|GPM_UP|GPM_DRAG|GPM_ENTER|GPM_LEAVE,
|
||||
handler,cldata);
|
||||
if (!cldata || !roi) { perror("malloc()"); exit(1); }
|
||||
|
||||
/* don't get modifiers */
|
||||
roi->maxMod=0;
|
||||
|
||||
/* put a backpointer */
|
||||
cldata->roi=roi;
|
||||
|
||||
/* init the window */
|
||||
winno++;
|
||||
cldata->number=winno;
|
||||
cldata->color=colors[winno%NR_COLORS];
|
||||
cldata->wid=X-x+1;
|
||||
cldata->hei=Y-y+1;
|
||||
dorefresh();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This extra handler is only used for the background and left bar
|
||||
*/
|
||||
|
||||
int xhandler(Gpm_Event *ePtr, void *clientdata)
|
||||
{
|
||||
static int x=0,y=0;
|
||||
int back=0;
|
||||
char msg[32];
|
||||
|
||||
msg[0]='\0';
|
||||
if (ePtr->type==GPM_MOVE) return 0;
|
||||
if (!clientdata)
|
||||
strcpy(msg,"bg"),back++;
|
||||
|
||||
if (ePtr->type&GPM_DOWN)
|
||||
{
|
||||
strcat(msg," down");
|
||||
if (back) x=ePtr->x,y=ePtr->y;
|
||||
}
|
||||
if (ePtr->type&GPM_UP)
|
||||
{
|
||||
strcat(msg," up");
|
||||
if (back) wincreate(x,y,ePtr->x,ePtr->y);
|
||||
}
|
||||
|
||||
newmsg(0,msg);
|
||||
/* GPM_DRAWPOINTER(ePtr); useless, gpm_visiblepointer is set to 1 BUG */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*============================================================ MOUSE-END */
|
||||
|
||||
/*
|
||||
* This function is not interesting, it is only involved in setting up
|
||||
* things. The real work has already been done.
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Gpm_Connect conn;
|
||||
char *s, t[4];
|
||||
char devname[32]; /* very secure buffer ... */
|
||||
int c;
|
||||
int vc;
|
||||
struct winsize win;
|
||||
|
||||
if (argc>1) {
|
||||
fprintf(stderr,"%s: This program is meant to be interactive, "
|
||||
"no option is needed\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!(s=ttyname(fileno(stdin)))) {
|
||||
perror("stdin");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* retrieve everything */
|
||||
conn.eventMask=~0;
|
||||
conn.defaultMask=GPM_MOVE|GPM_HARD;
|
||||
conn.maxMod=~0;
|
||||
conn.minMod=0;
|
||||
|
||||
if (sscanf(s,"/dev/tty%d%s",&vc,t)!=1) {
|
||||
if (sscanf(s,"/dev/vc/%d%s",&vc,t)!=1) {
|
||||
fprintf(stderr,"stdin: not a system console\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* open your dump/restore buffers */
|
||||
|
||||
sprintf(devname,"/dev/vcs%i",vc);
|
||||
if ((dev_vcs=open(devname,O_RDWR))<0) {
|
||||
perror(devname);
|
||||
sprintf(devname,"/dev/vcc/%i",vc);
|
||||
if ((dev_vcs=open(devname,O_RDWR))<0) {
|
||||
perror(devname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Gpm_Open(&conn,0) == -1) {
|
||||
fprintf(stderr,"%s: Can't open mouse connection\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Gpm_Close(); /* don't be clubbered by events now */
|
||||
|
||||
signal(SIGWINCH,killed); /* don't handle winchange */
|
||||
signal(SIGINT,killed); /* control-C kills us */
|
||||
|
||||
CLEAR;
|
||||
|
||||
printf("\t\t\t This program is a demonstration of the use of the\n"
|
||||
"\t\t\t high level gpm library. It is a tiny application\n"
|
||||
"\t\t\t not really useful, but you may be interested in\n"
|
||||
"\t\t\t reading the source (as well as the docs).\n\n"
|
||||
"\t\t\tWorkings:\n"
|
||||
"\t\t\t You can create windows by clicking on the background\n"
|
||||
"\t\t\t and dragging out the desired size (minimun is 5x3).\n"
|
||||
"\t\t\t The first 20 columns are reserved for messages.\n"
|
||||
"\t\t\t there is always one invisible window on the backgruond\n"
|
||||
"\t\t\t which gets shift-mouse events. All the others are only\n"
|
||||
"\t\t\t sensitive to mouse-only events (the library leaves you\n"
|
||||
"\t\t\t free about that, but this program makes things simple\n"
|
||||
"\n"
|
||||
"\t\t\t The left button raises the window\n"
|
||||
"\t\t\t The middle (if any) lowers the window\n"
|
||||
"\t\t\t The right one destroys the window\n\n"
|
||||
"\t\t\t Keyboard focus is changed by mouse motion\n"
|
||||
"\t\t\t Control-C kills the program\n\n"
|
||||
"\t\t\tEnjoy\n\t\t\t The Author\n\n"
|
||||
);
|
||||
|
||||
/* Ok, now retrieve window info, go to raw mode, and start it all */
|
||||
|
||||
ioctl(fileno(stdin), TIOCGWINSZ, &win);
|
||||
wid=win.ws_col; hei=win.ws_row;
|
||||
vcsize=hei*wid*2+4;
|
||||
dumpbuf=malloc(vcsize); dumpbuf_clean=malloc(vcsize);
|
||||
if (!dumpbuf || ! dumpbuf_clean)
|
||||
{ perror("malloc()"); exit(1); }
|
||||
scrdump(dumpbuf_clean);
|
||||
|
||||
gpm_zerobased=1; gpm_visiblepointer=1;
|
||||
if (Gpm_Open(&conn,0)==-1)
|
||||
{ fprintf(stderr,"%s: Can't open mouse connection\n",argv[0]); exit(1); }
|
||||
|
||||
/* Prepare the leftish roi, and the catch-all on the background */
|
||||
left_cldata.color=0x07; left_cldata.number=0;
|
||||
left_cldata.hei=hei; left_cldata.wid=LEFTWID;
|
||||
Gpm_PushRoi(0,0,LEFTWID-1,hei-1,
|
||||
GPM_DOWN|GPM_DRAG|GPM_UP|GPM_ENTER|GPM_LEAVE,
|
||||
xhandler,&left_cldata);
|
||||
gpm_roi_handler=xhandler;
|
||||
gpm_roi_data=NULL;
|
||||
|
||||
raw();
|
||||
newmsg(0,NULL); /* init data structures */
|
||||
while((c=Gpm_Getchar())!=EOF) {
|
||||
char s[32];
|
||||
Gpm_Roi *roi;
|
||||
|
||||
roi=gpm_current_roi;
|
||||
sprintf(s,"0x%x",c);
|
||||
if (c>0x1f && c<0x7f)
|
||||
sprintf(s+strlen(s)," ('%c')",c);
|
||||
newmsg(roi ? ((WinInfo *)roi->clientdata)->number : 0,s);
|
||||
}
|
||||
|
||||
noraw();
|
||||
exit(0);
|
||||
}
|
||||
488
software/gpm/browse_source/gpm-1.20.6/src/prog/mev.c
Normal file
488
software/gpm/browse_source/gpm-1.20.6/src/prog/mev.c
Normal file
|
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
* mev.c - simple client to print mouse events (gpm-Linux)
|
||||
*
|
||||
* Copyright 1994,1995 rubini@linux.it (Alessandro Rubini)
|
||||
* Copyright (C) 1998 Ian Zimmerman <itz@rahul.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********/
|
||||
|
||||
/*
|
||||
* This client is meant to be used both interactively to check
|
||||
* that gpm is working, and as a background process to convert gpm events
|
||||
* to textual strings. I'm using it to handle Linux mouse
|
||||
* events to emacs
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <linux/keyboard.h> /* to use KG_SHIFT and so on */
|
||||
|
||||
#define ALL_KEY_MODS ((1<<KG_SHIFT)|(1<<KG_ALT)|(1<<KG_ALTGR)|(1<<KG_CTRL))
|
||||
|
||||
#include "headers/message.h" /* messages */
|
||||
#include "headers/gpm.h"
|
||||
|
||||
#define GPM_NAME "gpm"
|
||||
#define GPM_DATE "X-Mas 2002"
|
||||
|
||||
char *prgname;
|
||||
struct node {char *name; int flag;};
|
||||
struct node tableEv[]= {
|
||||
{"move", GPM_MOVE},
|
||||
{"drag", GPM_DRAG},
|
||||
{"down", GPM_DOWN},
|
||||
{"up", GPM_UP},
|
||||
{"press", GPM_DOWN},
|
||||
{"release", GPM_UP},
|
||||
{"motion", GPM_MOVE | GPM_DRAG},
|
||||
{"hard", GPM_HARD},
|
||||
{"any", ~0},
|
||||
{"all", ~0},
|
||||
{"none", 0},
|
||||
{NULL,0}
|
||||
};
|
||||
struct node tableMod[]= {
|
||||
{"shift", 1<<KG_SHIFT},
|
||||
{"anyAlt", 1<<KG_ALT | 1<<KG_ALTGR},
|
||||
{"leftAlt", 1<<KG_ALT},
|
||||
{"rightAlt", 1<<KG_ALTGR},
|
||||
{"control", 1<<KG_CTRL},
|
||||
{"any", ~0},
|
||||
{"all", ~0},
|
||||
{"none", 0},
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
|
||||
/* provide defaults */
|
||||
int opt_mask = ~0; /* get everything */
|
||||
int opt_default = ~GPM_HARD; /* pass everithing unused */
|
||||
int opt_minMod = 0; /* run always */
|
||||
int opt_maxMod = ~0; /* with any modifier */
|
||||
int opt_intrct = 0;
|
||||
int opt_vc = 0; /* by default get the current vc */
|
||||
int opt_emacs = 0;
|
||||
int opt_fit = 0;
|
||||
int opt_pointer = 0;
|
||||
|
||||
/*===================================================================*/
|
||||
int user_handler(Gpm_Event *event, void *data)
|
||||
{
|
||||
if (opt_fit) Gpm_FitEvent(event);
|
||||
|
||||
printf("mouse: event 0x%02X, at %2i,%2i (delta %2i,%2i), "
|
||||
"buttons %i, modifiers 0x%02X\r\n",
|
||||
event->type,
|
||||
event->x, event->y,
|
||||
event->dx, event->dy,
|
||||
event->buttons, event->modifiers);
|
||||
|
||||
if (event->type & (GPM_DRAG|GPM_DOWN)) {
|
||||
if (0 != opt_pointer) {
|
||||
GPM_DRAWPOINTER(event);
|
||||
} /*if*/
|
||||
} /*if*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
int emacs_handler(Gpm_Event *event, void *data)
|
||||
{
|
||||
int i,j;
|
||||
static int dragX, dragY;
|
||||
static char buffer[64];
|
||||
|
||||
/* itz Mon Mar 23 20:54:54 PST 1998 emacs likes the modifier bits in
|
||||
alphabetical order, so I'll use a lookup table instead of a loop; it
|
||||
is faster anyways */
|
||||
/* static char *s_mod[]={"S-","M-","C-","M-",NULL}; */
|
||||
static char *s_mod[] = {
|
||||
"", /* 000 */
|
||||
"S-", /* 001 */
|
||||
"M-", /* 002 */
|
||||
"M-S-", /* 003 */
|
||||
"C-", /* 004 */
|
||||
"C-S-", /* 005 */
|
||||
"C-M-", /* 006 */
|
||||
"C-M-S-", /* 007 */
|
||||
/* idea: maybe we should map AltGr to Emacs Alt instead of Meta? */
|
||||
"M-", /* 010 */
|
||||
"M-S-", /* 011 */
|
||||
"M-", /* 012 */
|
||||
"M-S-", /* 013 */
|
||||
"C-M-", /* 014 */
|
||||
"C-M-S-", /* 015 */
|
||||
"C-M-", /* 016 */
|
||||
"C-M-S-", /* 017 */
|
||||
};
|
||||
/* itz Mon Mar 23 08:23:14 PST 1998 what emacs calls a `drag' event
|
||||
is our `up' event with coordinates different from the `down'
|
||||
event. What gpm calls `drag' is just `mouse-movement' to emacs. */
|
||||
|
||||
static char *s_type[]={"mouse-movement", "mouse-movement","down-mouse-","mouse-",NULL};
|
||||
static char *s_button[]={"3","2","1",NULL};
|
||||
static char *s_multi[]={"double-", "triple-", 0};
|
||||
static char s_count[]="23";
|
||||
char count = '1';
|
||||
struct timeval tv_cur;
|
||||
long timestamp;
|
||||
static long dragTime;
|
||||
|
||||
/* itz Mon Mar 23 08:27:53 PST 1998 this flag is needed because even
|
||||
if the final coordinates of a drag are identical to the initial
|
||||
ones, it is still a drag if there was any movement in between. Sigh. */
|
||||
static int dragFlag = 0;
|
||||
|
||||
gettimeofday(&tv_cur, 0);
|
||||
timestamp = ((short)tv_cur.tv_sec) * 1000 + (tv_cur.tv_usec / 1000);
|
||||
if (opt_fit) Gpm_FitEvent(event);
|
||||
buffer[0]=0;
|
||||
|
||||
/* itz Sun Mar 22 19:09:04 PST 1998 Emacs doesn't understand
|
||||
modifiers on motion events. */
|
||||
if (!(event->type & (GPM_MOVE|GPM_DRAG))) {
|
||||
/* modifiers */
|
||||
strcpy(buffer, s_mod[event->modifiers & ALL_KEY_MODS]);
|
||||
/* multiple */
|
||||
for (i=0, j=GPM_DOUBLE; s_multi[i]; i++, j<<=1)
|
||||
if (event->type & j) {
|
||||
count = s_count[i];
|
||||
strcat(buffer,s_multi[i]);
|
||||
} /*if*/
|
||||
} /*if*/
|
||||
|
||||
if (event->type & GPM_DRAG) {
|
||||
dragFlag = 1;
|
||||
} /*if*/
|
||||
|
||||
/* itz Mon Mar 23 08:26:33 PST 1998 up-event after movement is a drag. */
|
||||
if ((event->type & GPM_UP) && dragFlag) {
|
||||
strcat(buffer, "drag-");
|
||||
} /*if*/
|
||||
|
||||
/* type */
|
||||
for (i=0, j=GPM_MOVE; s_type[i]; i++, j<<=1)
|
||||
if (event->type & j)
|
||||
strcat(buffer,s_type[i]);
|
||||
|
||||
/* itz Sun Mar 22 19:09:04 PST 1998 Emacs doesn't understand
|
||||
modifiers on motion events. */
|
||||
if (!(event->type & (GPM_MOVE|GPM_DRAG)))
|
||||
/* button */
|
||||
for (i=0, j=GPM_B_RIGHT; s_button[i]; i++, j<<=1)
|
||||
if (event->buttons & j)
|
||||
strcat(buffer,s_button[i]);
|
||||
|
||||
if ((event->type & GPM_UP) && dragFlag) {
|
||||
printf("(%s ((%i . %i) %ld) %c ((%i . %i) %ld))\n",
|
||||
buffer,
|
||||
event->x, event->y, timestamp,
|
||||
count,
|
||||
dragX, dragY, dragTime);
|
||||
} else if (event->type & (GPM_DOWN|GPM_UP)) {
|
||||
printf("(%s ((%i . %i) %ld) %c)\n",
|
||||
buffer, event->x, event->y, timestamp, count);
|
||||
} else if (event->type & (GPM_MOVE|GPM_DRAG)) {
|
||||
printf("(%s ((%i . %i) %ld))\n",
|
||||
buffer, event->x, event->y, timestamp);
|
||||
} /*if*/
|
||||
|
||||
if (event->type & GPM_DOWN) {
|
||||
dragX=event->x;
|
||||
dragY=event->y;
|
||||
dragTime=timestamp;
|
||||
dragFlag = 0;
|
||||
} /*if*/
|
||||
|
||||
if (event->type & (GPM_DRAG|GPM_DOWN)) {
|
||||
if (0 == opt_pointer) {
|
||||
GPM_DRAWPOINTER(event);
|
||||
} /*if*/
|
||||
} /*if*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===================================================================*/
|
||||
int usage(void)
|
||||
{
|
||||
//printf( "(" GPM_NAME ") " GPM_RELEASE ", " GPM_DATE "\n"
|
||||
printf( "(" GPM_NAME ") , " GPM_DATE "\n"
|
||||
"Usage: %s [options]\n",prgname);
|
||||
printf(" Valid options are\n"
|
||||
" -C <number> choose virtual console (beware of it)\n"
|
||||
" -d <number> choose the default mask\n"
|
||||
" -e <number> choose the eventMask\n"
|
||||
" -E emacs-mode\n"
|
||||
" -i accept commands from stdin\n"
|
||||
" -f fit drag events inside the screen\n"
|
||||
" -m <number> minimum modifier mask\n"
|
||||
" -M <number> maximum modifier mask\n"
|
||||
" -p show pointer while dragging\n"
|
||||
" -u user-mode (default)\n"
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*===================================================================*/
|
||||
#define PARSE_EVENTS 0
|
||||
#define PARSE_MODIFIERS 1
|
||||
void getmask(char *arg, int which, int* where)
|
||||
{
|
||||
int last=0, value=0;
|
||||
char *cur;
|
||||
struct node *table, *n;
|
||||
int mode = 0; /* 0 = set, 1 = add, 2 = subtract */
|
||||
|
||||
if ('+' == arg[0]) {
|
||||
mode = 1;
|
||||
++arg;
|
||||
} else if ('-' == arg[0]) {
|
||||
mode = 2;
|
||||
++arg;
|
||||
}
|
||||
|
||||
if (isdigit(arg[0])) {
|
||||
switch(mode) {
|
||||
case 0: *where = atoi(arg); break;
|
||||
case 1: *where |= atoi(arg); break;
|
||||
case 2: *where &= ~atoi(arg); break;
|
||||
} /*switch*/
|
||||
return;
|
||||
} /*if*/
|
||||
|
||||
table= (PARSE_MODIFIERS == which) ? tableMod : tableEv;
|
||||
while (1)
|
||||
{
|
||||
while (*arg && !isalnum(*arg)) arg++; /* skip delimiters */
|
||||
cur=arg;
|
||||
while(isalnum(*cur)) cur++; /* scan the word */
|
||||
if (!*cur) last++;
|
||||
*cur=0;
|
||||
|
||||
for (n=table;n->name;n++)
|
||||
if (!strcmp(n->name,arg))
|
||||
{
|
||||
value |= n->flag;
|
||||
break;
|
||||
}
|
||||
if (!n->name) fprintf(stderr,"%s: Incorrect flag \"%s\"\n",prgname,arg);
|
||||
if (last) break;
|
||||
|
||||
cur++; arg=cur;
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case 0: *where = value; break;
|
||||
case 1: *where |= value; break;
|
||||
case 2: *where &= ~value; break;
|
||||
} /*switch*/
|
||||
}
|
||||
|
||||
/*===================================================================*/
|
||||
int cmdline(int argc, char **argv, char *options)
|
||||
{
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, options)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
/* itz Tue Mar 24 17:11:52 PST 1998 i hate options that do
|
||||
too much. Made them orthogonal. */
|
||||
|
||||
case 'C': sscanf(optarg,"%x",&opt_vc); break;
|
||||
case 'd': getmask(optarg, PARSE_EVENTS, &opt_default); break;
|
||||
case 'e': getmask(optarg, PARSE_EVENTS, &opt_mask); break;
|
||||
case 'E': opt_emacs = 1; break;
|
||||
case 'i': opt_intrct=1; break;
|
||||
case 'f': opt_fit=1; break;
|
||||
case 'm': getmask(optarg, PARSE_MODIFIERS, &opt_minMod); break;
|
||||
case 'M': getmask(optarg, PARSE_MODIFIERS, &opt_maxMod); break;
|
||||
case 'p': opt_pointer =1; break;
|
||||
case 'u': opt_emacs=0; break;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
do_snapshot()
|
||||
{
|
||||
Gpm_Event event;
|
||||
int i=Gpm_GetSnapshot(&event);
|
||||
char *s;
|
||||
|
||||
if (-1 == i) {
|
||||
fprintf(stderr,"Warning: cannot get snapshot!\n");
|
||||
fprintf(stderr,"Have you run \"configure\" and \"make install\"?\n");
|
||||
return;
|
||||
} /*if*/
|
||||
|
||||
fprintf(stderr,"Mouse has %d buttons\n",i);
|
||||
fprintf(stderr,"Currently sits at (%d,%d)\n",event.x,event.y);
|
||||
fprintf(stderr,"The window is %d columns by %d rows\n",event.dx,event.dy);
|
||||
s=Gpm_GetLibVersion(&i);
|
||||
fprintf(stderr,"The library is version \"%s\" (%i)\n",s,i);
|
||||
s=Gpm_GetServerVersion(&i);
|
||||
fprintf(stderr,"The daemon is version \"%s\" (%i)\n",s,i);
|
||||
fprintf(stderr,"The current console is %d, with modifiers 0x%02x\n",
|
||||
event.vc,event.modifiers);
|
||||
fprintf(stderr,"The button mask is 0x%02X\n",event.buttons);
|
||||
}
|
||||
|
||||
/*===================================================================*/
|
||||
int interact(char *cmd) /* returns 0 on success and !=0 on error */
|
||||
{
|
||||
Gpm_Connect conn;
|
||||
int argc=0;
|
||||
char *argv[20];
|
||||
|
||||
if (*cmd && cmd[strlen(cmd)-1]=='\n')
|
||||
cmd[strlen(cmd)-1]='\0';
|
||||
if (!*cmd) return 0;
|
||||
|
||||
/*
|
||||
* Interaction is accomplished by building an argv and passing it to
|
||||
* cmdline(), to use the same syntax used to invoke the program
|
||||
*/
|
||||
|
||||
while (argc<19)
|
||||
{
|
||||
while(isspace(*cmd)) cmd++;
|
||||
argv[argc++]=cmd;
|
||||
while (*cmd && isgraph(*cmd)) cmd++;
|
||||
if (!*cmd) break;
|
||||
*cmd=0;
|
||||
cmd++;
|
||||
}
|
||||
argv[argc]=NULL;
|
||||
|
||||
if (!strcmp(argv[0],"pop")) {
|
||||
return (Gpm_Close()==0 ? 1 : 0); /* a different convention on ret values */
|
||||
} /*if*/
|
||||
|
||||
if (!strcmp(argv[0],"info")) {
|
||||
fprintf(stderr,"The stack of connection info is %i depth\n",gpm_flag);
|
||||
return 0;
|
||||
} /*if*/
|
||||
|
||||
if (!strcmp(argv[0],"quit")) {
|
||||
exit(0);
|
||||
} /*if*/
|
||||
|
||||
if (!strcmp(argv[0],"snapshot")) {
|
||||
do_snapshot();
|
||||
return 0;
|
||||
} /*if*/
|
||||
|
||||
optind=0; /* scan the entire line */
|
||||
if (strcmp(argv[0],"push") || cmdline(argc,argv,"d:e:m:M:")) {
|
||||
fprintf(stderr,"Syntax error in input line\n");
|
||||
return 0;
|
||||
} /*if*/
|
||||
|
||||
conn.eventMask=opt_mask;
|
||||
conn.defaultMask=opt_default;
|
||||
conn.maxMod=opt_maxMod;
|
||||
conn.minMod=opt_minMod;
|
||||
|
||||
if (Gpm_Open(&conn,opt_vc)==-1)
|
||||
{
|
||||
fprintf(stderr,"%s: Can't open mouse connection\r\n",argv[0]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===================================================================*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Gpm_Connect conn;
|
||||
char cmd[128];
|
||||
Gpm_Handler* my_handler; /* not the real gpm handler! */
|
||||
fd_set readset;
|
||||
|
||||
prgname=argv[0];
|
||||
|
||||
if (cmdline(argc,argv,"C:d:e:Efim:M:pu")) exit(usage());
|
||||
|
||||
gpm_zerobased = opt_emacs;
|
||||
conn.eventMask=opt_mask;
|
||||
conn.defaultMask=opt_default;
|
||||
conn.maxMod=opt_maxMod;
|
||||
conn.minMod=opt_minMod;
|
||||
|
||||
if (Gpm_Open(&conn,opt_vc) == -1) {
|
||||
gpm_report(GPM_PR_ERR,"%s: Can't open mouse connection\n",prgname);
|
||||
exit(1);
|
||||
} else if (gpm_fd == -2) {
|
||||
gpm_report(GPM_PR_OOPS,"%s: use rmev to see gpm events in xterm or rxvt\n",prgname);
|
||||
}
|
||||
|
||||
gpm_report(GPM_PR_DEBUG,"STILL RUNNING_1");
|
||||
|
||||
my_handler= opt_emacs ? emacs_handler : user_handler;
|
||||
|
||||
/* itz Sun Mar 22 09:51:33 PST 1998 needed in case the output is a pipe */
|
||||
setvbuf(stdout, 0, _IOLBF, 0);
|
||||
setvbuf(stdin, 0, _IOLBF, 0);
|
||||
|
||||
while(1) { /* forever */
|
||||
FD_ZERO(&readset);
|
||||
FD_SET(gpm_fd, &readset);
|
||||
if (opt_intrct) {
|
||||
FD_SET(STDIN_FILENO, &readset);
|
||||
}
|
||||
|
||||
if (select(gpm_fd+1, &readset, 0, 0, 0) < 0 && errno == EINTR)
|
||||
continue;
|
||||
if (FD_ISSET(STDIN_FILENO, &readset)) {
|
||||
if (0 == fgets(cmd, sizeof(cmd), stdin) || interact(cmd)) {
|
||||
exit(0); /* ^D typed on input */
|
||||
} /*if*/
|
||||
} /*if*/
|
||||
if (FD_ISSET(gpm_fd, &readset)) {
|
||||
Gpm_Event evt;
|
||||
if (Gpm_GetEvent(&evt) > 0) {
|
||||
my_handler(&evt, 0);
|
||||
} else {
|
||||
fprintf(stderr, "mev says : Oops, Gpm_GetEvent()\n");
|
||||
}
|
||||
} /*if*/
|
||||
|
||||
} /*while*/
|
||||
|
||||
/*....................................... Done */
|
||||
|
||||
while (Gpm_Close()); /* close all the stack */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
740
software/gpm/browse_source/gpm-1.20.6/src/prog/mouse-test.c
Normal file
740
software/gpm/browse_source/gpm-1.20.6/src/prog/mouse-test.c
Normal file
|
|
@ -0,0 +1,740 @@
|
|||
/*
|
||||
* mouse-test.c
|
||||
*
|
||||
* Copyright 1995 rubini@linux.it (Alessandro Rubini)
|
||||
* Copyright (C) 1998 Ian Zimmerman <itz@rahul.net>
|
||||
* Copyright (C) 2002-2008 Nico Schottelius <nico-gpm2008 at schottelius.org>
|
||||
*
|
||||
* Tue, 5 Jan 1999 23:15:23 +0000, modified by James Troup <james@nocrew.org>:
|
||||
* (main): exclude devices with a minor number of 130 from
|
||||
* the device probe to avoid causing spontaneous reboots on machines
|
||||
* where watchdog is used. Reported by Jim Studt <jim@federated.com>
|
||||
* [Debian bug report #22602]
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********/
|
||||
|
||||
/* This code is horrible. Browse it at your risk */
|
||||
/* hmm..read worse code before :) -nicos */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "headers/message.h" /* to print */
|
||||
#include "headers/gpmInt.h" /* to get mouse types */
|
||||
#include "headers/daemon.h" /* FIXME: do not use that..rewrite mouse-test, anyway */
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ((a)>(b)?(b):(a))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
|
||||
/* this material is needed to pass options to mice.c */
|
||||
struct mouse_features mymouse = {
|
||||
DEF_TYPE, DEF_DEV, DEF_SEQUENCE,
|
||||
DEF_BAUD, DEF_SAMPLE, DEF_DELTA, DEF_ACCEL, DEF_SCALE, DEF_SCALE /*scaley*/,
|
||||
DEF_TIME, DEF_CLUSTER, DEF_THREE, DEF_GLIDEPOINT_TAP,
|
||||
(char *)NULL /* extra */,
|
||||
(Gpm_Type *)NULL,
|
||||
-1 /* fd */
|
||||
};
|
||||
|
||||
/* and this is a workaroud */
|
||||
struct winsize win;
|
||||
/* this too */
|
||||
struct options option;
|
||||
|
||||
struct mouse_features *which_mouse=&mymouse;
|
||||
|
||||
char *progname;
|
||||
char *consolename;
|
||||
int devcount=0;
|
||||
int typecount=0;
|
||||
|
||||
struct item {
|
||||
Gpm_Type *this;
|
||||
struct item *next;
|
||||
};
|
||||
|
||||
struct device {
|
||||
char *name;
|
||||
int fd;
|
||||
struct device *next;
|
||||
};
|
||||
|
||||
static int message(void)
|
||||
{
|
||||
printf("This program is designed to help you in detecting what type your\n"
|
||||
"mouse is. Please follow the instructions of this program. If you're\n"
|
||||
"bored before it is done, you can always press your 'Interrupt' key\n"
|
||||
"(usually Ctrl-C)\n\n");
|
||||
printf("\t *** Remember: don't run any software which reads the mouse device\n"
|
||||
"\t *** while making this test. This includes \"gpm\","
|
||||
"\"selection\", \"X\"\n\n");
|
||||
printf("Note that this program is by no means complete, and its main role is\n"
|
||||
"to detect how does the middle button work on serial mice\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* I don't like curses, so I'm doing low level stuff here */
|
||||
|
||||
#define GOTOXY(f,x,y) fprintf(f,"\x1B[%03i;%03iH",y,x)
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Place the description here.
|
||||
-----------------------------------------------------------------------------*/
|
||||
static void raw(void)
|
||||
{
|
||||
struct termios it;
|
||||
|
||||
tcgetattr(fileno(stdin),&it);
|
||||
it.c_lflag &= ~(ICANON);
|
||||
it.c_lflag &= ~(ECHO);
|
||||
it.c_iflag &= ~(INPCK|ISTRIP|IXON);
|
||||
it.c_oflag &= ~(OPOST);
|
||||
it.c_cc[VMIN] = 1;
|
||||
it.c_cc[VTIME] = 0;
|
||||
|
||||
tcsetattr(fileno(stdin),TCSANOW,&it);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Place the description here.
|
||||
-----------------------------------------------------------------------------*/
|
||||
static void noraw(void)
|
||||
{
|
||||
struct termios it;
|
||||
|
||||
tcgetattr(fileno(stdin),&it);
|
||||
it.c_lflag |= ICANON;
|
||||
it.c_lflag |= ECHO;
|
||||
it.c_iflag |= IXON;
|
||||
it.c_oflag |= OPOST;
|
||||
|
||||
tcsetattr(fileno(stdin),TCSANOW,&it);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Place the description here.
|
||||
-----------------------------------------------------------------------------*/
|
||||
void killed(int signo)
|
||||
{
|
||||
fprintf(stderr,"mouse-test: killed by signal %i\r\n",signo);
|
||||
noraw();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Place the description here.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct device **gpm_makedev(struct device **current, char *name)
|
||||
{
|
||||
int fd; int modes;
|
||||
if ((fd=open(name,O_RDWR|O_NONBLOCK))==-1) {
|
||||
perror(name);
|
||||
return current;
|
||||
}
|
||||
modes = fcntl(fd, F_GETFL);
|
||||
if (0 > fcntl(fd, F_SETFL, modes & ~O_NONBLOCK)) {
|
||||
close(fd);
|
||||
perror(name);
|
||||
return current;
|
||||
}
|
||||
|
||||
*current=malloc(sizeof(struct device));
|
||||
if (!*current) gpm_report(GPM_PR_OOPS,"malloc()");
|
||||
(*current)->name=strdup(name);
|
||||
if (!(*current)->name) gpm_report(GPM_PR_OOPS,"malloc()");
|
||||
(*current)->fd=fd;
|
||||
(*current)->next=NULL;
|
||||
devcount++;
|
||||
return &((*current)->next);
|
||||
}
|
||||
|
||||
Gpm_Type *(*I_serial)(int fd, unsigned short flags, struct Gpm_Type *type,
|
||||
int argc, char **argv);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Place the description here.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int mousereopen(int oldfd, char *name, Gpm_Type *type)
|
||||
{
|
||||
int fd;
|
||||
if (!type) type=mice+1; /* ms */
|
||||
close(oldfd);
|
||||
usleep(100000);
|
||||
fd=open(name,O_RDWR);
|
||||
if (fd < 0) gpm_report(GPM_PR_OOPS,name);
|
||||
(*I_serial)(fd,type->flags,type,1,&type->name); /* ms initialization */
|
||||
return fd;
|
||||
}
|
||||
|
||||
int noneofthem(void)
|
||||
{
|
||||
noraw();
|
||||
printf("\n\nSomething went wrong, I didn't manage to detect your"
|
||||
"protocol\n\nFeel free to report your problems to the author\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define CHECKFAIL(count) ((count)==0 && noneofthem())
|
||||
|
||||
/***************************************
|
||||
* This is the most useful function in
|
||||
* the program: it build an array
|
||||
* of data characters in order to run
|
||||
* several protocols on the returned
|
||||
* data.
|
||||
*/
|
||||
|
||||
int eventlist(int fd, char *buff, int buflen, int test, int readstep)
|
||||
{
|
||||
fd_set selSet, readySet;
|
||||
struct timeval to;
|
||||
int active=0;
|
||||
int pending;
|
||||
int got=0;
|
||||
|
||||
FD_ZERO(&readySet);
|
||||
FD_SET(fd,&readySet);
|
||||
FD_SET(fileno(stdin),&readySet);
|
||||
to.tv_sec=to.tv_usec=0;
|
||||
|
||||
switch(test) {
|
||||
case GPM_B_LEFT:
|
||||
printf("\r\nNow please press and release several times\r\n"
|
||||
"the left button of your mouse,"
|
||||
" *** trying not to move it ***\r\n\r\n");
|
||||
break;
|
||||
|
||||
case GPM_B_MIDDLE:
|
||||
printf("\r\nNow please press and release several times\r\n"
|
||||
"the middle button of your mouse,"
|
||||
" *** trying not to move it ***\r\n\r\n");
|
||||
break;
|
||||
|
||||
case 0:
|
||||
printf("\r\nNow please move the mouse around, without pressing any\r\n"
|
||||
"button. Move it both quickly and slowly\r\n\r\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown test to perform\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Press any key when you've done enough\r\n");
|
||||
|
||||
while(1) {
|
||||
selSet=readySet;
|
||||
if ((pending=select(fd+1,&selSet,NULL,NULL,&to)) < 0) continue;
|
||||
if (pending==0 && !active) {
|
||||
active++;
|
||||
to.tv_sec=10;
|
||||
continue;
|
||||
}
|
||||
if (pending==0) return got; /* timeout */
|
||||
|
||||
if (FD_ISSET(0,&selSet)) {
|
||||
getchar();
|
||||
if (active) return got;
|
||||
}
|
||||
if (FD_ISSET(fd,&selSet)) {
|
||||
if (active) got+=read(fd,buff+got,readstep);
|
||||
else read(fd,buff,buflen);
|
||||
}
|
||||
if (got>buflen-readstep)
|
||||
readstep=buflen-got;
|
||||
if (readstep==0)
|
||||
got--,readstep++; /* overwrite last char forever */
|
||||
|
||||
to.tv_sec=30;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Place the description here.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct item *list=NULL;
|
||||
struct item **nextitem;
|
||||
struct device *devlist=NULL;
|
||||
struct device **nextdev;
|
||||
Gpm_Type *cursor;
|
||||
int i, mousefd;
|
||||
char *mousename;
|
||||
#define BUFLEN 512
|
||||
char buf[BUFLEN];
|
||||
struct timeval timeout;
|
||||
fd_set checkSet;
|
||||
int pending, maxfd;
|
||||
int trial, readamount,packetsize,got;
|
||||
int baudtab[4]={1200,9600,4800,2400};
|
||||
#define BAUD(i) (baudtab[(i)%4])
|
||||
consolename = Gpm_get_console();
|
||||
|
||||
if (!isatty(fileno(stdin))) {
|
||||
fprintf(stderr,"%s: stdin: not a tty\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
progname=argv[0];
|
||||
message();
|
||||
|
||||
/* init the list of possible devices */
|
||||
|
||||
for (nextdev=&devlist, i=1; i<argc; i++)
|
||||
nextdev=gpm_makedev(nextdev,argv[i]);
|
||||
|
||||
if (argc==1) { /* no cmdline, get all devices */
|
||||
FILE *f;
|
||||
char s[64];
|
||||
|
||||
/* Skip 10, 130 (== watchdog) to avoid causing spontaneous reboots */
|
||||
f=popen("ls -l /dev/* | "
|
||||
"awk '/^c/ && $5==\"10,\" && $6!=\"130\" || $NF ~ \"ttyS[0-3]$\" {print $NF}'",
|
||||
"r");
|
||||
if (!f) gpm_report(GPM_PR_OOPS,"popen()");
|
||||
while (fgets(s,64,f)) {
|
||||
s[strlen(s)-1]='\0'; /* trim '\n' */
|
||||
nextdev=gpm_makedev(nextdev,s);
|
||||
}
|
||||
pclose(f);
|
||||
}
|
||||
|
||||
if (devcount==0) {
|
||||
fprintf(stderr,"%s: no devices found\n",progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
I_serial=mice->init; /* the first one has I_serial */
|
||||
|
||||
signal(SIGINT,killed); /* control-C kills us */
|
||||
raw();
|
||||
|
||||
/*====================================== First of all, detect the device */
|
||||
|
||||
trial=0;
|
||||
while (devcount > 1) {
|
||||
fd_set devSet, gotSet,savSet;
|
||||
struct device *cur;
|
||||
int gotthem;
|
||||
|
||||
/* BUG */ /* Logitech initialization is not performed */
|
||||
|
||||
(which_mouse->opt_baud)=BAUD(trial);
|
||||
printf("\r\nTrying with %i baud\r\n",(which_mouse->opt_baud));
|
||||
trial++;
|
||||
|
||||
FD_ZERO(&devSet); FD_ZERO(&gotSet);
|
||||
FD_SET(fileno(stdin),&devSet); maxfd=fileno(stdin);
|
||||
printf("\r\n The possible device nodes are:\r\n");
|
||||
for (nextdev=&devlist; *nextdev; nextdev=&((*nextdev)->next)) {
|
||||
printf("\t%s\r\n", (*nextdev)->name);
|
||||
FD_SET((*nextdev)->fd,&devSet);
|
||||
maxfd=max((*nextdev)->fd,maxfd);
|
||||
(*I_serial)((*nextdev)->fd,(mice+1)->flags,mice+1,
|
||||
1, &(mice+1)->name); /* try ms mode */
|
||||
}
|
||||
|
||||
savSet=devSet;
|
||||
|
||||
printf("\r\n\r\nI've still %i devices which may be your mouse,\r\n",
|
||||
devcount);
|
||||
printf("Please move the mouse. Press any key when done\r\n"
|
||||
" (You can specify your device name on cmdline, in order to\r\n"
|
||||
" avoid this step\r\n. Different baud rates are tried at "
|
||||
"different times\r\n");
|
||||
|
||||
timeout.tv_sec=10; /* max test time */
|
||||
gotthem=0;
|
||||
while (1) { /* extract files from the list */
|
||||
devSet=savSet;
|
||||
if ((pending=select(maxfd+1,&devSet,NULL,NULL,&timeout)) < 0)
|
||||
continue;
|
||||
if (pending==0 || FD_ISSET(fileno(stdin),&devSet)) {
|
||||
getchar();
|
||||
break;
|
||||
}
|
||||
for (nextdev=&devlist; *nextdev; nextdev=&((*nextdev)->next))
|
||||
if (FD_ISSET((*nextdev)->fd,&devSet)) {
|
||||
gotthem++;
|
||||
FD_CLR((*nextdev)->fd,&savSet);
|
||||
FD_SET((*nextdev)->fd,&gotSet);
|
||||
}
|
||||
}
|
||||
if (gotthem) for (nextdev=&devlist; *nextdev; /* nothing */ ) {
|
||||
cur=*nextdev;
|
||||
if (!FD_ISSET(cur->fd,&gotSet)) {
|
||||
printf("removing \"%s\" from the list\r\n",cur->name);
|
||||
*nextdev=cur->next;
|
||||
close(cur->fd);
|
||||
free(cur->name);
|
||||
free(cur);
|
||||
devcount--;
|
||||
} else {
|
||||
read(cur->fd,buf,80); /* flush */
|
||||
nextdev=&(cur->next); /* follow list */
|
||||
}
|
||||
}
|
||||
|
||||
} /* devcount>1 */
|
||||
|
||||
mousefd=devlist->fd;
|
||||
mousename=devlist->name;
|
||||
free(devlist);
|
||||
printf("\r\nOk, so your mouse device is \"%s\"\r\n",mousename);
|
||||
|
||||
/* now close and reopen it, complete with initialization */
|
||||
(which_mouse->opt_baud)=BAUD(0);
|
||||
mousefd=mousereopen(mousefd,mousename,NULL);
|
||||
|
||||
FD_ZERO(&checkSet);
|
||||
FD_SET(mousefd,&checkSet);
|
||||
FD_SET(fileno(stdin),&checkSet);
|
||||
maxfd=max(mousefd,fileno(stdin));
|
||||
|
||||
/*====================================== Identify mouse type */
|
||||
|
||||
/* init the list of possible types */
|
||||
|
||||
printf("\r\n\r\nThe possible mouse types are:\r\n");
|
||||
for (nextitem=&list, cursor=mice; cursor->fun; cursor++) {
|
||||
if (cursor->absolute) continue;
|
||||
*nextitem=malloc(sizeof(struct item));
|
||||
if (!*nextitem) gpm_report(GPM_PR_OOPS,"malloc()");
|
||||
(*nextitem)->this=cursor; (*nextitem)->next=NULL;
|
||||
printf("\t%s",cursor->name);
|
||||
if (cursor->synonyms && cursor->synonyms[0])
|
||||
printf(" (%s)",cursor->synonyms);
|
||||
printf("\r\n");
|
||||
typecount++;
|
||||
nextitem=&((*nextitem)->next);
|
||||
}
|
||||
|
||||
/*====================================== Packet size - first step */
|
||||
|
||||
printf("\r\nNow please press and release your left mouse button,\r\n"
|
||||
"one time only\r\n\r\n");
|
||||
|
||||
i=read(mousefd,buf,1);
|
||||
if (i==-1 && errno==EINVAL)
|
||||
readamount=3;
|
||||
else
|
||||
readamount=1;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
#define REMOVETYPE(cur,reason) \
|
||||
do { \
|
||||
printf("\tRemoving type \"%s\" because of '%s'\r\n", \
|
||||
(cur)->this->name,reason); \
|
||||
(*nextitem)=(cur)->next; \
|
||||
free(cur); \
|
||||
typecount--; \
|
||||
} while(0)
|
||||
|
||||
|
||||
for (nextitem=&list; *nextitem; /* nothing */) {
|
||||
struct item *cur=*nextitem;
|
||||
|
||||
if (readamount!=cur->this->howmany)
|
||||
REMOVETYPE(cur,"different read() semantics");
|
||||
else
|
||||
nextitem=&(cur->next);
|
||||
}
|
||||
read(mousefd,buf,BUFLEN); /* flush */
|
||||
|
||||
/*====================================== Packet size - second step */
|
||||
|
||||
printf("\r\nNow you will be asked to generate different kind of events,\r\n"
|
||||
"in order to understand what protocol is your mouse speaking\r\n");
|
||||
|
||||
if (readamount==1) readamount=10;
|
||||
/*
|
||||
* Otherwise, the packetsize is already known, but the different decoding
|
||||
* alghorithm allows for further refinement.
|
||||
*/
|
||||
|
||||
packetsize=1;
|
||||
trial=0;
|
||||
while (packetsize==1) {
|
||||
int success3=0,success5=0;
|
||||
|
||||
(which_mouse->opt_baud)=BAUD(trial);
|
||||
printf("\tBaud rate is %i\r\n",(which_mouse->opt_baud));
|
||||
mousefd=mousereopen(mousefd,mousename,NULL);
|
||||
|
||||
printf("\r\n==> Detecting the packet size\r\n");
|
||||
got=eventlist(mousefd,buf,BUFLEN,GPM_B_LEFT,readamount);
|
||||
|
||||
/* try three -- look at repeating arrays of 6 bytes */
|
||||
for (i=0;i<got-12;i++)
|
||||
if(!memcmp(buf+i,buf+i+6,6))
|
||||
success3++;
|
||||
|
||||
/* try five -- look at repeating arrays of 10 bytes */
|
||||
for (i=0;i<got-20;i++)
|
||||
if(!memcmp(buf+i,buf+i+10,10))
|
||||
success5++;
|
||||
|
||||
printf("matches for 3 bytes: %i -- matches for 5 bytes: %i\r\n",
|
||||
success3,success5);
|
||||
if (success3>5 && success5==0)
|
||||
packetsize=3;
|
||||
if (success5>5 && success3==0)
|
||||
packetsize=5;
|
||||
if (packetsize==1)
|
||||
printf("\r\n ** Ambiguous, try again\r\n");
|
||||
trial++;
|
||||
}
|
||||
|
||||
/*====================================== Use that info to discard protocols */
|
||||
|
||||
for (nextitem=&list; *nextitem; /* nothing */) {
|
||||
struct item *cur=*nextitem;
|
||||
int packetheads=0;
|
||||
int match=0;
|
||||
Gpm_Event event;
|
||||
|
||||
if (packetsize!=cur->this->packetlen) {
|
||||
REMOVETYPE(cur,"different packet lenght");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* try to decode button press and release */
|
||||
for (i=0;i<got;i++) {
|
||||
if ( ((buf[i] &(cur->this->proto)[0]) == (cur->this->proto)[1])
|
||||
&& ((buf[i+1]&(cur->this->proto)[2]) == (cur->this->proto)[3]) ) {
|
||||
packetheads++;
|
||||
if ((*(cur->this->fun))(&event,buf+i)==-1) {
|
||||
packetheads--;
|
||||
continue;
|
||||
}
|
||||
i+=packetsize-1; /* skip packet */
|
||||
if (event.dx || event.dy) continue;
|
||||
if (event.buttons==GPM_B_LEFT)
|
||||
match++;
|
||||
else if (event.buttons)
|
||||
match--;
|
||||
}
|
||||
}
|
||||
if (match<=0) {
|
||||
REMOVETYPE(cur,"incorrect button detected");
|
||||
continue;
|
||||
}
|
||||
if (packetheads<got/(packetsize+2)) {
|
||||
REMOVETYPE(cur,"too few events got decoded");
|
||||
continue;
|
||||
}
|
||||
printf("** type '%s' still possible\r\n",cur->this->name);
|
||||
nextitem=&(cur->next);
|
||||
}
|
||||
|
||||
/*====================================== It's all done? */
|
||||
|
||||
/*
|
||||
* At this point, msc, would be unique (and 3-button aware) due to the
|
||||
* packet size; sun,mm and ps2 would be unique due to the different
|
||||
* representation of buttons (and they usually are not dual mode).
|
||||
*/
|
||||
|
||||
/* why checking and not using return value ??? */
|
||||
CHECKFAIL(typecount);
|
||||
if (typecount==1) {
|
||||
noraw();
|
||||
printf("\n\n\nWell, it seems like your mouse is already detected:\n"
|
||||
"it is on the device \"%s\", and speaks the protocol \"%s\"\n",
|
||||
mousename,list->this->name);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If it is in the "ms" family, however, three possibilities are still
|
||||
* there, and all of them depend on the middle button
|
||||
*/
|
||||
|
||||
do {
|
||||
printf("\r\nYour mouse is one of the ms family, "
|
||||
"but do you have the middle button (y/n)? ");
|
||||
putchar(i=getchar()); printf("\r\n");
|
||||
} while(i!='y' && i!='n');
|
||||
|
||||
if (i=='n') {
|
||||
noraw();
|
||||
printf("\nThen, you should use the \"bare\" protocol on \"%s\"\n",
|
||||
mousename);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* First trial: remove the "-t ms" extension if spurious buttons come in
|
||||
*/
|
||||
|
||||
got=eventlist(mousefd,buf,BUFLEN,0,readamount);
|
||||
pending=0;
|
||||
for (nextitem=&list; *nextitem; /* nothing */) {
|
||||
struct item *cur=*nextitem;
|
||||
Gpm_Event event;
|
||||
|
||||
/* try to decode button press and release */
|
||||
for (i=0;i<got;i++) {
|
||||
if ( ((buf[i] &(cur->this->proto)[0]) == (cur->this->proto)[1])
|
||||
&& ((buf[i+1]&(cur->this->proto)[2]) == (cur->this->proto)[3]) ) {
|
||||
if ((*(cur->this->fun))(&event,buf+i)==-1) continue;
|
||||
i+=packetsize-1;
|
||||
if (event.buttons) pending--;
|
||||
}
|
||||
}
|
||||
if (pending<0) {
|
||||
REMOVETYPE(cur,"spurious button reported");
|
||||
continue;
|
||||
}
|
||||
printf("** type '%s' still possible\r\n",cur->this->name);
|
||||
nextitem=&(cur->next);
|
||||
}
|
||||
CHECKFAIL(typecount);
|
||||
|
||||
/*
|
||||
* Second trial: look if it is one of the two mman ways (In the second
|
||||
* test, extended ms is caught as well
|
||||
*/
|
||||
|
||||
printf("\r\n==> Looking for '-t mman'and enhanced ms\r\n");
|
||||
mousefd=mousereopen(mousefd,mousename, mice /* mman */);
|
||||
got=eventlist(mousefd,buf,BUFLEN,GPM_B_MIDDLE,readamount);
|
||||
|
||||
/* if it uses the 4-byte protocol, find it in a rude way */
|
||||
for (pending=0,i=0;i<got-16;i++)
|
||||
if(!memcmp(buf+i,buf+i+8,8)) pending++;
|
||||
if (pending > 3) {
|
||||
noraw();
|
||||
printf("\nYour mouse seems to be a 'mman' one on \"%s\" (%i matches)\n",
|
||||
mousename,pending);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pending=0;
|
||||
for (nextitem=&list; *nextitem; /* nothing */) {
|
||||
struct item *cur=*nextitem;
|
||||
Gpm_Event event;
|
||||
|
||||
/* try to decode button press and release */
|
||||
for (i=0;i<got;i++) {
|
||||
if ( ((buf[i] &(cur->this->proto)[0]) == (cur->this->proto)[1])
|
||||
&& ((buf[i+1]&(cur->this->proto)[2]) == (cur->this->proto)[3]) ) {
|
||||
if ((*(cur->this->fun))(&event,buf+i)==-1) continue;
|
||||
i+=packetsize-1;
|
||||
if (event.buttons && event.buttons!=GPM_B_MIDDLE) pending--;
|
||||
if (event.buttons==GPM_B_MIDDLE) pending++;
|
||||
}
|
||||
}
|
||||
if (pending<0) {
|
||||
REMOVETYPE(cur,"spurious button reported");
|
||||
continue;
|
||||
}
|
||||
if (pending>3) {
|
||||
noraw();
|
||||
printf("\nYour mouse seems to be a '%s' one on \"%s\" (%i matches)\n",
|
||||
cur->this->name,mousename,pending);
|
||||
exit(0);
|
||||
}
|
||||
printf("** type '%s' still possible\r\n",cur->this->name);
|
||||
nextitem=&(cur->next);
|
||||
}
|
||||
CHECKFAIL(typecount);
|
||||
|
||||
/*
|
||||
* Then, try to toggle dtr and rts
|
||||
*/
|
||||
|
||||
{
|
||||
int toggle[3]={TIOCM_DTR|TIOCM_RTS, TIOCM_DTR,TIOCM_RTS};
|
||||
char *tognames[3]={"both","dtr","rts"};
|
||||
char *Xtognames[3]={"'ClearDTR' and 'ClearRTS'","'ClearDTR'","'ClearRTS'"};
|
||||
int alllines,lines, index;
|
||||
|
||||
ioctl(mousefd, TIOCMGET, &alllines);
|
||||
|
||||
printf("\r\nSome mice change protocol to three-buttons-aware if some\r\n"
|
||||
"\r\ncontrol lines are toggled after opening\r\n");
|
||||
for (index=0;index<3;index++) {
|
||||
mousereopen(mousefd,mousename,NULL);
|
||||
lines = alllines & ~toggle[index];
|
||||
ioctl(mousefd, TIOCMSET, &lines);
|
||||
printf("\r\n==> Trying with '-o %s'\r\n",tognames[index]);
|
||||
got=eventlist(mousefd,buf,BUFLEN,GPM_B_MIDDLE,readamount);
|
||||
|
||||
/* if it uses the 5-byte protocol, find it in a rude way */
|
||||
for (pending=0,i=0;i<got-20;i++)
|
||||
if(!memcmp(buf+i,buf+i+10,10)) pending++;
|
||||
if (pending>3) {
|
||||
noraw();
|
||||
printf("\nYour mouse becomes a 3-buttons ('-t msc') one when\n"
|
||||
"gpm gets '-o %s' on it command line, and X gets\n"
|
||||
"%s in XF86Config\nThe device is \"%s\"",
|
||||
tognames[index],Xtognames[index],mousename);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* still here? Then, the only resort is keeping the middle button
|
||||
* pressed while initializing the mouse
|
||||
*/
|
||||
|
||||
printf("\r\nYour damned device doesn't respond to anything\r\n"
|
||||
"the only remaining possibility is to keep presses the middle\r\n"
|
||||
"button _while_the_mouse_is_being_opened. This is the worst thing\r\n"
|
||||
"ever thought after caps-lock-near-the-A\r\n");
|
||||
|
||||
printf("\r\nNow please press the middle button, and then press any key\r\n"
|
||||
"while keeping the button down. Wait to release it until the\r\n"
|
||||
"next message.\r\n");
|
||||
|
||||
getchar();
|
||||
|
||||
got=eventlist(mousefd,buf,BUFLEN,GPM_B_MIDDLE,readamount);
|
||||
|
||||
/* if it uses the 5-byte protocol, find it in a rude way */
|
||||
for (pending=0,i=0;i<got-20;i++)
|
||||
if(!memcmp(buf+i,buf+i+10,10)) pending++;
|
||||
if (pending>3) {
|
||||
noraw();
|
||||
printf("\nWorked. You should keep the button pressed every time the\n"
|
||||
"computer boots, and run gpm in '-R' mode in order to ignore\n"
|
||||
"such hassle when starting X\n\nStill better, but a better mouse\n"
|
||||
"\nThe current mouse device is \"%s\"\n",mousename);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
noraw();
|
||||
printf("\nI'm lost. Can't tell you how to use your middle button\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* general purpose mouse (gpm)
|
||||
*
|
||||
* Copyright (c) 2008 Nico Schottelius <nico-gpm2008 at schottelius.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
********/
|
||||
|
||||
#include "headers/message.h" /* messaging in gpm */
|
||||
#include "headers/daemon.h" /* daemon internals */
|
||||
#include <fcntl.h>
|
||||
|
||||
int open_console(const int mode)
|
||||
{
|
||||
int fd;
|
||||
if ((fd = open(option.consolename, mode)) < 0)
|
||||
gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN, option.consolename);
|
||||
return fd;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue