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