]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libdraw/mouse.c
mothra: fix alt display resizing, filter control characters in panel entries, use...
[plan9front.git] / sys / src / libdraw / mouse.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <cursor.h>
6 #include <mouse.h>
7
8 void
9 moveto(Mousectl *m, Point pt)
10 {
11         fprint(m->mfd, "m%d %d", pt.x, pt.y);
12         m->xy = pt;
13 }
14
15 void
16 closemouse(Mousectl *mc)
17 {
18         if(mc == nil)
19                 return;
20         close(mc->mfd);
21         close(mc->cfd);
22         mc->mfd = mc->cfd = -1;
23         threadint(mc->pid);
24 }
25
26 int
27 readmouse(Mousectl *mc)
28 {
29         if(mc->image)
30                 flushimage(mc->image->display, 1);
31         if(recv(mc->c, &mc->Mouse) < 0){
32                 fprint(2, "readmouse: %r\n");
33                 return -1;
34         }
35         return 0;
36 }
37
38 static
39 void
40 _ioproc(void *arg)
41 {
42         int n, one;
43         char buf[1+5*12];
44         Mouse m;
45         Mousectl *mc;
46
47         mc = arg;
48         threadsetname("mouseproc");
49         one = 1;
50         memset(&m, 0, sizeof m);
51 loop:
52         while(mc->mfd >= 0){
53                 n = read(mc->mfd, buf, sizeof buf);
54                 if(n != 1+4*12)
55                         goto loop;
56                 switch(buf[0]){
57                 case 'r':
58                         if(send(mc->resizec, &one) < 0)
59                                 goto loop;
60                         /* fall through */
61                 case 'm':
62                         m.xy.x = atoi(buf+1+0*12);
63                         m.xy.y = atoi(buf+1+1*12);
64                         m.buttons = atoi(buf+1+2*12);
65                         m.msec = atoi(buf+1+3*12);
66                         if(send(mc->c, &m) < 0)
67                                 goto loop;
68                         /*
69                          * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
70                          * This means that programs should receive into mc->Mouse (see readmouse() above) if
71                          * they want full synchrony.
72                          */
73                         mc->Mouse = m;
74                         break;
75                 }
76         }
77         free(mc->file);
78         chanfree(mc->c);
79         chanfree(mc->resizec);
80         free(mc);
81 }
82
83 Mousectl*
84 initmouse(char *file, Image *i)
85 {
86         Mousectl *mc;
87         char *t, *sl;
88
89         mc = mallocz(sizeof(Mousectl), 1);
90         if(file == nil)
91                 file = "/dev/mouse";
92         mc->file = strdup(file);
93         mc->mfd = open(file, ORDWR|OCEXEC);
94         if(mc->mfd<0 && strcmp(file, "/dev/mouse")==0){
95                 bind("#m", "/dev", MAFTER);
96                 mc->mfd = open(file, ORDWR|OCEXEC);
97         }
98         if(mc->mfd < 0){
99                 free(mc);
100                 return nil;
101         }
102         t = malloc(strlen(file)+16);
103         if (t == nil) {
104                 close(mc->mfd);
105                 free(mc);
106                 return nil;
107         }
108         strcpy(t, file);
109         sl = utfrrune(t, '/');
110         if(sl)
111                 strcpy(sl, "/cursor");
112         else
113                 strcpy(t, "/dev/cursor");
114         mc->cfd = open(t, ORDWR|OCEXEC);
115         free(t);
116         mc->image = i;
117         mc->c = chancreate(sizeof(Mouse), 0);
118         mc->resizec = chancreate(sizeof(int), 2);
119         mc->pid = proccreate(_ioproc, mc, 4096);
120         return mc;
121 }
122
123 void
124 setcursor(Mousectl *mc, Cursor *c)
125 {
126         char curs[2*4+2*2*16];
127
128         if(c == nil)
129                 write(mc->cfd, curs, 0);
130         else{
131                 BPLONG(curs+0*4, c->offset.x);
132                 BPLONG(curs+1*4, c->offset.y);
133                 memmove(curs+2*4, c->clr, 2*2*16);
134                 write(mc->cfd, curs, sizeof curs);
135         }
136 }