accupoint.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <draw.h>
  12. #include <event.h>
  13. /*
  14. * Convert AccuPoint buttons 4 and 5 to a simulation of button 2.
  15. * The buttons generate down events, repeat, and have no up events,
  16. * so it's a struggle. This program turns the left button into a near-as-
  17. * possible simulation of a regular button 2, but it can only sense up
  18. * events by timeout, so it's sluggish. Thus it also turns the right button
  19. * into a click on button 2, useful for acme and chords.
  20. */
  21. typedef struct M M;
  22. struct M
  23. {
  24. Mouse Mouse;
  25. int byte;
  26. };
  27. int button2;
  28. int interrupted;
  29. int
  30. readmouse(M *m)
  31. {
  32. char buf[1+4*12];
  33. int n;
  34. n = read(0, buf, sizeof buf);
  35. if(n < 0)
  36. return n;
  37. if(n != sizeof buf)
  38. return 0;
  39. m->byte = buf[0];
  40. m->Mouse.xy.x = atoi(buf+1+0*12);
  41. m->Mouse.xy.y = atoi(buf+1+1*12);
  42. m->Mouse.buttons = atoi(buf+1+2*12);
  43. m->Mouse.msec = atoi(buf+1+3*12);
  44. return 1;
  45. }
  46. void
  47. writemouse(M *m)
  48. {
  49. print("%c%11d %11d %11d %11ld ",
  50. m->byte,
  51. m->Mouse.xy.x,
  52. m->Mouse.xy.y,
  53. m->Mouse.buttons&7,
  54. m->Mouse.msec);
  55. }
  56. void
  57. notifyf(void *v, char *s)
  58. {
  59. if(strcmp(s, "alarm") == 0)
  60. interrupted = 1;
  61. noted(NCONT);
  62. }
  63. void
  64. main(void)
  65. {
  66. M m, om;
  67. int n;
  68. notify(notifyf);
  69. memset(&m, 0, sizeof m);
  70. om = m;
  71. for(;;){
  72. interrupted = 0;
  73. /* first click waits 500ms before repeating; after that they're 150, but that's ok */
  74. if(button2)
  75. alarm(550);
  76. n = readmouse(&m);
  77. if(button2)
  78. alarm(0);
  79. if(interrupted){
  80. /* timed out; clear button 2 */
  81. om.Mouse.buttons &= ~2;
  82. button2 = 0;
  83. writemouse(&om);
  84. continue;
  85. }
  86. if(n <= 0)
  87. break;
  88. /* avoid bounce caused by button 5 click */
  89. if((om.Mouse.buttons&16) && (m.Mouse.buttons&16)){
  90. om.Mouse.buttons &= ~16;
  91. continue;
  92. }
  93. if(m.Mouse.buttons & 2)
  94. button2 = 0;
  95. else{
  96. /* only check 4 and 5 if 2 isn't down of its own accord */
  97. if(m.Mouse.buttons & 16){
  98. /* generate quick button 2 click */
  99. button2 = 0;
  100. m.Mouse.buttons |= 2;
  101. writemouse(&m);
  102. m.Mouse.buttons &= ~2;
  103. /* fall through to generate up event */
  104. }else if(m.Mouse.buttons & 8){
  105. /* press and hold button 2 */
  106. button2 = 1;
  107. }
  108. }
  109. if(button2)
  110. m.Mouse.buttons |= 2;
  111. if(m.byte!=om.byte || m.Mouse.buttons!=om.Mouse.buttons || !eqpt(m.Mouse.xy, om.Mouse.xy))
  112. writemouse(&m);
  113. om = m;
  114. }
  115. }