event.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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 <cursor.h>
  13. #include <event.h>
  14. typedef struct Slave Slave;
  15. typedef struct Ebuf Ebuf;
  16. struct Slave
  17. {
  18. int pid;
  19. Ebuf *head; /* queue of messages for this descriptor */
  20. Ebuf *tail;
  21. int (*fn)(int, Event*, uint8_t*, int);
  22. };
  23. struct Ebuf
  24. {
  25. Ebuf *next;
  26. int n; /* number of bytes in buf */
  27. uint8_t buf[EMAXMSG];
  28. };
  29. static Slave eslave[MAXSLAVE];
  30. static int Skeyboard = -1;
  31. static int Smouse = -1;
  32. static int Stimer = -1;
  33. static int logfid;
  34. static int nslave;
  35. static int parentpid;
  36. static int epipe[2];
  37. static int eforkslave(uint32_t);
  38. static void extract(void);
  39. static void ekill(void);
  40. static int enote(void *, char *);
  41. static int mousefd;
  42. static int cursorfd;
  43. static
  44. Ebuf*
  45. ebread(Slave *s)
  46. {
  47. Ebuf *eb;
  48. Dir *d;
  49. uint32_t l;
  50. for(;;){
  51. d = dirfstat(epipe[0]);
  52. if(d == nil)
  53. drawerror(display, "events: eread stat error");
  54. l = d->length;
  55. free(d);
  56. if(s->head && l==0)
  57. break;
  58. extract();
  59. }
  60. eb = s->head;
  61. s->head = s->head->next;
  62. if(s->head == 0)
  63. s->tail = 0;
  64. return eb;
  65. }
  66. uint32_t
  67. event(Event *e)
  68. {
  69. return eread((uint32_t)~0UL, e);
  70. }
  71. uint32_t
  72. eread(uint32_t keys, Event *e)
  73. {
  74. Ebuf *eb;
  75. int i, id;
  76. if(keys == 0)
  77. return 0;
  78. for(;;){
  79. for(i=0; i<nslave; i++)
  80. if((keys & (1<<i)) && eslave[i].head){
  81. id = 1<<i;
  82. if(i == Smouse)
  83. e->mouse = emouse();
  84. else if(i == Skeyboard)
  85. e->kbdc = ekbd();
  86. else if(i == Stimer)
  87. eslave[i].head = 0;
  88. else{
  89. eb = ebread(&eslave[i]);
  90. e->n = eb->n;
  91. if(eslave[i].fn)
  92. id = (*eslave[i].fn)(id, e, eb->buf, eb->n);
  93. else
  94. memmove(e->data, eb->buf, eb->n);
  95. free(eb);
  96. }
  97. return id;
  98. }
  99. extract();
  100. }
  101. }
  102. int
  103. ecanmouse(void)
  104. {
  105. if(Smouse < 0)
  106. drawerror(display, "events: mouse not initialized");
  107. return ecanread(Emouse);
  108. }
  109. int
  110. ecankbd(void)
  111. {
  112. if(Skeyboard < 0)
  113. drawerror(display, "events: keyboard not initialzed");
  114. return ecanread(Ekeyboard);
  115. }
  116. int
  117. ecanread(uint32_t keys)
  118. {
  119. Dir *d;
  120. int i;
  121. uint32_t l;
  122. for(;;){
  123. for(i=0; i<nslave; i++)
  124. if((keys & (1<<i)) && eslave[i].head)
  125. return 1;
  126. d = dirfstat(epipe[0]);
  127. if(d == nil)
  128. drawerror(display, "events: ecanread stat error");
  129. l = d->length;
  130. free(d);
  131. if(l == 0)
  132. return 0;
  133. extract();
  134. }
  135. }
  136. uint32_t
  137. estartfn(uint32_t key, int fd, int n, int (*fn)(int, Event*, uint8_t*, int))
  138. {
  139. char buf[EMAXMSG+1];
  140. int i, r;
  141. if(fd < 0)
  142. drawerror(display, "events: bad file descriptor");
  143. if(n <= 0 || n > EMAXMSG)
  144. n = EMAXMSG;
  145. i = eforkslave(key);
  146. if(i < MAXSLAVE){
  147. eslave[i].fn = fn;
  148. return 1<<i;
  149. }
  150. buf[0] = i - MAXSLAVE;
  151. while((r = read(fd, buf+1, n))>0)
  152. if(write(epipe[1], buf, r+1)!=r+1)
  153. break;
  154. buf[0] = MAXSLAVE;
  155. write(epipe[1], buf, 1);
  156. _exits(0);
  157. return 0;
  158. }
  159. uint32_t
  160. estart(uint32_t key, int fd, int n)
  161. {
  162. return estartfn(key, fd, n, nil);
  163. }
  164. uint32_t
  165. etimer(uint32_t key, int n)
  166. {
  167. char t[2];
  168. if(Stimer != -1)
  169. drawerror(display, "events: timer started twice");
  170. Stimer = eforkslave(key);
  171. if(Stimer < MAXSLAVE)
  172. return 1<<Stimer;
  173. if(n <= 0)
  174. n = 1000;
  175. t[0] = t[1] = Stimer - MAXSLAVE;
  176. do
  177. sleep(n);
  178. while(write(epipe[1], t, 2) == 2);
  179. t[0] = MAXSLAVE;
  180. write(epipe[1], t, 1);
  181. _exits(0);
  182. return 0;
  183. }
  184. static void
  185. ekeyslave(int fd)
  186. {
  187. Rune r;
  188. char t[3], k[10];
  189. int kr, kn, w;
  190. if(eforkslave(Ekeyboard) < MAXSLAVE)
  191. return;
  192. kn = 0;
  193. t[0] = Skeyboard;
  194. for(;;){
  195. while(!fullrune(k, kn)){
  196. kr = read(fd, k+kn, sizeof k - kn);
  197. if(kr <= 0)
  198. goto breakout;
  199. kn += kr;
  200. }
  201. w = chartorune(&r, k);
  202. kn -= w;
  203. memmove(k, &k[w], kn);
  204. t[1] = r;
  205. t[2] = r>>8;
  206. if(write(epipe[1], t, 3) != 3)
  207. break;
  208. }
  209. breakout:;
  210. t[0] = MAXSLAVE;
  211. write(epipe[1], t, 1);
  212. _exits(0);
  213. }
  214. void
  215. einit(uint32_t keys)
  216. {
  217. int ctl, fd;
  218. char buf[256];
  219. parentpid = getpid();
  220. if(pipe(epipe) < 0)
  221. drawerror(display, "events: einit pipe");
  222. atexit(ekill);
  223. atnotify(enote, 1);
  224. snprint(buf, sizeof buf, "%s/mouse", display->devdir);
  225. mousefd = open(buf, ORDWR|OCEXEC);
  226. if(mousefd < 0)
  227. drawerror(display, "einit: can't open mouse\n");
  228. snprint(buf, sizeof buf, "%s/cursor", display->devdir);
  229. cursorfd = open(buf, ORDWR|OCEXEC);
  230. if(cursorfd < 0)
  231. drawerror(display, "einit: can't open cursor\n");
  232. if(keys&Ekeyboard){
  233. snprint(buf, sizeof buf, "%s/cons", display->devdir);
  234. fd = open(buf, OREAD);
  235. if(fd < 0)
  236. drawerror(display, "events: can't open console");
  237. snprint(buf, sizeof buf, "%s/consctl", display->devdir);
  238. ctl = open("/dev/consctl", OWRITE|OCEXEC);
  239. if(ctl < 0)
  240. drawerror(display, "events: can't open consctl");
  241. write(ctl, "rawon", 5);
  242. for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
  243. ;
  244. ekeyslave(fd);
  245. // if (ctl > 0) {
  246. // close(ctl);
  247. // }
  248. }
  249. if(keys&Emouse){
  250. estart(Emouse, mousefd, 1+4*12);
  251. for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
  252. ;
  253. }
  254. }
  255. static void
  256. extract(void)
  257. {
  258. Slave *s;
  259. Ebuf *eb;
  260. int i, n;
  261. uint8_t ebuf[EMAXMSG+1];
  262. /* avoid generating a message if there's nothing to show. */
  263. /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
  264. /* also: make sure we don't interfere if we're multiprocessing the display */
  265. if(display->locking){
  266. /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
  267. if(canqlock(&display->qlock)){
  268. if(display->bufp > display->buf)
  269. flushimage(display, 1);
  270. unlockdisplay(display);
  271. }
  272. }else
  273. if(display->bufp > display->buf)
  274. flushimage(display, 1);
  275. loop:
  276. if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0
  277. || ebuf[0] >= MAXSLAVE)
  278. drawerror(display, "eof on event pipe");
  279. if(n == 0)
  280. goto loop;
  281. i = ebuf[0];
  282. if(i >= nslave || n <= 1)
  283. drawerror(display, "events: protocol error: short read");
  284. s = &eslave[i];
  285. if(i == Stimer){
  286. s->head = (Ebuf *)1;
  287. return;
  288. }
  289. if(i == Skeyboard && n != 3)
  290. drawerror(display, "events: protocol error: keyboard");
  291. if(i == Smouse){
  292. if(n < 1+1+2*12)
  293. drawerror(display, "events: protocol error: mouse");
  294. if(ebuf[1] == 'r')
  295. eresized(1);
  296. /* squash extraneous mouse events */
  297. if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){
  298. memmove(eb->buf, &ebuf[1], n - 1);
  299. return;
  300. }
  301. }
  302. /* try to save space by only allocating as much buffer as we need */
  303. eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1);
  304. if(eb == 0)
  305. drawerror(display, "events: protocol error 4");
  306. eb->n = n - 1;
  307. memmove(eb->buf, &ebuf[1], n - 1);
  308. eb->next = 0;
  309. if(s->head)
  310. s->tail = s->tail->next = eb;
  311. else
  312. s->head = s->tail = eb;
  313. }
  314. static int
  315. eforkslave(uint32_t key)
  316. {
  317. int i, pid;
  318. for(i=0; i<MAXSLAVE; i++)
  319. if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){
  320. if(nslave <= i)
  321. nslave = i + 1;
  322. /*
  323. * share the file descriptors so the last child
  324. * out closes all connections to the window server.
  325. */
  326. switch(pid = rfork(RFPROC)){
  327. case 0:
  328. return MAXSLAVE+i;
  329. case -1:
  330. fprint(2, "events: fork error\n");
  331. exits("fork");
  332. }
  333. eslave[i].pid = pid;
  334. eslave[i].head = eslave[i].tail = 0;
  335. return i;
  336. }
  337. drawerror(display, "events: bad slave assignment");
  338. return 0;
  339. }
  340. static int
  341. enote(void *v, char *s)
  342. {
  343. char t[1];
  344. int i, pid;
  345. USED(v);USED(s);
  346. pid = getpid();
  347. if(pid != parentpid){
  348. for(i=0; i<nslave; i++){
  349. if(pid == eslave[i].pid){
  350. t[0] = MAXSLAVE;
  351. write(epipe[1], t, 1);
  352. break;
  353. }
  354. }
  355. return 0;
  356. }
  357. close(epipe[0]);
  358. epipe[0] = -1;
  359. close(epipe[1]);
  360. epipe[1] = -1;
  361. for(i=0; i<nslave; i++){
  362. if(pid == eslave[i].pid)
  363. continue; /* don't kill myself */
  364. postnote(PNPROC, eslave[i].pid, "die");
  365. }
  366. return 0;
  367. }
  368. static void
  369. ekill(void)
  370. {
  371. enote(0, 0);
  372. }
  373. Mouse
  374. emouse(void)
  375. {
  376. Mouse m;
  377. Ebuf *eb;
  378. //static but[2];
  379. int b;
  380. if(Smouse < 0)
  381. drawerror(display, "events: mouse not initialized");
  382. eb = ebread(&eslave[Smouse]);
  383. m.xy.x = atoi((char*)eb->buf+1+0*12);
  384. m.xy.y = atoi((char*)eb->buf+1+1*12);
  385. b = atoi((char*)eb->buf+1+2*12);
  386. m.buttons = b;
  387. m.msec = atoi((char*)eb->buf+1+3*12);
  388. if (logfid)
  389. fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy);
  390. free(eb);
  391. return m;
  392. }
  393. int
  394. ekbd(void)
  395. {
  396. Ebuf *eb;
  397. int c;
  398. if(Skeyboard < 0)
  399. drawerror(display, "events: keyboard not initialzed");
  400. eb = ebread(&eslave[Skeyboard]);
  401. c = eb->buf[0] + (eb->buf[1]<<8);
  402. free(eb);
  403. return c;
  404. }
  405. void
  406. emoveto(Point pt)
  407. {
  408. char buf[2*12+2];
  409. int n;
  410. n = sprint(buf, "m%d %d", pt.x, pt.y);
  411. write(mousefd, buf, n);
  412. }
  413. void
  414. esetcursor(Cursor *c)
  415. {
  416. uint8_t curs[2*4+2*2*16];
  417. if(c == 0)
  418. write(cursorfd, curs, 0);
  419. else{
  420. BPLONG(curs+0*4, c->offset.x);
  421. BPLONG(curs+1*4, c->offset.y);
  422. memmove(curs+2*4, c->clr, 2*2*16);
  423. write(cursorfd, curs, sizeof curs);
  424. }
  425. }
  426. int
  427. ereadmouse(Mouse *m)
  428. {
  429. int n;
  430. char buf[128];
  431. do{
  432. n = read(mousefd, buf, sizeof(buf));
  433. if(n < 0) /* probably interrupted */
  434. return -1;
  435. n = eatomouse(m, buf, n);
  436. }while(n == 0);
  437. return n;
  438. }
  439. int
  440. eatomouse(Mouse *m, char *buf, int n)
  441. {
  442. if(n != 1+4*12){
  443. werrstr("atomouse: bad count");
  444. return -1;
  445. }
  446. if(buf[0] == 'r')
  447. eresized(1);
  448. m->xy.x = atoi(buf+1+0*12);
  449. m->xy.y = atoi(buf+1+1*12);
  450. m->buttons = atoi(buf+1+2*12);
  451. m->msec = atoi(buf+1+3*12);
  452. return n;
  453. }