add /dev/kbd support to rio

This commit is contained in:
cinap_lenrek 2011-05-11 05:55:48 +00:00
parent 2febff5948
commit 4fcc906e7f
7 changed files with 343 additions and 200 deletions

View file

@ -22,25 +22,42 @@ extern void closekeyboard(Keyboardctl*);
enum { enum {
KF= 0xF000, /* Rune: beginning of private Unicode space */ KF= 0xF000, /* Rune: beginning of private Unicode space */
Spec= 0xF800, 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 */ /* KF|1, KF|2, ..., KF|0xC is F1, F2, ..., F12 */
Khome= KF|0x0D, Khome= KF|0x0D,
Kup= KF|0x0E, Kup= KF|0x0E,
Kdown= Kview,
Kpgup= KF|0x0F, Kpgup= KF|0x0F,
Kprint= KF|0x10, Kprint= KF|0x10,
Kleft= KF|0x11, Kleft= KF|0x11,
Kright= KF|0x12, Kright= KF|0x12,
Kdown= Spec|0x00,
Kview= Spec|0x00,
Kpgdown= KF|0x13, Kpgdown= KF|0x13,
Kins= KF|0x14, Kins= KF|0x14,
Kend= KF|0x18,
Kalt= KF|0x15, Kalt= KF|0x15,
Kshift= KF|0x16, 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, Kbs= 0x08,
Knack= 0x15,
Ketb= 0x17,
Kdel= 0x7f, Kdel= 0x7f,
Kesc= 0x1b, Kesc= 0x1b,
Keof= 0x04,
Kbreak= Spec|0x61,
Kcaps= Spec|0x64,
Knum= Spec|0x65,
Kmiddle= Spec|0x66,
Kaltgr= Spec|0x67,
Kmouse= Spec|0x100,
}; };

View file

