Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <keyboard.h>
8 void
9 closekeyboard(Keyboardctl *kc)
10 {
11 if(kc == nil)
12 return;
14 postnote(PNPROC, kc->pid, "kill");
16 #ifdef BUG
17 /* Drain the channel */
18 while(?kc->c)
19 <-kc->c;
20 #endif
22 close(kc->ctlfd);
23 close(kc->consfd);
24 free(kc->file);
25 free(kc->c);
26 free(kc);
27 }
29 static
30 void
31 _ioproc(void *arg)
32 {
33 int m, n;
34 char buf[20];
35 Rune r;
36 Keyboardctl *kc;
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 }
59 Keyboardctl*
60 initkeyboard(char *file)
61 {
62 Keyboardctl *kc;
63 char *t;
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 chansetname(kc->c, "kbdc");
95 proccreate(_ioproc, kc, 4096);
96 return kc;
97 }
99 int
100 ctlkeyboard(Keyboardctl *kc, char *m)
102 return write(kc->ctlfd, m, strlen(m));