win.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <thread.h>
  5. #include "dat.h"
  6. Window*
  7. newwindow(void)
  8. {
  9. char buf[12];
  10. Window *w;
  11. w = emalloc(sizeof(Window));
  12. w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC);
  13. if(w->ctl<0 || read(w->ctl, buf, 12)!=12)
  14. error("can't open window ctl file: %r");
  15. ctlprint(w->ctl, "noscroll\n");
  16. w->id = atoi(buf);
  17. w->event = winopenfile(w, "event");
  18. w->addr = winopenfile(w, "addr");
  19. w->body = winopenfile(w, "body");
  20. w->data = winopenfile(w, "data");
  21. w->cevent = chancreate(sizeof(Event*), 0);
  22. return w;
  23. }
  24. void
  25. winsetdump(Window *w, char *dir, char *cmd)
  26. {
  27. if(dir != nil)
  28. ctlprint(w->ctl, "dumpdir %s\n", dir);
  29. if(cmd != nil)
  30. ctlprint(w->ctl, "dump %s\n", cmd);
  31. }
  32. void
  33. wineventproc(void *v)
  34. {
  35. Window *w;
  36. int i;
  37. w = v;
  38. for(i=0; ; i++){
  39. if(i >= NEVENT)
  40. i = 0;
  41. wingetevent(w, &w->e[i]);
  42. sendp(w->cevent, &w->e[i]);
  43. }
  44. }
  45. int
  46. winopenfile(Window *w, char *f)
  47. {
  48. char buf[64];
  49. int fd;
  50. sprint(buf, "/mnt/wsys/%d/%s", w->id, f);
  51. fd = open(buf, ORDWR|OCEXEC);
  52. if(fd < 0)
  53. error("can't open window file %s: %r", f);
  54. return fd;
  55. }
  56. void
  57. wintagwrite(Window *w, char *s, int n)
  58. {
  59. int fd;
  60. fd = winopenfile(w, "tag");
  61. if(write(fd, s, n) != n)
  62. error("tag write: %r");
  63. close(fd);
  64. }
  65. void
  66. winname(Window *w, char *s)
  67. {
  68. ctlprint(w->ctl, "name %s\n", s);
  69. }
  70. int
  71. wingetec(Window *w)
  72. {
  73. if(w->nbuf == 0){
  74. w->nbuf = read(w->event, w->buf, sizeof w->buf);
  75. if(w->nbuf <= 0){
  76. /* probably because window has exited, and only called by wineventproc, so just shut down */
  77. threadexits(nil);
  78. }
  79. w->bufp = w->buf;
  80. }
  81. w->nbuf--;
  82. return *w->bufp++;
  83. }
  84. int
  85. wingeten(Window *w)
  86. {
  87. int n, c;
  88. n = 0;
  89. while('0'<=(c=wingetec(w)) && c<='9')
  90. n = n*10+(c-'0');
  91. if(c != ' ')
  92. error("event number syntax");
  93. return n;
  94. }
  95. int
  96. wingeter(Window *w, char *buf, int *nb)
  97. {
  98. Rune r;
  99. int n;
  100. r = wingetec(w);
  101. buf[0] = r;
  102. n = 1;
  103. if(r >= Runeself) {
  104. while(!fullrune(buf, n))
  105. buf[n++] = wingetec(w);
  106. chartorune(&r, buf);
  107. }
  108. *nb = n;
  109. return r;
  110. }
  111. void
  112. wingetevent(Window *w, Event *e)
  113. {
  114. int i, nb;
  115. e->c1 = wingetec(w);
  116. e->c2 = wingetec(w);
  117. e->q0 = wingeten(w);
  118. e->q1 = wingeten(w);
  119. e->flag = wingeten(w);
  120. e->nr = wingeten(w);
  121. if(e->nr > EVENTSIZE)
  122. error("event string too long");
  123. e->nb = 0;
  124. for(i=0; i<e->nr; i++){
  125. e->r[i] = wingeter(w, e->b+e->nb, &nb);
  126. e->nb += nb;
  127. }
  128. e->r[e->nr] = 0;
  129. e->b[e->nb] = 0;
  130. if(wingetec(w) != '\n')
  131. error("event syntax error");
  132. }
  133. void
  134. winwriteevent(Window *w, Event *e)
  135. {
  136. fprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1);
  137. }
  138. static int
  139. nrunes(char *s, int nb)
  140. {
  141. int i, n;
  142. Rune r;
  143. n = 0;
  144. for(i=0; i<nb; n++)
  145. i += chartorune(&r, s+i);
  146. return n;
  147. }
  148. int
  149. winread(Window *w, uint q0, uint q1, char *data)
  150. {
  151. int m, n, nr, nb;
  152. char buf[256];
  153. if(w->addr < 0)
  154. w->addr = winopenfile(w, "addr");
  155. if(w->data < 0)
  156. w->data = winopenfile(w, "data");
  157. m = q0;
  158. nb = 0;
  159. while(m < q1){
  160. n = sprint(buf, "#%d", m);
  161. if(write(w->addr, buf, n) != n)
  162. error("error writing addr: %r");
  163. n = read(w->data, buf, sizeof buf);
  164. if(n < 0)
  165. error("reading data: %r");
  166. nr = nrunes(buf, n);
  167. while(m+nr >q1){
  168. do; while(n>0 && (buf[--n]&0xC0)==0x80);
  169. --nr;
  170. }
  171. if(n == 0)
  172. break;
  173. memmove(data, buf, n);
  174. nb += n;
  175. data += n;
  176. *data = 0;
  177. m += nr;
  178. }
  179. return nb;
  180. }
  181. void
  182. windormant(Window *w)
  183. {
  184. if(w->addr >= 0){
  185. close(w->addr);
  186. w->addr = -1;
  187. }
  188. if(w->body >= 0){
  189. close(w->body);
  190. w->body = -1;
  191. }
  192. if(w->data >= 0){
  193. close(w->data);
  194. w->data = -1;
  195. }
  196. }
  197. int
  198. windel(Window *w, int sure)
  199. {
  200. if(sure)
  201. write(w->ctl, "delete\n", 7);
  202. else if(write(w->ctl, "del\n", 4) != 4)
  203. return 0;
  204. /* event proc will die due to read error from event file */
  205. windormant(w);
  206. close(w->ctl);
  207. w->ctl = -1;
  208. close(w->event);
  209. w->event = -1;
  210. return 1;
  211. }
  212. void
  213. winclean(Window *w)
  214. {
  215. ctlprint(w->ctl, "clean\n");
  216. }
  217. int
  218. winsetaddr(Window *w, char *addr, int errok)
  219. {
  220. if(w->addr < 0)
  221. w->addr = winopenfile(w, "addr");
  222. if(write(w->addr, addr, strlen(addr)) < 0){
  223. if(!errok)
  224. error("error writing addr(%s): %r", addr);
  225. return 0;
  226. }
  227. return 1;
  228. }
  229. int
  230. winselect(Window *w, char *addr, int errok)
  231. {
  232. if(winsetaddr(w, addr, errok)){
  233. ctlprint(w->ctl, "dot=addr\n");
  234. return 1;
  235. }
  236. return 0;
  237. }