aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/devdraw/x11-srv.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2013-03-07 22:40:47 -0500
committerRuss Cox <rsc@swtch.com>2013-03-07 22:40:47 -0500
commit36bb28dc638bb3091e05996156b5fbecbc67dcd5 (patch)
tree038ccb895431d6872f5a3b38c3aaa4f61ac696d2 /src/cmd/devdraw/x11-srv.c
parent17934beda0895d1b584e09f0253b8205b7fd6de2 (diff)
downloadplan9port-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.c105
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;