wsys.c 4.0 KB

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