diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-11 05:55:48 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-11 05:55:48 +0000 |
commit | 4fcc906e7f37678eae7c0b933250c9170dac9487 (patch) | |
tree | 5e3a6443c5399a90a56e5e3aa72e84cf7dbd6a13 | |
parent | 2febff5948ebb7bf7092911b8fe5dc54cb36cc8b (diff) |
add /dev/kbd support to rio
-rw-r--r-- | sys/include/keyboard.h | 29 | ||||
-rw-r--r-- | sys/src/cmd/aux/kbdfs.c | 210 | ||||
-rw-r--r-- | sys/src/cmd/rio/dat.h | 18 | ||||
-rw-r--r-- | sys/src/cmd/rio/fsys.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/rio/rio.c | 125 | ||||
-rw-r--r-- | sys/src/cmd/rio/wind.c | 115 | ||||
-rw-r--r-- | sys/src/cmd/rio/xfid.c | 47 |
7 files changed, 344 insertions, 201 deletions
diff --git a/sys/include/keyboard.h b/sys/include/keyboard.h index 96a18e1ff..c3aff395d 100644 --- a/sys/include/keyboard.h +++ b/sys/include/keyboard.h @@ -22,25 +22,42 @@ extern void closekeyboard(Keyboardctl*); enum { KF= 0xF000, /* Rune: beginning of private Unicode space */ Spec= 0xF800, + PF= Spec|0x20, /* num pad function key */ + Kview= Spec|0x00, /* view (shift window up) */ /* KF|1, KF|2, ..., KF|0xC is F1, F2, ..., F12 */ Khome= KF|0x0D, Kup= KF|0x0E, + Kdown= Kview, Kpgup= KF|0x0F, Kprint= KF|0x10, Kleft= KF|0x11, Kright= KF|0x12, - Kdown= Spec|0x00, - Kview= Spec|0x00, Kpgdown= KF|0x13, Kins= KF|0x14, - Kend= KF|0x18, - Kalt= KF|0x15, + Kalt= KF|0x15, Kshift= KF|0x16, - Kctl= KF|0x17, + Kctl= KF|0x17, + + Kend= KF|0x18, + Kscroll= KF|0x19, + Kscrolloneup= KF|0x20, + Kscrollonedown= KF|0x21, + Ksoh= 0x01, + Keof= 0x04, + Kenq= 0x05, + Kack= 0x06, Kbs= 0x08, + Knack= 0x15, + Ketb= 0x17, Kdel= 0x7f, Kesc= 0x1b, - Keof= 0x04, + + Kbreak= Spec|0x61, + Kcaps= Spec|0x64, + Knum= Spec|0x65, + Kmiddle= Spec|0x66, + Kaltgr= Spec|0x67, + Kmouse= Spec|0x100, }; diff --git a/sys/src/cmd/aux/kbdfs.c b/sys/src/cmd/aux/kbdfs.c index 32a1b4344..8d8747c6c 100644 --- a/sys/src/cmd/aux/kbdfs.c +++ b/sys/src/cmd/aux/kbdfs.c @@ -3,43 +3,12 @@ #include <auth.h> #include <fcall.h> #include <thread.h> +#include <keyboard.h> #include <9p.h> enum { - Spec= 0xF800, /* Unicode private space */ - PF= Spec|0x20, /* num pad function key */ - View= Spec|0x00, /* view (shift window up) */ - KF= 0xF000, /* function key (begin Unicode private space) */ - Shift= Spec|0x60, - Break= Spec|0x61, - Ctrl= Spec|0x62, - Latin= Spec|0x63, - Caps= Spec|0x64, - Num= Spec|0x65, - Middle= Spec|0x66, - Altgr= Spec|0x67, - Kmouse= Spec|0x100, - No= 0x00, /* peter */ - - Home= KF|13, - Up= KF|14, - Pgup= KF|15, - Print= KF|16, - Left= KF|17, - Right= KF|18, - End= KF|24, - Down= View, - Pgdown= KF|19, - Ins= KF|20, - Del= 0x7F, - Scroll= KF|21, - Nscan= 128, - Int= 0, /* scans indices */ - Ext, - Nscans, - Qroot= 0, Qkbd, Qkbin, @@ -138,102 +107,102 @@ Channel *kbdchan; /* char* */ */ Rune kbtab[Nscan] = { -[0x00] No, 0x1b, '1', '2', '3', '4', '5', '6', +[0x00] 0, 0x1b, '1', '2', '3', '4', '5', '6', [0x08] '7', '8', '9', '0', '-', '=', '\b', '\t', [0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', -[0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's', +[0x18] 'o', 'p', '[', ']', '\n', Kctl, 'a', 's', [0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', -[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v', -[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*', -[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5, -[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7', +[0x28] '\'', '`', Kshift, '\\', 'z', 'x', 'c', 'v', +[0x30] 'b', 'n', 'm', ',', '.', '/', Kshift, '*', +[0x38] Kalt, ' ', Kctl, KF|1, KF|2, KF|3, KF|4, KF|5, +[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Knum, Kscroll, '7', [0x48] '8', '9', '-', '4', '5', '6', '+', '1', -[0x50] '2', '3', '0', '.', No, No, No, KF|11, -[0x58] KF|12, No, No, No, No, No, No, No, -[0x60] No, No, No, No, No, No, No, No, -[0x68] No, No, No, No, No, No, No, No, -[0x70] No, No, No, No, No, No, No, No, -[0x78] No, View, No, Up, No, No, No, No, +[0x50] '2', '3', '0', '.', 0, 0, 0, KF|11, +[0x58] KF|12, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, Kdown, 0, Kup, 0, 0, 0, 0, }; Rune kbtabshift[Nscan] = { -[0x00] No, 0x1b, '!', '@', '#', '$', '%', '^', +[0x00] 0, 0x1b, '!', '@', '#', '$', '%', '^', [0x08] '&', '*', '(', ')', '_', '+', '\b', '\t', [0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', -[0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S', +[0x18] 'O', 'P', '{', '}', '\n', Kctl, 'A', 'S', [0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', -[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V', -[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*', -[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5, -[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7', +[0x28] '"', '~', Kshift, '|', 'Z', 'X', 'C', 'V', +[0x30] 'B', 'N', 'M', '<', '>', '?', Kshift, '*', +[0x38] Kalt, ' ', Kctl, KF|1, KF|2, KF|3, KF|4, KF|5, +[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Knum, Kscroll, '7', [0x48] '8', '9', '-', '4', '5', '6', '+', '1', -[0x50] '2', '3', '0', '.', No, No, No, KF|11, -[0x58] KF|12, No, No, No, No, No, No, No, -[0x60] No, No, No, No, No, No, No, No, -[0x68] No, No, No, No, No, No, No, No, -[0x70] No, No, No, No, No, No, No, No, -[0x78] No, Up, No, Up, No, No, No, No, +[0x50] '2', '3', '0', '.', 0, 0, 0, KF|11, +[0x58] KF|12, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, Kup, 0, Kup, 0, 0, 0, 0, }; Rune kbtabesc1[Nscan] = { -[0x00] No, No, No, No, No, No, No, No, -[0x08] No, No, No, No, No, No, No, No, -[0x10] No, No, No, No, No, No, No, No, -[0x18] No, No, No, No, '\n', Ctrl, No, No, -[0x20] No, No, No, No, No, No, No, No, -[0x28] No, No, Shift, No, No, No, No, No, -[0x30] No, No, No, No, No, '/', No, Print, -[0x38] Altgr, No, No, No, No, No, No, No, -[0x40] No, No, No, No, No, No, Break, Home, -[0x48] Up, Pgup, No, Left, No, Right, No, End, -[0x50] Down, Pgdown, Ins, Del, No, No, No, No, -[0x58] No, No, No, No, No, No, No, No, -[0x60] No, No, No, No, No, No, No, No, -[0x68] No, No, No, No, No, No, No, No, -[0x70] No, No, No, No, No, No, No, No, -[0x78] No, Up, No, No, No, No, No, No, +[0x00] 0, 0, 0, 0, 0, 0, 0, 0, +[0x08] 0, 0, 0, 0, 0, 0, 0, 0, +[0x10] 0, 0, 0, 0, 0, 0, 0, 0, +[0x18] 0, 0, 0, 0, '\n', Kctl, 0, 0, +[0x20] 0, 0, 0, 0, 0, 0, 0, 0, +[0x28] 0, 0, Kshift, 0, 0, 0, 0, 0, +[0x30] 0, 0, 0, 0, 0, '/', 0, Kprint, +[0x38] Kaltgr, 0, 0, 0, 0, 0, 0, 0, +[0x40] 0, 0, 0, 0, 0, 0, Kbreak, Khome, +[0x48] Kup, Kpgup, 0, Kleft, 0, Kright, 0, Kend, +[0x50] Kdown, Kpgdown, Kins, Kdel, 0, 0, 0, 0, +[0x58] 0, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, Kup, 0, 0, 0, 0, 0, 0, }; Rune kbtabaltgr[Nscan] = { -[0x00] No, No, No, No, No, No, No, No, -[0x08] No, No, No, No, No, No, No, No, -[0x10] No, No, No, No, No, No, No, No, -[0x18] No, No, No, No, '\n', Ctrl, No, No, -[0x20] No, No, No, No, No, No, No, No, -[0x28] No, No, Shift, No, No, No, No, No, -[0x30] No, No, No, No, No, '/', No, Print, -[0x38] Altgr, No, No, No, No, No, No, No, -[0x40] No, No, No, No, No, No, Break, Home, -[0x48] Up, Pgup, No, Left, No, Right, No, End, -[0x50] Down, Pgdown, Ins, Del, No, No, No, No, -[0x58] No, No, No, No, No, No, No, No, -[0x60] No, No, No, No, No, No, No, No, -[0x68] No, No, No, No, No, No, No, No, -[0x70] No, No, No, No, No, No, No, No, -[0x78] No, Up, No, No, No, No, No, No, +[0x00] 0, 0, 0, 0, 0, 0, 0, 0, +[0x08] 0, 0, 0, 0, 0, 0, 0, 0, +[0x10] 0, 0, 0, 0, 0, 0, 0, 0, +[0x18] 0, 0, 0, 0, '\n', Kctl, 0, 0, +[0x20] 0, 0, 0, 0, 0, 0, 0, 0, +[0x28] 0, 0, Kshift, 0, 0, 0, 0, 0, +[0x30] 0, 0, 0, 0, 0, '/', 0, Kprint, +[0x38] Kaltgr, 0, 0, 0, 0, 0, 0, 0, +[0x40] 0, 0, 0, 0, 0, 0, Kbreak, Khome, +[0x48] Kup, Kpgup, 0, Kleft, 0, Kright, 0, Kend, +[0x50] Kdown, Kpgdown, Kins, Kdel, 0, 0, 0, 0, +[0x58] 0, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, Kup, 0, 0, 0, 0, 0, 0, }; Rune kbtabctrl[Nscan] = { -[0x00] No, '', '', '', '', '', '', '', +[0x00] 0, '', '', '', '', '', '', '', [0x08] '', '', '', '', '
', '', '\b', '\t', [0x10] '', '', '', '', '', '', '', '\t', -[0x18] '', '', '', '', '\n', Ctrl, '', '', +[0x18] '', '', '', '', '\n', Kctl, '', '', [0x20] '', '', '', '\b', '\n', '', '', '', -[0x28] '', No, Shift, '', '', '', '', '', -[0x30] '', '', '
', '', '', '', Shift, '\n', -[0x38] Latin, No, Ctrl, '', '', '', '', '', +[0x28] '', 0, Kshift, '', '', '', '', '', +[0x30] '', '', '
', '', '', '', Kshift, '\n', +[0x38] Kalt, 0, Kctl, '', '', '', '', '', [0x40] '', '', '', '
', '', '', '', '', [0x48] '', '', '
', '', '', '', '', '', -[0x50] '', '', '', '', No, No, No, '', -[0x58] '', No, No, No, No, No, No, No, -[0x60] No, No, No, No, No, No, No, No, -[0x68] No, No, No, No, No, No, No, No, -[0x70] No, No, No, No, No, No, No, No, -[0x78] No, '', No, '\b', No, No, No, No, +[0x50] '', '', '', '', 0, 0, 0, '', +[0x58] '', 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, '', 0, '\b', 0, 0, 0, 0, }; void reboot(void); @@ -278,7 +247,7 @@ kbdputsc(Scan *scan, int c) if(scan->caps && key.r<='z' && key.r>='a') key.r += 'A' - 'a'; - if(scan->ctrl && scan->latin && key.r == Del) + if(scan->ctrl && scan->latin && key.r == Kdel) reboot(); send(keychan, &key); @@ -289,22 +258,22 @@ kbdputsc(Scan *scan, int c) scan->esc2--; switch(key.r){ - case Shift: + case Kshift: scan->shift = key.down; break; - case Ctrl: + case Kctl: scan->ctrl = key.down; break; - case Altgr: + case Kaltgr: scan->altgr = key.down; break; - case Latin: + case Kalt: scan->latin = key.down; break; - case Num: + case Knum: scan->num ^= key.down; break; - case Caps: + case Kcaps: scan->caps ^= key.down; break; } @@ -377,27 +346,19 @@ keyproc(void *) while(recv(keychan, &key) > 0){ if(key.down){ switch(key.r){ - case No: - case Caps: - case Num: - case Shift: - case Latin: - case Ctrl: - case Altgr: - case Kmouse|1: - case Kmouse|2: - case Kmouse|3: - case Kmouse|4: - case Kmouse|5: - case KF|11: - case KF|12: + case 0: + case Kcaps: + case Knum: + case Kshift: + case Kalt: + case Kctl: + case Kaltgr: break; default: nbsend(rawchan, &key.r); } } - s = nil; for(i=0; i<nb && cb[i] != key.c; i++) ; if(!key.down){ @@ -405,15 +366,14 @@ keyproc(void *) memmove(cb+i, cb+i+1, (nb-i+1) * sizeof(cb[0])); memmove(rb+i, rb+i+1, (nb-i+1) * sizeof(rb[0])); nb--; - s = utfconv(rb, nb); } } else if(i == nb && nb < nelem(cb) && key.r){ cb[nb] = key.c; rb[nb] = key.r; nb++; - s = utfconv(rb, nb); } - if(s && nbsendp(kbdchan, s) <= 0) + s = utfconv(rb, nb); + if(nbsendp(kbdchan, s) <= 0) free(s); } } @@ -480,7 +440,7 @@ lineproc(void *aux) } write(echofd, "\b", 1); continue; - case 0x04: /* eof */ + case Keof: p = l; done = 1; break; diff --git a/sys/src/cmd/rio/dat.h b/sys/src/cmd/rio/dat.h index 8deb25199..6db0a4cb4 100644 --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -9,6 +9,7 @@ enum Qwinname, Qkbdin, Qlabel, + Qkbd, Qmouse, Qnew, Qscreen, @@ -22,16 +23,11 @@ enum QMAX, }; -enum -{ - Kscrolloneup = KF|0x20, - Kscrollonedown = KF|0x21, -}; - #define STACK 8192 typedef struct Consreadmesg Consreadmesg; typedef struct Conswritemesg Conswritemesg; +typedef struct Kbdreadmesg Kbdreadmesg; typedef struct Stringpair Stringpair; typedef struct Dirtab Dirtab; typedef struct Fid Fid; @@ -98,6 +94,11 @@ struct Mousereadmesg Channel *cm; /* chan(Mouse) */ }; +struct Kbdreadmesg +{ + Channel *ck; /* chan(char*) */ +}; + struct Stringpair /* rune and nrune or byte and nbyte */ { void *s; @@ -129,12 +130,13 @@ struct Window Image *i; Mousectl mc; Mouseinfo mouse; - Channel *ck; /* chan(Rune[10]) */ + Channel *ck; /* chan(char*) */ Channel *cctl; /* chan(Wctlmesg)[20] */ Channel *conswrite; /* chan(Conswritemesg) */ Channel *consread; /* chan(Consreadmesg) */ Channel *mouseread; /* chan(Mousereadmesg) */ Channel *wctlread; /* chan(Consreadmesg) */ + Channel *kbdread; /* chan(Kbdreadmesg) */ uint nr; /* number of runes in window */ uint maxr; /* number of runes allocated in r */ Rune *r; @@ -167,6 +169,7 @@ struct Window uchar wctlopen; uchar deleted; uchar mouseopen; + uchar kbdopen; char *label; int pid; char *dir; @@ -303,7 +306,6 @@ struct Timer Font *font; Mousectl *mousectl; Mouse *mouse; -Keyboardctl *keyboardctl; Display *display; Image *view; Screen *wscreen; diff --git a/sys/src/cmd/rio/fsys.c b/sys/src/cmd/rio/fsys.c index f8cfa3e14..3f7e87e19 100644 --- a/sys/src/cmd/rio/fsys.c +++ b/sys/src/cmd/rio/fsys.c @@ -32,6 +32,7 @@ Dirtab dirtab[]= { "winname", QTFILE, Qwinname, 0400 }, { "kbdin", QTFILE, Qkbdin, 0200 }, { "label", QTFILE, Qlabel, 0600 }, + { "kbd", QTFILE, Qkbd, 0600 }, { "mouse", QTFILE, Qmouse, 0600 }, { "screen", QTFILE, Qscreen, 0400 }, { "snarf", QTFILE, Qsnarf, 0600 }, diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c index e699b0d69..91cbe6086 100644 --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -33,6 +33,7 @@ void refresh(Rectangle); void resized(void); Channel *exitchan; /* chan(int) */ Channel *winclosechan; /* chan(Window*); */ +Channel *kbdchan; /* chan(char*); */ Rectangle viewr; int threadrforkflag = 0; /* should be RFENVG but that hides rio from plumber */ @@ -41,6 +42,7 @@ void keyboardthread(void*); void winclosethread(void*); void deletethread(void*); void initcmd(void*); +Channel* initkbd(void); char *fontname; int mainpid; @@ -189,8 +191,8 @@ threadmain(int argc, char *argv[]) if(mousectl == nil) error("can't find mouse"); mouse = mousectl; - keyboardctl = initkeyboard(nil); - if(keyboardctl == nil) + kbdchan = initkbd(); + if(kbdchan == nil) error("can't find keyboard"); wscreen = allocscreen(screen, background, 0); if(wscreen == nil) @@ -332,21 +334,12 @@ killprocs(void) void keyboardthread(void*) { - Rune buf[2][20], *rp; - int n, i; + char *s; threadsetname("keyboardthread"); - n = 0; - for(;;){ - rp = buf[n]; - n = 1-n; - recv(keyboardctl->c, rp); - for(i=1; i<nelem(buf[0])-1; i++) - if(nbrecv(keyboardctl->c, rp+i) <= 0) - break; - rp[i] = L'\0'; - if(input != nil) - sendp(input->ck, rp); + while(s = recvp(kbdchan)){ + if(input == nil || sendp(input->ck, s) <= 0) + free(s); } } @@ -356,15 +349,22 @@ keyboardthread(void*) void keyboardsend(char *s, int cnt) { - Rune *r; - int i, nb, nr; - - r = runemalloc(cnt); - /* BUGlet: partial runes will be converted to error runes */ - cvttorunes(s, cnt, r, &nb, &nr, nil); - for(i=0; i<nr; i++) - send(keyboardctl->c, &r[i]); - free(r); + if(cnt <= 0) + return; + if(s[cnt-1] == 0) + chanprint(kbdchan, "%s", s); + else { + Rune *r; + int i, nb, nr; + + r = runemalloc(cnt); + cvttorunes(s, cnt, r, &nb, &nr, nil); + for(i=0; i<nr; i++){ + chanprint(kbdchan, "%C", r[i]); + chanprint(kbdchan, ""); + } + free(r); + } } int @@ -1141,7 +1141,7 @@ new(Image *i, int hideit, int scrollit, int pid, char *dir, char *cmd, char **ar if(i == nil) return nil; cm = chancreate(sizeof(Mouse), 0); - ck = chancreate(sizeof(Rune*), 0); + ck = chancreate(sizeof(char*), 0); cctl = chancreate(sizeof(Wctlmesg), 4); cpid = chancreate(sizeof(int), 0); if(cm==nil || ck==nil || cctl==nil) @@ -1189,3 +1189,78 @@ new(Image *i, int hideit, int scrollit, int pid, char *dir, char *cmd, char **ar chanfree(cpid); return w; } + +static void +kbdioproc(void *arg) +{ + Channel *c = arg; + char buf[128], *p, *e; + int fd, cfd, kfd, n; + + threadsetname("kbdioproc"); + + if((fd = open("/dev/cons", OREAD)) < 0){ + chanprint(c, "%r"); + return; + } + if((cfd = open("/dev/consctl", OWRITE)) < 0){ + chanprint(c, "%r"); + return; + } + fprint(cfd, "rawon"); + + if(sendp(c, nil) <= 0){ + close(cfd); + close(fd); + return; + } + + if((kfd = open("/dev/kbd", OREAD)) >= 0){ + close(fd); + + /* read kbd state */ + while((n = read(kfd, buf, sizeof(buf))) > 0) + chanprint(c, "%.*s", n, buf); + close(kfd); + } else { + /* read single characters */ + p = buf; + for(;;){ + Rune r; + + e = buf + sizeof(buf); + if((n = read(fd, p, e-p)) <= 0) + break; + e = p + n; + while(p < e && fullrune(p, e - p)){ + p += chartorune(&r, p); + chanprint(c, "%C", r); + chanprint(c, ""); + } + n = e - p; + if(n > 0){ + memmove(buf, p, n); + p = buf + n; + } + } + close(fd); + } + close(cfd); +} + +Channel* +initkbd(void) +{ + Channel *c; + char *err; + + c = chancreate(sizeof(char*), 16); + proccreate(kbdioproc, c, STACK); + if(err = recvp(c)){ + chanfree(c); + werrstr(err); + free(err); + return nil; + } + return c; +} diff --git a/sys/src/cmd/rio/wind.c b/sys/src/cmd/rio/wind.c index f3dc1a777..534d0cdb6 100644 --- a/sys/src/cmd/rio/wind.c +++ b/sys/src/cmd/rio/wind.c @@ -65,6 +65,7 @@ wmk(Image *i, Mousectl *mc, Channel *ck, Channel *cctl, int scrolling) w->cursorp = nil; w->conswrite = chancreate(sizeof(Conswritemesg), 0); w->consread = chancreate(sizeof(Consreadmesg), 0); + w->kbdread = chancreate(sizeof(Kbdreadmesg), 0); w->mouseread = chancreate(sizeof(Mousereadmesg), 0); w->wctlread = chancreate(sizeof(Consreadmesg), 0); w->scrollr = r; @@ -184,37 +185,42 @@ wclose(Window *w) void winctl(void *arg) { - Rune *rp, *bp, *tp, *up, *kbdr; + Rune *rp, *bp, *tp, *up; uint qh; int nr, nb, c, wid, i, npart, initial, lastb; char *s, *t, part[3]; Window *w; Mousestate *mp, m; - enum { WKey, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, NWALT }; + enum { WKbd, WKbdread, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, NWALT }; Alt alts[NWALT+1]; Mousereadmesg mrm; + Kbdreadmesg krm; Conswritemesg cwm; Consreadmesg crm; Consreadmesg cwrm; Stringpair pair; Wctlmesg wcm; - char buf[4*12+1]; + char buf[4*12+1], *kbdq[8], *kbds; + int kbdqr, kbdqw; w = arg; snprint(buf, sizeof buf, "winctl-id%d", w->id); threadsetname(buf); mrm.cm = chancreate(sizeof(Mouse), 0); + krm.ck = chancreate(sizeof(char*), 0); cwm.cw = chancreate(sizeof(Stringpair), 0); crm.c1 = chancreate(sizeof(Stringpair), 0); crm.c2 = chancreate(sizeof(Stringpair), 0); cwrm.c1 = chancreate(sizeof(Stringpair), 0); cwrm.c2 = chancreate(sizeof(Stringpair), 0); - - alts[WKey].c = w->ck; - alts[WKey].v = &kbdr; - alts[WKey].op = CHANRCV; + alts[WKbd].c = w->ck; + alts[WKbd].v = &kbds; + alts[WKbd].op = CHANRCV; + alts[WKbdread].c = w->kbdread; + alts[WKbdread].v = &krm; + alts[WKbdread].op = CHANSND; alts[WMouse].c = w->mc.c; alts[WMouse].v = &w->mc.Mouse; alts[WMouse].op = CHANRCV; @@ -235,21 +241,20 @@ winctl(void *arg) alts[WWread].op = CHANSND; alts[NWALT].op = CHANEND; + memset(kbdq, 0, sizeof(kbdq)); + kbdqr = kbdqw = 0; npart = 0; lastb = -1; for(;;){ - if(w->mouseopen && w->mouse.counter != w->mouse.lastcounter) - alts[WMouseread].op = CHANSND; - else - alts[WMouseread].op = CHANNOP; - if(!w->scrolling && !w->mouseopen && w->qh>w->org+w->nchars) - alts[WCwrite].op = CHANNOP; - else - alts[WCwrite].op = CHANSND; - if(w->deleted || !w->wctlready) - alts[WWread].op = CHANNOP; - else - alts[WWread].op = CHANSND; + alts[WKbdread].op = (w->kbdopen && kbdqw != kbdqr) ? + CHANSND : CHANNOP; + alts[WMouseread].op = (w->mouseopen && w->mouse.counter != w->mouse.lastcounter) ? + CHANSND : CHANNOP; + alts[WCwrite].op = (!w->scrolling && !w->mouseopen && w->qh>w->org+w->nchars) ? + CHANNOP : CHANSND; + alts[WWread].op = (w->deleted || !w->wctlready) ? + CHANNOP : CHANSND; + /* this code depends on NL and EOT fitting in a single byte */ /* kind of expensive for each loop; worth precomputing? */ if(w->holding) @@ -267,13 +272,36 @@ winctl(void *arg) } } switch(alt(alts)){ - case WKey: - for(i=0; kbdr[i]!=L'\0'; i++) - wkeyctl(w, kbdr[i]); -// wkeyctl(w, r); -/// while(nbrecv(w->ck, &r)) -// wkeyctl(w, r); + case WKbd: + if(utflen(kbds) >= utflen(kbdq[kbdqw] ? kbdq[kbdqw] : "")){ + Rune r; + + i = 0; + r = 0; + while(kbds[i]) + i += chartorune(&r, kbds+i); + wkeyctl(w, r); + } + if(w->kbdopen){ + i = (kbdqw+1) % nelem(kbdq); + if(i != kbdqr) + kbdqw = i; + } + free(kbdq[kbdqw]); + kbdq[kbdqw] = kbds; break; + + case WKbdread: + i = (kbdqr+1) % nelem(kbdq); + if(kbdqr != kbdqw) + kbdqr = i; + if(kbdq[i]){ + sendp(krm.ck, kbdq[i]); + kbdq[i] = nil; + }else + sendp(krm.ck, strdup("")); + continue; + case WMouse: if(w->mouseopen) { w->mouse.counter++; @@ -309,9 +337,12 @@ winctl(void *arg) continue; case WCtl: if(wctlmesg(w, wcm.type, wcm.r, wcm.image) == Exited){ + for(i=0; i<nelem(kbdq); i++) + free(kbdq[i]); chanfree(crm.c1); chanfree(crm.c2); chanfree(mrm.cm); + chanfree(krm.ck); chanfree(cwm.cw); chanfree(cwrm.c1); chanfree(cwrm.c2); @@ -560,8 +591,17 @@ wkeyctl(Window *w, Rune r) Rune *rp; int *notefd; - if(r == 0) + switch(r){ + case 0: + case Kcaps: + case Knum: + case Kshift: + case Kalt: + case Kctl: + case Kaltgr: return; + } + if(w->deleted) return; /* navigation keys work only when mouse is not open */ @@ -615,14 +655,14 @@ wkeyctl(Window *w, Rune r) case Kend: wshow(w, w->nr); return; - case 0x01: /* ^A: beginning of line */ + case Ksoh: /* ^A: beginning of line */ if(w->q0==0 || w->q0==w->qh || w->r[w->q0-1]=='\n') return; nb = wbswidth(w, 0x15 /* ^U */); wsetselect(w, w->q0-nb, w->q0-nb); wshow(w, w->q0); return; - case 0x05: /* ^E: end of line */ + case Kenq: /* ^E: end of line */ q0 = w->q0; while(q0 < w->nr && w->r[q0]!='\n') q0++; @@ -634,29 +674,29 @@ wkeyctl(Window *w, Rune r) waddraw(w, &r, 1); return; } - if(r==0x1B || (w->holding && r==0x7F)){ /* toggle hold */ + if(r==Kesc || (w->holding && r==Kdel)){ /* toggle hold */ if(w->holding) --w->holding; else w->holding++; wrepaint(w); - if(r == 0x1B) + if(r == Kesc) return; } - if(r != 0x7F){ + if(r != Kdel){ wsnarf(w); wcut(w); } switch(r){ - case 0x7F: /* send interrupt */ + case Kdel: /* send interrupt */ w->qh = w->nr; wshow(w, w->qh); notefd = emalloc(sizeof(int)); *notefd = w->notefd; proccreate(interruptproc, notefd, 4096); return; - case 0x06: /* ^F: file name completion */ - case Kins: /* Insert: file name completion */ + case Kack: /* ^F: file name completion */ + case Kins: /* Insert: file name completion */ rp = namecomplete(w); if(rp == nil) return; @@ -666,9 +706,9 @@ wkeyctl(Window *w, Rune r) wshow(w, q0+nr); free(rp); return; - case 0x08: /* ^H: erase character */ - case 0x15: /* ^U: erase line */ - case 0x17: /* ^W: erase word */ + case Kbs: /* ^H: erase character */ + case Knack: /* ^U: erase line */ + case Ketb: /* ^W: erase word */ if(w->q0==0 || w->q0==w->qh) return; nb = wbswidth(w, r); @@ -1122,6 +1162,7 @@ wctlmesg(Window *w, int m, Rectangle r, Image *i) chanfree(w->consread); chanfree(w->mouseread); chanfree(w->wctlread); + chanfree(w->kbdread); free(w->raw); free(w->r); free(w->dir); diff --git a/sys/src/cmd/rio/xfid.c b/sys/src/cmd/rio/xfid.c index c67f783fb..a13b6afed 100644 --- a/sys/src/cmd/rio/xfid.c +++ b/sys/src/cmd/rio/xfid.c @@ -243,6 +243,13 @@ xfidopen(Xfid *x) return; } break; + case Qkbd: + if(w->kbdopen){ + filsysrespond(x->fs, x, &t, Einuse); + return; + } + w->kbdopen = TRUE; + break; case Qmouse: if(w->mouseopen){ filsysrespond(x->fs, x, &t, Einuse); @@ -318,6 +325,9 @@ xfidclose(Xfid *x) w->cursorp = nil; wsetcursor(w, FALSE); break; + case Qkbd: + w->kbdopen = FALSE; + break; case Qmouse: w->resized = FALSE; w->mouseopen = FALSE; @@ -587,6 +597,7 @@ xfidread(Xfid *x) Consreadmesg crm; Mousereadmesg mrm; Consreadmesg cwrm; + Kbdreadmesg krm; Stringpair pair; enum { CRdata, CRflush, NCR }; enum { MRdata, MRflush, NMR }; @@ -696,6 +707,42 @@ xfidread(Xfid *x) qunlock(&x->active); break; + case Qkbd: + x->flushtag = x->tag; + + alts[MRdata].c = w->kbdread; + alts[MRdata].v = &krm; + alts[MRdata].op = CHANRCV; + alts[MRflush].c = x->flushc; + alts[MRflush].v = nil; + alts[MRflush].op = CHANRCV; + alts[NMR].op = CHANEND; + + switch(alt(alts)){ + case MRdata: + break; + case MRflush: + filsyscancel(x); + return; + } + + /* received data */ + t = recvp(krm.ck); + x->flushtag = -1; + if(x->flushing){ + free(t); /* wake up window and toss data */ + recv(x->flushc, nil); /* wake up flushing xfid */ + filsyscancel(x); + return; + } + qlock(&x->active); + fc.data = t; + fc.count = strlen(t)+1; + filsysrespond(x->fs, x, &fc, nil); + qunlock(&x->active); + free(t); + break; + case Qcursor: filsysrespond(x->fs, x, &fc, "cursor read not implemented"); break; |