2 #include <sys/select.h>
10 typedef struct Slave Slave;
11 typedef struct Ebuf Ebuf;
16 Ebuf *head; /* queue of messages for this descriptor */
18 int (*fn)(int, Event*, uchar*, int);
28 int n; /* number of bytes in buf */
36 static Slave eslave[MAXSLAVE];
37 static int Skeyboard = -1;
38 static int Smouse = -1;
39 static int Stimer = -1;
42 static int newkey(ulong);
43 static int extract(int canblock);
54 s->head = s->head->next;
63 return eread(~0UL, e);
67 eread(ulong keys, Event *e)
75 for(i=0; i<nslave; i++)
76 if((keys & (1<<i)) && eslave[i].head){
80 else if(i == Skeyboard)
85 eb = ebread(&eslave[i]);
88 id = (*eslave[i].fn)(id, e, eb->u.buf, eb->n);
90 memmove(e->data, eb->u.buf, eb->n);
104 drawerror(display, "events: mouse not initialized");
105 return ecanread(Emouse);
112 drawerror(display, "events: keyboard not initialzed");
113 return ecanread(Ekeyboard);
122 for(i=0; i<nslave; i++)
123 if((keys & (1<<i)) && eslave[i].head)
132 estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
137 drawerror(display, "events: bad file descriptor");
138 if(n <= 0 || n > EMAXMSG)
148 estart(ulong key, int fd, int n)
150 return estartfn(key, fd, n, nil);
154 etimer(ulong key, int n)
157 drawerror(display, "events: timer started twice");
158 Stimer = newkey(key);
161 eslave[Stimer].n = n;
162 eslave[Stimer].nexttick = nsec()+n*1000000LL;
170 for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
172 eslave[Skeyboard].inuse = 1;
173 if(nslave <= Skeyboard)
174 nslave = Skeyboard+1;
177 for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
179 eslave[Smouse].inuse = 1;
186 newebuf(Slave *s, int n)
190 eb = malloc(sizeof(*eb) - sizeof(eb->u.buf) + n);
192 drawerror(display, "events: out of memory");
196 s->tail = s->tail->next = eb;
198 s->head = s->tail = eb;
209 convW2M(&w, buf, sizeof buf);
210 return muxrpcstart(display->mux, buf);
214 finishrpc(Muxrpc *r, Wsysmsg *w)
220 if(!muxrpccanfinish(r, &v))
223 if(p == nil) /* eof on connection */
232 extract(int canblock)
236 fd_set rset, wset, xset;
237 struct timeval tv, *timeout;
242 * Flush draw buffer before waiting for responses.
243 * Avoid doing so if buffer is empty.
244 * Also make sure that we don't interfere with app-specific locking.
246 if(display->locking){
248 * if locking is being done by program,
249 * this means it can't depend on automatic
250 * flush in emouse() etc.
252 if(canqlock(&display->qlock)){
253 if(display->bufp > display->buf)
254 flushimage(display, 1);
255 unlockdisplay(display);
258 if(display->bufp > display->buf)
259 flushimage(display, 1);
269 for(i=0; i<nslave; i++){
273 if(eslave[i].rpc == nil)
274 eslave[i].rpc = startrpc(Trdmouse);
276 /* if ready, don't block in select */
279 FD_SET(display->srvfd, &rset);
280 FD_SET(display->srvfd, &xset);
281 if(display->srvfd > max)
282 max = display->srvfd;
284 }else if(i == Skeyboard){
285 if(eslave[i].rpc == nil)
286 eslave[i].rpc = startrpc(Trdkbd);
288 /* if ready, don't block in select */
291 FD_SET(display->srvfd, &rset);
292 FD_SET(display->srvfd, &xset);
293 if(display->srvfd > max)
294 max = display->srvfd;
296 }else if(i == Stimer){
298 if(t0 >= eslave[i].nexttick){
302 tv.tv_sec = (eslave[i].nexttick-t0)/1000000000;
303 tv.tv_usec = (eslave[i].nexttick-t0)%1000000000 / 1000;
307 FD_SET(eslave[i].fd, &rset);
308 FD_SET(eslave[i].fd, &xset);
309 if(eslave[i].fd > max)
320 if(select(max+1, &rset, &wset, &xset, timeout) < 0)
321 drawerror(display, "select failure");
324 * Look to see what can proceed.
327 for(i=0; i<nslave; i++){
331 if(finishrpc(eslave[i].rpc, &w)){
333 eb = newebuf(&eslave[i], sizeof(Mouse));
334 eb->u.mouse = w.mouse;
339 }else if(i == Skeyboard){
340 if(finishrpc(eslave[i].rpc, &w)){
342 eb = newebuf(&eslave[i], sizeof(Rune)+2); /* +8: alignment */
346 }else if(i == Stimer){
348 while(t0 > eslave[i].nexttick){
349 eslave[i].nexttick += eslave[i].n*1000000LL;
350 eslave[i].head = (Ebuf*)1;
354 if(FD_ISSET(eslave[i].fd, &rset)){
355 eb = newebuf(&eslave[i], eslave[i].n);
356 eb->n = read(eslave[i].fd, eb->u.buf, eslave[i].n);
369 for(i=0; i<MAXSLAVE; i++)
370 if((key & ~(1<<i)) == 0 && eslave[i].inuse == 0){
376 drawerror(display, "events: bad slave assignment");
387 drawerror(display, "events: mouse not initialized");
388 eb = ebread(&eslave[Smouse]);
401 drawerror(display, "events: keyboard not initialzed");
402 eb = ebread(&eslave[Skeyboard]);
411 _displaymoveto(display, pt);
415 esetcursor(Cursor *c)
417 _displaycursor(display, c);
426 if(_displayrdmouse(display, m, &resized) < 0)