17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <keyboard.h>
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier void
closekeyboard(Keyboardctl * kc)97dd7cddfSDavid du Colombier closekeyboard(Keyboardctl *kc)
107dd7cddfSDavid du Colombier {
117dd7cddfSDavid du Colombier if(kc == nil)
127dd7cddfSDavid du Colombier return;
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier postnote(PNPROC, kc->pid, "kill");
157dd7cddfSDavid du Colombier
167dd7cddfSDavid du Colombier #ifdef BUG
177dd7cddfSDavid du Colombier /* Drain the channel */
187dd7cddfSDavid du Colombier while(?kc->c)
197dd7cddfSDavid du Colombier <-kc->c;
207dd7cddfSDavid du Colombier #endif
217dd7cddfSDavid du Colombier
227dd7cddfSDavid du Colombier close(kc->ctlfd);
237dd7cddfSDavid du Colombier close(kc->consfd);
247dd7cddfSDavid du Colombier free(kc->file);
257dd7cddfSDavid du Colombier free(kc->c);
267dd7cddfSDavid du Colombier free(kc);
277dd7cddfSDavid du Colombier }
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier static
307dd7cddfSDavid du Colombier void
_ioproc(void * arg)313ff48bf5SDavid du Colombier _ioproc(void *arg)
327dd7cddfSDavid du Colombier {
337dd7cddfSDavid du Colombier int m, n;
347dd7cddfSDavid du Colombier char buf[20];
357dd7cddfSDavid du Colombier Rune r;
367dd7cddfSDavid du Colombier Keyboardctl *kc;
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier kc = arg;
397dd7cddfSDavid du Colombier threadsetname("kbdproc");
407dd7cddfSDavid du Colombier kc->pid = getpid();
417dd7cddfSDavid du Colombier n = 0;
427dd7cddfSDavid du Colombier for(;;){
437dd7cddfSDavid du Colombier while(n>0 && fullrune(buf, n)){
447dd7cddfSDavid du Colombier m = chartorune(&r, buf);
457dd7cddfSDavid du Colombier n -= m;
467dd7cddfSDavid du Colombier memmove(buf, buf+m, n);
477dd7cddfSDavid du Colombier send(kc->c, &r);
487dd7cddfSDavid du Colombier }
497dd7cddfSDavid du Colombier m = read(kc->consfd, buf+n, sizeof buf-n);
507dd7cddfSDavid du Colombier if(m <= 0){
519a747e4fSDavid du Colombier yield(); /* if error is due to exiting, we'll exit here */
529a747e4fSDavid du Colombier fprint(2, "keyboard read error: %r\n");
537dd7cddfSDavid du Colombier threadexits("error");
547dd7cddfSDavid du Colombier }
557dd7cddfSDavid du Colombier n += m;
567dd7cddfSDavid du Colombier }
577dd7cddfSDavid du Colombier }
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier Keyboardctl*
initkeyboard(char * file)607dd7cddfSDavid du Colombier initkeyboard(char *file)
617dd7cddfSDavid du Colombier {
62*b2d38b96SDavid du Colombier int nb;
637dd7cddfSDavid du Colombier Keyboardctl *kc;
647dd7cddfSDavid du Colombier char *t;
657dd7cddfSDavid du Colombier
667dd7cddfSDavid du Colombier kc = mallocz(sizeof(Keyboardctl), 1);
677dd7cddfSDavid du Colombier if(kc == nil)
687dd7cddfSDavid du Colombier return nil;
697dd7cddfSDavid du Colombier if(file == nil)
707dd7cddfSDavid du Colombier file = "/dev/cons";
717dd7cddfSDavid du Colombier kc->file = strdup(file);
727dd7cddfSDavid du Colombier kc->consfd = open(file, ORDWR|OCEXEC);
73*b2d38b96SDavid du Colombier nb = strlen(file)+16;
74*b2d38b96SDavid du Colombier t = malloc(nb);
757dd7cddfSDavid du Colombier if(kc->consfd<0 || t==nil){
767dd7cddfSDavid du Colombier Error1:
777dd7cddfSDavid du Colombier free(kc);
787dd7cddfSDavid du Colombier return nil;
797dd7cddfSDavid du Colombier }
80*b2d38b96SDavid du Colombier snprint(t, nb, "%sctl", file);
817dd7cddfSDavid du Colombier kc->ctlfd = open(t, OWRITE|OCEXEC);
827dd7cddfSDavid du Colombier if(kc->ctlfd < 0){
839a747e4fSDavid du Colombier fprint(2, "initkeyboard: can't open %s: %r\n", t);
847dd7cddfSDavid du Colombier Error2:
857dd7cddfSDavid du Colombier close(kc->consfd);
867dd7cddfSDavid du Colombier free(t);
877dd7cddfSDavid du Colombier goto Error1;
887dd7cddfSDavid du Colombier }
897dd7cddfSDavid du Colombier if(ctlkeyboard(kc, "rawon") < 0){
909a747e4fSDavid du Colombier fprint(2, "initkeyboard: can't turn on raw mode on %s: %r\n", t);
917dd7cddfSDavid du Colombier close(kc->ctlfd);
927dd7cddfSDavid du Colombier goto Error2;
937dd7cddfSDavid du Colombier }
947dd7cddfSDavid du Colombier free(t);
957dd7cddfSDavid du Colombier kc->c = chancreate(sizeof(Rune), 20);
963ff48bf5SDavid du Colombier proccreate(_ioproc, kc, 4096);
977dd7cddfSDavid du Colombier return kc;
987dd7cddfSDavid du Colombier }
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier int
ctlkeyboard(Keyboardctl * kc,char * m)1017dd7cddfSDavid du Colombier ctlkeyboard(Keyboardctl *kc, char *m)
1027dd7cddfSDavid du Colombier {
1037dd7cddfSDavid du Colombier return write(kc->ctlfd, m, strlen(m));
1047dd7cddfSDavid du Colombier }
105