9 #include "x11-memdraw.h"
11 int _windowhasfocus = 1;
12 int _wantfocuschanges;
15 moveto(Mousectl *m, Point pt)
21 closemouse(Mousectl *mc)
26 /* postnote(PNPROC, mc->pid, "kill");
28 do; while(nbrecv(mc->c, &mc->m) > 0);
33 chanfree(mc->resizec);
38 readmouse(Mousectl *mc)
41 flushimage(mc->display, 1);
42 if(recv(mc->c, &mc->m) < 0){
43 fprint(2, "readmouse: %r\n");
62 threadsetname("mouseproc");
63 memset(&m, 0, sizeof m);
65 mask = MouseMask|ExposureMask|StructureNotifyMask;
66 XSelectInput(_x.mousecon, _x.drawable, mask);
67 fd = XConnectionNumber(_x.mousecon);
69 while(XPending(_x.mousecon) == False)
70 threadfdwait(fd, 'r');
71 XNextEvent(_x.mousecon, &xevent);
74 _xexpose(&xevent, _x.mousecon);
77 if(_xdestroy(&xevent, _x.mousecon)){
78 /* drain it before sending */
79 /* apps that care can notice we sent a 0 */
80 /* otherwise we'll have getwindow send SIGHUP */
81 nbrecv(mc->resizec, 0);
82 nbrecv(mc->resizec, 0);
87 if(_xconfigure(&xevent, _x.mousecon))
88 nbsend(mc->resizec, &one);
90 case SelectionRequest:
91 _xselect(&xevent, _x.mousecon);
96 /* If the motion notifications are backing up, skip over some. */
97 if(xevent.type == MotionNotify){
98 while(XCheckWindowEvent(_x.mousecon, _x.drawable, MouseMask, &xevent)){
99 if(xevent.type != MotionNotify)
103 if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0)
107 * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
108 * This means that programs should receive into mc->Mouse (see readmouse() above) if
109 * they want full synchrony.
114 if(xevent.xclient.message_type == _x.wmprotos){
115 a = xevent.xclient.data.l[0];
116 if(_wantfocuschanges && a == _x.takefocus){
118 _x.newscreenr = _x.screenr;
119 nbsend(mc->resizec, &one);
120 }else if(_wantfocuschanges && a == _x.losefocus){
122 _x.newscreenr = _x.screenr;
123 nbsend(mc->resizec, &one);
132 initmouse(char *file, Image *i)
137 mc = mallocz(sizeof(Mousectl), 1);
139 mc->display = i->display;
140 mc->c = chancreate(sizeof(Mouse), 0);
141 mc->resizec = chancreate(sizeof(int), 2);
142 threadcreate(_ioproc, mc, 32768);
147 setcursor(Mousectl *mc, Cursor *c)
153 * Send the mouse event back to the window manager.
154 * So that 9term can tell rio to pop up its button3 menu.
155 * Note that we're using _x.mousecon in a few places,
156 * so we have to be sure that the mouse proc isn't using it
157 * when we call! This is all a bit wonky and should be
158 * avoided unless you know what you're doing.
161 bouncemouse(Mouse *m)
166 e.type = ButtonPress;
171 else if(m->buttons&2)
173 else if(m->buttons&4)
176 XTranslateCoordinates(_x.display, _x.drawable,
177 DefaultRootWindow(_x.display),
178 m->xy.x, m->xy.y, &e.x_root, &e.y_root, &dw);
179 e.root = DefaultRootWindow(_x.mousecon);
185 e.time = CurrentTime;
186 XUngrabPointer(_x.mousecon, m->msec);
187 XSendEvent(_x.mousecon, e.root, True, ButtonPressMask, (XEvent*)&e);