diff options
author | Russ Cox <rsc@swtch.com> | 2013-03-07 22:40:47 -0500 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2013-03-07 22:40:47 -0500 |
commit | 36bb28dc638bb3091e05996156b5fbecbc67dcd5 (patch) | |
tree | 038ccb895431d6872f5a3b38c3aaa4f61ac696d2 /src/cmd/devdraw/x11-srv.c | |
parent | 17934beda0895d1b584e09f0253b8205b7fd6de2 (diff) | |
download | plan9port-36bb28dc638bb3091e05996156b5fbecbc67dcd5.tar.gz plan9port-36bb28dc638bb3091e05996156b5fbecbc67dcd5.tar.bz2 plan9port-36bb28dc638bb3091e05996156b5fbecbc67dcd5.zip |
devdraw: control+click = button 2, alt/shift+click = button 3
For single-button mouse users.
R=rsc
https://codereview.appspot.com/7620043
Diffstat (limited to 'src/cmd/devdraw/x11-srv.c')
-rw-r--r-- | src/cmd/devdraw/x11-srv.c | 105 |
1 files changed, 87 insertions, 18 deletions
diff --git a/src/cmd/devdraw/x11-srv.c b/src/cmd/devdraw/x11-srv.c index 5a4be705..04ecabee 100644 --- a/src/cmd/devdraw/x11-srv.c +++ b/src/cmd/devdraw/x11-srv.c @@ -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; |