Blame


1 76193d7c 2003-09-30 devnull #include <u.h>
2 be22ae2d 2004-03-26 devnull #include "x11-inc.h"
3 76193d7c 2003-09-30 devnull #include <libc.h>
4 76193d7c 2003-09-30 devnull #include <draw.h>
5 76193d7c 2003-09-30 devnull #include <thread.h>
6 76193d7c 2003-09-30 devnull #include <cursor.h>
7 76193d7c 2003-09-30 devnull #include <mouse.h>
8 76193d7c 2003-09-30 devnull #include <memdraw.h>
9 76193d7c 2003-09-30 devnull #include "x11-memdraw.h"
10 76193d7c 2003-09-30 devnull
11 4f30f3b4 2004-03-30 devnull int _windowhasfocus = 1;
12 4f30f3b4 2004-03-30 devnull int _wantfocuschanges;
13 4f30f3b4 2004-03-30 devnull
14 76193d7c 2003-09-30 devnull void
15 76193d7c 2003-09-30 devnull moveto(Mousectl *m, Point pt)
16 76193d7c 2003-09-30 devnull {
17 32f69c36 2003-12-11 devnull _xmoveto(pt);
18 76193d7c 2003-09-30 devnull }
19 76193d7c 2003-09-30 devnull
20 76193d7c 2003-09-30 devnull void
21 76193d7c 2003-09-30 devnull closemouse(Mousectl *mc)
22 76193d7c 2003-09-30 devnull {
23 76193d7c 2003-09-30 devnull if(mc == nil)
24 76193d7c 2003-09-30 devnull return;
25 76193d7c 2003-09-30 devnull
26 76193d7c 2003-09-30 devnull /* postnote(PNPROC, mc->pid, "kill");
27 76193d7c 2003-09-30 devnull */
28 76193d7c 2003-09-30 devnull do; while(nbrecv(mc->c, &mc->m) > 0);
29 76193d7c 2003-09-30 devnull close(mc->mfd);
30 76193d7c 2003-09-30 devnull close(mc->cfd);
31 76193d7c 2003-09-30 devnull free(mc->file);
32 76193d7c 2003-09-30 devnull chanfree(mc->c);
33 76193d7c 2003-09-30 devnull chanfree(mc->resizec);
34 76193d7c 2003-09-30 devnull free(mc);
35 76193d7c 2003-09-30 devnull }
36 76193d7c 2003-09-30 devnull
37 76193d7c 2003-09-30 devnull int
38 76193d7c 2003-09-30 devnull readmouse(Mousectl *mc)
39 76193d7c 2003-09-30 devnull {
40 76193d7c 2003-09-30 devnull if(mc->display)
41 76193d7c 2003-09-30 devnull flushimage(mc->display, 1);
42 76193d7c 2003-09-30 devnull if(recv(mc->c, &mc->m) < 0){
43 76193d7c 2003-09-30 devnull fprint(2, "readmouse: %r\n");
44 76193d7c 2003-09-30 devnull return -1;
45 76193d7c 2003-09-30 devnull }
46 76193d7c 2003-09-30 devnull return 0;
47 76193d7c 2003-09-30 devnull }
48 76193d7c 2003-09-30 devnull
49 dd4afdf4 2005-02-08 devnull /*
50 dd4afdf4 2005-02-08 devnull * This is necessary because some X libraries (e.g., on FC3)
51 dd4afdf4 2005-02-08 devnull * use an inordinate amount of stack space to do _xsetcursor.
52 dd4afdf4 2005-02-08 devnull * Perhaps instead there should be a generic "run this X routine"
53 dd4afdf4 2005-02-08 devnull * stack that you send a function and argument to.
54 dd4afdf4 2005-02-08 devnull */
55 76193d7c 2003-09-30 devnull static
56 76193d7c 2003-09-30 devnull void
57 dd4afdf4 2005-02-08 devnull _cursorproc(void *arg)
58 dd4afdf4 2005-02-08 devnull {
59 dd4afdf4 2005-02-08 devnull Mousectl *mc;
60 dd4afdf4 2005-02-08 devnull Cursor *c;
61 dd4afdf4 2005-02-08 devnull
62 dd4afdf4 2005-02-08 devnull mc = arg;
63 dd4afdf4 2005-02-08 devnull threadsetname("cursorproc (sigh)");
64 dd4afdf4 2005-02-08 devnull for(;;){
65 dd4afdf4 2005-02-08 devnull c = recvp(mc->ccursor);
66 dd4afdf4 2005-02-08 devnull _xsetcursor(c);
67 dd4afdf4 2005-02-08 devnull sendp(mc->ccursorwait, nil);
68 dd4afdf4 2005-02-08 devnull }
69 dd4afdf4 2005-02-08 devnull }
70 dd4afdf4 2005-02-08 devnull
71 dd4afdf4 2005-02-08 devnull static
72 dd4afdf4 2005-02-08 devnull void
73 76193d7c 2003-09-30 devnull _ioproc(void *arg)
74 76193d7c 2003-09-30 devnull {
75 b20f06ab 2004-12-26 devnull int fd, one, buttons;
76 4f30f3b4 2004-03-30 devnull Atom a;
77 161060a4 2003-10-11 devnull ulong mask;
78 76193d7c 2003-09-30 devnull Mouse m;
79 76193d7c 2003-09-30 devnull Mousectl *mc;
80 76193d7c 2003-09-30 devnull XEvent xevent;
81 76193d7c 2003-09-30 devnull
82 76193d7c 2003-09-30 devnull one = 1;
83 76193d7c 2003-09-30 devnull mc = arg;
84 76193d7c 2003-09-30 devnull threadsetname("mouseproc");
85 76193d7c 2003-09-30 devnull memset(&m, 0, sizeof m);
86 76193d7c 2003-09-30 devnull mc->pid = getpid();
87 161060a4 2003-10-11 devnull mask = MouseMask|ExposureMask|StructureNotifyMask;
88 161060a4 2003-10-11 devnull XSelectInput(_x.mousecon, _x.drawable, mask);
89 5a8e63b2 2004-02-29 devnull fd = XConnectionNumber(_x.mousecon);
90 b20f06ab 2004-12-26 devnull buttons = 0;
91 76193d7c 2003-09-30 devnull for(;;){
92 161060a4 2003-10-11 devnull XNextEvent(_x.mousecon, &xevent);
93 76193d7c 2003-09-30 devnull switch(xevent.type){
94 76193d7c 2003-09-30 devnull case Expose:
95 32f69c36 2003-12-11 devnull _xexpose(&xevent, _x.mousecon);
96 76193d7c 2003-09-30 devnull continue;
97 16a70966 2003-11-23 devnull case DestroyNotify:
98 32f69c36 2003-12-11 devnull if(_xdestroy(&xevent, _x.mousecon)){
99 16a70966 2003-11-23 devnull /* drain it before sending */
100 16a70966 2003-11-23 devnull /* apps that care can notice we sent a 0 */
101 16a70966 2003-11-23 devnull /* otherwise we'll have getwindow send SIGHUP */
102 16a70966 2003-11-23 devnull nbrecv(mc->resizec, 0);
103 16a70966 2003-11-23 devnull nbrecv(mc->resizec, 0);
104 16a70966 2003-11-23 devnull send(mc->resizec, 0);
105 16a70966 2003-11-23 devnull }
106 16a70966 2003-11-23 devnull continue;
107 76193d7c 2003-09-30 devnull case ConfigureNotify:
108 32f69c36 2003-12-11 devnull if(_xconfigure(&xevent, _x.mousecon))
109 76193d7c 2003-09-30 devnull nbsend(mc->resizec, &one);
110 76193d7c 2003-09-30 devnull continue;
111 161060a4 2003-10-11 devnull case SelectionRequest:
112 32f69c36 2003-12-11 devnull _xselect(&xevent, _x.mousecon);
113 161060a4 2003-10-11 devnull continue;
114 76193d7c 2003-09-30 devnull case ButtonPress:
115 76193d7c 2003-09-30 devnull case ButtonRelease:
116 76193d7c 2003-09-30 devnull case MotionNotify:
117 732be70c 2004-03-31 devnull /* If the motion notifications are backing up, skip over some. */
118 b20f06ab 2004-12-26 devnull if(0 && xevent.type == MotionNotify){
119 732be70c 2004-03-31 devnull while(XCheckWindowEvent(_x.mousecon, _x.drawable, MouseMask, &xevent)){
120 732be70c 2004-03-31 devnull if(xevent.type != MotionNotify)
121 732be70c 2004-03-31 devnull break;
122 732be70c 2004-03-31 devnull }
123 732be70c 2004-03-31 devnull }
124 b20f06ab 2004-12-26 devnull m.buttons = buttons;
125 32f69c36 2003-12-11 devnull if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0)
126 76193d7c 2003-09-30 devnull continue;
127 b20f06ab 2004-12-26 devnull buttons = m.buttons;
128 76193d7c 2003-09-30 devnull send(mc->c, &m);
129 76193d7c 2003-09-30 devnull /*
130 76193d7c 2003-09-30 devnull * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
131 76193d7c 2003-09-30 devnull * This means that programs should receive into mc->Mouse (see readmouse() above) if
132 76193d7c 2003-09-30 devnull * they want full synchrony.
133 76193d7c 2003-09-30 devnull */
134 76193d7c 2003-09-30 devnull mc->m = m;
135 76193d7c 2003-09-30 devnull break;
136 4f30f3b4 2004-03-30 devnull case ClientMessage:
137 4f30f3b4 2004-03-30 devnull if(xevent.xclient.message_type == _x.wmprotos){
138 4f30f3b4 2004-03-30 devnull a = xevent.xclient.data.l[0];
139 4f30f3b4 2004-03-30 devnull if(_wantfocuschanges && a == _x.takefocus){
140 4f30f3b4 2004-03-30 devnull _windowhasfocus = 1;
141 4f30f3b4 2004-03-30 devnull _x.newscreenr = _x.screenr;
142 4f30f3b4 2004-03-30 devnull nbsend(mc->resizec, &one);
143 4f30f3b4 2004-03-30 devnull }else if(_wantfocuschanges && a == _x.losefocus){
144 4f30f3b4 2004-03-30 devnull _windowhasfocus = 0;
145 4f30f3b4 2004-03-30 devnull _x.newscreenr = _x.screenr;
146 4f30f3b4 2004-03-30 devnull nbsend(mc->resizec, &one);
147 4f30f3b4 2004-03-30 devnull }
148 4f30f3b4 2004-03-30 devnull }
149 4f30f3b4 2004-03-30 devnull break;
150 76193d7c 2003-09-30 devnull }
151 76193d7c 2003-09-30 devnull }
152 76193d7c 2003-09-30 devnull }
153 76193d7c 2003-09-30 devnull
154 76193d7c 2003-09-30 devnull Mousectl*
155 76193d7c 2003-09-30 devnull initmouse(char *file, Image *i)
156 76193d7c 2003-09-30 devnull {
157 76193d7c 2003-09-30 devnull Mousectl *mc;
158 76193d7c 2003-09-30 devnull
159 76193d7c 2003-09-30 devnull mc = mallocz(sizeof(Mousectl), 1);
160 76193d7c 2003-09-30 devnull if(i)
161 76193d7c 2003-09-30 devnull mc->display = i->display;
162 76193d7c 2003-09-30 devnull mc->c = chancreate(sizeof(Mouse), 0);
163 b20f06ab 2004-12-26 devnull chansetname(mc->c, "mousec");
164 76193d7c 2003-09-30 devnull mc->resizec = chancreate(sizeof(int), 2);
165 b20f06ab 2004-12-26 devnull chansetname(mc->resizec, "resizec");
166 dd4afdf4 2005-02-08 devnull mc->ccursor = chancreate(sizeof(void*), 0);
167 dd4afdf4 2005-02-08 devnull chansetname(mc->ccursor, "ccursor");
168 dd4afdf4 2005-02-08 devnull mc->ccursorwait = chancreate(sizeof(void*), 0);
169 dd4afdf4 2005-02-08 devnull chansetname(mc->ccursor, "ccursorwait");
170 a0e8d02d 2005-01-23 devnull proccreate(_ioproc, mc, 256*1024);
171 dd4afdf4 2005-02-08 devnull proccreate(_cursorproc, mc, 256*1024); /* sigh */
172 76193d7c 2003-09-30 devnull return mc;
173 76193d7c 2003-09-30 devnull }
174 76193d7c 2003-09-30 devnull
175 76193d7c 2003-09-30 devnull void
176 76193d7c 2003-09-30 devnull setcursor(Mousectl *mc, Cursor *c)
177 76193d7c 2003-09-30 devnull {
178 dd4afdf4 2005-02-08 devnull qlock(&mc->cursorlock);
179 dd4afdf4 2005-02-08 devnull sendp(mc->ccursor, c);
180 dd4afdf4 2005-02-08 devnull recvp(mc->ccursorwait);
181 dd4afdf4 2005-02-08 devnull qunlock(&mc->cursorlock);
182 76193d7c 2003-09-30 devnull }
183 76193d7c 2003-09-30 devnull
184 78802e69 2004-04-24 devnull /*
185 78802e69 2004-04-24 devnull * Send the mouse event back to the window manager.
186 78802e69 2004-04-24 devnull * So that 9term can tell rio to pop up its button3 menu.
187 78802e69 2004-04-24 devnull * Note that we're using _x.mousecon in a few places,
188 78802e69 2004-04-24 devnull * so we have to be sure that the mouse proc isn't using it
189 78802e69 2004-04-24 devnull * when we call! This is all a bit wonky and should be
190 78802e69 2004-04-24 devnull * avoided unless you know what you're doing.
191 78802e69 2004-04-24 devnull */
192 4f30f3b4 2004-03-30 devnull void
193 4f30f3b4 2004-03-30 devnull bouncemouse(Mouse *m)
194 4f30f3b4 2004-03-30 devnull {
195 4f30f3b4 2004-03-30 devnull XButtonEvent e;
196 78802e69 2004-04-24 devnull XWindow dw;
197 4f30f3b4 2004-03-30 devnull
198 4f30f3b4 2004-03-30 devnull e.type = ButtonPress;
199 4f30f3b4 2004-03-30 devnull e.state = 0;
200 4f30f3b4 2004-03-30 devnull e.button = 0;
201 4f30f3b4 2004-03-30 devnull if(m->buttons&1)
202 4f30f3b4 2004-03-30 devnull e.button = 1;
203 4f30f3b4 2004-03-30 devnull else if(m->buttons&2)
204 4f30f3b4 2004-03-30 devnull e.button = 2;
205 4f30f3b4 2004-03-30 devnull else if(m->buttons&4)
206 4f30f3b4 2004-03-30 devnull e.button = 3;
207 78802e69 2004-04-24 devnull e.same_screen = 1;
208 78802e69 2004-04-24 devnull XTranslateCoordinates(_x.display, _x.drawable,
209 78802e69 2004-04-24 devnull DefaultRootWindow(_x.display),
210 78802e69 2004-04-24 devnull m->xy.x, m->xy.y, &e.x_root, &e.y_root, &dw);
211 78802e69 2004-04-24 devnull e.root = DefaultRootWindow(_x.mousecon);
212 78802e69 2004-04-24 devnull e.window = e.root;
213 78802e69 2004-04-24 devnull e.subwindow = None;
214 78802e69 2004-04-24 devnull e.x = e.x_root;
215 78802e69 2004-04-24 devnull e.y = e.y_root;
216 4f30f3b4 2004-03-30 devnull #undef time
217 4f30f3b4 2004-03-30 devnull e.time = CurrentTime;
218 78802e69 2004-04-24 devnull XUngrabPointer(_x.mousecon, m->msec);
219 78802e69 2004-04-24 devnull XSendEvent(_x.mousecon, e.root, True, ButtonPressMask, (XEvent*)&e);
220 78802e69 2004-04-24 devnull XFlush(_x.mousecon);
221 4f30f3b4 2004-03-30 devnull }