@ -3,43 +3,12 @@
#include <auth.h> #include <auth.h>
#include <fcall.h> #include <fcall.h>
#include <thread.h> #include <thread.h>
#include <keyboard.h>
#include <9p.h> #include <9p.h>
enum { 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, Nscan= 128,
Int= 0, /* scans indices */
Ext,
Nscans,
Qroot= 0, Qroot= 0,
Qkbd, Qkbd,
Qkbin, Qkbin,
@ -138,102 +107,102 @@ Channel *kbdchan; /* char* */
*/ */
Rune kbtab[Nscan] = 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', [0x08] '7', '8', '9', '0', '-', '=', '\b', '\t',
[0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', [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', ';', [0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v', [0x28] '\'', '`', Kshift, '\\', 'z', 'x', 'c', 'v',
[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*', [0x30] 'b', 'n', 'm', ',', '.', '/', Kshift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5, [0x38] Kalt, ' ', Kctl, KF|1, KF|2, KF|3, KF|4, KF|5,
[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7', [0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Knum, Kscroll, '7',
[0x48] '8', '9', '-', '4', '5', '6', '+', '1', [0x48] '8', '9', '-', '4', '5', '6', '+', '1',
[0x50] '2', '3', '0', '.', No, No, No, KF|11, [0x50] '2', '3', '0', '.', 0, 0, 0, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No, [0x58] KF|12, 0, 0, 0, 0, 0, 0, 0,
[0x60] No, No, No, No, No, No, No, No, [0x60] 0, 0, 0, 0, 0, 0, 0, 0,
[0x68] No, No, No, No, No, No, No, No, [0x68] 0, 0, 0, 0, 0, 0, 0, 0,
[0x70] No, No, No, No, No, No, No, No, [0x70] 0, 0, 0, 0, 0, 0, 0, 0,
[0x78] No, View, No, Up, No, No, No, No, [0x78] 0, Kdown, 0, Kup, 0, 0, 0, 0,
}; };
Rune kbtabshift[Nscan] = Rune kbtabshift[Nscan] =
{ {
[0x00] No, 0x1b, '!', '@', '#', '$', '%', '^', [0x00] 0, 0x1b, '!', '@', '#', '$', '%', '^',
[0x08] '&', '*', '(', ')', '_', '+', '\b', '\t', [0x08] '&', '*', '(', ')', '_', '+', '\b', '\t',
[0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', [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', ':', [0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V', [0x28] '"', '~', Kshift, '|', 'Z', 'X', 'C', 'V',
[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*', [0x30] 'B', 'N', 'M', '<', '>', '?', Kshift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5, [0x38] Kalt, ' ', Kctl, KF|1, KF|2, KF|3, KF|4, KF|5,
[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7', [0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Knum, Kscroll, '7',
[0x48] '8', '9', '-', '4', '5', '6', '+', '1', [0x48] '8', '9', '-', '4', '5', '6', '+', '1',
[0x50] '2', '3', '0', '.', No, No, No, KF|11, [0x50] '2', '3', '0', '.', 0, 0, 0, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No, [0x58] KF|12, 0, 0, 0, 0, 0, 0, 0,
[0x60] No, No, No, No, No, No, No, No, [0x60] 0, 0, 0, 0, 0, 0, 0, 0,
[0x68] No, No, No, No, No, No, No, No, [0x68] 0, 0, 0, 0, 0, 0, 0, 0,
[0x70] No, No, No, No, No, No, No, No, [0x70] 0, 0, 0, 0, 0, 0, 0, 0,
[0x78] No, Up, No, Up, No, No, No, No, [0x78] 0, Kup, 0, Kup, 0, 0, 0, 0,
}; };
Rune kbtabesc1[Nscan] = Rune kbtabesc1[Nscan] =
{ {
[0x00] No, No, No, No, No, No, No, No, [0x00] 0, 0, 0, 0, 0, 0, 0, 0,
[0x08] No, No, No, No, No, No, No, No, [0x08] 0, 0, 0, 0, 0, 0, 0, 0,
[0x10] No, No, No, No, No, No, No, No, [0x10] 0, 0, 0, 0, 0, 0, 0, 0,
[0x18] No, No, No, No, '\n', Ctrl, No, No, [0x18] 0, 0, 0, 0, '\n', Kctl, 0, 0,
[0x20] No, No, No, No, No, No, No, No, [0x20] 0, 0, 0, 0, 0, 0, 0, 0,
[0x28] No, No, Shift, No, No, No, No, No, [0x28] 0, 0, Kshift, 0, 0, 0, 0, 0,
[0x30] No, No, No, No, No, '/', No, Print, [0x30] 0, 0, 0, 0, 0, '/', 0, Kprint,
[0x38] Altgr, No, No, No, No, No, No, No, [0x38] Kaltgr, 0, 0, 0, 0, 0, 0, 0,
[0x40] No, No, No, No, No, No, Break, Home, [0x40] 0, 0, 0, 0, 0, 0, Kbreak, Khome,
[0x48] Up, Pgup, No, Left, No, Right, No, End, [0x48] Kup, Kpgup, 0, Kleft, 0, Kright, 0, Kend,
[0x50] Down, Pgdown, Ins, Del, No, No, No, No, [0x50] Kdown, Kpgdown, Kins, Kdel, 0, 0, 0, 0,
[0x58] No, No, No, No, No, No, No, No, [0x58] 0, 0, 0, 0, 0, 0, 0, 0,
[0x60] No, No, No, No, No, No, No, No, [0x60] 0, 0, 0, 0, 0, 0, 0, 0,
[0x68] No, No, No, No, No, No, No, No, [0x68] 0, 0, 0, 0, 0, 0, 0, 0,
[0x70] No, No, No, No, No, No, No, No, [0x70] 0, 0, 0, 0, 0, 0, 0, 0,
[0x78] No, Up, No, No, No, No, No, No, [0x78] 0, Kup, 0, 0, 0, 0, 0, 0,
}; };
Rune kbtabaltgr[Nscan] = Rune kbtabaltgr[Nscan] =
{ {
[0x00] No, No, No, No, No, No, No, No, [0x00] 0, 0, 0, 0, 0, 0, 0, 0,
[0x08] No, No, No, No, No, No, No, No, [0x08] 0, 0, 0, 0, 0, 0, 0, 0,
[0x10] No, No, No, No, No, No, No, No, [0x10] 0, 0, 0, 0, 0, 0, 0, 0,
[0x18] No, No, No, No, '\n', Ctrl, No, No, [0x18] 0, 0, 0, 0, '\n', Kctl, 0, 0,
[0x20] No, No, No, No, No, No, No, No, [0x20] 0, 0, 0, 0, 0, 0, 0, 0,
[0x28] No, No, Shift, No, No, No, No, No, [0x28] 0, 0, Kshift, 0, 0, 0, 0, 0,
[0x30] No, No, No, No, No, '/', No, Print, [0x30] 0, 0, 0, 0, 0, '/', 0, Kprint,
[0x38] Altgr, No, No, No, No, No, No, No, [0x38] Kaltgr, 0, 0, 0, 0, 0, 0, 0,
[0x40] No, No, No, No, No, No, Break, Home, [0x40] 0, 0, 0, 0, 0, 0, Kbreak, Khome,
[0x48] Up, Pgup, No, Left, No, Right, No, End, [0x48] Kup, Kpgup, 0, Kleft, 0, Kright, 0, Kend,
[0x50] Down, Pgdown, Ins, Del, No, No, No, No, [0x50] Kdown, Kpgdown, Kins, Kdel, 0, 0, 0, 0,
[0x58] No, No, No, No, No, No, No, No, [0x58] 0, 0, 0, 0, 0, 0, 0, 0,
[0x60] No, No, No, No, No, No, No, No, [0x60] 0, 0, 0, 0, 0, 0, 0, 0,
[0x68] No, No, No, No, No, No, No, No, [0x68] 0, 0, 0, 0, 0, 0, 0, 0,
[0x70] No, No, No, No, No, No, No, No, [0x70] 0, 0, 0, 0, 0, 0, 0, 0,
[0x78] No, Up, No, No, No, No, No, No, [0x78] 0, Kup, 0, 0, 0, 0, 0, 0,
}; };
Rune kbtabctrl[Nscan] = Rune kbtabctrl[Nscan] =
{ {
[0x00] No, '', '', '', '', '', '', '', [0x00] 0, '', '', '', '', '', '', '',
[0x08] '', '', '', '', ' ', '', '\b', '\t', [0x08] '', '', '', '', ' ', '', '\b', '\t',
[0x10] '', '', '', '', '', '', '', '\t', [0x10] '', '', '', '', '', '', '', '\t',
[0x18] '', '', '', '', '\n', Ctrl, '', '', [0x18] '', '', '', '', '\n', Kctl, '', '',
[0x20] '', '', '', '\b', '\n', ' ', ' ', '', [0x20] '', '', '', '\b', '\n', ' ', ' ', '',
[0x28] '', No, Shift, '', '', '', '', '', [0x28] '', 0, Kshift, '', '', '', '', '',
[0x30] '', '', ' ', ' ', '', '', Shift, '\n', [0x30] '', '', ' ', ' ', '', '', Kshift, '\n',
[0x38] Latin, No, Ctrl, '', '', '', '', '', [0x38] Kalt, 0, Kctl, '', '', '', '', '',
[0x40] '', '', ' ', ' ', '', '', '', '', [0x40] '', '', ' ', ' ', '', '', '', '',
[0x48] '', '', ' ', '', '', '', ' ', '', [0x48] '', '', ' ', '', '', '', ' ', '',
[0x50] '', '', '', '', No, No, No, '', [0x50] '', '', '', '', 0, 0, 0, '',
[0x58] ' ', No, No, No, No, No, No, No, [0x58] ' ', 0, 0, 0, 0, 0, 0, 0,
[0x60] No, No, No, No, No, No, No, No, [0x60] 0, 0, 0, 0, 0, 0, 0, 0,
[0x68] No, No, No, No, No, No, No, No, [0x68] 0, 0, 0, 0, 0, 0, 0, 0,
[0x70] No, No, No, No, No, No, No, No, [0x70] 0, 0, 0, 0, 0, 0, 0, 0,
[0x78] No, '', No, '\b', No, No, No, No, [0x78] 0, '', 0, '\b', 0, 0, 0, 0,
}; };
void reboot(void); void reboot(void);
@ -278,7 +247,7 @@ kbdputsc(Scan *scan, int c)
if(scan->caps && key.r<='z' && key.r>='a') if(scan->caps && key.r<='z' && key.r>='a')
key.r += 'A' - 'a'; key.r += 'A' - 'a';
if(scan->ctrl && scan->latin && key.r == Del) if(scan->ctrl && scan->latin && key.r == Kdel)
reboot(); reboot();
send(keychan, &key); send(keychan, &key);
@ -289,22 +258,22 @@ kbdputsc(Scan *scan, int c)
scan->esc2--; scan->esc2--;
switch(key.r){ switch(key.r){
case Shift: case Kshift:
scan->shift = key.down; scan->shift = key.down;
break; break;
case Ctrl: case Kctl:
scan->ctrl = key.down; scan->ctrl = key.down;
break; break;
case Altgr: case Kaltgr:
scan->altgr = key.down; scan->altgr = key.down;
break; break;
case Latin: case Kalt:
scan->latin = key.down; scan->latin = key.down;
break; break;
case Num: case Knum:
scan->num ^= key.down; scan->num ^= key.down;
break; break;
case Caps: case Kcaps:
scan->caps ^= key.down; scan->caps ^= key.down;
break; break;
} }
@ -377,27 +346,19 @@ keyproc(void *)
while(recv(keychan, &key) > 0){ while(recv(keychan, &key) > 0){
if(key.down){ if(key.down){
switch(key.r){ switch(key.r){
case No: case 0:
case Caps: case Kcaps:
case Num: case Knum:
case Shift: case Kshift:
case Latin: case Kalt:
case Ctrl: case Kctl:
case Altgr: case Kaltgr:
case Kmouse|1:
case Kmouse|2:
case Kmouse|3:
case Kmouse|4:
case Kmouse|5:
case KF|11:
case KF|12:
break; break;
default: default:
nbsend(rawchan, &key.r); nbsend(rawchan, &key.r);
} }
} }
s = nil;
for(i=0; i<nb && cb[i] != key.c; i++) for(i=0; i<nb && cb[i] != key.c; i++)
; ;
if(!key.down){ if(!key.down){
@ -405,15 +366,14 @@ keyproc(void *)
memmove(cb+i, cb+i+1, (nb-i+1) * sizeof(cb[0])); memmove(cb+i, cb+i+1, (nb-i+1) * sizeof(cb[0]));
memmove(rb+i, rb+i+1, (nb-i+1) * sizeof(rb[0])); memmove(rb+i, rb+i+1, (nb-i+1) * sizeof(rb[0]));
nb--; nb--;
s = utfconv(rb, nb);
} }
} else if(i == nb && nb < nelem(cb) && key.r){ } else if(i == nb && nb < nelem(cb) && key.r){
cb[nb] = key.c; cb[nb] = key.c;
rb[nb] = key.r; rb[nb] = key.r;
nb++; nb++;
s = utfconv(rb, nb);
} }
if(s && nbsendp(kbdchan, s) <= 0) s = utfconv(rb, nb);
if(nbsendp(kbdchan, s) <= 0)
free(s); free(s);
} }
} }
@ -480,7 +440,7 @@ lineproc(void *aux)
} }
write(echofd, "\b", 1); write(echofd, "\b", 1);
continue; continue;
case 0x04: /* eof */ case Keof:
p = l; p = l;
done = 1; done = 1;
break; break;

View file

@ -9,6 +9,7 @@ enum
Qwinname, Qwinname,
Qkbdin, Qkbdin,
Qlabel, Qlabel,
Qkbd,
Qmouse, Qmouse,
Qnew, Qnew,
Qscreen, Qscreen,
@ -22,16 +23,11 @@ enum
QMAX, QMAX,
}; };
enum
{
Kscrolloneup = KF|0x20,
Kscrollonedown = KF|0x21,
};
#define STACK 8192 #define STACK 8192
typedef struct Consreadmesg Consreadmesg; typedef struct Consreadmesg Consreadmesg;
typedef struct Conswritemesg Conswritemesg; typedef struct Conswritemesg Conswritemesg;
typedef struct Kbdreadmesg Kbdreadmesg;
typedef struct Stringpair Stringpair; typedef struct Stringpair Stringpair;
typedef struct Dirtab Dirtab; typedef struct Dirtab Dirtab;
typedef struct Fid Fid; typedef struct Fid Fid;
@ -98,6 +94,11 @@ struct Mousereadmesg
Channel *cm; /* chan(Mouse) */ Channel *cm; /* chan(Mouse) */
}; };
struct Kbdreadmesg
{
Channel *ck; /* chan(char*) */
};
struct Stringpair /* rune and nrune or byte and nbyte */ struct Stringpair /* rune and nrune or byte and nbyte */
{ {
void *s; void *s;
@ -129,12 +130,13 @@ struct Window
Image *i; Image *i;
Mousectl mc; Mousectl mc;
Mouseinfo mouse; Mouseinfo mouse;
Channel *ck; /* chan(Rune[10]) */ Channel *ck; /* chan(char*) */
Channel *cctl; /* chan(Wctlmesg)[20] */ Channel *cctl; /* chan(Wctlmesg)[20] */
Channel *conswrite; /* chan(Conswritemesg) */ Channel *conswrite; /* chan(Conswritemesg) */
Channel *consread; /* chan(Consreadmesg) */ Channel *consread; /* chan(Consreadmesg) */
Channel *mouseread; /* chan(Mousereadmesg) */ Channel *mouseread; /* chan(Mousereadmesg) */
Channel *wctlread; /* chan(Consreadmesg) */ Channel *wctlread; /* chan(Consreadmesg) */
Channel *kbdread; /* chan(Kbdreadmesg) */
uint nr; /* number of runes in window */ uint nr; /* number of runes in window */
uint maxr; /* number of runes allocated in r */ uint maxr; /* number of runes allocated in r */
Rune *r; Rune *r;
@ -167,6 +169,7 @@ struct Window
uchar wctlopen; uchar wctlopen;
uchar deleted; uchar deleted;
uchar mouseopen; uchar mouseopen;
uchar kbdopen;
char *label; char *label;
int pid; int pid;
char *dir; char *dir;
@ -303,7 +306,6 @@ struct Timer
Font *font; Font *font;
Mousectl *mousectl; Mousectl *mousectl;
Mouse *mouse; Mouse *mouse;
Keyboardctl *keyboardctl;
Display *display; Display *display;
Image *view; Image *view;
Screen *wscreen; Screen *wscreen;

View file

@ -32,6 +32,7 @@ Dirtab dirtab[]=
{ "winname", QTFILE, Qwinname, 0400 }, { "winname", QTFILE, Qwinname, 0400 },
{ "kbdin", QTFILE, Qkbdin, 0200 }, { "kbdin", QTFILE, Qkbdin, 0200 },
{ "label", QTFILE, Qlabel, 0600 }, { "label", QTFILE, Qlabel, 0600 },
{ "kbd", QTFILE, Qkbd, 0600 },
{ "mouse", QTFILE, Qmouse, 0600 }, { "mouse", QTFILE, Qmouse, 0600 },
{ "screen", QTFILE, Qscreen, 0400 }, { "screen", QTFILE, Qscreen, 0400 },
{ "snarf", QTFILE, Qsnarf, 0600 }, { "snarf", QTFILE, Qsnarf, 0600 },

View file

@ -33,6 +33,7 @@ void refresh(Rectangle);
void resized(void); void resized(void);
Channel *exitchan; /* chan(int) */ Channel *exitchan; /* chan(int) */
Channel *winclosechan; /* chan(Window*); */ Channel *winclosechan; /* chan(Window*); */
Channel *kbdchan; /* chan(char*); */
Rectangle viewr; Rectangle viewr;
int threadrforkflag = 0; /* should be RFENVG but that hides rio from plumber */ int threadrforkflag = 0; /* should be RFENVG but that hides rio from plumber */
@ -41,6 +42,7 @@ void keyboardthread(void*);
void winclosethread(void*); void winclosethread(void*);
void deletethread(void*); void deletethread(void*);
void initcmd(void*); void initcmd(void*);
Channel* initkbd(void);
char *fontname; char *fontname;
int mainpid; int mainpid;
@ -189,8 +191,8 @@ threadmain(int argc, char *argv[])
if(mousectl == nil) if(mousectl == nil)
error("can't find mouse"); error("can't find mouse");
mouse = mousectl; mouse = mousectl;
keyboardctl = initkeyboard(nil); kbdchan = initkbd();
if(keyboardctl == nil) if(kbdchan == nil)
error("can't find keyboard"); error("can't find keyboard");
wscreen = allocscreen(screen, background, 0); wscreen = allocscreen(screen, background, 0);
if(wscreen == nil) if(wscreen == nil)
@ -332,21 +334,12 @@ killprocs(void)
void void
keyboardthread(void*) keyboardthread(void*)
{ {
Rune buf[2][20], *rp; char *s;
int n, i;
threadsetname("keyboardthread"); threadsetname("keyboardthread");
n = 0; while(s = recvp(kbdchan)){
for(;;){ if(input == nil || sendp(input->ck, s) <= 0)
rp = buf[n]; free(s);
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);
} }
} }
@ -356,15 +349,22 @@ keyboardthread(void*)
void void
keyboardsend(char *s, int cnt) keyboardsend(char *s, int cnt)
{ {
Rune *r; if(cnt <= 0)
int i, nb, nr; return;
if(s[cnt-1] == 0)
chanprint(kbdchan, "%s", s);
else {
Rune *r;
int i, nb, nr;
r = runemalloc(cnt); r = runemalloc(cnt);
/* BUGlet: partial runes will be converted to error runes */ cvttorunes(s, cnt, r, &nb, &nr, nil);
cvttorunes(s, cnt, r, &nb, &nr, nil); for(i=0; i<nr; i++){
for(i=0; i<nr; i++) chanprint(kbdchan, "%C", r[i]);
send(keyboardctl->c, &r[i]); chanprint(kbdchan, "");
free(r); }
free(r);
}
} }
int int
@ -1141,7 +1141,7 @@ new(Image *i, int hideit, int scrollit, int pid, char *dir, char *cmd, char **ar
if(i == nil) if(i == nil)
return nil; return nil;
cm = chancreate(sizeof(Mouse), 0); cm = chancreate(sizeof(Mouse), 0);
ck = chancreate(sizeof(Rune*), 0); ck = chancreate(sizeof(char*), 0);
cctl = chancreate(sizeof(Wctlmesg), 4); cctl = chancreate(sizeof(Wctlmesg), 4);
cpid = chancreate(sizeof(int), 0); cpid = chancreate(sizeof(int), 0);
if(cm==nil || ck==nil || cctl==nil) 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); chanfree(cpid);
return w; 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;
}

