io.c 4.5 KB

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