io.c 4.6 KB

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