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
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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue