wsys.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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 "vnc.h"
  10. #include "vncv.h"
  11. #include <cursor.h>
  12. typedef struct Cursor Cursor;
  13. typedef struct Mouse Mouse;
  14. struct Mouse {
  15. int buttons;
  16. Point xy;
  17. };
  18. static void
  19. resize(Vnc *v, int first)
  20. {
  21. int fd;
  22. Point d;
  23. d = addpt(v->dim, Pt(2*Borderwidth, 2*Borderwidth));
  24. lockdisplay(display);
  25. if(getwindow(display, Refnone) < 0)
  26. sysfatal("internal error: can't get the window image");
  27. /*
  28. * limit the window to at most the vnc server's size
  29. */
  30. if(first || d.x < Dx(screen->r) || d.y < Dy(screen->r)){
  31. fd = open("/dev/wctl", OWRITE);
  32. if(fd >= 0){
  33. fprint(fd, "resize -dx %d -dy %d", d.x, d.y);
  34. close(fd);
  35. }
  36. }
  37. unlockdisplay(display);
  38. }
  39. static void
  40. eresized(void)
  41. {
  42. resize(vnc, 0);
  43. requestupdate(vnc, 0);
  44. }
  45. static Cursor dotcursor = {
  46. {-7, -7},
  47. {0x00, 0x00,
  48. 0x00, 0x00,
  49. 0x00, 0x00,
  50. 0x00, 0x00,
  51. 0x03, 0xc0,
  52. 0x07, 0xe0,
  53. 0x0f, 0xf0,
  54. 0x0f, 0xf0,
  55. 0x0f, 0xf0,
  56. 0x07, 0xe0,
  57. 0x03, 0xc0,
  58. 0x00, 0x00,
  59. 0x00, 0x00,
  60. 0x00, 0x00,
  61. 0x00, 0x00,
  62. 0x00, 0x00, },
  63. {0x00, 0x00,
  64. 0x00, 0x00,
  65. 0x00, 0x00,
  66. 0x00, 0x00,
  67. 0x00, 0x00,
  68. 0x03, 0xc0,
  69. 0x07, 0xe0,
  70. 0x07, 0xe0,
  71. 0x07, 0xe0,
  72. 0x03, 0xc0,
  73. 0x00, 0x00,
  74. 0x00, 0x00,
  75. 0x00, 0x00,
  76. 0x00, 0x00,
  77. 0x00, 0x00,
  78. 0x00, 0x00, }
  79. };
  80. static void
  81. mouseevent(Vnc *v, Mouse m)
  82. {
  83. vnclock(v);
  84. vncwrchar(v, MMouse);
  85. vncwrchar(v, m.buttons);
  86. vncwrpoint(v, m.xy);
  87. vncflush(v);
  88. vncunlock(v);
  89. }
  90. void
  91. mousewarp(Point pt)
  92. {
  93. pt = addpt(pt, screen->r.min);
  94. if(fprint(mousefd, "m%d %d", pt.x, pt.y) < 0)
  95. fprint(2, "mousefd write: %r\n");
  96. }
  97. void
  98. initmouse(void)
  99. {
  100. char buf[1024];
  101. snprint(buf, sizeof buf, "%s/mouse", display->devdir);
  102. if((mousefd = open(buf, ORDWR)) < 0)
  103. sysfatal("open %s: %r", buf);
  104. }
  105. enum {
  106. EventSize = 1+4*12
  107. };
  108. void
  109. readmouse(Vnc *v)
  110. {
  111. int cursorfd, len, n;
  112. char buf[10*EventSize], *start, *end;
  113. uint8_t curs[2*4+2*2*16];
  114. Cursor *cs;
  115. Mouse m;
  116. cs = &dotcursor;
  117. snprint(buf, sizeof buf, "%s/cursor", display->devdir);
  118. if((cursorfd = open(buf, OWRITE)) < 0)
  119. sysfatal("open %s: %r", buf);
  120. BPLONG(curs+0*4, cs->offset.x);
  121. BPLONG(curs+1*4, cs->offset.y);
  122. memmove(curs+2*4, cs->clr, 2*2*16);
  123. write(cursorfd, curs, sizeof curs);
  124. resize(v, 1);
  125. requestupdate(vnc, 0);
  126. start = end = buf;
  127. len = 0;
  128. for(;;){
  129. if((n = read(mousefd, end, sizeof(buf) - (end - buf))) < 0)
  130. sysfatal("read mouse failed");
  131. len += n;
  132. end += n;
  133. while(len >= EventSize){
  134. if(*start == 'm'){
  135. m.xy.x = atoi(start+1);
  136. m.xy.y = atoi(start+1+12);
  137. m.buttons = atoi(start+1+2*12) & 0x1F;
  138. m.xy = subpt(m.xy, screen->r.min);
  139. if(ptinrect(m.xy, Rpt(ZP, v->dim))){
  140. mouseevent(v, m);
  141. /* send wheel button *release* */
  142. if ((m.buttons & 0x7) != m.buttons) {
  143. m.buttons &= 0x7;
  144. mouseevent(v, m);
  145. }
  146. }
  147. } else
  148. eresized();
  149. start += EventSize;
  150. len -= EventSize;
  151. }
  152. if(start - buf > sizeof(buf) - EventSize){
  153. memmove(buf, start, len);
  154. start = buf;
  155. end = start+len;
  156. }
  157. }
  158. }
  159. static int snarffd = -1;
  160. static uint32_t snarfvers;
  161. void
  162. writesnarf(Vnc *v, int32_t n)
  163. {
  164. uint8_t buf[8192];
  165. int32_t m;
  166. Biobuf *b;
  167. if((b = Bopen("/dev/snarf", OWRITE)) == nil){
  168. vncgobble(v, n);
  169. return;
  170. }
  171. while(n > 0){
  172. m = n;
  173. if(m > sizeof(buf))
  174. m = sizeof(buf);
  175. vncrdbytes(v, buf, m);
  176. n -= m;
  177. Bwrite(b, buf, m);
  178. }
  179. Bterm(b);
  180. snarfvers++;
  181. }
  182. char *
  183. getsnarf(int *sz)
  184. {
  185. char *snarf, *p;
  186. int n, c;
  187. *sz =0;
  188. n = 8192;
  189. p = snarf = malloc(n);
  190. seek(snarffd, 0, 0);
  191. while ((c = read(snarffd, p, n)) > 0){
  192. p += c;
  193. n -= c;
  194. *sz += c;
  195. if (n == 0){
  196. snarf = realloc(snarf, *sz + 8192);
  197. n = 8192;
  198. }
  199. }
  200. return snarf;
  201. }
  202. void
  203. checksnarf(Vnc *v)
  204. {
  205. Dir *dir;
  206. char *snarf;
  207. int len;
  208. if(snarffd < 0){
  209. snarffd = open("/dev/snarf", OREAD);
  210. if(snarffd < 0)
  211. sysfatal("can't open /dev/snarf: %r");
  212. }
  213. for(;;){
  214. sleep(1000);
  215. dir = dirstat("/dev/snarf");
  216. if(dir == nil) /* this happens under old drawterm */
  217. continue;
  218. if(dir->qid.vers > snarfvers){
  219. snarf = getsnarf(&len);
  220. vnclock(v);
  221. vncwrchar(v, MCCut);
  222. vncwrbytes(v, "pad", 3);
  223. vncwrlong(v, len);
  224. vncwrbytes(v, snarf, len);
  225. vncflush(v);
  226. vncunlock(v);
  227. free(snarf);
  228. snarfvers = dir->qid.vers;
  229. }
  230. free(dir);
  231. }
  232. }