tdevdraw: control+click = button 2, alt/shift+click = button 3 - plan9port - [f… | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 36bb28dc638bb3091e05996156b5fbecbc67dcd5 | |
parent 17934beda0895d1b584e09f0253b8205b7fd6de2 | |
Author: Russ Cox <[email protected]> | |
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(-) | |
--- | |
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); | |
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; | |
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|EnterWind… | |
+#define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|KeyReleas… | |
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; |