aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/cmd/devdraw/x11-inc.h1
-rw-r--r--src/cmd/devdraw/x11-itrans.c31
-rw-r--r--src/cmd/devdraw/x11-srv.c105
3 files changed, 111 insertions, 26 deletions
diff --git a/src/cmd/devdraw/x11-inc.h b/src/cmd/devdraw/x11-inc.h
index 5371eacb..1ac27d65 100644
--- a/src/cmd/devdraw/x11-inc.h
+++ b/src/cmd/devdraw/x11-inc.h
@@ -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
index b08601ea..4eac847e 100644
--- a/src/cmd/devdraw/x11-itrans.c
+++ b/src/cmd/devdraw/x11-itrans.c
@@ -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);
@@ -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;
@@ -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.
@@ -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
@@ -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
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;