1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 #include <thread.h> 5 #include <keyboard.h> 6 7 8 void 9 closekeyboard(Keyboardctl *kc) 10 { 11 if(kc == nil) 12 return; 13 14 postnote(PNPROC, kc->pid, "kill"); 15 16 #ifdef BUG 17 /* Drain the channel */ 18 while(?kc->c) 19 <-kc->c; 20 #endif 21 22 close(kc->ctlfd); 23 close(kc->consfd); 24 free(kc->file); 25 free(kc->c); 26 free(kc); 27 } 28 29 static 30 void 31 _ioproc(void *arg) 32 { 33 int m, n; 34 char buf[20]; 35 Rune r; 36 Keyboardctl *kc; 37 38 kc = arg; 39 threadsetname("kbdproc"); 40 kc->pid = getpid(); 41 n = 0; 42 for(;;){ 43 while(n>0 && fullrune(buf, n)){ 44 m = chartorune(&r, buf); 45 n -= m; 46 memmove(buf, buf+m, n); 47 send(kc->c, &r); 48 } 49 m = read(kc->consfd, buf+n, sizeof buf-n); 50 if(m <= 0){ 51 yield(); /* if error is due to exiting, we'll exit here */ 52 fprint(2, "keyboard read error: %r\n"); 53 threadexits("error"); 54 } 55 n += m; 56 } 57 } 58 59 Keyboardctl* 60 initkeyboard(char *file) 61 { 62 Keyboardctl *kc; 63 char *t; 64 65 kc = mallocz(sizeof(Keyboardctl), 1); 66 if(kc == nil) 67 return nil; 68 if(file == nil) 69 file = "/dev/cons"; 70 kc->file = strdup(file); 71 kc->consfd = open(file, ORDWR|OCEXEC); 72 t = malloc(strlen(file)+16); 73 if(kc->consfd<0 || t==nil){ 74 Error1: 75 free(kc); 76 return nil; 77 } 78 sprint(t, "%sctl", file); 79 kc->ctlfd = open(t, OWRITE|OCEXEC); 80 if(kc->ctlfd < 0){ 81 fprint(2, "initkeyboard: can't open %s: %r\n", t); 82 Error2: 83 close(kc->consfd); 84 free(t); 85 goto Error1; 86 } 87 if(ctlkeyboard(kc, "rawon") < 0){ 88 fprint(2, "initkeyboard: can't turn on raw mode on %s: %r\n", t); 89 close(kc->ctlfd); 90 goto Error2; 91 } 92 free(t); 93 kc->c = chancreate(sizeof(Rune), 20); 94 proccreate(_ioproc, kc, 4096); 95 return kc; 96 } 97 98 int 99 ctlkeyboard(Keyboardctl *kc, char *m) 100 { 101 return write(kc->ctlfd, m, strlen(m)); 102 } 103