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)31*3ff48bf5SDavid 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 {
627dd7cddfSDavid du Colombier Keyboardctl *kc;
637dd7cddfSDavid du Colombier char *t;
647dd7cddfSDavid du Colombier
657dd7cddfSDavid du Colombier kc = mallocz(sizeof(Keyboardctl), 1);
667dd7cddfSDavid du Colombier if(kc == nil)
677dd7cddfSDavid du Colombier return nil;
687dd7cddfSDavid du Colombier if(file == nil)
697dd7cddfSDavid du Colombier file = "/dev/cons";
707dd7cddfSDavid du Colombier kc->file = strdup(file);
717dd7cddfSDavid du Colombier kc->consfd = open(file, ORDWR|OCEXEC);
727dd7cddfSDavid du Colombier t = malloc(strlen(file)+16);
737dd7cddfSDavid du Colombier if(kc->consfd<0 || t==nil){
747dd7cddfSDavid du Colombier Error1:
757dd7cddfSDavid du Colombier free(kc);
767dd7cddfSDavid du Colombier return nil;
777dd7cddfSDavid du Colombier }
787dd7cddfSDavid du Colombier sprint(t, "%sctl", file);
797dd7cddfSDavid du Colombier kc->ctlfd = open(t, OWRITE|OCEXEC);
807dd7cddfSDavid du Colombier if(kc->ctlfd < 0){
819a747e4fSDavid du Colombier fprint(2, "initkeyboard: can't open %s: %r\n", t);
827dd7cddfSDavid du Colombier Error2:
837dd7cddfSDavid du Colombier close(kc->consfd);
847dd7cddfSDavid du Colombier free(t);
857dd7cddfSDavid du Colombier goto Error1;
867dd7cddfSDavid du Colombier }
877dd7cddfSDavid du Colombier if(ctlkeyboard(kc, "rawon") < 0){
889a747e4fSDavid du Colombier fprint(2, "initkeyboard: can't turn on raw mode on %s: %r\n", t);
897dd7cddfSDavid du Colombier close(kc->ctlfd);
907dd7cddfSDavid du Colombier goto Error2;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier free(t);
937dd7cddfSDavid du Colombier kc->c = chancreate(sizeof(Rune), 20);
94*3ff48bf5SDavid du Colombier proccreate(_ioproc, kc, 4096);
957dd7cddfSDavid du Colombier return kc;
967dd7cddfSDavid du Colombier }
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier int
ctlkeyboard(Keyboardctl * kc,char * m)997dd7cddfSDavid du Colombier ctlkeyboard(Keyboardctl *kc, char *m)
1007dd7cddfSDavid du Colombier {
1017dd7cddfSDavid du Colombier return write(kc->ctlfd, m, strlen(m));
1027dd7cddfSDavid du Colombier }
103