View file

@ -65,6 +65,7 @@ wmk(Image *i, Mousectl *mc, Channel *ck, Channel *cctl, int scrolling)
w->cursorp = nil; w->cursorp = nil;
w->conswrite = chancreate(sizeof(Conswritemesg), 0); w->conswrite = chancreate(sizeof(Conswritemesg), 0);
w->consread = chancreate(sizeof(Consreadmesg), 0); w->consread = chancreate(sizeof(Consreadmesg), 0);
w->kbdread = chancreate(sizeof(Kbdreadmesg), 0);
w->mouseread = chancreate(sizeof(Mousereadmesg), 0); w->mouseread = chancreate(sizeof(Mousereadmesg), 0);
w->wctlread = chancreate(sizeof(Consreadmesg), 0); w->wctlread = chancreate(sizeof(Consreadmesg), 0);
w->scrollr = r; w->scrollr = r;
@ -184,37 +185,42 @@ wclose(Window *w)
void void
winctl(void *arg) winctl(void *arg)
{ {
Rune *rp, *bp, *tp, *up, *kbdr; Rune *rp, *bp, *tp, *up;
uint qh; uint qh;
int nr, nb, c, wid, i, npart, initial, lastb; int nr, nb, c, wid, i, npart, initial, lastb;
char *s, *t, part[3]; char *s, *t, part[3];
Window *w; Window *w;
Mousestate *mp, m; 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]; Alt alts[NWALT+1];
Mousereadmesg mrm; Mousereadmesg mrm;
Kbdreadmesg krm;
Conswritemesg cwm; Conswritemesg cwm;
Consreadmesg crm; Consreadmesg crm;
Consreadmesg cwrm; Consreadmesg cwrm;
Stringpair pair; Stringpair pair;
Wctlmesg wcm; Wctlmesg wcm;
char buf[4*12+1]; char buf[4*12+1], *kbdq[8], *kbds;
int kbdqr, kbdqw;
w = arg; w = arg;
snprint(buf, sizeof buf, "winctl-id%d", w->id); snprint(buf, sizeof buf, "winctl-id%d", w->id);
threadsetname(buf); threadsetname(buf);
mrm.cm = chancreate(sizeof(Mouse), 0); mrm.cm = chancreate(sizeof(Mouse), 0);
krm.ck = chancreate(sizeof(char*), 0);
cwm.cw = chancreate(sizeof(Stringpair), 0); cwm.cw = chancreate(sizeof(Stringpair), 0);
crm.c1 = chancreate(sizeof(Stringpair), 0); crm.c1 = chancreate(sizeof(Stringpair), 0);
crm.c2 = chancreate(sizeof(Stringpair), 0); crm.c2 = chancreate(sizeof(Stringpair), 0);
cwrm.c1 = chancreate(sizeof(Stringpair), 0); cwrm.c1 = chancreate(sizeof(Stringpair), 0);
cwrm.c2 = chancreate(sizeof(Stringpair), 0); cwrm.c2 = chancreate(sizeof(Stringpair), 0);
alts[WKbd].c = w->ck;
alts[WKey].c = w->ck; alts[WKbd].v = &kbds;
alts[WKey].v = &kbdr; alts[WKbd].op = CHANRCV;
alts[WKey].op = CHANRCV; alts[WKbdread].c = w->kbdread;
alts[WKbdread].v = &krm;
alts[WKbdread].op = CHANSND;
alts[WMouse].c = w->mc.c; alts[WMouse].c = w->mc.c;
alts[WMouse].v = &w->mc.Mouse; alts[WMouse].v = &w->mc.Mouse;
alts[WMouse].op = CHANRCV; alts[WMouse].op = CHANRCV;
@ -235,21 +241,20 @@ winctl(void *arg)
alts[WWread].op = CHANSND; alts[WWread].op = CHANSND;
alts[NWALT].op = CHANEND; alts[NWALT].op = CHANEND;
memset(kbdq, 0, sizeof(kbdq));
kbdqr = kbdqw = 0;
npart = 0; npart = 0;
lastb = -1; lastb = -1;
for(;;){ for(;;){
if(w->mouseopen && w->mouse.counter != w->mouse.lastcounter) alts[WKbdread].op = (w->kbdopen && kbdqw != kbdqr) ?
alts[WMouseread].op = CHANSND; CHANSND : CHANNOP;
else alts[WMouseread].op = (w->mouseopen && w->mouse.counter != w->mouse.lastcounter) ?
alts[WMouseread].op = CHANNOP; CHANSND : CHANNOP;
if(!w->scrolling && !w->mouseopen && w->qh>w->org+w->nchars) alts[WCwrite].op = (!w->scrolling && !w->mouseopen && w->qh>w->org+w->nchars) ?
alts[WCwrite].op = CHANNOP; CHANNOP : CHANSND;
else alts[WWread].op = (w->deleted || !w->wctlready) ?
alts[WCwrite].op = CHANSND; CHANNOP : CHANSND;
if(w->deleted || !w->wctlready)
alts[WWread].op = CHANNOP;
else
alts[WWread].op = CHANSND;
/* this code depends on NL and EOT fitting in a single byte */ /* this code depends on NL and EOT fitting in a single byte */
/* kind of expensive for each loop; worth precomputing? */ /* kind of expensive for each loop; worth precomputing? */
if(w->holding) if(w->holding)
@ -267,13 +272,36 @@ winctl(void *arg)
} }
} }
switch(alt(alts)){ switch(alt(alts)){
case WKey: case WKbd:
for(i=0; kbdr[i]!=L'\0'; i++) if(utflen(kbds) >= utflen(kbdq[kbdqw] ? kbdq[kbdqw] : "")){
wkeyctl(w, kbdr[i]); Rune r;
// wkeyctl(w, r);
/// while(nbrecv(w->ck, &r)) i = 0;
// wkeyctl(w, r); 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; 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: case WMouse:
if(w->mouseopen) { if(w->mouseopen) {
w->mouse.counter++; w->mouse.counter++;
@ -309,9 +337,12 @@ winctl(void *arg)
continue; continue;
case WCtl: case WCtl:
if(wctlmesg(w, wcm.type, wcm.r, wcm.image) == Exited){ 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.c1);
chanfree(crm.c2); chanfree(crm.c2);
chanfree(mrm.cm); chanfree(mrm.cm);
chanfree(krm.ck);
chanfree(cwm.cw); chanfree(cwm.cw);
chanfree(cwrm.c1); chanfree(cwrm.c1);
chanfree(cwrm.c2); chanfree(cwrm.c2);
@ -560,8 +591,17 @@ wkeyctl(Window *w, Rune r)
Rune *rp; Rune *rp;
int *notefd; int *notefd;
if(r == 0) switch(r){
case 0:
case Kcaps:
case Knum:
case Kshift:
case Kalt:
case Kctl:
case Kaltgr:
return; return;
}
if(w->deleted) if(w->deleted)
return; return;
/* navigation keys work only when mouse is not open */ /* navigation keys work only when mouse is not open */
@ -615,14 +655,14 @@ wkeyctl(Window *w, Rune r)
case Kend: case Kend:
wshow(w, w->nr); wshow(w, w->nr);
return; 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') if(w->q0==0 || w->q0==w->qh || w->r[w->q0-1]=='\n')
return; return;
nb = wbswidth(w, 0x15 /* ^U */); nb = wbswidth(w, 0x15 /* ^U */);
wsetselect(w, w->q0-nb, w->q0-nb); wsetselect(w, w->q0-nb, w->q0-nb);
wshow(w, w->q0); wshow(w, w->q0);
return; return;
case 0x05: /* ^E: end of line */ case Kenq: /* ^E: end of line */
q0 = w->q0; q0 = w->q0;
while(q0 < w->nr && w->r[q0]!='\n') while(q0 < w->nr && w->r[q0]!='\n')
q0++; q0++;
@ -634,29 +674,29 @@ wkeyctl(Window *w, Rune r)
waddraw(w, &r, 1); waddraw(w, &r, 1);
return; return;
} }
if(r==0x1B || (w->holding && r==0x7F)){ /* toggle hold */ if(r==Kesc || (w->holding && r==Kdel)){ /* toggle hold */
if(w->holding) if(w->holding)
--w->holding; --w->holding;
else else
w->holding++; w->holding++;
wrepaint(w); wrepaint(w);
if(r == 0x1B) if(r == Kesc)
return; return;
} }
if(r != 0x7F){ if(r != Kdel){
wsnarf(w); wsnarf(w);
wcut(w); wcut(w);
} }
switch(r){ switch(r){
case 0x7F: /* send interrupt */ case Kdel: /* send interrupt */
w->qh = w->nr; w->qh = w->nr;
wshow(w, w->qh); wshow(w, w->qh);
notefd = emalloc(sizeof(int)); notefd = emalloc(sizeof(int));
*notefd = w->notefd; *notefd = w->notefd;
proccreate(interruptproc, notefd, 4096); proccreate(interruptproc, notefd, 4096);
return; return;
case 0x06: /* ^F: file name completion */ case Kack: /* ^F: file name completion */
case Kins: /* Insert: file name completion */ case Kins: /* Insert: file name completion */
rp = namecomplete(w); rp = namecomplete(w);
if(rp == nil) if(rp == nil)
return; return;
@ -666,9 +706,9 @@ wkeyctl(Window *w, Rune r)
wshow(w, q0+nr); wshow(w, q0+nr);
free(rp); free(rp);
return; return;
case 0x08: /* ^H: erase character */ case Kbs: /* ^H: erase character */
case 0x15: /* ^U: erase line */ case Knack: /* ^U: erase line */
case 0x17: /* ^W: erase word */ case Ketb: /* ^W: erase word */
if(w->q0==0 || w->q0==w->qh) if(w->q0==0 || w->q0==w->qh)
return; return;
nb = wbswidth(w, r); nb = wbswidth(w, r);
@ -1122,6 +1162,7 @@ wctlmesg(Window *w, int m, Rectangle r, Image *i)
chanfree(w->consread); chanfree(w->consread);
chanfree(w->mouseread); chanfree(w->mouseread);
chanfree(w->wctlread); chanfree(w->wctlread);
chanfree(w->kbdread);
free(w->raw); free(w->raw);
free(w->r); free(w->r);
free(w->dir); free(w->dir);

View file

@ -243,6 +243,13 @@ xfidopen(Xfid *x)
return; return;
} }
break; break;
case Qkbd:
if(w->kbdopen){
filsysrespond(x->fs, x, &t, Einuse);
return;
}
w->kbdopen = TRUE;
break;
case Qmouse: case Qmouse:
if(w->mouseopen){ if(w->mouseopen){
filsysrespond(x->fs, x, &t, Einuse); filsysrespond(x->fs, x, &t, Einuse);
@ -318,6 +325,9 @@ xfidclose(Xfid *x)
w->cursorp = nil; w->cursorp = nil;
wsetcursor(w, FALSE); wsetcursor(w, FALSE);
break; break;
case Qkbd:
w->kbdopen = FALSE;
break;
case Qmouse: case Qmouse:
w->resized = FALSE; w->resized = FALSE;
w->mouseopen = FALSE; w->mouseopen = FALSE;
@ -587,6 +597,7 @@ xfidread(Xfid *x)
Consreadmesg crm; Consreadmesg crm;
Mousereadmesg mrm; Mousereadmesg mrm;
Consreadmesg cwrm; Consreadmesg cwrm;
Kbdreadmesg krm;
Stringpair pair; Stringpair pair;
enum { CRdata, CRflush, NCR }; enum { CRdata, CRflush, NCR };
enum { MRdata, MRflush, NMR }; enum { MRdata, MRflush, NMR };
@ -696,6 +707,42 @@ xfidread(Xfid *x)
qunlock(&x->active); qunlock(&x->active);
break; 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: case Qcursor:
filsysrespond(x->fs, x, &fc, "cursor read not implemented"); filsysrespond(x->fs, x, &fc, "cursor read not implemented");
break; break;