summaryrefslogtreecommitdiff
path: root/sys/src/cmd/rio/rio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/src/cmd/rio/rio.c')
-rw-r--r--sys/src/cmd/rio/rio.c125
1 files changed, 100 insertions, 25 deletions
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;
+}