17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier void
moveto(Mousectl * m,Point pt)97dd7cddfSDavid du Colombier moveto(Mousectl *m, Point pt)
107dd7cddfSDavid du Colombier {
119a747e4fSDavid du Colombier fprint(m->mfd, "m%d %d", pt.x, pt.y);
127dd7cddfSDavid du Colombier m->xy = pt;
137dd7cddfSDavid du Colombier }
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier void
closemouse(Mousectl * mc)167dd7cddfSDavid du Colombier closemouse(Mousectl *mc)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier if(mc == nil)
197dd7cddfSDavid du Colombier return;
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier postnote(PNPROC, mc->pid, "kill");
227dd7cddfSDavid du Colombier
239a747e4fSDavid du Colombier do; while(nbrecv(mc->c, &mc->Mouse) > 0);
247dd7cddfSDavid du Colombier
257dd7cddfSDavid du Colombier close(mc->mfd);
267dd7cddfSDavid du Colombier close(mc->cfd);
277dd7cddfSDavid du Colombier free(mc->file);
287dd7cddfSDavid du Colombier free(mc->c);
297dd7cddfSDavid du Colombier free(mc->resizec);
307dd7cddfSDavid du Colombier free(mc);
317dd7cddfSDavid du Colombier }
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier int
readmouse(Mousectl * mc)347dd7cddfSDavid du Colombier readmouse(Mousectl *mc)
357dd7cddfSDavid du Colombier {
367dd7cddfSDavid du Colombier if(mc->image)
377dd7cddfSDavid du Colombier flushimage(mc->image->display, 1);
387dd7cddfSDavid du Colombier if(recv(mc->c, &mc->Mouse) < 0){
399a747e4fSDavid du Colombier fprint(2, "readmouse: %r\n");
407dd7cddfSDavid du Colombier return -1;
417dd7cddfSDavid du Colombier }
427dd7cddfSDavid du Colombier return 0;
437dd7cddfSDavid du Colombier }
447dd7cddfSDavid du Colombier
457dd7cddfSDavid du Colombier static
467dd7cddfSDavid du Colombier void
_ioproc(void * arg)473ff48bf5SDavid du Colombier _ioproc(void *arg)
487dd7cddfSDavid du Colombier {
497dd7cddfSDavid du Colombier int n, nerr, one;
507dd7cddfSDavid du Colombier char buf[1+5*12];
517dd7cddfSDavid du Colombier Mouse m;
527dd7cddfSDavid du Colombier Mousectl *mc;
537dd7cddfSDavid du Colombier
547dd7cddfSDavid du Colombier mc = arg;
557dd7cddfSDavid du Colombier threadsetname("mouseproc");
567dd7cddfSDavid du Colombier one = 1;
577dd7cddfSDavid du Colombier memset(&m, 0, sizeof m);
587dd7cddfSDavid du Colombier mc->pid = getpid();
597dd7cddfSDavid du Colombier nerr = 0;
607dd7cddfSDavid du Colombier for(;;){
617dd7cddfSDavid du Colombier n = read(mc->mfd, buf, sizeof buf);
627dd7cddfSDavid du Colombier if(n != 1+4*12){
639a747e4fSDavid du Colombier yield(); /* if error is due to exiting, we'll exit here */
649a747e4fSDavid du Colombier fprint(2, "mouse: bad count %d not 49: %r\n", n);
657dd7cddfSDavid du Colombier if(n<0 || ++nerr>10)
667dd7cddfSDavid du Colombier threadexits("read error");
677dd7cddfSDavid du Colombier continue;
687dd7cddfSDavid du Colombier }
697dd7cddfSDavid du Colombier nerr = 0;
707dd7cddfSDavid du Colombier switch(buf[0]){
717dd7cddfSDavid du Colombier case 'r':
727dd7cddfSDavid du Colombier send(mc->resizec, &one);
737dd7cddfSDavid du Colombier /* fall through */
747dd7cddfSDavid du Colombier case 'm':
757dd7cddfSDavid du Colombier m.xy.x = atoi(buf+1+0*12);
767dd7cddfSDavid du Colombier m.xy.y = atoi(buf+1+1*12);
777dd7cddfSDavid du Colombier m.buttons = atoi(buf+1+2*12);
787dd7cddfSDavid du Colombier m.msec = atoi(buf+1+3*12);
797dd7cddfSDavid du Colombier send(mc->c, &m);
807dd7cddfSDavid du Colombier /*
817dd7cddfSDavid du Colombier * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
827dd7cddfSDavid du Colombier * This means that programs should receive into mc->Mouse (see readmouse() above) if
837dd7cddfSDavid du Colombier * they want full synchrony.
847dd7cddfSDavid du Colombier */
857dd7cddfSDavid du Colombier mc->Mouse = m;
867dd7cddfSDavid du Colombier break;
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier }
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier Mousectl*
initmouse(char * file,Image * i)927dd7cddfSDavid du Colombier initmouse(char *file, Image *i)
937dd7cddfSDavid du Colombier {
947dd7cddfSDavid du Colombier Mousectl *mc;
957dd7cddfSDavid du Colombier char *t, *sl;
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier mc = mallocz(sizeof(Mousectl), 1);
987dd7cddfSDavid du Colombier if(file == nil)
997dd7cddfSDavid du Colombier file = "/dev/mouse";
1007dd7cddfSDavid du Colombier mc->file = strdup(file);
1017dd7cddfSDavid du Colombier mc->mfd = open(file, ORDWR|OCEXEC);
1027dd7cddfSDavid du Colombier if(mc->mfd<0 && strcmp(file, "/dev/mouse")==0){
1037dd7cddfSDavid du Colombier bind("#m", "/dev", MAFTER);
1047dd7cddfSDavid du Colombier mc->mfd = open(file, ORDWR|OCEXEC);
1057dd7cddfSDavid du Colombier }
1067dd7cddfSDavid du Colombier if(mc->mfd < 0){
1077dd7cddfSDavid du Colombier free(mc);
1087dd7cddfSDavid du Colombier return nil;
1097dd7cddfSDavid du Colombier }
1107dd7cddfSDavid du Colombier t = malloc(strlen(file)+16);
111*223a0358SDavid du Colombier if (t == nil) {
112*223a0358SDavid du Colombier close(mc->mfd);
113*223a0358SDavid du Colombier free(mc);
114*223a0358SDavid du Colombier return nil;
115*223a0358SDavid du Colombier }
1167dd7cddfSDavid du Colombier strcpy(t, file);
1177dd7cddfSDavid du Colombier sl = utfrrune(t, '/');
1187dd7cddfSDavid du Colombier if(sl)
1197dd7cddfSDavid du Colombier strcpy(sl, "/cursor");
1207dd7cddfSDavid du Colombier else
1217dd7cddfSDavid du Colombier strcpy(t, "/dev/cursor");
1227dd7cddfSDavid du Colombier mc->cfd = open(t, ORDWR|OCEXEC);
1237dd7cddfSDavid du Colombier free(t);
1247dd7cddfSDavid du Colombier mc->image = i;
1257dd7cddfSDavid du Colombier mc->c = chancreate(sizeof(Mouse), 0);
1267dd7cddfSDavid du Colombier mc->resizec = chancreate(sizeof(int), 2);
1273ff48bf5SDavid du Colombier proccreate(_ioproc, mc, 4096);
1287dd7cddfSDavid du Colombier return mc;
1297dd7cddfSDavid du Colombier }
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier void
setcursor(Mousectl * mc,Cursor * c)1327dd7cddfSDavid du Colombier setcursor(Mousectl *mc, Cursor *c)
1337dd7cddfSDavid du Colombier {
1347dd7cddfSDavid du Colombier char curs[2*4+2*2*16];
1357dd7cddfSDavid du Colombier
1367dd7cddfSDavid du Colombier if(c == nil)
1377dd7cddfSDavid du Colombier write(mc->cfd, curs, 0);
1387dd7cddfSDavid du Colombier else{
1397dd7cddfSDavid du Colombier BPLONG(curs+0*4, c->offset.x);
1407dd7cddfSDavid du Colombier BPLONG(curs+1*4, c->offset.y);
1417dd7cddfSDavid du Colombier memmove(curs+2*4, c->clr, 2*2*16);
1427dd7cddfSDavid du Colombier write(mc->cfd, curs, sizeof curs);
1437dd7cddfSDavid du Colombier }
1447dd7cddfSDavid du Colombier }
145