2 #include <sys/select.h>
10 typedef struct Slave Slave;
11 typedef struct Ebuf Ebuf;
12 extern Mouse _drawmouse;
17 Ebuf *head; /* queue of messages for this descriptor */
19 int (*fn)(int, Event*, uchar*, int);
29 int n; /* number of bytes in buf */
37 static Slave eslave[MAXSLAVE];
38 static int Skeyboard = -1;
39 static int Smouse = -1;
40 static int Stimer = -1;
43 static int newkey(ulong);
44 static int extract(int canblock);
55 s->head = s->head->next;
64 return eread(~0UL, e);
68 eread(ulong keys, Event *e)
76 for(i=0; i<nslave; i++)
77 if((keys & (1<<i)) && eslave[i].head){
81 else if(i == Skeyboard)
86 eb = ebread(&eslave[i]);
89 id = (*eslave[i].fn)(id, e, eb->u.buf, eb->n);
91 memmove(e->data, eb->u.buf, eb->n);
105 drawerror(display, "events: mouse not initialized");
106 return ecanread(Emouse);
113 drawerror(display, "events: keyboard not initialzed");
114 return ecanread(Ekeyboard);
123 for(i=0; i<nslave; i++)
124 if((keys & (1<<i)) && eslave[i].head)
133 estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
138 drawerror(display, "events: bad file descriptor");
139 if(n <= 0 || n > EMAXMSG)
149 estart(ulong key, int fd, int n)
151 return estartfn(key, fd, n, nil);
155 etimer(ulong key, int n)
158 drawerror(display, "events: timer started twice");
159 Stimer = newkey(key);
162 eslave[Stimer].n = n;
163 eslave[Stimer].nexttick = nsec()+n*1000000LL;
171 for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
173 eslave[Skeyboard].inuse = 1;
174 if(nslave <= Skeyboard)
175 nslave = Skeyboard+1;
178 for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
180 eslave[Smouse].inuse = 1;
187 newebuf(Slave *s, int n)
191 eb = malloc(sizeof(*eb) - sizeof(eb->u.buf) + n);
193 drawerror(display, "events: out of memory");
197 s->tail = s->tail->next = eb;
199 s->head = s->tail = eb;
210 if(convW2M(&w, buf, sizeof buf) == 0)
212 return muxrpcstart(display->mux, buf);
216 finishrpc(Muxrpc *r, Wsysmsg *w)
222 if(!muxrpccanfinish(r, &v))
225 if(p == nil) /* eof on connection */
234 extract(int canblock)
238 fd_set rset, wset, xset;
239 struct timeval tv, *timeout;
244 * Flush draw buffer before waiting for responses.
245 * Avoid doing so if buffer is empty.
246 * Also make sure that we don't interfere with app-specific locking.
248 if(display->locking){
250 * if locking is being done by program,
251 * this means it can't depend on automatic
252 * flush in emouse() etc.
254 if(canqlock(&display->qlock)){
255 if(display->bufp > display->buf)
256 flushimage(display, 1);
257 unlockdisplay(display);
260 if(display->bufp > display->buf)
261 flushimage(display, 1);
271 for(i=0; i<nslave; i++){
275 if(eslave[i].rpc == nil)
276 eslave[i].rpc = startrpc(Trdmouse);
278 /* if ready, don't block in select */
281 FD_SET(display->srvfd, &rset);
282 FD_SET(display->srvfd, &xset);
283 if(display->srvfd > max)
284 max = display->srvfd;
286 }else if(i == Skeyboard){
287 if(eslave[i].rpc == nil)
288 eslave[i].rpc = startrpc(Trdkbd4);
290 /* if ready, don't block in select */
293 FD_SET(display->srvfd, &rset);
294 FD_SET(display->srvfd, &xset);
295 if(display->srvfd > max)
296 max = display->srvfd;
298 }else if(i == Stimer){
300 if(t0 >= eslave[i].nexttick){
304 tv.tv_sec = (eslave[i].nexttick-t0)/1000000000;
305 tv.tv_usec = (eslave[i].nexttick-t0)%1000000000 / 1000;
309 FD_SET(eslave[i].fd, &rset);
310 FD_SET(eslave[i].fd, &xset);
311 if(eslave[i].fd > max)
322 if(select(max+1, &rset, &wset, &xset, timeout) < 0)
323 drawerror(display, "select failure");
326 * Look to see what can proceed.
329 for(i=0; i<nslave; i++){
333 if(finishrpc(eslave[i].rpc, &w)){
335 eb = newebuf(&eslave[i], sizeof(Mouse));
336 _drawmouse = w.mouse;
337 eb->u.mouse = w.mouse;
342 }else if(i == Skeyboard){
343 if(finishrpc(eslave[i].rpc, &w)){
345 eb = newebuf(&eslave[i], sizeof(Rune)+2); /* +8: alignment */
349 }else if(i == Stimer){
351 while(t0 > eslave[i].nexttick){
352 eslave[i].nexttick += eslave[i].n*1000000LL;
353 eslave[i].head = (Ebuf*)1;
357 if(FD_ISSET(eslave[i].fd, &rset)){
358 eb = newebuf(&eslave[i], eslave[i].n);
359 eb->n = read(eslave[i].fd, eb->u.buf, eslave[i].n);
372 for(i=0; i<MAXSLAVE; i++)
373 if((key & ~(1<<i)) == 0 && eslave[i].inuse == 0){
379 drawerror(display, "events: bad slave assignment");
390 drawerror(display, "events: mouse not initialized");
391 eb = ebread(&eslave[Smouse]);
404 drawerror(display, "events: keyboard not initialzed");
405 eb = ebread(&eslave[Skeyboard]);
414 _displaymoveto(display, pt);
418 esetcursor(Cursor *c)
420 _displaycursor(display, c, nil);
424 esetcursor2(Cursor *c, Cursor2 *c2)
426 _displaycursor(display, c, c2);
435 if(_displayrdmouse(display, m, &resized) < 0)