usbmouse.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. int mousefd, ctlfd, mousein;
  5. char hbm[] = "Enabled 0x020103";
  6. char *mouseinfile = "/dev/mousein";
  7. char *statfmt = "/dev/usb%d/%d/status";
  8. char *ctlfmt = "/dev/usb%d/%d/ctl";
  9. char *msefmt = "/dev/usb%d/%d/ep1data";
  10. char *ctl3str = "ep 1 bulk r 3 32";
  11. char *ctl5str = "ep 1 bulk r 5 32";
  12. char ctlfile[32];
  13. char msefile[32];
  14. int verbose;
  15. int nofork;
  16. int accel;
  17. int scroll;
  18. int maxacc = 3;
  19. int debug;
  20. void work(void *);
  21. int
  22. robusthandler(void*, char *s)
  23. {
  24. if (debug) fprint(2, "inthandler: %s\n", s);
  25. return (s && (strstr(s, "interrupted")|| strstr(s, "hangup")));
  26. }
  27. long
  28. robustread(int fd, void *buf, long sz)
  29. {
  30. long r;
  31. char err[ERRMAX];
  32. do {
  33. r = read(fd , buf, sz);
  34. if (r < 0)
  35. rerrstr(err, sizeof(err));
  36. } while (r < 0 && robusthandler(nil, err));
  37. return r;
  38. }
  39. static int
  40. scale(int x)
  41. {
  42. int sign = 1;
  43. if(x < 0){
  44. sign = -1;
  45. x = -x;
  46. }
  47. switch(x){
  48. case 0:
  49. case 1:
  50. case 2:
  51. case 3:
  52. break;
  53. case 4:
  54. x = 6 + (accel>>2);
  55. break;
  56. case 5:
  57. x = 9 + (accel>>1);
  58. break;
  59. default:
  60. x *= maxacc;
  61. break;
  62. }
  63. return sign*x;
  64. }
  65. char maptab[] = {
  66. 0x0, 0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7
  67. };
  68. void
  69. usage(void)
  70. {
  71. fprint(2, "usage: %s [-fsv] [-a accel] [ctlrno usbport]\n", argv0);
  72. threadexitsall("usage");
  73. }
  74. void
  75. threadmain(int argc, char *argv[])
  76. {
  77. int ctlrno, i, sfd;
  78. char line[256];
  79. ARGBEGIN{
  80. case 's':
  81. scroll=1;
  82. break;
  83. case 'v':
  84. verbose=1;
  85. break;
  86. case 'f':
  87. nofork=1;
  88. break;
  89. case 'a':
  90. accel=strtol(EARGF(usage()), nil, 0);
  91. break;
  92. default:
  93. usage();
  94. }ARGEND
  95. switch (argc) {
  96. case 0:
  97. for (ctlrno = 0; ctlrno < 16; ctlrno++) {
  98. for (i = 0; i < 128; i++) {
  99. snprint(line, sizeof line, statfmt, ctlrno, i);
  100. sfd = open(line, OREAD);
  101. if (sfd < 0)
  102. break;
  103. if (read(sfd, line, strlen(hbm)) && strncmp(hbm, line, strlen(hbm)) == 0) {
  104. snprint(ctlfile, sizeof ctlfile, ctlfmt, ctlrno, i);
  105. snprint(msefile, sizeof msefile, msefmt, ctlrno, i);
  106. close(sfd);
  107. goto found;
  108. }
  109. close(sfd);
  110. }
  111. }
  112. threadexitsall("no mouse");
  113. found:
  114. break;
  115. case 2:
  116. ctlrno = atoi(argv[0]);
  117. i = atoi(argv[1]);
  118. snprint(ctlfile, sizeof ctlfile, ctlfmt, ctlrno, i);
  119. snprint(msefile, sizeof msefile, msefmt, ctlrno, i);
  120. break;
  121. default:
  122. usage();
  123. }
  124. if ((ctlfd = open(ctlfile, OWRITE)) < 0)
  125. sysfatal("%s: %r", ctlfile);
  126. if (verbose)
  127. fprint(2, "Send %s to %s\n", scroll?ctl5str:ctl3str, ctlfile);
  128. write(ctlfd, scroll?ctl5str:ctl3str, scroll?strlen(ctl5str):strlen(ctl3str));
  129. close(ctlfd);
  130. if ((mousefd = open(msefile, OREAD)) < 0)
  131. sysfatal("%s: %r", msefile);
  132. if (verbose)
  133. fprint(2, "Start reading from %s\n", msefile);
  134. if ((mousein = open(mouseinfile, OWRITE)) < 0)
  135. sysfatal("%s: %r", mouseinfile);
  136. atnotify(robusthandler, 1);
  137. if (nofork)
  138. work(nil);
  139. else
  140. proccreate(work, nil, 4*1024);
  141. threadexits(nil);
  142. }
  143. void
  144. work(void *){
  145. char buf[6];
  146. int x, y, buts;
  147. for (;;) {
  148. buts = 0;
  149. switch (robustread(mousefd, buf, scroll?5:3)) {
  150. case 4:
  151. if(buf[3] == 1)
  152. buts |= 0x08;
  153. else if(buf[3] == -1)
  154. buts |= 0x10;
  155. /* Fall through */
  156. case 5:
  157. if(buf[3] > 10)
  158. buts |= 0x08;
  159. else if(buf[3] < -10)
  160. buts |= 0x10;
  161. /* Fall through */
  162. case 3:
  163. if (accel) {
  164. x = scale(buf[1]);
  165. y = scale(buf[2]);
  166. } else {
  167. x = buf[1];
  168. y = buf[2];
  169. }
  170. fprint(mousein, "m%11d %11d %11d", x, y, buts | maptab[buf[0]&0x7]);
  171. break;
  172. case -1:
  173. sysfatal("read error: %r");
  174. }
  175. }
  176. }