devdraw: control+click = button 2, alt/shift+click = button 3

For single-button mouse users.

R=rsc
https://codereview.appspot.com/7620043
This commit is contained in:
Russ Cox 2013-03-07 22:40:47 -05:00
parent 17934beda0
commit 36bb28dc63
3 changed files with 111 additions and 26 deletions

View file

@ -32,3 +32,4 @@
#undef Visual
#undef Window
void sendalt(void);

View file

@ -114,8 +114,7 @@ __xtoplan9kbd(XEvent *e)
case XK_Alt_R:
case XK_Meta_R: /* Shift Alt on PCs */
case XK_Multi_key:
k = Kalt;
break;
return -1;
default: /* not ISO-1 or tty control */
if(k>0xff) {
k = _p9keysym2ucs(k);
@ -128,7 +127,7 @@ __xtoplan9kbd(XEvent *e)
if(k == XK_hyphen)
k = XK_minus;
/* Do control mapping ourselves if translator doesn't */
if(e->xkey.state&ControlMask && k != Kalt)
if(e->xkey.state&ControlMask)
k &= 0x9f;
if(k == NoSymbol) {
return -1;
@ -145,18 +144,33 @@ abortcompose(void)
alting = 0;
}
static Rune* sendrune(Rune);
extern int _latin1(Rune*, int);
static Rune*
xtoplan9latin1(XEvent *e)
{
static Rune k[10];
static int nk;
int n;
int r;
Rune r;
r = __xtoplan9kbd(e);
if(r < 0)
return nil;
return sendrune(r);
}
void
sendalt(void)
{
sendrune(Kalt);
}
static Rune*
sendrune(Rune r)
{
static Rune k[10];
static int nk;
int n;
if(alting){
/*
* Kludge for Mac's X11 3-button emulation.
@ -228,6 +242,7 @@ _xtoplan9mouse(XEvent *e, Mouse *m)
switch(e->type){
case ButtonPress:
be = (XButtonEvent*)e;
/*
* Fake message, just sent to make us announce snarf.
* Apparently state and button are 16 and 8 bits on
@ -292,7 +307,7 @@ _xtoplan9mouse(XEvent *e, Mouse *m)
m->xy.x = me->x;
m->xy.y = me->y;
m->msec = me->time;
break;
return 0; // do not set buttons
default:
return -1;

View file

@ -36,7 +36,7 @@
Button2MotionMask|\
Button3MotionMask)
#define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|EnterWindowMask|LeaveWindowMask|FocusChangeMask
#define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask|EnterWindowMask|LeaveWindowMask|FocusChangeMask
typedef struct Kbdbuf Kbdbuf;
typedef struct Mousebuf Mousebuf;
@ -463,6 +463,28 @@ matchmouse(void)
}
}
static int kbuttons;
static int altdown;
static int kstate;
static void
sendmouse(Mouse m)
{
m.buttons |= kbuttons;
mouse.m[mouse.wi] = m;
mouse.wi++;
if(mouse.wi == nelem(mouse.m))
mouse.wi = 0;
if(mouse.wi == mouse.ri){
mouse.stall = 1;
mouse.ri = 0;
mouse.wi = 1;
mouse.m[0] = m;
/* fprint(2, "mouse stall\n"); */
}
matchmouse();
}
/*
* Handle an incoming X event.
*/
@ -472,6 +494,8 @@ runxevent(XEvent *xev)
int c;
KeySym k;
static Mouse m;
XButtonEvent *be;
XKeyEvent *ke;
#ifdef SHOWEVENT
static int first = 1;
@ -504,41 +528,86 @@ runxevent(XEvent *xev)
if(_xconfigure(xev)){
mouse.resized = 1;
_xreplacescreenimage();
goto addmouse;
sendmouse(m);
}
break;
case ButtonPress:
be = (XButtonEvent*)xev;
if(be->button == 1) {
if(kstate & ControlMask)
be->button = 2;
else if(kstate & Mod1Mask)
be->button = 3;
}
// fall through
case ButtonRelease:
altdown = 0;
// fall through
case MotionNotify:
if(mouse.stall)
return;
if(_xtoplan9mouse(xev, &m) < 0)
return;
addmouse:
mouse.m[mouse.wi] = m;
mouse.wi++;
if(mouse.wi == nelem(mouse.m))
mouse.wi = 0;
if(mouse.wi == mouse.ri){
mouse.stall = 1;
mouse.ri = 0;
mouse.wi = 1;
mouse.m[0] = m;
/* fprint(2, "mouse stall\n"); */
}
matchmouse();
sendmouse(m);
break;
case KeyRelease:
case KeyPress:
if(kbd.stall)
return;
XLookupString((XKeyEvent*)xev, NULL, 0, &k, NULL);
ke = (XKeyEvent*)xev;
XLookupString(ke, NULL, 0, &k, NULL);
c = ke->state;
switch(k) {
case XK_Alt_L:
case XK_Meta_L: /* Shift Alt on PCs */
case XK_Alt_R:
case XK_Meta_R: /* Shift Alt on PCs */
case XK_Multi_key:
if(xev->type == KeyPress)
altdown = 1;
else if(altdown) {
altdown = 0;
sendalt();
}
break;
}
switch(k) {
case XK_Control_L:
if(xev->type == KeyPress)
c |= ControlMask;
else
c &= ~ControlMask;
goto kbutton;
case XK_Alt_L:
case XK_Shift_L:
if(xev->type == KeyPress)
c |= Mod1Mask;
else
c &= ~Mod1Mask;
kbutton:
kstate = c;
if(m.buttons || kbuttons) {
altdown = 0; // used alt
kbuttons = 0;
if(c & ControlMask)
kbuttons |= 2;
if(c & Mod1Mask)
kbuttons |= 4;
sendmouse(m);
break;
}
}
if(xev->type != KeyPress)
break;
if(k == XK_F11){
fullscreen = !fullscreen;
_xmovewindow(fullscreen ? screenrect : windowrect);
return;
}
if(kbd.stall)
return;
if((c = _xtoplan9kbd(xev)) < 0)
return;
kbd.r[kbd.wi++] = c;