io.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <mouse.h>
  6. #include <keyboard.h>
  7. #include <frame.h>
  8. #include "flayer.h"
  9. #include "samterm.h"
  10. int cursorfd;
  11. int plumbfd = -1;
  12. int input;
  13. int got;
  14. int block;
  15. int kbdc;
  16. int resized;
  17. uchar *hostp;
  18. uchar *hoststop;
  19. uchar *plumbbase;
  20. uchar *plumbp;
  21. uchar *plumbstop;
  22. Channel *plumbc;
  23. Channel *hostc;
  24. Mousectl *mousectl;
  25. Mouse *mousep;
  26. Keyboardctl *keyboardctl;
  27. void panic(char*);
  28. void
  29. initio(void)
  30. {
  31. threadsetname("main");
  32. mousectl = initmouse(nil, display->image);
  33. if(mousectl == nil){
  34. fprint(2, "samterm: mouse init failed: %r\n");
  35. threadexitsall("mouse");
  36. }
  37. mousep = mousectl;
  38. keyboardctl = initkeyboard(nil);
  39. if(keyboardctl == nil){
  40. fprint(2, "samterm: keyboard init failed: %r\n");
  41. threadexitsall("kbd");
  42. }
  43. hoststart();
  44. if(plumbstart() < 0)
  45. extstart();
  46. }
  47. void
  48. getmouse(void)
  49. {
  50. if(readmouse(mousectl) < 0)
  51. panic("mouse");
  52. }
  53. void
  54. mouseunblock(void)
  55. {
  56. got &= ~(1<<RMouse);
  57. }
  58. void
  59. kbdblock(void)
  60. { /* ca suffit */
  61. block = (1<<RKeyboard)|(1<<RPlumb);
  62. }
  63. int
  64. button(int but)
  65. {
  66. getmouse();
  67. return mousep->buttons&(1<<(but-1));
  68. }
  69. void
  70. externload(int i)
  71. {
  72. plumbbase = malloc(plumbbuf[i].n);
  73. if(plumbbase == 0)
  74. return;
  75. memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);
  76. plumbp = plumbbase;
  77. plumbstop = plumbbase + plumbbuf[i].n;
  78. got |= 1<<RPlumb;
  79. }
  80. int
  81. waitforio(void)
  82. {
  83. Alt alts[NRes+1];
  84. Rune r;
  85. int i;
  86. ulong type;
  87. again:
  88. alts[RPlumb].c = plumbc;
  89. alts[RPlumb].v = &i;
  90. alts[RPlumb].op = CHANRCV;
  91. if((block & (1<<RPlumb)) || plumbc == nil)
  92. alts[RPlumb].op = CHANNOP;
  93. alts[RHost].c = hostc;
  94. alts[RHost].v = &i;
  95. alts[RHost].op = CHANRCV;
  96. if(block & (1<<RHost))
  97. alts[RHost].op = CHANNOP;
  98. alts[RKeyboard].c = keyboardctl->c;
  99. alts[RKeyboard].v = &r;
  100. alts[RKeyboard].op = CHANRCV;
  101. if(block & (1<<RKeyboard))
  102. alts[RKeyboard].op = CHANNOP;
  103. alts[RMouse].c = mousectl->c;
  104. alts[RMouse].v = &mousectl->Mouse;
  105. alts[RMouse].op = CHANRCV;
  106. if(block & (1<<RMouse))
  107. alts[RMouse].op = CHANNOP;
  108. alts[RResize].c = mousectl->resizec;
  109. alts[RResize].v = nil;
  110. alts[RResize].op = CHANRCV;
  111. if(block & (1<<RResize))
  112. alts[RResize].op = CHANNOP;
  113. alts[NRes].op = CHANEND;
  114. if(got & ~block)
  115. return got & ~block;
  116. flushimage(display, 1);
  117. type = alt(alts);
  118. switch(type){
  119. case RHost:
  120. hostp = hostbuf[i].data;
  121. hoststop = hostbuf[i].data + hostbuf[i].n;
  122. block = 0;
  123. break;
  124. case RPlumb:
  125. externload(i);
  126. break;
  127. case RKeyboard:
  128. kbdc = r;
  129. break;
  130. case RMouse:
  131. break;
  132. case RResize:
  133. resized = 1;
  134. /* do the resize in line if we've finished initializing and we're not in a blocking state */
  135. if(hasunlocked && block==0 && RESIZED())
  136. resize();
  137. goto again;
  138. }
  139. got |= 1<<type;
  140. return got;
  141. }
  142. int
  143. rcvchar(void)
  144. {
  145. int c;
  146. if(!(got & (1<<RHost)))
  147. return -1;
  148. c = *hostp++;
  149. if(hostp == hoststop)
  150. got &= ~(1<<RHost);
  151. return c;
  152. }
  153. char*
  154. rcvstring(void)
  155. {
  156. *hoststop = 0;
  157. got &= ~(1<<RHost);
  158. return (char*)hostp;
  159. }
  160. int
  161. getch(void)
  162. {
  163. int c;
  164. while((c = rcvchar()) == -1){
  165. block = ~(1<<RHost);
  166. waitforio();
  167. block = 0;
  168. }
  169. return c;
  170. }
  171. int
  172. externchar(void)
  173. {
  174. Rune r;
  175. loop:
  176. if(got & ((1<<RPlumb) & ~block)){
  177. plumbp += chartorune(&r, (char*)plumbp);
  178. if(plumbp >= plumbstop){
  179. got &= ~(1<<RPlumb);
  180. free(plumbbase);
  181. }
  182. if(r == 0)
  183. goto loop;
  184. return r;
  185. }
  186. return -1;
  187. }
  188. int kpeekc = -1;
  189. int
  190. ecankbd(void)
  191. {
  192. Rune r;
  193. if(kpeekc >= 0)
  194. return 1;
  195. if(nbrecv(keyboardctl->c, &r) > 0){
  196. kpeekc = r;
  197. return 1;
  198. }
  199. return 0;
  200. }
  201. int
  202. ekbd(void)
  203. {
  204. int c;
  205. Rune r;
  206. if(kpeekc >= 0){
  207. c = kpeekc;
  208. kpeekc = -1;
  209. return c;
  210. }
  211. if(recv(keyboardctl->c, &r) < 0){
  212. fprint(2, "samterm: keybard recv error: %r\n");
  213. panic("kbd");
  214. }
  215. return r;
  216. }
  217. int
  218. kbdchar(void)
  219. {
  220. int c, i;
  221. c = externchar();
  222. if(c > 0)
  223. return c;
  224. if(got & (1<<RKeyboard)){
  225. c = kbdc;
  226. kbdc = -1;
  227. got &= ~(1<<RKeyboard);
  228. return c;
  229. }
  230. while(plumbc!=nil && nbrecv(plumbc, &i)>0){
  231. externload(i);
  232. c = externchar();
  233. if(c > 0)
  234. return c;
  235. }
  236. if(!ecankbd())
  237. return -1;
  238. return ekbd();
  239. }
  240. int
  241. qpeekc(void)
  242. {
  243. return kbdc;
  244. }
  245. int
  246. RESIZED(void)
  247. {
  248. if(resized){
  249. if(getwindow(display, Refnone) < 0)
  250. panic("can't reattach to window");
  251. resized = 0;
  252. return 1;
  253. }
  254. return 0;
  255. }