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:
parent
17934beda0
commit
36bb28dc63
3 changed files with 111 additions and 26 deletions
|
|
@ -32,3 +32,4 @@
|
||||||
#undef Visual
|
#undef Visual
|
||||||
#undef Window
|
#undef Window
|
||||||
|
|
||||||
|
void sendalt(void);
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,7 @@ __xtoplan9kbd(XEvent *e)
|
||||||
case XK_Alt_R:
|
case XK_Alt_R:
|
||||||
case XK_Meta_R: /* Shift Alt on PCs */
|
case XK_Meta_R: /* Shift Alt on PCs */
|
||||||
case XK_Multi_key:
|
case XK_Multi_key:
|
||||||
k = Kalt;
|
return -1;
|
||||||
break;
|
|
||||||
default: /* not ISO-1 or tty control */
|
default: /* not ISO-1 or tty control */
|
||||||
if(k>0xff) {
|
if(k>0xff) {
|
||||||
k = _p9keysym2ucs(k);
|
k = _p9keysym2ucs(k);
|
||||||
|
|
@ -128,7 +127,7 @@ __xtoplan9kbd(XEvent *e)
|
||||||
if(k == XK_hyphen)
|
if(k == XK_hyphen)
|
||||||
k = XK_minus;
|
k = XK_minus;
|
||||||
/* Do control mapping ourselves if translator doesn't */
|
/* Do control mapping ourselves if translator doesn't */
|
||||||
if(e->xkey.state&ControlMask && k != Kalt)
|
if(e->xkey.state&ControlMask)
|
||||||
k &= 0x9f;
|
k &= 0x9f;
|
||||||
if(k == NoSymbol) {
|
if(k == NoSymbol) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -145,18 +144,33 @@ abortcompose(void)
|
||||||
alting = 0;
|
alting = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Rune* sendrune(Rune);
|
||||||
|
|
||||||
extern int _latin1(Rune*, int);
|
extern int _latin1(Rune*, int);
|
||||||
static Rune*
|
static Rune*
|
||||||
xtoplan9latin1(XEvent *e)
|
xtoplan9latin1(XEvent *e)
|
||||||
{
|
{
|
||||||
static Rune k[10];
|
Rune r;
|
||||||
static int nk;
|
|
||||||
int n;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = __xtoplan9kbd(e);
|
r = __xtoplan9kbd(e);
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
return nil;
|
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){
|
if(alting){
|
||||||
/*
|
/*
|
||||||
* Kludge for Mac's X11 3-button emulation.
|
* Kludge for Mac's X11 3-button emulation.
|
||||||
|
|
@ -228,6 +242,7 @@ _xtoplan9mouse(XEvent *e, Mouse *m)
|
||||||
switch(e->type){
|
switch(e->type){
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
be = (XButtonEvent*)e;
|
be = (XButtonEvent*)e;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fake message, just sent to make us announce snarf.
|
* Fake message, just sent to make us announce snarf.
|
||||||
* Apparently state and button are 16 and 8 bits on
|
* 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.x = me->x;
|
||||||
m->xy.y = me->y;
|
m->xy.y = me->y;
|
||||||
m->msec = me->time;
|
m->msec = me->time;
|
||||||
break;
|
return 0; // do not set buttons
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
Button2MotionMask|\
|
Button2MotionMask|\
|
||||||
Button3MotionMask)
|
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 Kbdbuf Kbdbuf;
|
||||||
typedef struct Mousebuf Mousebuf;
|
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.
|
* Handle an incoming X event.
|
||||||
*/
|
*/
|
||||||
|
|
@ -472,6 +494,8 @@ runxevent(XEvent *xev)
|
||||||
int c;
|
int c;
|
||||||
KeySym k;
|
KeySym k;
|
||||||
static Mouse m;
|
static Mouse m;
|
||||||
|
XButtonEvent *be;
|
||||||
|
XKeyEvent *ke;
|
||||||
|
|
||||||
#ifdef SHOWEVENT
|
#ifdef SHOWEVENT
|
||||||
static int first = 1;
|
static int first = 1;
|
||||||
|
|
@ -504,41 +528,86 @@ runxevent(XEvent *xev)
|
||||||
if(_xconfigure(xev)){
|
if(_xconfigure(xev)){
|
||||||
mouse.resized = 1;
|
mouse.resized = 1;
|
||||||
_xreplacescreenimage();
|
_xreplacescreenimage();
|
||||||
goto addmouse;
|
sendmouse(m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPress:
|
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:
|
case ButtonRelease:
|
||||||
|
altdown = 0;
|
||||||
|
// fall through
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
if(mouse.stall)
|
if(mouse.stall)
|
||||||
return;
|
return;
|
||||||
if(_xtoplan9mouse(xev, &m) < 0)
|
if(_xtoplan9mouse(xev, &m) < 0)
|
||||||
return;
|
return;
|
||||||
addmouse:
|
sendmouse(m);
|
||||||
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();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case KeyRelease:
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
if(kbd.stall)
|
ke = (XKeyEvent*)xev;
|
||||||
return;
|
XLookupString(ke, NULL, 0, &k, NULL);
|
||||||
XLookupString((XKeyEvent*)xev, 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){
|
if(k == XK_F11){
|
||||||
fullscreen = !fullscreen;
|
fullscreen = !fullscreen;
|
||||||
_xmovewindow(fullscreen ? screenrect : windowrect);
|
_xmovewindow(fullscreen ? screenrect : windowrect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(kbd.stall)
|
||||||
|
return;
|
||||||
if((c = _xtoplan9kbd(xev)) < 0)
|
if((c = _xtoplan9kbd(xev)) < 0)
|
||||||
return;
|
return;
|
||||||
kbd.r[kbd.wi++] = c;
|
kbd.r[kbd.wi++] = c;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue