|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <draw.h> | 
|  | #include <thread.h> | 
|  | #include <cursor.h> | 
|  | #include <mouse.h> | 
|  |  | 
|  | void | 
|  | moveto(Mousectl *mc, Point pt) | 
|  | { | 
|  | _displaymoveto(mc->display, pt); | 
|  | mc->m.xy = pt; | 
|  | } | 
|  |  | 
|  | void | 
|  | closemouse(Mousectl *mc) | 
|  | { | 
|  | if(mc == nil) | 
|  | return; | 
|  |  | 
|  | /*	postnote(PNPROC, mc->pid, "kill"); */ | 
|  |  | 
|  | do; while(nbrecv(mc->c, &mc->m) > 0); | 
|  | chanfree(mc->c); | 
|  | chanfree(mc->resizec); | 
|  | free(mc); | 
|  | } | 
|  |  | 
|  | int | 
|  | readmouse(Mousectl *mc) | 
|  | { | 
|  | if(mc->display) | 
|  | flushimage(mc->display, 1); | 
|  | if(recv(mc->c, &mc->m) < 0){ | 
|  | fprint(2, "readmouse: %r\n"); | 
|  | return -1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static | 
|  | void | 
|  | _ioproc(void *arg) | 
|  | { | 
|  | int one, resized; | 
|  | Mouse m; | 
|  | Mousectl *mc; | 
|  |  | 
|  | mc = arg; | 
|  | threadsetname("mouseproc"); | 
|  | memset(&m, 0, sizeof m); | 
|  | one = 1; | 
|  | resized = 0; | 
|  | for(;;){ | 
|  | if(_displayrdmouse(mc->display, &m, &resized) < 0) | 
|  | threadexitsall("mouse read error"); | 
|  | if(resized) | 
|  | send(mc->resizec, &one); | 
|  | send(mc->c, &m); | 
|  | /* | 
|  | * mc->m is updated after send so it doesn't have wrong value if we block during send. | 
|  | * This means that programs should receive into mc->Mouse (see readmouse() above) if | 
|  | * they want full synchrony. | 
|  | */ | 
|  | mc->m = m; | 
|  | } | 
|  | } | 
|  |  | 
|  | Mousectl* | 
|  | initmouse(char *file, Image *i) | 
|  | { | 
|  | Mousectl *mc; | 
|  |  | 
|  | mc = mallocz(sizeof(Mousectl), 1); | 
|  | if(i) | 
|  | mc->display = i->display; | 
|  | mc->c = chancreate(sizeof(Mouse), 0); | 
|  | chansetname(mc->c, "mousec"); | 
|  | mc->resizec = chancreate(sizeof(int), 2); | 
|  | chansetname(mc->resizec, "resizec"); | 
|  | proccreate(_ioproc, mc, 32*1024); | 
|  | return mc; | 
|  | } | 
|  |  | 
|  | void | 
|  | setcursor(Mousectl *mc, Cursor *c) | 
|  | { | 
|  | _displaycursor(mc->display, c); | 
|  | } | 
|  |  |