tdevdraw: control+click = button 2, alt/shift+click = button 3 - plan9port - [fork] Plan 9 from user space (HTM) git clone git://src.adamsgaard.dk/plan9port (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit 36bb28dc638bb3091e05996156b5fbecbc67dcd5 (DIR) parent 17934beda0895d1b584e09f0253b8205b7fd6de2 (HTM) Author: Russ Cox <rsc@swtch.com> Date: Thu, 7 Mar 2013 22:40:47 -0500 devdraw: control+click = button 2, alt/shift+click = button 3 For single-button mouse users. R=rsc https://codereview.appspot.com/7620043 Diffstat: M src/cmd/devdraw/x11-inc.h | 1 + M src/cmd/devdraw/x11-itrans.c | 31 +++++++++++++++++++++++-------- M src/cmd/devdraw/x11-srv.c | 105 +++++++++++++++++++++++++------ 3 files changed, 111 insertions(+), 26 deletions(-) --- (DIR) diff --git a/src/cmd/devdraw/x11-inc.h b/src/cmd/devdraw/x11-inc.h t@@ -32,3 +32,4 @@ #undef Visual #undef Window +void sendalt(void); (DIR) diff --git a/src/cmd/devdraw/x11-itrans.c b/src/cmd/devdraw/x11-itrans.c t@@ -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); t@@ -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; t@@ -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. t@@ -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 t@@ -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; (DIR) diff --git a/src/cmd/devdraw/x11-srv.c b/src/cmd/devdraw/x11-srv.c t@@ -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; t@@ -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. */ t@@ -472,6 +494,8 @@ runxevent(XEvent *xev) int c; KeySym k; static Mouse m; + XButtonEvent *be; + XKeyEvent *ke; #ifdef SHOWEVENT static int first = 1; t@@ -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;