Several code changes here: 1) eliminate irrelevant or deprecated

imwheel options; 2) add support for more than 9 buttons; and 3) grab a few
upstream changes that were never released.
Last-Update: 2010-02-20

Gbp-Pq: Name support-more-buttons
This commit is contained in:
Thomas Liebetraut thomas@tommie-lie.de and Christopher Martin 2022-05-14 03:32:58 +08:00 committed by openKylinBot
parent 9663f34954
commit 940d478dcb
3 changed files with 120 additions and 57 deletions

View File

@ -59,22 +59,18 @@ const struct option options[]=
//{"restart", 0, 0, 'R'}, //not used by users!
{"root-window", 0, 0, 'r'},
{"quit", 0, 0, 'q'},
{"sensitivity", 1, 0, 's'},
{"threshhold", 1, 0, 't'},
{"version", 0, 0, 'v'},
{"wheel-fifo", 2, 0, 'W'},
{"transpose", 0, 0, 'x'},
{0, 0, 0, 0}
};
const char *optionusage[][2]=
{ /*{argument name, usage}*/
{"delay-rate", "auto repeat until button release (default=250)"}, //a
{"grab-buttons", "Specify up to 6 remappings 0=none (default=456789)"}, //b
{"grab-buttons", "Specify button remappings (default=\"4 5 6 7 8 9\", 0=skip)"},//b
{NULL, "Open configuration helper window imediately"}, //c
{NULL, "Spit out all debugging info (it's a lot!)"}, //D
{NULL, "IMWHeel process doesn't detach from terminal"}, //d
{"display-name", "Sets X display to use (one per FIFO if FIFO used)"}, //X
{NULL, "Swaps buttons 4 and 5 events (same as -b 54"}, //4
{"display-name", "Sets X display to use"}, //X
{NULL, "Swaps buttons 4 and 5 events (same as -b \"5 4\")"}, //4
{NULL, "Use event subwindow instead of XGetInputFocus"}, //f
{NULL, "Disable the use of Focus Events for button grabs"}, //g
{NULL, "For this help! Now you know"}, //h
@ -84,11 +80,7 @@ const char *optionusage[][2]=
//{NULL, "RESERVED: used when imwheel reloads itself"}, //R
{NULL, "Allow wheeling in the root window (no cfg dialog)"}, //r
{NULL, "Don't start imwheel process, after args"}, //q
{"sum-min", "Stick devices require this much total movment (w/fifo)"}, //s
{"stick-min", "Stick devices require this much pressure (w/fifo)"}, //t
{NULL, "Show version info and exit"}, //v
{"fifo-path", "Use a GPM fifo instead of XGrabButton"}, //W
{NULL, "swap X and Y stick axis (w/fifo)"}, //x
{NULL, NULL}
};
int buttonFlip=False, useFifo=False, detach=True, quit=False,
@ -108,6 +100,7 @@ int main(int argc, char **argv)
getOptions(argc,argv,opts,options);
setupstatebits();
setupbuttonnames();
if(!displayName)
displayName=XDisplayName(NULL);
Printf("display=%s\n",displayName);
@ -137,7 +130,7 @@ void grabButtons(Display *d, Window w)
return;
Printf("Grab buttons!\n");
grabbed=True;
for(i=0;i<NUM_BUTTONS;i++)
for(i=0;i<buttons_cnt;i++)
{
if(buttons[i])
{
@ -168,7 +161,7 @@ void ungrabButtons(Display *d, Window w)
Printf("Ungrab buttons!\n");
XSync(d,False);
grabbed=False;
for(i=0;i<NUM_BUTTONS;i++)
for(i=0;i<buttons_cnt;i++)
{
if(buttons[i])
{
@ -331,7 +324,7 @@ signed char getInput(Display *d, XEvent *e, XModifierKeymap **xmk, signed char k
{
//e->xbutton.button^=buttonFlip;
button= buttonIndex(e->xbutton.button);
if(button<NUM_BUTTONS)
if(button<buttons_cnt)
e->xbutton.button= button= button+4;
XQueryKeymap(d,km);
if(debug)
@ -635,9 +628,9 @@ void eventLoop(Display *d, char **argv)
int k;
j=button-4;
if(j>=NUM_BUTTONS)
if(j>=buttons_cnt)
{
Printf("No we aren't because j(%d) is >= NUM_BUTTONS(%d)!\n",j,NUM_BUTTONS);
Printf("No we aren't because j(%d) is >= NUM_BUTTONS(%d)!\n",j,buttons_cnt);
break;
}
k=statebits[makeModMask(xmk,km)&STATE_MASK];
@ -647,6 +640,11 @@ void eventLoop(Display *d, char **argv)
break;
}
// simply cut off all new buttons and map the odd ones to "Thumb1" and
// the even ones to "Thumb2"
if (j>NUM_STDCOMMANDS) // we have NUM_STDCOMMANDS standard actions
j = 5 - (j % 2); // all odds become a 4, all evens a 5
out[0]=(char*)keys[j][k];
wa.reps=reps[k];
doWA(d,(XButtonEvent*)&e.xbutton,xmk,km,&wa);

137
util.c
View File

@ -9,6 +9,7 @@
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <regex.h>
@ -51,15 +52,9 @@
typedef void (*sighandler_t)(int);
int buttons[NUM_BUTTONS+1]={4,5,6,7,8,9,0};
const char *button_names[]={
"Up",
"Down",
"Left",
"Right",
"Thumb1",
"Thumb2"
};
int *buttons = NULL;
int buttons_cnt = 0;
char *(*button_names)[] = NULL;
int statebits[STATE_MASK+1];
char *wname=NULL;
XClassHint xch={NULL,NULL};
@ -92,7 +87,7 @@ const int reps[1<<NUM_STATES]=
20, // ControlMask|Mod1Mask
50 //ShiftMask|ControlMask|Mod1Mask
};
const char *keys[NUM_BUTTONS][1<<NUM_STATES]=
const char *keys[NUM_STDCOMMANDS][1<<NUM_STATES]=
{
{
"Page_Up", //None
@ -184,6 +179,43 @@ void setupstatebits()
/*----------------------------------------------------------------------------*/
void setupbuttonnames()
{
char buf[10 + 5 + 1]; // strlen(2^31=2147483648) + strlen("ExtBt") + NULL
int i;
// allocate enough memory (buttons_cnt should be known by now)
Printf("Allocating %d names\n", buttons_cnt);
button_names = malloc(buttons_cnt * sizeof(char *) + 1000);
// we have the 6 legacy buttons, but only as many as the user has declared
switch ((buttons_cnt<=6)?buttons_cnt:6)
{
case 6:
(*button_names)[5] = "Thumb2";
case 5:
(*button_names)[4] = "Thumb1";
case 4:
(*button_names)[3] = "Right";
case 3:
(*button_names)[2] = "Left";
case 2:
(*button_names)[1] = "Down";
case 1:
(*button_names)[0] = "Up";
break;
}
// add the remaining extended buttons
for (i=6; i<buttons_cnt; i++)
{
snprintf(buf, 16, "ExtBt%d", i +1);
(*button_names)[i] = malloc(strlen(buf)+1);
strcpy((*button_names)[i], buf);
}
}
/*----------------------------------------------------------------------------*/
RETSIGTYPE exitParent(int num)
{
exit(0);
@ -196,11 +228,11 @@ int isUsedButton(int b)
int i;
Printf("isUsedButton(%d)=",b);
for(i=0;i<NUM_BUTTONS;i++)
for(i=0;i<buttons_cnt;i++)
if(buttons[i]==b)
break;
Printf("%s\n",i<NUM_BUTTONS?"yes":"no");
return i<NUM_BUTTONS;
Printf("%s\n",i<buttons_cnt?"yes":"no");
return i<buttons_cnt;
}
/*----------------------------------------------------------------------------*/
@ -209,10 +241,10 @@ int buttonIndex(int b)
{
int i;
for(i=0;i<NUM_BUTTONS;i++)
for(i=0;i<buttons_cnt;i++)
if(buttons[i]==b)
return(i);
return(NUM_BUTTONS);
return(buttons_cnt);
}
/*----------------------------------------------------------------------------*/
@ -220,6 +252,8 @@ int buttonIndex(int b)
void getOptions(int argc, char **argv, char *opts, const struct option *options)
{
int ch,i,j,killold=False,invalidOpts=False;
char *ButtonOpt = NULL;
while((ch=getopt_long_only(argc,argv,opts,options,&i))>=0)
{
@ -296,6 +330,16 @@ void getOptions(int argc, char **argv, char *opts, const struct option *options)
exit(0);
break;
case 'b':
for (j = 0; j < strlen(optarg); j++)
if (optarg[j] == ' ')
buttons_cnt++;
buttons_cnt++;
buttons = malloc(sizeof(int) * buttons_cnt);
ButtonOpt = strtok(optarg, " ");
for(j = 0; ButtonOpt != NULL; ButtonOpt = strtok(NULL, " "), j++)
buttons[j] = atoi(ButtonOpt);
/*
memset(buttons,0,NUM_BUTTONS*sizeof(int));
for(j=0;optarg[j] && j<NUM_BUTTONS;j++)
{
@ -306,6 +350,7 @@ void getOptions(int argc, char **argv, char *opts, const struct option *options)
}
buttons[j]=optarg[j]-'0';
}
*/
break;
case 'h':
case '?':
@ -317,6 +362,12 @@ void getOptions(int argc, char **argv, char *opts, const struct option *options)
}
Printf("\n");
}
if(buttons_cnt == 0) {
buttons_cnt = 6;
buttons = malloc(sizeof(int) * buttons_cnt);
for(j = 0; j < buttons_cnt; j++)
buttons[j] = j+4;
}
if(invalidOpts)
exit(1);
if(!restart)
@ -525,7 +576,7 @@ void printUsage(char *pname, const struct option options[], const char *usage[][
int i,maxa=0,maxb=0,len;
char str[80];
printf("imwheel %s by -=<Long Island Man>=- <jcatki@jonatkins.org>\n",VERSION);
printf("imwheel %s by -=<Long Island Man>=- <jcatki@jcatki.no-ip.org>\n",VERSION);
if(!options || !usage)
return;
printf("%s",pname);
@ -564,12 +615,13 @@ void printUsage(char *pname, const struct option options[], const char *usage[][
for(i=0;options[i].name;i++)
{
*str=0;
if(options[i].name)
sprintf(str,"--%s",options[i].name);
if(options[i].val && options[i].name)
sprintf(str,"%s|",str);
sprintf(str,"%s%s%s ",
options[i].name?"--":"",
options[i].name?options[i].name:"",
options[i].name&&options[i].val?"|-":
options[i].val?"-":"");
if(options[i].val)
sprintf(str,"%s-%c",str,options[i].val);
str[strlen(str)-1]=options[i].val;
printf("%-*.*s",maxa,maxa,str);
if(usage[i][0])
printf(" %-*.*s",maxb,maxb,usage[i][0]);
@ -847,7 +899,8 @@ struct WinAction *getRC()
exitString("expected 3 args, got 1, in config.\n%s\n",line);
Printf("Keysym mask: \"%s\"\n",line);
newwa[num_wa-1].in=getPipeArray(line);
memmove(line,p+1,strlen(p+1)+1);
for(p++; isspace(*p); p++);
memmove(line,p,strlen(p)+1);
//Get Button
p=strchr(line,',');
if(p)
@ -859,16 +912,16 @@ struct WinAction *getRC()
{
sscanf(line+6,"%d",&i);
Printf("(Button%d)",i);
if(i>NUM_BUTTONS)
i=NUM_BUTTONS;
if(i>buttons_cnt)
i=buttons_cnt;
else
newwa[num_wa-1].button=i;
}
else
{
for(i=0; i<NUM_BUTTONS; i++)
for(i=0; i<buttons_cnt; i++)
{
if(!strcasecmp(line,button_names[i]))
if(!strcasecmp(line,(*button_names)[i]))
{
if(buttons[i])
newwa[num_wa-1].button=i+4;//buttons[i];
@ -878,12 +931,12 @@ struct WinAction *getRC()
}
}
}
if(i==NUM_BUTTONS) // nothing found
if(i==buttons_cnt) // nothing found
{
if(!strncasecmp(line,button_names[4],strlen(button_names[4])-1))
newwa[num_wa-1].button=buttons[4];
else
exitString("Unrecognized wheel action in config.\n%s\n",line);
fprintf(stderr, "Unrecognized wheel action in config. Ignoring action.\n%s\n", line);
newwa[num_wa-1].button = 0;
}
Printf("\t=%d\n",newwa[num_wa-1].button);
if(!newwa[num_wa-1].button)
@ -895,7 +948,8 @@ struct WinAction *getRC()
newwa[num_wa].id=NULL;
continue;
}
memmove(line,p+1,strlen(p+1)+1);
for(p++; isspace(*p); p++);
memmove(line,p,strlen(p)+1);
//Get Keysym Out
p=strchr(line,',');
if(p)
@ -908,7 +962,10 @@ struct WinAction *getRC()
else
exitString("Unrecognized or missing Keysym Outs (arg 3) in config.\n%s\n",line);
if(p)
memmove(line,p+1,strlen(p+1)+1);
{
for(p++; isspace(*p); p++);
memmove(line,p,strlen(p)+1);
}
else
continue;
//Get Reps
@ -921,7 +978,10 @@ struct WinAction *getRC()
newwa[num_wa-1].reps=strtol(line,NULL,10);
}
if(p)
memmove(line,p+1,strlen(p+1)+1);
{
for(p++; isspace(*p); p++);
memmove(line,p,strlen(p)+1);
}
else
continue;
//Get Delay
@ -934,7 +994,10 @@ struct WinAction *getRC()
newwa[num_wa-1].delay=strtol(line,NULL,10);
}
if(p)
memmove(line,p+1,strlen(p+1)+1);
{
for(p++; isspace(*p); p++);
memmove(line,p,strlen(p)+1);
}
else
continue;
//Get Delay Up
@ -1079,7 +1142,7 @@ void writeRC(struct WinAction *wa)
perror("imwheel,writeRC");
return;
}
fprintf(f,"# IMWheel Configuration file (%s)\n# (C)Jon Atkins <jcatki@jonatkins.org>\n#\n# Generated by imwheel\n# Any extra comments will be lost on reconfiguration\n# However order will be maintained\n# Order! ORDER, I SAY!!\n",fname);
fprintf(f,"# IMWheel Configuration file (%s)\n# (C)Jon Atkins <jcatki@jcatki.no-ip.org>\n#\n# Generated by imwheel\n# Any extra comments will be lost on reconfiguration\n# However order will be maintained\n# Order! ORDER, I SAY!!\n",fname);
for(cur=NULL,p=wa;p->id;p=&p[1])
{
if(!cur || strcmp(cur->id,p->id))
@ -1091,7 +1154,7 @@ void writeRC(struct WinAction *wa)
{
for(i=0; p->in[i]; i++)
fprintf(f,"%s%s",(i?"|":""),p->in[i]);
fprintf(f,",\t%s,\t",button_names[p->button-4]);
fprintf(f,",\t%s,\t",(*button_names)[p->button-4]);
for(i=0; p->out[i]; i++)
fprintf(f,"%s%s",(i?"|":""),p->out[i]);
if(p->delayup>0||p->delay>0||p->reps>1||p->reps==0)

10
util.h
View File

@ -10,7 +10,7 @@
#define PIDFILE PIDDIR"/imwheel.pid"
#define NUM_BUTTONS 6
#define NUM_STDCOMMANDS 6
#define STATE_MASK (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
#define NUM_STATES 3
#define MAX_MASKTRANS 8
@ -42,17 +42,18 @@ struct WinAction
int delayup;//microsecond delay while key down
};
extern int buttons[NUM_BUTTONS+1];
extern int *buttons;
extern int buttons_cnt;
extern int statebits[STATE_MASK+1];
extern int debug;
extern struct WinAction *wa;
extern int num_wa;
extern struct Trans masktrans[MAX_MASKTRANS];
extern const int reps[1<<NUM_STATES];
extern const char *keys[NUM_BUTTONS][1<<NUM_STATES];
extern const char *keys[NUM_STDCOMMANDS][1<<NUM_STATES];
extern char *wname;
extern XClassHint xch;
extern const char *button_names[];
extern char *(*button_names)[];
extern Atom ATOM_NET_WM_NAME, ATOM_UTF8_STRING, ATOM_WM_NAME, ATOM_STRING;
void getOptions(int,char**,char*,const struct option*);
@ -66,6 +67,7 @@ void printKeymap(Display *d, char[32]);
int getbit(char*, int);
void setbit(char*, int, Bool);
void setupstatebits(void);
void setupbuttonnames(void);
int isMod(XModifierKeymap*, int);
unsigned int makeModMask(XModifierKeymap*, char[32]);
unsigned int makeKeysymModMask(Display*,XModifierKeymap*, char**);