keyboard.c 1.7 KB

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