commit d1635c671e977867910c517e904f00cd0aacd948 Author: Russ Cox Date: Fri Mar 7 16:19:04 2025 -0500 sys/src/9: add control-option-shift mouse modifiers like in plan9port Work in progress. Have not updated the non-pc kernels yet. Also shift seems to be broken now: using tr m $nl collecting = 0; + k->nk = 0; + } +} + +int kdebug; /* * set keyboard's leds for lock states (scroll, numeric, caps). @@ -390,7 +404,7 @@ kbdputsc(int c, int external) kbscan = &kbscans[Int]; if(kdebug) - print("sc %x ms %d\n", c, mouseshifted); + print("sc %x ms %d esc1=%d esc2=%d shift=%d altgr=%d ctl=%d\n", c, mousekeys, kbscan->esc1, kbscan->esc2, kbscan->shift, kbscan->altgr, kbscan->ctl); /* * e0's is the first of a 2 character sequence, e1 the first * of a 3 character sequence (on the safari) @@ -430,6 +444,9 @@ kbdputsc(int c, int external) if(kbscan->caps && c<='z' && c>='a') c += 'A' - 'a'; + if(kdebug) + print("kbd %d %c%x\n", mousekeys, !keyup?'+':'-', c); + /* * keyup only important for shifts */ @@ -437,15 +454,28 @@ kbdputsc(int c, int external) switch(c){ case Latin: kbscan->alt = 0; + mousekeys &= ~MouseAlt; + if(mouseshift) + mouseshift(mousekeys|MouseAlt); break; case Shift: kbscan->shift = 0; - mouseshifted = 0; + mousekeys &= ~MouseShift; + if(mouseshift) + mouseshift(mousekeys|MouseShift); if(kdebug) print("shiftclr\n"); break; case Ctrl: kbscan->ctl = 0; + mousekeys &= ~MouseCtrl; + if(mouseshift) + mouseshift(mousekeys|MouseCtrl); + break; + case MacCmd: + mousekeys &= ~MouseCmd; + if(mouseshift) + mouseshift(mousekeys|MouseCmd); break; case Altgr: kbscan->altgr = 0; @@ -470,19 +500,28 @@ kbdputsc(int c, int external) if(kbscan->ctl) if(kbscan->alt && c == Del) exit(0); + if(c == 'Z'-'@'){ + kdebug ^= 1; + if(kdebug) + print("kbd debug on, ^Z toggles it\n"); + } if(!kbscan->collecting){ kbdputc(kbdq, c); return; } - kbscan->kc[kbscan->nk++] = c; - c = latin1(kbscan->kc, kbscan->nk); - if(c < -1) /* need more keystrokes */ - return; - if(c != -1) /* valid sequence */ - kbdputc(kbdq, c); - else /* dump characters */ - for(i=0; ink; i++) - kbdputc(kbdq, kbscan->kc[i]); + if(kbscan->nk < nelem(kbscan->kc)) { + kbscan->kc[kbscan->nk++] = c; + c = latin1(kbscan->kc, kbscan->nk); + if(c < -1) /* need more keystrokes */ + return; + if(c != -1){ /* valid sequence */ + kbdputc(kbdq, c); + return; + } + } + /* dump characters */ + for(i=0; ink; i++) + kbdputc(kbdq, kbscan->kc[i]); kbscan->nk = 0; kbscan->collecting = 0; return; @@ -500,9 +539,14 @@ kbdputsc(int c, int external) kbscan->shift = 1; if(kdebug) print("shift\n"); - mouseshifted = 1; + mousekeys |= MouseShift; + if(mouseshift) + mouseshift(mousekeys&~MouseShift); return; case Latin: + mousekeys |= MouseAlt; + if(mouseshift && mouseshift(mousekeys&~MouseAlt)) + return; kbscan->alt = 1; /* * VMware and Qemu use Ctl-Alt as the key combination @@ -521,6 +565,14 @@ kbdputsc(int c, int external) return; case Ctrl: kbscan->ctl = 1; + mousekeys |= MouseCtrl; + if(mouseshift) + mouseshift(mousekeys&~MouseCtrl); + return; + case MacCmd: + mousekeys |= MouseCmd; + if(mouseshift) + mouseshift(mousekeys&~MouseCmd); return; case Altgr: kbscan->altgr = 1; @@ -684,6 +736,8 @@ kbdenable(void) kbscans[Int].num = 0; setleds(&kbscans[Int]); + + kbdnocollect = xkbdnocollect; } void diff --git a/sys/src/9/pc/mouse.c b/sys/src/9/pc/mouse.c index 282e3595..34dde948 100755 --- a/sys/src/9/pc/mouse.c +++ b/sys/src/9/pc/mouse.c @@ -22,7 +22,7 @@ enum MousePS2= 2, }; -extern int mouseshifted; +extern int mousekeys; static QLock mousectlqlock; static int mousetype; @@ -86,20 +86,15 @@ static Cmdtab mousectlmsg[] = * after the previous byte, we assume it's the first in a packet. */ static void -ps2mouseputc(int c, int shift) +ps2mouseputc(int c, int) { static short msg[4]; static int nb; - static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 }; + static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7}; static ulong lasttick; ulong m; int buttons, dx, dy; - /* - * non-ps2 keyboards might not set shift - * but still set mouseshifted. - */ - shift |= mouseshifted; /* * Resynchronize in stream with timing; see comment above. */ @@ -108,7 +103,7 @@ ps2mouseputc(int c, int shift) nb = 0; lasttick = m; - /* + /* * check byte 0 for consistency */ if(nb==0 && (c&0xc8)!=0x08) @@ -126,7 +121,7 @@ ps2mouseputc(int c, int shift) if(msg[0] & 0x20) msg[2] |= 0xFF00; - buttons = b[(msg[0]&7) | (shift ? 8 : 0)]; + buttons = b[msg[0]&7]; if(intellimouse && packetsize==4){ if((msg[3]&0xc8) == 0x08){ /* first byte of 3-byte packet */ @@ -148,9 +143,9 @@ ps2mouseputc(int c, int shift) * and generate a single button 4 or 5 click * accordingly. */ - if((msg[3] >> 3) & 1) + if((msg[3] >> 3) & 1) buttons |= 1<<3; - else if(msg[3] & 0x7) + else if(msg[3] & 0x7) buttons |= 1<<4; } } diff --git a/sys/src/9/port/devmouse.c b/sys/src/9/port/devmouse.c index 4e5de193..f39a737d 100755 --- a/sys/src/9/port/devmouse.c +++ b/sys/src/9/port/devmouse.c @@ -18,6 +18,8 @@ enum { ScrollRight = 0x40, }; +int kdebug; + typedef struct Mouseinfo Mouseinfo; typedef struct Mousestate Mousestate; @@ -70,9 +72,10 @@ static Cmdtab mousectlmsg[] = Mouseinfo mouse; Cursorinfo cursor; -int mouseshifted; +int mousekeys; int kbdbuttons; void (*kbdmouse)(int); +int (*mouseshift)(int); Cursor curs; void Cursortocursor(Cursor*); @@ -126,6 +129,27 @@ mousefromkbd(int buttons) mousetrack(0, 0, 0, TK2MS(MACHP(0)->ticks)); } +static int +mousefromshift(int old) +{ + int b; + + b = mouse.buttons; + if(b == 0) + return 0; + if(mousekeys & ~old & MouseCtrl) + b |= 1; + if(mousekeys & ~old & MouseAlt){ + if(kbdnocollect) + kbdnocollect(); + b |= 2; + } + if(mousekeys & ~old & MouseCmd) + b |= 4; + mousetrack(0, 0, b, TK2MS(MACHP(0)->ticks)); + return 1; +} + static int mousedevgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) { @@ -147,6 +171,7 @@ mouseinit(void) Cursortocursor(&arrow); cursoron(1); kbdmouse = mousefromkbd; + mouseshift = mousefromshift; mousetime = seconds(); } @@ -314,6 +339,8 @@ mouseread(Chan *c, void *va, long n, vlong off) mouse.lastresize = mouse.resize; buf[0] = 'r'; } + if(kdebug) + print("M %s\n", buf); memmove(va, buf, n); return n; } @@ -568,10 +595,28 @@ void mousetrack(int dx, int dy, int b, int msec) { int x, y, lastb; +int ob; if(gscreen==nil) return; + ob = b; + + if(b == 1){ + if(mousekeys & MouseAlt){ + b = 2; + if(kbdnocollect) + kbdnocollect(); + } + else if(mousekeys & MouseCmd) + b = 4; + } + // Shift swaps middle and right buttons. + if(mousekeys & MouseShift) + b = (b&~6) | ((b&4)>>1) | ((b&2)<<1); + if(kdebug) + print("mousetrack %d %d %d->%d %d [%d]\n", dx, dy, ob, b, msec, kbdbuttons); + if(mouse.acceleration){ dx = scale(dx); dy = scale(dy); @@ -599,6 +644,8 @@ mousetrack(int dx, int dy, int b, int msec) * queue any more events until a reader polls the mouse. */ if(!mouse.qfull && lastb != b) { /* add to ring */ + if(kdebug) + print("mousequeue %d %d %d %lud\n", mouse.xy.x, mouse.xy.y, mouse.buttons, mouse.msec); mouse.queue[mouse.wi] = mouse.Mousestate; if(++mouse.wi == nelem(mouse.queue)) mouse.wi = 0; @@ -625,7 +672,7 @@ m3mouseputc(Queue*, int c) static uchar msg[3]; static int nb; static int middle; - static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 3 }; + static uchar b[] = { 0, 4, 1, 5 }; short x; int dx, dy, newbuttons; static ulong lasttick; @@ -653,7 +700,7 @@ m3mouseputc(Queue*, int c) msg[nb] = c; if(++nb == 3){ nb = 0; - newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)]; + newbuttons = middle | b[(msg[0]>>4)&3]; x = (msg[0]&0x3)<<14; dx = (x>>8) | msg[1]; x = (msg[0]&0xc)<<12; @@ -697,7 +744,7 @@ m5mouseputc(Queue*, int c) dx = msg[1] | (msg[0] & 0x3) << 6; dy = msg[2] | (msg[0] & 0xc) << 4; newbuttons = - (msg[0] & 0x10) >> (mouseshifted ? 3 : 2) + (msg[0] & 0x10) >> 2 | (msg[0] & 0x20) >> 5 | ( msg[3] == 0x10 ? 0x02 : msg[3] == 0x0f ? ScrollUp : @@ -718,7 +765,7 @@ mouseputc(Queue*, int c) { static short msg[5]; static int nb; - static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 3, 3, 7}; + static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7}; int dx, dy, newbuttons; static ulong lasttick; ulong m; @@ -735,7 +782,7 @@ mouseputc(Queue*, int c) if(c & 0x80) msg[nb] |= ~0xFF; /* sign extend */ if(++nb == 5){ - newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)]; + newbuttons = b[(msg[0]&7)^7]; dx = msg[1]+msg[3]; dy = -(msg[2]+msg[4]); mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks)); diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index a2ddc3d4..902ec62c 100755 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -802,6 +802,14 @@ enum READSTR = 4000, /* temporary buffer size for device reads */ }; +enum /* mousekeys bits */ +{ + MouseShift = 1<<0, + MouseCtrl = 1<<1, + MouseAlt = 1<<2, + MouseCmd = 1<<3, +}; + struct Execvals { uvlong entry; ulong textsize; @@ -818,6 +826,9 @@ extern uchar initcode[]; extern int kbdbuttons; extern Queue* kbdq; extern Queue* kprintoq; + void (*kbdnocollect)(void); + int (*mouseshift)(int); +extern int mousekeys; extern Ref noteidalloc; extern int nsyscall; extern Palloc palloc;