Blob


1 #include "x11-inc.h"
2 #include <u.h>
3 #include <libc.h>
4 #include <draw.h>
5 #include <thread.h>
6 #include <cursor.h>
7 #include <mouse.h>
8 #include <memdraw.h>
9 #include "x11-memdraw.h"
11 void
12 moveto(Mousectl *m, Point pt)
13 {
14 _xmoveto(pt);
15 }
17 void
18 closemouse(Mousectl *mc)
19 {
20 if(mc == nil)
21 return;
23 /* postnote(PNPROC, mc->pid, "kill");
24 */
25 do; while(nbrecv(mc->c, &mc->m) > 0);
26 close(mc->mfd);
27 close(mc->cfd);
28 free(mc->file);
29 chanfree(mc->c);
30 chanfree(mc->resizec);
31 free(mc);
32 }
34 int
35 readmouse(Mousectl *mc)
36 {
37 if(mc->display)
38 flushimage(mc->display, 1);
39 if(recv(mc->c, &mc->m) < 0){
40 fprint(2, "readmouse: %r\n");
41 return -1;
42 }
43 return 0;
44 }
46 static
47 void
48 _ioproc(void *arg)
49 {
50 int fd, one;
51 ulong mask;
52 Mouse m;
53 Mousectl *mc;
54 XEvent xevent;
56 one = 1;
57 mc = arg;
58 threadsetname("mouseproc");
59 memset(&m, 0, sizeof m);
60 mc->pid = getpid();
61 mask = MouseMask|ExposureMask|StructureNotifyMask;
62 XSelectInput(_x.mousecon, _x.drawable, mask);
63 fd = XConnectionNumber(_x.mousecon);
64 for(;;){
65 while(XPending(_x.mousecon) == False)
66 threadfdwait(fd, 'r');
67 XNextEvent(_x.mousecon, &xevent);
68 switch(xevent.type){
69 case Expose:
70 _xexpose(&xevent, _x.mousecon);
71 continue;
72 case DestroyNotify:
73 if(_xdestroy(&xevent, _x.mousecon)){
74 /* drain it before sending */
75 /* apps that care can notice we sent a 0 */
76 /* otherwise we'll have getwindow send SIGHUP */
77 nbrecv(mc->resizec, 0);
78 nbrecv(mc->resizec, 0);
79 send(mc->resizec, 0);
80 }
81 continue;
82 case ConfigureNotify:
83 if(_xconfigure(&xevent, _x.mousecon))
84 nbsend(mc->resizec, &one);
85 continue;
86 case SelectionRequest:
87 _xselect(&xevent, _x.mousecon);
88 continue;
89 case ButtonPress:
90 case ButtonRelease:
91 case MotionNotify:
92 if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0)
93 continue;
94 send(mc->c, &m);
95 /*
96 * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
97 * This means that programs should receive into mc->Mouse (see readmouse() above) if
98 * they want full synchrony.
99 */
100 mc->m = m;
101 break;
106 Mousectl*
107 initmouse(char *file, Image *i)
109 Mousectl *mc;
111 threadfdwaitsetup();
112 mc = mallocz(sizeof(Mousectl), 1);
113 if(i)
114 mc->display = i->display;
115 mc->c = chancreate(sizeof(Mouse), 0);
116 mc->resizec = chancreate(sizeof(int), 2);
117 threadcreate(_ioproc, mc, 16384);
118 return mc;
121 void
122 setcursor(Mousectl *mc, Cursor *c)
124 _xsetcursor(c);