mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
103 lines
1.7 KiB
C
103 lines
1.7 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <draw.h>
|
|
#include <thread.h>
|
|
#include <keyboard.h>
|
|
|
|
|
|
void
|
|
closekeyboard(Keyboardctl *kc)
|
|
{
|
|
if(kc == nil)
|
|
return;
|
|
|
|
postnote(PNPROC, kc->pid, "kill");
|
|
|
|
#ifdef BUG
|
|
/* Drain the channel */
|
|
while(?kc->c)
|
|
<-kc->c;
|
|
#endif
|
|
|
|
close(kc->ctlfd);
|
|
close(kc->consfd);
|
|
free(kc->file);
|
|
free(kc->c);
|
|
free(kc);
|
|
}
|
|
|
|
static
|
|
void
|
|
_ioproc(void *arg)
|
|
{
|
|
int m, n;
|
|
char buf[20];
|
|
Rune r;
|
|
Keyboardctl *kc;
|
|
|
|
kc = arg;
|
|
threadsetname("kbdproc");
|
|
kc->pid = getpid();
|
|
n = 0;
|
|
for(;;){
|
|
while(n>0 && fullrune(buf, n)){
|
|
m = chartorune(&r, buf);
|
|
n -= m;
|
|
memmove(buf, buf+m, n);
|
|
send(kc->c, &r);
|
|
}
|
|
m = read(kc->consfd, buf+n, sizeof buf-n);
|
|
if(m <= 0){
|
|
yield(); /* if error is due to exiting, we'll exit here */
|
|
fprint(2, "keyboard read error: %r\n");
|
|
threadexits("error");
|
|
}
|
|
n += m;
|
|
}
|
|
}
|
|
|
|
Keyboardctl*
|
|
initkeyboard(char *file)
|
|
{
|
|
Keyboardctl *kc;
|
|
char *t;
|
|
|
|
kc = mallocz(sizeof(Keyboardctl), 1);
|
|
if(kc == nil)
|
|
return nil;
|
|
if(file == nil)
|
|
file = "/dev/cons";
|
|
kc->file = strdup(file);
|
|
kc->consfd = open(file, ORDWR|OCEXEC);
|
|
t = malloc(strlen(file)+16);
|
|
if(kc->consfd<0 || t==nil){
|
|
Error1:
|
|
free(kc);
|
|
return nil;
|
|
}
|
|
sprint(t, "%sctl", file);
|
|
kc->ctlfd = open(t, OWRITE|OCEXEC);
|
|
if(kc->ctlfd < 0){
|
|
fprint(2, "initkeyboard: can't open %s: %r\n", t);
|
|
Error2:
|
|
close(kc->consfd);
|
|
free(t);
|
|
goto Error1;
|
|
}
|
|
if(ctlkeyboard(kc, "rawon") < 0){
|
|
fprint(2, "initkeyboard: can't turn on raw mode on %s: %r\n", t);
|
|
close(kc->ctlfd);
|
|
goto Error2;
|
|
}
|
|
free(t);
|
|
kc->c = chancreate(sizeof(Rune), 20);
|
|
chansetname(kc->c, "kbdc");
|
|
proccreate(_ioproc, kc, 4096);
|
|
return kc;
|
|
}
|
|
|
|
int
|
|
ctlkeyboard(Keyboardctl *kc, char *m)
|
|
{
|
|
return write(kc->ctlfd, m, strlen(m));
|
|
}
|